Wysyłka maila CURL MIME z SSL - Proszę o pomoc

0

Witam,
Próbuję napisać użyteczna klasę do wysyłania maili z MIME (HTML w treści) + załącznik , tak żeby przesyłać regularnie raporty wewnątrz firmy - poniżej kod. Używam libCurl. Ogólnie klasa działa i wysyła maile z załącznikami, html w treści itp, ale tylko w przypadku serwerów smtp bez ssl. W momencie gdy chcę użyć ssl biblioteka wyrzuca mi błędy z połączeniem i certyfikatem: "SSL peer certificate or SSH remote key was not ok" - Oczywiście znam angielski i rozumiem to zdanie:) Ale próbowałem już na wszystkie sposoby podmieniać certyfikat na nowszy , konwertować itp i nic to nie dało . . Jestem początkujący w tych sprawach i wydaje mi się, że albo do końca nie rozumiem tematyki szyfrowania TLS albo popełniam jakiś błąd z samym certyfikatem. Serdecznie proszę o pomoc. Gdzieś tam przewinął mi się temat OpenSSL nie wiem czy użycie tej biblioteki coś da i w ogóle jak to ugryźć...

#include <windows.h>
#include <cmath>
#include <time.h>
#include <iostream>
#include <string>
#include <fstream>
#include <conio.h>
#include <cstdlib>
#include <cstdio>
#include <sstream>
#include <windows.h>
#include <time.h>
#include <iostream>
#include <string>
#include <cmath>
#include <vector>
#include <algorithm>
#include <inttypes.h>


 #include "curl/curl.h"



using namespace std;




class MailMIME
{




public:

string LosujLitery(int ilosc)
{


srand( time( NULL ) );
    string wylosowane;

    for( int i = 0; i < ilosc; i++ )
    {
        string los;
        los =(( rand() %( 'z' - 'a' ) ) + 'a' );
        wylosowane = wylosowane + los;


    } //for

    //cout << "wylosowane litery to: " << wylosowane<<endl;

    return wylosowane;
}


string LosujCyfry(int ilosc)
{


srand( time( NULL ) );
    string wylosowane;
    ostringstream wylosowane_o;

    for( int i = 0; i < ilosc; i++ )
    {
        int los;
        los =(( rand() %( 9 - 0 ) ) + 0 );
        wylosowane_o<<los;


    } //for
    wylosowane=wylosowane_o.str();
    wylosowane_o.str("");
    //cout << "wylosowane litery to: " << wylosowane<<endl;

    return wylosowane;
}



string GenerujMID()
{

ostringstream midd_o;
midd_o<<"Message-ID: <"<<LosujCyfry(3)<<LosujLitery(3)<<"-"<<LosujCyfry(2)<<LosujLitery(2)<<"-"<<LosujCyfry(3)<<LosujLitery(2)<<"-"<<LosujCyfry(1)<<LosujLitery(1)<<LosujCyfry(1)<<LosujLitery(1)<<"-"<<LosujLitery(1)<<LosujCyfry(3)<<LosujLitery(1)<<LosujCyfry(3)<<LosujLitery(3)<<"@gmail.com>";



    string midd= midd_o.str();

    midd_o.str("");
    return midd;
}

string GenerujDate()
{
    string data_m="Date: Sat, 7 Apr 2018 12:59:43 +0100";
    return data_m;

}


int Wyslij(string from_od,string to_do,string cc_dw,string subject_s,char inline_text[],char inline_html[],string attach_zal)
{



string date_s=GenerujDate();
string mid_s=GenerujMID();


ostringstream too_s;
ostringstream ccc_s;
ostringstream fromm_s;
ostringstream subject_o;
too_s<<"To: "<<" "<<to_do;
fromm_s<<"From: "<<" "<<from_od;
ccc_s<<"Cc: "<<" "<<cc_dw;
subject_o<<"Subject: "<<subject_s;

string too=too_s.str();
string fromm=fromm_s.str();
string ccc=ccc_s.str();
string subject_tt=subject_o.str();

char* date_w=&date_s[0];
char* mid_w=&mid_s[0];
char* subject_w=&subject_tt[0];

char* fromm_w=&fromm[0];
char* too_w=&too[0];
char* ccc_w=&ccc[0];


char* attachment=&attach_zal[0];

string too_ii=to_do;
string fromm_ii=from_od;
string ccc_ii=cc_dw;
char* fromm_ii_w=&fromm_ii[0];
char* too_ii_w=&too_ii[0];
char* ccc_ii_w=&ccc_ii[0];


static const char *headers_text[] = {
  date_w,
  too_w,
  fromm_w,
  ccc_w ,
  mid_w,
  subject_w,
  NULL
};

/*

static const char inline_text[] =
"Lista produktow zawiera m.in.:"
"- pozycje, ktorych ceny zakupu z ostatnich dostaw roznia sie w sposob znaczny,"
"- pozycje, ktore zostaly ostatnio zamowione na stan pomimo znikomej rotacji."

"Listę nalezy zweryfikowac przed zgloszeniem zwrotow do hurtowni."
 "Zachecam do zapoznania sie.";

 static const char inline_html[] =
*/


  CURL *curl;
  CURLcode res = CURLE_OK;
  struct curl_slist *headers = NULL;
  struct curl_slist *recipients = NULL;
  struct curl_slist *slist = NULL;
  curl_mime *mime;
  curl_mime *alt;



  curl_mimepart *part;
  const char **cpp;

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_USERNAME, "[email protected]");//
    curl_easy_setopt(curl, CURLOPT_PASSWORD, "xxxx");//
    /* This is the URL for your mailserver. Note the use of smtps:// rather
     * than smtp:// to request a SSL based connection. */
    curl_easy_setopt(curl, CURLOPT_URL, "smtps://smtp.gmail.com:465");
curl_easy_setopt(curl, CURLOPT_CAPATH, "curl-ca-bundle.crt");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);

    /* Note that this option isn't strictly required, omitting it will result
     * in libcurl sending the MAIL FROM command with empty sender data. All
     * autoresponses should have an empty reverse-path, and should be directed
     * to the address in the reverse-path which triggered them. Otherwise,
     * they could cause an endless loop. See RFC 5321 Section 4.5.5 for more
     * details.
     */
    curl_easy_setopt(curl, CURLOPT_MAIL_FROM,fromm_ii_w);

    /* Add two recipients, in this particular case they correspond to the
     * To: and Cc: addressees in the header, but they could be any kind of
     * recipient. */
    recipients = curl_slist_append(recipients, too_ii_w);
    recipients = curl_slist_append(recipients, ccc_ii_w);
    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);

    /* Build and set the message header list. */
    for(cpp = headers_text; *cpp; cpp++)
      headers = curl_slist_append(headers, *cpp);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    /* Build the mime message. */
    mime = curl_mime_init(curl);

    /* The inline part is an alterative proposing the html and the text
       versions of the e-mail. */
    alt = curl_mime_init(curl);

