From 5abd626fb1338dc6781f6a2febd7bfb1c906cc3d Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 14 Jul 2016 12:47:29 +0200 Subject: update libquickmail from 0.1.20 to 0.1.24 --- 3rdParty/libquickmail/quickmail.c | 87 +++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 18 deletions(-) (limited to '3rdParty/libquickmail/quickmail.c') diff --git a/3rdParty/libquickmail/quickmail.c b/3rdParty/libquickmail/quickmail.c index d6827ff..92ce3e6 100644 --- a/3rdParty/libquickmail/quickmail.c +++ b/3rdParty/libquickmail/quickmail.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifndef _WIN32 #include #endif @@ -41,7 +42,7 @@ #define LIBQUICKMAIL_VERSION_MAJOR 0 #define LIBQUICKMAIL_VERSION_MINOR 1 -#define LIBQUICKMAIL_VERSION_MICRO 20 +#define LIBQUICKMAIL_VERSION_MICRO 24 #define VERSION_STRINGIZE_(major, minor, micro) #major"."#minor"."#micro #define VERSION_STRINGIZE(major, minor, micro) VERSION_STRINGIZE_(major, minor, micro) @@ -56,7 +57,7 @@ #define MIME_LINE_WIDTH 72 #define BODY_BUFFER_SIZE 256 -//definitions of the differen stages of generating the message data +//definitions of the different stages of generating the message data #define MAILPART_INITIALIZE 0 #define MAILPART_HEADER 1 #define MAILPART_BODY 2 @@ -406,12 +407,25 @@ DLL_EXPORT_LIBQUICKMAIL const char* quickmail_get_version () DLL_EXPORT_LIBQUICKMAIL int quickmail_initialize () { +/* #if defined(NOCURL) && defined(_WIN32) static WSADATA wsaData; int wsaerr = WSAStartup(MAKEWORD(1, 0), &wsaData); if (wsaerr) return -1; atexit((void(*)())WSACleanup); +#endif +*/ +#ifndef NOCURL + curl_global_init(CURL_GLOBAL_ALL); +#endif + return 0; +} + +DLL_EXPORT_LIBQUICKMAIL int quickmail_cleanup () +{ +#ifndef NOCURL + curl_global_cleanup(); #endif return 0; } @@ -548,17 +562,17 @@ DLL_EXPORT_LIBQUICKMAIL char* quickmail_get_body (quickmail mailobj) DLL_EXPORT_LIBQUICKMAIL void quickmail_add_body_file (quickmail mailobj, const char* mimetype, const char* path) { - email_info_attachment_list_add(&mailobj->bodylist, (mimetype ? mimetype : default_mime_type), (mimetype ? mimetype : default_mime_type), (void*)strdup(path), email_info_attachment_open_file, email_info_attachment_read_file, email_info_attachment_close_file, NULL); + email_info_attachment_list_add(&mailobj->bodylist, NULL, (mimetype ? mimetype : default_mime_type), (void*)strdup(path), email_info_attachment_open_file, email_info_attachment_read_file, email_info_attachment_close_file, NULL); } DLL_EXPORT_LIBQUICKMAIL void quickmail_add_body_memory (quickmail mailobj, const char* mimetype, char* data, size_t datalen, int mustfree) { - email_info_attachment_list_add_memory(&mailobj->bodylist, (mimetype ? mimetype : default_mime_type), (mimetype ? mimetype : default_mime_type), data, datalen, mustfree); + email_info_attachment_list_add_memory(&mailobj->bodylist, NULL, (mimetype ? mimetype : default_mime_type), data, datalen, mustfree); } DLL_EXPORT_LIBQUICKMAIL void quickmail_add_body_custom (quickmail mailobj, const char* mimetype, char* data, quickmail_attachment_open_fn attachment_data_open, quickmail_attachment_read_fn attachment_data_read, quickmail_attachment_close_fn attachment_data_close, quickmail_attachment_free_filedata_fn attachment_data_filedata_free) { - email_info_attachment_list_add(&mailobj->bodylist, (mimetype ? mimetype : default_mime_type), (mimetype ? mimetype : default_mime_type), data, (attachment_data_open ? attachment_data_open : email_info_attachment_open_dummy), (attachment_data_read ? attachment_data_read : email_info_attachment_read_dummy), attachment_data_close, attachment_data_filedata_free); + email_info_attachment_list_add(&mailobj->bodylist, NULL, (mimetype ? mimetype : default_mime_type), data, (attachment_data_open ? attachment_data_open : email_info_attachment_open_dummy), (attachment_data_read ? attachment_data_read : email_info_attachment_read_dummy), attachment_data_close, attachment_data_filedata_free); } DLL_EXPORT_LIBQUICKMAIL int quickmail_remove_body (quickmail mailobj, const char* mimetype) @@ -649,7 +663,14 @@ DLL_EXPORT_LIBQUICKMAIL size_t quickmail_get_data (void* ptr, size_t size, size_ char** p = &mailobj->buf; str_append(p, "User-Agent: libquickmail v" LIBQUICKMAIL_VERSION NEWLINE); if (mailobj->timestamp != 0) { + char* oldlocale; char timestamptext[32]; + //get original locale settings and switch to C locale (so date is in English) + if ((oldlocale = setlocale(LC_TIME, NULL)) != NULL) { + oldlocale = strdup(oldlocale); + setlocale(LC_TIME, "C"); + } + //format timestamp if (strftime(timestamptext, sizeof(timestamptext), "%a, %d %b %Y %H:%M:%S %z", localtime(&mailobj->timestamp))) { str_append(p, "Date: "); str_append(p, timestamptext); @@ -659,13 +680,21 @@ DLL_EXPORT_LIBQUICKMAIL size_t quickmail_get_data (void* ptr, size_t size, size_ //fallback method for Windows when %z (time zone offset) fails else if (strftime(timestamptext, sizeof(timestamptext), "%a, %d %b %Y %H:%M:%S", localtime(&mailobj->timestamp))) { TIME_ZONE_INFORMATION tzinfo; - if (GetTimeZoneInformation(&tzinfo) != TIME_ZONE_ID_INVALID) - sprintf(timestamptext + strlen(timestamptext), " %c%02i%02i", (tzinfo.Bias > 0 ? '-' : '+'), (int)-tzinfo.Bias / 60, (int)-tzinfo.Bias % 60); + DWORD result; + if ((result = GetTimeZoneInformation(&tzinfo)) != TIME_ZONE_ID_INVALID) { + LONG bias = tzinfo.Bias + (result == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : tzinfo.StandardBias); + sprintf(timestamptext + strlen(timestamptext), " %c%02i%02i", (bias > 0 ? '-' : '+'), (int)-bias / 60, (int)-bias % 60); + } str_append(p, "Date: "); str_append(p, timestamptext); str_append(p, NEWLINE); } #endif + //restore original locale + if (oldlocale) { + setlocale(LC_TIME, oldlocale); + free(oldlocale); + } } if (mailobj->from && *mailobj->from) { str_append(p, "From: <"); @@ -707,7 +736,7 @@ DLL_EXPORT_LIBQUICKMAIL size_t quickmail_get_data (void* ptr, size_t size, size_ mailobj->mime_boundary_body = randomize_zeros(strdup("=BODY=SEPARATOR=_0000_0000_0000_0000_0000_0000_=")); str_append(p, "Content-Type: multipart/alternative; boundary=\""); str_append(p, mailobj->mime_boundary_body); - str_append(p, NEWLINE); + str_append(p, "\"" NEWLINE); } mailobj->buflen = (mailobj->buf ? strlen(mailobj->buf) : 0); mailobj->current++; @@ -720,6 +749,7 @@ DLL_EXPORT_LIBQUICKMAIL size_t quickmail_get_data (void* ptr, size_t size, size_ if ((mailobj->current_attachment->handle = mailobj->current_attachment->email_info_attachment_open(mailobj->current_attachment->filedata)) != NULL) { break; } + /////to do: notify/log the file could not be opened mailobj->current_attachment = mailobj->current_attachment->next; } if (!mailobj->current_attachment) { @@ -735,7 +765,7 @@ DLL_EXPORT_LIBQUICKMAIL size_t quickmail_get_data (void* ptr, size_t size, size_ mailobj->buf = str_append(&mailobj->buf, NEWLINE); } mailobj->buf = str_append(&mailobj->buf, "Content-Type: "); - mailobj->buf = str_append(&mailobj->buf, (mailobj->bodylist && mailobj->current_attachment->filename ? mailobj->current_attachment->filename : default_mime_type)); + mailobj->buf = str_append(&mailobj->buf, (mailobj->bodylist && mailobj->current_attachment->mimetype ? mailobj->current_attachment->mimetype : default_mime_type)); mailobj->buf = str_append(&mailobj->buf, NEWLINE "Content-Transfer-Encoding: 8bit" NEWLINE "Content-Disposition: inline" NEWLINE NEWLINE); mailobj->buflen = (mailobj->buf ? strlen(mailobj->buf) : 0); } @@ -795,7 +825,7 @@ DLL_EXPORT_LIBQUICKMAIL size_t quickmail_get_data (void* ptr, size_t size, size_ mailobj->buf = str_append(&mailobj->buf, "Content-Type: "); mailobj->buf = str_append(&mailobj->buf, (mailobj->current_attachment->mimetype ? mailobj->current_attachment->mimetype : "application/octet-stream")); mailobj->buf = str_append(&mailobj->buf, "; Name=\""); - mailobj->buf = str_append(&mailobj->buf, mailobj->current_attachment->filename); + mailobj->buf = str_append(&mailobj->buf, (mailobj->current_attachment->filename ? mailobj->current_attachment->filename : "ATTACHMENT")); mailobj->buf = str_append(&mailobj->buf, "\"" NEWLINE "Content-Transfer-Encoding: base64" NEWLINE NEWLINE); mailobj->buflen = strlen(mailobj->buf); } @@ -903,13 +933,15 @@ char* add_angle_brackets (const char* data) } #endif -DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send (quickmail mailobj, const char* smtpserver, unsigned int smtpport, const char* username, const char* password) +#define QUICKMAIL_PROT_SMTP 1 +#define QUICKMAIL_PROT_SMTPS 2 + +const char* quickmail_protocol_send (quickmail mailobj, const char* smtpserver, unsigned int smtpport, int protocol, const char* username, const char* password) { #ifndef NOCURL //libcurl based sending CURL *curl; CURLcode result = CURLE_FAILED_INIT; - //curl_global_init(CURL_GLOBAL_ALL); if ((curl = curl_easy_init()) != NULL) { struct curl_slist *recipients = NULL; struct email_info_email_list_struct* listentry; @@ -920,7 +952,7 @@ DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send (quickmail mailobj, const cha DEBUG_ERROR(ERRMSG_MEMORY_ALLOCATION_ERROR) return ERRMSG_MEMORY_ALLOCATION_ERROR; } - snprintf(addr, len, "smtp://%s:%u", smtpserver, smtpport); + snprintf(addr, len, "%s://%s:%u", (protocol == QUICKMAIL_PROT_SMTPS ? "smtps" : "smtp"), smtpserver, smtpport); curl_easy_setopt(curl, CURLOPT_URL, addr); free(addr); //try Transport Layer Security (TLS), but continue anyway if it fails @@ -994,6 +1026,10 @@ DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send (quickmail mailobj, const cha struct email_info_email_list_struct* listentry; char local_hostname[64]; int statuscode; + //SMTPS not supported without libcurl + if (protocol == QUICKMAIL_PROT_SMTPS) { + return "SMTPS not supported"; + } //determine local host name if (gethostname(local_hostname, sizeof(local_hostname)) != 0) strcpy(local_hostname, "localhost"); @@ -1021,7 +1057,7 @@ DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send (quickmail mailobj, const cha size_t passwordlen = (password ? strlen(password) : 0); char* auth; char* base64auth; - if ((auth = (char*)malloc(usernamelen + passwordlen + 4)) == NULL) { + if ((auth = (char*)malloc(usernamelen + passwordlen + 5 + 5)) == NULL) { DEBUG_ERROR(ERRMSG_MEMORY_ALLOCATION_ERROR) return ERRMSG_MEMORY_ALLOCATION_ERROR; } @@ -1038,8 +1074,9 @@ DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send (quickmail mailobj, const cha //set the password memcpy(auth + len, (password ? password : ""), passwordlen + 1); len += passwordlen; - //padd with extra zero so groups of 3 bytes can be read + //padd with extra zeros so groups of 3 bytes can be read auth[usernamelen + len + 1] = 0; + auth[usernamelen + len + 2] = 0; //encode in base64 while (inpos < len) { //encode data @@ -1048,9 +1085,9 @@ DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send (quickmail mailobj, const cha base64auth[outpos + 2] = mailobj->dtable[((auth[inpos + 1] & 0xF) << 2) | (auth[inpos + 2] >> 6)]; base64auth[outpos + 3] = mailobj->dtable[auth[inpos + 2] & 0x3F]; //padd with "=" characters if less than 3 characters were read - if (inpos + 1 >= len) { + if (inpos + 2 >= len) { base64auth[outpos + 3] = '='; - if (inpos + 2 >= len) + if (inpos + 1 >= len) base64auth[outpos + 2] = '='; } //advance to next position @@ -1059,7 +1096,12 @@ DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send (quickmail mailobj, const cha } base64auth[outpos] = 0; //send originator e-mail address - if ((statuscode = socket_smtp_command(sock, mailobj->debuglog, "AUTH PLAIN %s", base64auth)) >= 400) { + statuscode = socket_smtp_command(sock, mailobj->debuglog, "AUTH PLAIN %s", base64auth); + //clean up + free(auth); + free(base64auth); + //error if authentication failed + if (statuscode >= 400) { errmsg = "SMTP authentication failed"; break; } @@ -1120,3 +1162,12 @@ DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send (quickmail mailobj, const cha return errmsg; #endif } + +DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send (quickmail mailobj, const char* smtpserver, unsigned int smtpport, const char* username, const char* password) +{ + return quickmail_protocol_send(mailobj, smtpserver, smtpport, QUICKMAIL_PROT_SMTP, username, password); +} +DLL_EXPORT_LIBQUICKMAIL const char* quickmail_send_secure (quickmail mailobj, const char* smtpserver, unsigned int smtpport, const char* username, const char* password) +{ + return quickmail_protocol_send(mailobj, smtpserver, smtpport, QUICKMAIL_PROT_SMTPS, username, password); +} -- cgit v1.2.3-54-g00ecf