From 2841aa95db84f3563c94c90f84bf7f47ba159a2d Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 3 Mar 2015 20:42:28 +0100 Subject: [PATCH] fix thread safety for win32/sendmail --- win32/php_win32_globals.h | 7 +++ win32/sendmail.c | 95 ++++++++++++++++----------------------- 2 files changed, 46 insertions(+), 56 deletions(-) diff --git a/win32/php_win32_globals.h b/win32/php_win32_globals.h index ad2435d99c..b22c227eda 100644 --- a/win32/php_win32_globals.h +++ b/win32/php_win32_globals.h @@ -23,6 +23,8 @@ /* misc globals for thread-safety under win32 */ +#include "win32/sendmail.h" + typedef struct _php_win32_core_globals php_win32_core_globals; #ifdef ZTS @@ -41,6 +43,11 @@ struct _php_win32_core_globals { HKEY registry_key; HANDLE registry_event; HashTable *registry_directories; + + char mail_buffer[MAIL_BUFFER_SIZE]; + SOCKET mail_socket; + char mail_host[HOST_NAME_LEN]; + char mail_local_host[HOST_NAME_LEN]; }; void php_win32_core_globals_ctor(void *vg); diff --git a/win32/sendmail.c b/win32/sendmail.c index 7dacf5ce41..b8d18d195e 100644 --- a/win32/sendmail.c +++ b/win32/sendmail.c @@ -40,6 +40,8 @@ #include "php_ini.h" #include "inet.h" +#include "php_win32_globals.h" + #if HAVE_PCRE || HAVE_BUNDLED_PCRE #include "ext/pcre/php_pcre.h" #endif @@ -69,22 +71,6 @@ #define SMTP_SKIP_SPACE(str) { while (isspace(*str)) { str++; } } -#ifndef THREAD_SAFE -char Buffer[MAIL_BUFFER_SIZE]; - -/* socket related data */ -SOCKET sc; -#ifndef NETWARE -WSADATA Data; -struct hostent *adr; -int WinsockStarted; -/* values set by the constructor */ -char *AppName; -#endif /* NETWARE */ -SOCKADDR_IN sock_in; -char MailHost[HOST_NAME_LEN]; -char LocalHost[HOST_NAME_LEN]; -#endif char seps[] = " ,\t\n"; #ifndef NETWARE char *php_mailer = "PHP 7 WIN32"; @@ -223,10 +209,6 @@ PHPAPI int TSendMail(char *host, int *error, char **error_message, zend_string *headers_lc = NULL; /* headers_lc is only created if we've a header at all */ char *pos1 = NULL, *pos2 = NULL; -#ifndef NETWARE - WinsockStarted = FALSE; -#endif - if (host == NULL) { *error = BAD_MAIL_HOST; return FAILURE; @@ -234,7 +216,7 @@ PHPAPI int TSendMail(char *host, int *error, char **error_message, *error = BAD_MAIL_HOST; return FAILURE; } else { - strcpy(MailHost, host); + strcpy(PW32G(mail_host), host); } if (headers) { @@ -296,7 +278,7 @@ PHPAPI int TSendMail(char *host, int *error, char **error_message, snprintf(*error_message, HOST_NAME_LEN + 128, "Failed to connect to mailserver at \"%s\" port %d, verify your \"SMTP\" " "and \"smtp_port\" setting in php.ini or use ini_set()", - MailHost, !INI_INT("smtp_port") ? 25 : INI_INT("smtp_port")); + PW32G(mail_host), !INI_INT("smtp_port") ? 25 : INI_INT("smtp_port")); return FAILURE; } else { ret = SendText(RPath, Subject, mailTo, mailCc, mailBcc, data, headers, headers_lc->val, error_message); @@ -332,8 +314,8 @@ PHPAPI void TSMClose() elesewhere */ - shutdown(sc, 0); - closesocket(sc); + shutdown(PW32G(mail_socket), 0); + closesocket(PW32G(mail_socket)); } @@ -405,17 +387,17 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char return (BAD_MSG_DESTINATION); */ - snprintf(Buffer, sizeof(Buffer), "HELO %s\r\n", LocalHost); + snprintf(PW32G(mail_buffer), sizeof(PW32G(mail_buffer)), "HELO %s\r\n", PW32G(mail_local_host)); /* in the beginning of the dialog */ /* attempt reconnect if the first Post fail */ - if ((res = Post(Buffer)) != SUCCESS) { + if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { int err = MailConnect(); if (0 != err) { return (FAILED_TO_SEND); } - if ((res = Post(Buffer)) != SUCCESS) { + if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { return (res); } } @@ -425,8 +407,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char } SMTP_SKIP_SPACE(RPath); - FormatEmailAddress(Buffer, RPath, "MAIL FROM:<%s>\r\n"); - if ((res = Post(Buffer)) != SUCCESS) { + FormatEmailAddress(PW32G(mail_buffer), RPath, "MAIL FROM:<%s>\r\n"); + if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { return (res); } if ((res = Ack(&server_response)) != SUCCESS) { @@ -440,8 +422,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); - if ((res = Post(Buffer)) != SUCCESS) { + FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); + if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } @@ -461,8 +443,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); - if ((res = Post(Buffer)) != SUCCESS) { + FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); + if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } @@ -491,8 +473,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); - if ((res = Post(Buffer)) != SUCCESS) { + FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); + if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } @@ -516,8 +498,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); - if ((res = Post(Buffer)) != SUCCESS) { + FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); + if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } @@ -549,8 +531,8 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); - if ((res = Post(Buffer)) != SUCCESS) { + FormatEmailAddress(PW32G(mail_buffer), token, "RCPT TO:<%s>\r\n"); + if ((res = Post(PW32G(mail_buffer))) != SUCCESS) { efree(tempMailTo); return (res); } @@ -775,22 +757,23 @@ static int MailConnect() #ifdef HAVE_IPV6 IN6_ADDR addr6; #endif + SOCKADDR_IN sock_in; /* Create Socket */ - if ((sc = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { + if ((PW32G(mail_socket) = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { return (FAILED_TO_OBTAIN_SOCKET_HANDLE); } /* Get our own host name */ - if (gethostname(LocalHost, HOST_NAME_LEN)) { - closesocket(sc); + if (gethostname(PW32G(mail_local_host), HOST_NAME_LEN)) { + closesocket(PW32G(mail_socket)); return (FAILED_TO_GET_HOSTNAME); } - ent = gethostbyname(LocalHost); + ent = gethostbyname(PW32G(mail_local_host)); if (!ent) { - closesocket(sc); + closesocket(PW32G(mail_socket)); return (FAILED_TO_GET_HOSTNAME); } @@ -803,25 +786,25 @@ static int MailConnect() #endif { if (namelen + 2 >= HOST_NAME_LEN) { - closesocket(sc); + closesocket(PW32G(mail_socket)); return (FAILED_TO_GET_HOSTNAME); } - strcpy(LocalHost, "["); - strcpy(LocalHost + 1, ent->h_name); - strcpy(LocalHost + namelen + 1, "]"); + strcpy(PW32G(mail_local_host), "["); + strcpy(PW32G(mail_local_host) + 1, ent->h_name); + strcpy(PW32G(mail_local_host) + namelen + 1, "]"); } else { if (namelen >= HOST_NAME_LEN) { - closesocket(sc); + closesocket(PW32G(mail_socket)); return (FAILED_TO_GET_HOSTNAME); } - strcpy(LocalHost, ent->h_name); + strcpy(PW32G(mail_local_host), ent->h_name); } /* Resolve the servers IP */ /* - if (!isdigit(MailHost[0])||!gethostbyname(MailHost)) + if (!isdigit(PW32G(mail_host)[0])||!gethostbyname(PW32G(mail_host))) { return (FAILED_TO_RESOLVE_HOST); } @@ -835,10 +818,10 @@ static int MailConnect() /* Connect to server */ sock_in.sin_family = AF_INET; sock_in.sin_port = htons(portnum); - sock_in.sin_addr.S_un.S_addr = GetAddr(MailHost); + sock_in.sin_addr.S_un.S_addr = GetAddr(PW32G(mail_host)); - if (connect(sc, (LPSOCKADDR) & sock_in, sizeof(sock_in))) { - closesocket(sc); + if (connect(PW32G(mail_socket), (LPSOCKADDR) & sock_in, sizeof(sock_in))) { + closesocket(PW32G(mail_socket)); return (FAILED_TO_CONNECT); } @@ -863,7 +846,7 @@ static int Post(LPCSTR msg) int index = 0; while (len > 0) { - if ((slen = send(sc, msg + index, len, 0)) < 1) + if ((slen = send(PW32G(mail_socket), msg + index, len, 0)) < 1) return (FAILED_TO_SEND); len -= slen; index += slen; @@ -892,7 +875,7 @@ static int Ack(char **server_response) again: - if ((rlen = recv(sc, buf + Index, ((MAIL_BUFFER_SIZE) - 1) - Received, 0)) < 1) { + if ((rlen = recv(PW32G(mail_socket), buf + Index, ((MAIL_BUFFER_SIZE) - 1) - Received, 0)) < 1) { return (FAILED_TO_RECEIVE); } Received += rlen; -- 2.50.1