Diff for /embedaddon/php/ext/standard/mail.c between versions 1.1.1.1 and 1.1.1.4.2.1

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);
                 }                  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.4.2.1


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>