/* Text message. */
    part = curl_mime_addpart(alt);
    curl_mime_data(part, inline_text, CURL_ZERO_TERMINATED);
    /* HTML message. */
    part = curl_mime_addpart(mime);
    curl_mime_data(part, inline_html, CURL_ZERO_TERMINATED);
    curl_mime_type(part, "text/html");
    curl_mime_encoder(part, "iso-8859-2");


    /* Create the inline part. */
    part = curl_mime_addpart(mime);
    curl_mime_subparts(part, alt);
    curl_mime_type(part, "multipart/related");
    slist = curl_slist_append(NULL, "Content-Disposition: inline");
    curl_mime_headers(part, slist, 1);




    /* Add the current source program as an attachment. */
   part = curl_mime_addpart(mime);
    curl_mime_type(part, "text");
    curl_mime_filedata(part, attachment);
    curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);

    /* Send the message */
    res = curl_easy_perform(curl);

    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));

    /* Free lists. */
    curl_slist_free_all(recipients);
    curl_slist_free_all(headers);

    /* curl won't send the QUIT command until you call cleanup, so you should
     * be able to re-use this connection for additional messages (setting
     * CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling
     * curl_easy_perform() again. It may not be a good idea to keep the
     * connection open for a very long time though (more than a few minutes
     * may result in the server timing out the connection), and you do want to
     * clean up in the end.
     */
    curl_easy_cleanup(curl);

    /* Free multipart message. */
    curl_mime_free(mime);
  }

  return (int)res;
}






};





