summaryrefslogtreecommitdiff
path: root/3rdParty/libquickmail/quickmail.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/libquickmail/quickmail.c')
-rw-r--r--3rdParty/libquickmail/quickmail.c87
1 files changed, 69 insertions, 18 deletions
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 <stdio.h>
#include <string.h>
#include <time.h>
+#include <locale.h>
#ifndef _WIN32
#include <unistd.h>
#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,6 +407,7 @@ 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);
@@ -413,6 +415,18 @@ DLL_EXPORT_LIBQUICKMAIL int quickmail_initialize ()
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);
+}