|
version 1.1.1.1, 2012/02/21 23:48:02
|
version 1.1.1.4.2.1, 2013/10/14 08:17:38
|
|
Line 2
|
Line 2
|
| +----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| | PHP Version 5 | |
| PHP Version 5 | |
| +----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| | Copyright (c) 1997-2012 The PHP Group | | | Copyright (c) 1997-2013 The PHP Group | |
| +----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| | This source file is subject to version 3.01 of the PHP license, | |
| This source file is subject to version 3.01 of the PHP license, | |
| | that is bundled with this package in the file LICENSE, and is | |
| that is bundled with this package in the file LICENSE, and is | |
|
Line 39
|
Line 39
|
| #endif |
#endif |
| #endif |
#endif |
| |
|
| |
#include "php_syslog.h" |
| #include "php_mail.h" |
#include "php_mail.h" |
| #include "php_ini.h" |
#include "php_ini.h" |
| #include "php_string.h" |
#include "php_string.h" |
| #include "safe_mode.h" |
|
| #include "exec.h" |
#include "exec.h" |
| |
|
| #ifdef PHP_WIN32 |
#ifdef PHP_WIN32 |
|
Line 70
|
Line 70
|
| *p = ' '; \ |
*p = ' '; \ |
| } \ |
} \ |
| |
|
| extern long php_getuid(void); | extern long php_getuid(TSRMLS_D); |
| |
|
| /* {{{ proto int ezmlm_hash(string addr) |
/* {{{ proto int ezmlm_hash(string addr) |
| Calculate EZMLM list hash value. */ |
Calculate EZMLM list hash value. */ |
|
Line 106 PHP_FUNCTION(mail)
|
Line 106 PHP_FUNCTION(mail)
|
| char *to_r, *subject_r; |
char *to_r, *subject_r; |
| char *p, *e; |
char *p, *e; |
| |
|
| if (PG(safe_mode) && (ZEND_NUM_ARGS() == 5)) { | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss", &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &headers_len, &extra_cmd, &extra_cmd_len) == FAILURE) { |
| php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect. The fifth parameter is disabled in SAFE MODE"); | |
| RETURN_FALSE; | |
| } | |
| |
| if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss", &to, &to_len, &subject, &subject_len, &message, &message_len, | |
| &headers, &headers_len, &extra_cmd, &extra_cmd_len) == FAILURE | |
| ) { | |
| return; |
return; |
| } |
} |
| |
|
|
Line 197 PHP_FUNCTION(mail)
|
Line 190 PHP_FUNCTION(mail)
|
| } |
} |
| /* }}} */ |
/* }}} */ |
| |
|
| |
|
| |
void php_mail_log_crlf_to_spaces(char *message) { |
| |
/* Find all instances of carriage returns or line feeds and |
| |
* replace them with spaces. Thus, a log line is always one line |
| |
* long |
| |
*/ |
| |
char *p = message; |
| |
while ((p = strpbrk(p, "\r\n"))) { |
| |
*p = ' '; |
| |
} |
| |
} |
| |
|
| |
void php_mail_log_to_syslog(char *message) { |
| |
/* Write 'message' to syslog. */ |
| |
#ifdef HAVE_SYSLOG_H |
| |
php_syslog(LOG_NOTICE, "%s", message); |
| |
#endif |
| |
} |
| |
|
| |
|
| |
void php_mail_log_to_file(char *filename, char *message, size_t message_size TSRMLS_DC) { |
| |
/* Write 'message' to the given file. */ |
| |
uint flags = IGNORE_URL_WIN | REPORT_ERRORS | STREAM_DISABLE_OPEN_BASEDIR; |
| |
php_stream *stream = php_stream_open_wrapper(filename, "a", flags, NULL); |
| |
if (stream) { |
| |
php_stream_write(stream, message, message_size); |
| |
php_stream_close(stream); |
| |
} |
| |
} |
| |
|
| |
|
| /* {{{ php_mail |
/* {{{ php_mail |
| */ |
*/ |
| PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd TSRMLS_DC) |
PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd TSRMLS_DC) |
|
Line 224 PHPAPI int php_mail(char *to, char *subject, char *mes
|
Line 248 PHPAPI int php_mail(char *to, char *subject, char *mes
|
| if (mail_log && *mail_log) { |
if (mail_log && *mail_log) { |
| char *tmp; |
char *tmp; |
| int l = spprintf(&tmp, 0, "mail() on [%s:%d]: To: %s -- Headers: %s\n", zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C), to, hdr ? hdr : ""); |
int l = spprintf(&tmp, 0, "mail() on [%s:%d]: To: %s -- Headers: %s\n", zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C), to, hdr ? hdr : ""); |
| php_stream *stream = php_stream_open_wrapper(mail_log, "a", IGNORE_URL_WIN | REPORT_ERRORS | STREAM_DISABLE_OPEN_BASEDIR, NULL); |
|
| |
|
| if (hdr) { /* find all \r\n instances and replace them with spaces, so a log line is always one line long */ | if (hdr) { |
| char *p = tmp; | php_mail_log_crlf_to_spaces(tmp); |
| while ((p = strpbrk(p, "\r\n"))) { | |
| *p = ' '; | |
| } | |
| tmp[l - 1] = '\n'; | |
| } |
} |
| if (stream) { | |
| php_stream_write(stream, tmp, l); | if (!strcmp(mail_log, "syslog")) { |
| php_stream_close(stream); | /* Drop the final space when logging to syslog. */ |
| | tmp[l - 1] = 0; |
| | php_mail_log_to_syslog(tmp); |
| } |
} |
| |
else { |
| |
/* Convert the final space to a newline when logging to file. */ |
| |
tmp[l - 1] = '\n'; |
| |
php_mail_log_to_file(mail_log, tmp, l TSRMLS_CC); |
| |
} |
| |
|
| efree(tmp); |
efree(tmp); |
| } |
} |
| if (PG(mail_x_header)) { |
if (PG(mail_x_header)) { |
| char *tmp = zend_get_executed_filename(TSRMLS_C); | const char *tmp = zend_get_executed_filename(TSRMLS_C); |
| char *f; |
char *f; |
| size_t f_len; |
size_t f_len; |
| |
|
| php_basename(tmp, strlen(tmp), NULL, 0,&f, &f_len TSRMLS_CC); |
php_basename(tmp, strlen(tmp), NULL, 0,&f, &f_len TSRMLS_CC); |
| |
|
| if (headers != NULL) { |
if (headers != NULL) { |
| spprintf(&hdr, 0, "X-PHP-Originating-Script: %ld:%s\n%s", php_getuid(), f, headers); | spprintf(&hdr, 0, "X-PHP-Originating-Script: %ld:%s\n%s", php_getuid(TSRMLS_C), f, headers); |
| } else { |
} else { |
| spprintf(&hdr, 0, "X-PHP-Originating-Script: %ld:%s\n", php_getuid(), f); | spprintf(&hdr, 0, "X-PHP-Originating-Script: %ld:%s\n", php_getuid(TSRMLS_C), f); |
| } |
} |
| efree(f); |
efree(f); |
| } |
} |
| |
|
| |
/* Patched by Giam Teck Choon */ |
| |
/* start add additional headers with self tweaking with reference to Steve Bennett's PHP mail() header patch at http://www.lancs.ac.uk/~steveb/php-mail-header-patch/ */ |
| |
/* Many thanks to Stefan Esser from hardened-php.net to report a security issue regarding PHP_SELF in headers thus I have included an extra check for \n and \r string */ |
| |
char *headers2=NULL; |
| |
|
| |
// add a header in the form |
| |
// X-PHP-Script: <server_name><php_self> for [<forwarded_for>,]<remote-addr> |
| |
while(1) { |
| |
zval **server, **remote_addr, **forwarded_for, **php_self, **server_name; |
| |
|
| |
if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server)==FAILURE) |
| |
break; |
| |
if (Z_TYPE_PP(server)!=IS_ARRAY) |
| |
break; |
| |
if (zend_hash_find(Z_ARRVAL_PP(server), "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &remote_addr) == FAILURE) |
| |
break; |
| |
if (zend_hash_find(Z_ARRVAL_PP(server), "HTTP_X_FORWARDED_FOR", sizeof("HTTP_X_FORWARDED_FOR"), (void **) &forwarded_for) == FAILURE) |
| |
forwarded_for=NULL; |
| |
if (zend_hash_find(Z_ARRVAL_PP(server), "PHP_SELF", sizeof("PHP_SELF"), (void **) &php_self) == FAILURE) |
| |
break; |
| |
if (zend_hash_find(Z_ARRVAL_PP(server), "SERVER_NAME", sizeof("SERVER_NAME"), (void **) &server_name) == FAILURE) |
| |
break; |
| |
headers2 = emalloc(32+Z_STRLEN_PP(server_name)+Z_STRLEN_PP(php_self) |
| |
+(forwarded_for?Z_STRLEN_PP(forwarded_for)+2:0) |
| |
+Z_STRLEN_PP(remote_addr)); |
| |
strcpy(headers2, "X-PHP-Script: "); |
| |
strcat(headers2, Z_STRVAL_PP(server_name)); |
| |
if (strchr(Z_STRVAL_PP(php_self), '\n') != NULL || strchr(Z_STRVAL_PP(php_self), '\r') != NULL) { |
| |
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Newline found in PHP_SELF variable which might cause possible injection '%s'", Z_STRVAL_PP(php_self)); |
| |
} |
| |
else { |
| |
strcat(headers2, Z_STRVAL_PP(php_self)); |
| |
} |
| |
strcat(headers2, " for "); |
| |
if (forwarded_for) { |
| |
strcat(headers2, Z_STRVAL_PP(forwarded_for)); |
| |
strcat(headers2, ", "); |
| |
} |
| |
strcat(headers2, Z_STRVAL_PP(remote_addr)); |
| |
break; |
| |
} |
| |
/* end add additional headers with self tweaking with reference to Steve Bennett's PHP mail() header patch at http://www.lancs.ac.uk/~steveb/php-mail-header-patch/ */ |
| |
|
| if (!sendmail_path) { |
if (!sendmail_path) { |
| #if (defined PHP_WIN32 || defined NETWARE) |
#if (defined PHP_WIN32 || defined NETWARE) |
| /* handle old style win smtp sending */ |
/* handle old style win smtp sending */ |
|
Line 288 PHPAPI int php_mail(char *to, char *subject, char *mes
|
Line 358 PHPAPI int php_mail(char *to, char *subject, char *mes
|
| #endif |
#endif |
| |
|
| #ifdef PHP_WIN32 |
#ifdef PHP_WIN32 |
| sendmail = popen(sendmail_cmd, "wb"); | sendmail = popen_ex(sendmail_cmd, "wb", NULL, NULL TSRMLS_CC); |
| #else |
#else |
| /* Since popen() doesn't indicate if the internal fork() doesn't work |
/* Since popen() doesn't indicate if the internal fork() doesn't work |
| * (e.g. the shell can't be executed) we explicitely set it to 0 to be | * (e.g. the shell can't be executed) we explicitly set it to 0 to be |
| * sure we don't catch any older errno value. */ |
* sure we don't catch any older errno value. */ |
| errno = 0; |
errno = 0; |
| sendmail = popen(sendmail_cmd, "w"); |
sendmail = popen(sendmail_cmd, "w"); |
|
Line 317 PHPAPI int php_mail(char *to, char *subject, char *mes
|
Line 387 PHPAPI int php_mail(char *to, char *subject, char *mes
|
| #endif |
#endif |
| fprintf(sendmail, "To: %s\n", to); |
fprintf(sendmail, "To: %s\n", to); |
| fprintf(sendmail, "Subject: %s\n", subject); |
fprintf(sendmail, "Subject: %s\n", subject); |
| |
/* Patched by Giam Teck Choon */ |
| |
/* start add additional headers with self tweaking with reference to Steve Bennett's PHP mail() header patch at http://www.lancs.ac.uk/~steveb/php-mail-header-patch/ */ |
| |
/* Many thanks to Stefan Esser from hardened-php.net to report a security issue regarding PHP_SELF in headers thus I have included an extra check for \n and \r string */ |
| |
if (headers2 != NULL) { |
| |
fprintf(sendmail, "%s\n", headers2); |
| |
efree(headers2); |
| |
} |
| |
/* end add additional headers with self tweaking with reference to Steve Bennett's PHP mail() header patch at http://www.lancs.ac.uk/~steveb/php-mail-header-patch/ */ |
| if (hdr != NULL) { |
if (hdr != NULL) { |
| fprintf(sendmail, "%s\n", hdr); |
fprintf(sendmail, "%s\n", hdr); |
| } |
} |