int main()
{





string odkogo= "<[email protected]>";
string dokogo= "<[email protected]>";
string dowiad= "<[email protected]> XXXX <[email protected]>";
string Temat="TEST WIADOMOŚCI 0826";

char TrescHtml[]="<html>\r\n"
  "<head>\r\n"
  "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-2' />\r\n"


  "<br />\r\n"
  "</head>\r\n"
  "<body>\r\n"
  "<table border='1 px'>\r\n"


"</tr>\r\n""<tr>\r\n"
"<td><a>bloz1</a></td><td><a>nazwa1</a></td><td><a>ilosc1</a></td><td><a>sprzedaz1</a></td>\r\n"
"</tr>\r\n""<tr>\r\n"
"<td><a>bloz1</a></td><td><a>nazwa1</a></td><td><a>ilosc1</a></td><td><a>sprzedaz1</a></td>\r\n"
"</tr>\r\n""<tr>\r\n"
"<td><a>bloz1</a></td><td><a>nazwa1</a></td><td><a>ilosc1</a></td><td><a>sprzedaz1</a></td>\r\n"
"</tr>\r\n""<tr>\r\n"
"<td><a>bloz1</a></td><td><a>nazwa1</a></td><td><a>ilosc1</a></td><td><a>sprzedaz1</a></td>\r\n"
"</tr>\r\n""<tr>\r\n"
"<td><a>bloz1</a></td><td><a>nazwa1</a></td><td><a>ilosc1</a></td><td><a>sprzedaz1</a></td>\r\n"
"</tr>\r\n""<tr>\r\n"
"<td><a>bloz1</a></td><td><a>nazwa1</a></td><td><a>ilosc1</a></td><td><a>sprzedaz1</a></td>\r\n"
"</tr>\r\n""<tr>\r\n"
"<td><a>bloz1</a></td><td><a>nazwa1</a></td><td><a>ilosc1</a></td><td><a>sprzedaz1</a></td>\r\n"
"</tr>\r\n""<tr>\r\n"
"<td><a>bloz1</a></td><td><a>nazwa1</a></td><td><a>ilosc1</a></td><td><a>sprzedaz1</a></td>\r\n"
"</tr>\r\n""<tr>\r\n"

  "</table>\r\n"
  "TO JEST TEST WYSYŁKI 1303"
"<img src='https://www.fototapety24.net/fotografia/700/82972458/slonce-panorama-buk-natura.jpg' />"
  "</body></html>\r\n";


   char TrescText[] =
"Lista produktow zawiera m.in.:"
"- pozycje, ktorych ceny zakupu z ostatnich dostaw roznia sie w sposob znaczny,"
"- pozycje, ktore zostaly ostatnio zamowione na stan pomimo znikomej rotacji."

"Listę nalezy zweryfikowac przed zgloszeniem zwrotow do hurtowni."
 "Zachecam do zapoznania sie."
 "TO JEST TEST WYSYŁKI 1303";



string zalacznik="sqldatazak.docx";

  MailMIME wiadomosc;

 wiadomosc.Wyslij(odkogo,dokogo,dowiad,Temat,TrescText,TrescHtml,zalacznik);

  cout<<"Wyslane!!!"<<endl;
  cin.get();
    return 0;
}

Może, ktoś z Was będzie w stanie mi pomóc, bo ja już wyrwałem sobie wszystkie włosy z głowy i obgryzłem resztę paznokci przy tym problemie:P . Być może zna ktoś lepszy sposób na wysyłkę maili z MIME w c++ ?

Pozdr

0

Drobna uwaga: wywal srand z LosujLitery i LosujCyfry, a daj w GenerujMID.

0
0x666 napisał(a):

Drobna uwaga: wywal srand z LosujLitery i LosujCyfry, a daj w GenerujMID.

Ok, dzięki za uwagę. Domyślam się, że chodzi o to, żeby Message ID było bardziej różnorodne:)

0

Widziałeś oficjalny przykład?

https://curl.haxx.se/libcurl/c/smtp-tls.html

0

Tak widziałem i działa ok przy wiadomościach tekstowych, ale gdy próbuję w treści umieścić html (oczywiście wg protokołu SMTP MIME), to na skrzynkę dostaję albo pustego maila lub ew. czysty tekst bez formatu html... Nie bardzo mam pomysł jak mógłbym zmodyfikować kod ,żeby wiadomości przechodziły właściwie... W przykładzie, który napisałem nie ma tego problemu - w wiadomości ładnie wyświetla się tabela html + obrazy + style itp.

0

Jeszcze takie pytanie. Ustawiłem sobie wyświetlanie kolejnych kroków logowania na skrzynkę ( curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);) i dzięki temu dowiedziałem się, że problem prawie na pewno leży w certyfikacie... Muszę jeszcze poszperać w necie, ale główny błąd teraz to SSL peer certificate or SSH remote key was not ok, a wcześniej wyświetla mi : "subjectAltName does not match 'adres.serwera.smtp'" oraz "SSL: no alternative certificate subject name matchestarget host name 'adres.serwera.smtp' . Może ktoś mógłby mi wyjaśnić którego certyfikatu/klucza muszę użyć. Może w skrócie jak działa w ogóle certyfikat SSL w takiej sytuacji. Powinienem mieć swój kupiony certyfikat i jakoś go tu zaimplementować.. Nie wiem już...

1 użytkowników online, w tym zalogowanych: 0, gości: 1