Re: [PHP-DEV] Default Return-Path with mail() and qmail

2002-12-07 Thread Daniel Lorch
hi,

Here's an improved version of this patch, which doesn't SEGFAULT on invalid
input. Someone just brought up this topic on php-de and qmail, so I thought
there is some interest in this patch .. Everbody else just ignore me :)

-daniel

-- 
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP-DEV] Default Return-Path with mail() and qmail

2002-12-07 Thread Daniel Lorch
--- php-4.2.3/ext/standard/mail.c   Sat Aug 24 13:38:13 2002
+++ php-4.2.3-daniel/ext/standard/mail.cMon Dec  2 01:24:35 2002
@@ -21,6 +21,7 @@
 #include stdlib.h
 #include ctype.h
 #include stdio.h
+#include string.h
 #include php.h
 #include ext/standard/info.h
 #if !defined(PHP_WIN32)
@@ -124,6 +125,84 @@
 }
 /* }}} */
 
+char *get_header_value(char *line)
+{
+   while(*line  *line != ':')
+   line++;
+
+   if(!*line)
+   return NULL;
+
+   line++;
+   
+   while(isspace(*line))
+   line++;
+
+   return strdup(line);
+}
+
+char *get_header(char *header_name, char *headers)
+{
+   char *line, *value=NULL;
+   int header_name_len = strlen(header_name);
+   int len=0;
+   
+   do {
+   if(*headers == '\n' || *headers == '\0') {
+   if(len  header_name_len) {
+   len = 0;
+   continue;
+   }
+   
+   if((line = (char *)malloc(len + 1)) == NULL)
+   return NULL;
+   
+   headers -= len;
+
+   strncpy(line, headers, len);
+   line[len] = '\0';
+
+   headers += len;
+   
+   if(strncmp(line, header_name, header_name_len) == 0) {
+   value = get_header_value(line);
+   }
+   
+   free(line);
+   
+   len = 0;
+   } else {
+   ++len;
+   }
+   } while(*headers++  value == NULL);
+   
+   return value;
+}
+
+char *extract_address(char *address)
+{
+   char *start, *stop, *tmp;
+   
+   if((start = stop = strchr(address, '@')) == NULL)
+   return NULL;
+   
+   while(start = address  !isspace(*start)  *start != '')
+   start--;
+   
+   start++;
+   
+   while(*stop  !isspace(*stop)  *stop != '')
+   stop++;
+   
+   if((tmp = (char *)malloc(stop - start + 1)) == NULL)
+   return NULL;
+   
+   strncpy(tmp, start, stop - start);
+   tmp[stop-start] = '\0';
+   
+   return tmp;
+}
+
 /* {{{ php_mail
  */
 PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char 
*extra_cmd)
@@ -135,6 +214,8 @@
int ret;
char *sendmail_path = INI_STR(sendmail_path);
char *sendmail_cmd = NULL;
+   char *return_path;
+   char *address;
 
if (!sendmail_path) {
 #ifdef PHP_WIN32
@@ -169,6 +250,25 @@
fprintf(sendmail, To: %s\n, to);
fprintf(sendmail, Subject: %s\n, subject);
if (headers != NULL) {
+
+   /* Existing Return-Path should not be overwritten */
+   if((return_path = get_header(Return-Path, headers)) != NULL) 
+{
+   free(return_path);
+   }
+   else {
+
+   if((return_path = get_header(From, headers)) != 
+NULL) {
+   
+   if((address = extract_address(return_path)) != 
+NULL) {
+   fprintf(sendmail, Return-Path: 
+%s\n, address);
+   free(address);
+   }
+
+   free(return_path);
+
+   }
+   }
+
fprintf(sendmail, %s\n, headers);
}
fprintf(sendmail, \n%s\n, message);

-- 
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php




Re: [PHP-DEV] Default Return-Path with mail() and qmail

2002-12-07 Thread Andi Gutmans
Are you sure you should be using malloc()/free() and not emalloc()/efree()?
Also please use strlcpy() instead of strncpy(). (Weird I mentioned it twice 
in one day :)
http://www.courtesan.com/todd/papers/strlcpy.html

Andi


At 04:54 PM 12/7/2002 +0100, Daniel Lorch wrote:
--- php-4.2.3/ext/standard/mail.c   Sat Aug 24 13:38:13 2002
+++ php-4.2.3-daniel/ext/standard/mail.cMon Dec  2 01:24:35 2002
@@ -21,6 +21,7 @@
 #include stdlib.h
 #include ctype.h
 #include stdio.h
+#include string.h
 #include php.h
 #include ext/standard/info.h
 #if !defined(PHP_WIN32)
@@ -124,6 +125,84 @@
 }
 /* }}} */

+char *get_header_value(char *line)
+{
+   while(*line  *line != ':')
+   line++;
+
+   if(!*line)
+   return NULL;
+
+   line++;
+
+   while(isspace(*line))
+   line++;
+
+   return strdup(line);
+}
+
+char *get_header(char *header_name, char *headers)
+{
+   char *line, *value=NULL;
+   int header_name_len = strlen(header_name);
+   int len=0;
+
+   do {
+   if(*headers == '\n' || *headers == '\0') {
+   if(len  header_name_len) {
+   len = 0;
+   continue;
+   }
+
+   if((line = (char *)malloc(len + 1)) == NULL)
+   return NULL;
+
+   headers -= len;
+
+   strncpy(line, headers, len);
+   line[len] = '\0';
+
+   headers += len;
+
+   if(strncmp(line, header_name, header_name_len) == 0) {
+   value = get_header_value(line);
+   }
+
+   free(line);
+
+   len = 0;
+   } else {
+   ++len;
+   }
+   } while(*headers++  value == NULL);
+
+   return value;
+}
+
+char *extract_address(char *address)
+{
+   char *start, *stop, *tmp;
+
+   if((start = stop = strchr(address, '@')) == NULL)
+   return NULL;
+
+   while(start = address  !isspace(*start)  *start != '')
+   start--;
+
+   start++;
+
+   while(*stop  !isspace(*stop)  *stop != '')
+   stop++;
+
+   if((tmp = (char *)malloc(stop - start + 1)) == NULL)
+   return NULL;
+
+   strncpy(tmp, start, stop - start);
+   tmp[stop-start] = '\0';
+
+   return tmp;
+}
+
 /* {{{ php_mail
  */
 PHPAPI int php_mail(char *to, char *subject, char *message, char 
*headers, char *extra_cmd)
@@ -135,6 +214,8 @@
int ret;
char *sendmail_path = INI_STR(sendmail_path);
char *sendmail_cmd = NULL;
+   char *return_path;
+   char *address;

if (!sendmail_path) {
 #ifdef PHP_WIN32
@@ -169,6 +250,25 @@
fprintf(sendmail, To: %s\n, to);
fprintf(sendmail, Subject: %s\n, subject);
if (headers != NULL) {
+
+   /* Existing Return-Path should not be overwritten */
+   if((return_path = get_header(Return-Path, 
headers)) != NULL) {
+   free(return_path);
+   }
+   else {
+
+   if((return_path = get_header(From, 
headers)) != NULL) {
+
+   if((address = 
extract_address(return_path)) != NULL) {
+   fprintf(sendmail, 
Return-Path: %s\n, address);
+   free(address);
+   }
+
+   free(return_path);
+
+   }
+   }
+
fprintf(sendmail, %s\n, headers);
}
fprintf(sendmail, \n%s\n, message);

--
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php


--
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php




Re: [PHP-DEV] Default Return-Path with mail() and qmail

2002-11-29 Thread Daniel Lorch
hi,

 I'm a big -1 on this.  The patch will not actually solve the root problem.

 On Unix systems, the MTA needs to know that the webserver user is
 'trusted' to masquerade as another user.  In exim this would be the
 'trusted-users' directive, sendmail, qmail, and postfix have similar
 directives.

Thanks for pointing this out. I was pretty sure there was something un-RFC-ish
about my patch. However, I think the patch creates a more intuitive behaviour:
If the user supplies a From:  header, he expects all replies coming back to
this address -- be it human generated responses or bounce messages.

In contrast to qmail-inject (handling local mails), qmail-smtp (the SMTP-daemon)
DOES use the From header (of the mail envelope, not header) for the
Return-Path. I would call this inconsistent behaviour. However, I'm currently
discussing this on the qmail mailing list, please don't be bothered by this
here :)

 You might consider recommending a configuration setting like the following 
 in each VirtualHost block on a multi-domain Apache server.  This sends 
 bounces and replies to the webmaster of the domain if no attempt is made to 
 set the From: and Reply-to: headers when mail() is used.
 
 VirtualHost www.mydomain.com
 pph_admin_value sendmail_path /usr/sbin/sendmail -t [EMAIL PROTECTED]

That's actually a good proposition. The documentation team might want to
catch this up. Unfortunately, this doesn't work with my setup, as I'm
(mod_cgi-)wrapping all scripts. 

-daniel

-- 
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php




Re: [PHP-DEV] Default Return-Path with mail() and qmail

2002-11-28 Thread Daniel Lorch
--- php-4.2.3/ext/standard/mail.c   Thu Nov 28 11:37:12 2002
+++ php-4.2.3-daniel/ext/standard/mail.cFri Nov 29 01:50:09 2002
@@ -21,6 +21,7 @@
 #include stdlib.h
 #include ctype.h
 #include stdio.h
+#include string.h
 #include php.h
 #include ext/standard/info.h
 #if !defined(PHP_WIN32)
@@ -124,6 +125,66 @@
 }
 /* }}} */
 
+char *get_header(char *header_name, char *headers)
+{
+   char *tmp;
+   char *header_value = NULL;
+   int len=0, i;
+   
+   do {
+   if(*headers == '\n' || *headers == '\0') {
+   if(len  strlen(header_name)) {
+   len = 0;
+   continue;
+   }
+   
+   if((tmp = (char *)malloc(strlen(header_name) + 1)) == NULL)
+   return NULL;
+
+   /* rewind pointer */
+   for(i = 0; i  len; ++i)
+   --headers;
+
+   /* copy data */
+   for(i = 0; i  strlen(header_name); ++i) {
+   tmp[i] = *headers++;
+   }
+   
+   tmp[i] = '\0';
+
+   /* compare */
+   if(strcasecmp(header_name, tmp) == 0) {
+   header_value = (char *)malloc(len - 
+strlen(header_name) - 2 /* colon and space */ + 1);
+   
+   *headers++; /* colon */
+   *headers++; /* space */
+   
+   for(i = 0; i  len - strlen(header_name) - 2 /* colon 
+and space */; ++i) {
+   header_value[i] = *headers++;
+   }
+   
+   header_value[i] = '\0';
+   }
+   else {
+   /* fast foward pointer :) */
+   for(i = strlen(header_name); i  len; ++i) {
+   headers++;
+   }
+   }
+
+   free(tmp);
+   
+   len = 0;
+   }
+   else {
+   ++len;
+   }
+   }
+   while(*headers++  header_value == NULL);
+
+   return header_value;
+}
+
 /* {{{ php_mail
  */
 PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char 
*extra_cmd)
@@ -135,6 +196,7 @@
int ret;
char *sendmail_path = INI_STR(sendmail_path);
char *sendmail_cmd = NULL;
+   char *return_path;
 
if (!sendmail_path) {
 #ifdef PHP_WIN32
@@ -169,6 +231,21 @@
fprintf(sendmail, To: %s\n, to);
fprintf(sendmail, Subject: %s\n, subject);
if (headers != NULL) {
+
+   if((return_path = get_header(Return-Path, headers)) == NULL) 
+{
+   if((return_path = get_header(From, headers)) != 
+NULL) {
+   if(strchr(return_path, ''))
+   fprintf(sendmail, Return-Path: %s\n, 
+return_path);
+   else
+   fprintf(sendmail, Return-Path: 
+%s\n, return_path);
+
+   free(return_path);
+   }
+   }
+   else {
+   free(return_path);
+   }
+
fprintf(sendmail, %s\n, headers);
}
fprintf(sendmail, \n%s\n, message);

-- 
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php




Re: [PHP-DEV] Default Return-Path with mail() and qmail

2002-11-28 Thread Sara
I'm a big -1 on this.  The patch will not actually solve the root problem.

On Unix systems, the MTA needs to know that the webserver user is
'trusted' to masquerade as another user.  In exim this would be the
'trusted-users' directive, sendmail, qmail, and postfix have similar
directives.

On Windows systems it is necessary to use ini_set() to change the value of
sendmail_from, though this won't necessarily work with all MTAs.

It doesn't help that the behavior of mail() varies so greatly between
platforms.

I agree that the documentation could use some updating in this regard and
would be happy to make that modification after I collect up some examples
of the correct directives to use on common systems.

-Pollita

 I was fed up with getting a lot of bounce mails of users on my host, who
 apparently just have discovered the mail() function in PHP and are
 writing mails to bogus recipients.

 Apparently, the default Return-Path that is being set by our MTA
 (qmail) is Return-Path: anonymous@myhost, even if the user has set a
 From: header. I thought this was quite counter-intuitive, as any error
 messages, such as not available mailboxes etc.. were bouncing back to me
 instead of the users.

 Instead of documenting this behaviour and telling all users that they
 should also add a Return-Path to their mail() commands, I decided to
 write a patch which, if no Return-Path header was set, would use the
From header instead (if it existed, of course).

 I'm pretty sure this is not the right thing (tm) to do, as I should
 rather fix this problem with my MTA. However, I am currently too dumb to
 understand qmail's sources (DJB should have really commented his
 sourcecode), therefore I just did this quick fix. I posted it here
 because I heard others having the same problem. All others please
 just ignore this posting :)

 Warning(s):
   - This is NOT a general-purpose patch (do not apply to main branch) -
 This patch probably breaks all rules on coding style and consistency
 (malloc instead of emalloc etc..)
   - I know C for only a couple of weeks. Don't blame me if everything
 crashes and your machine burns down.

 -daniel




-- 
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php




Re: [PHP-DEV] Default Return-Path with mail() and qmail

2002-11-28 Thread Rick Widmer
At 06:28 PM 11/28/02 -0800, Sara Pollita Golemon wrote:

I'm a big -1 on this.  The patch will not actually solve the root problem.

On Unix systems, the MTA needs to know that the webserver user is
'trusted' to masquerade as another user.  In exim this would be the
'trusted-users' directive, sendmail, qmail, and postfix have similar
directives.

I agree that the documentation could use some updating in this regard and
would be happy to make that modification after I collect up some examples
of the correct directives to use on common systems.


Qmail seems to trust everyone on the system by default.  I did nothing 
special to allow 'nobody' rights to use sendmail -f to set the From: 
address.  (Running Qmail's sendmail wrapper.)


You might consider recommending a configuration setting like the following 
in each VirtualHost block on a multi-domain Apache server.  This sends 
bounces and replies to the webmaster of the domain if no attempt is made to 
set the From: and Reply-to: headers when mail() is used.

VirtualHost www.mydomain.com
pph_admin_value sendmail_path /usr/sbin/sendmail -t [EMAIL PROTECTED]



I think sendmail requires the user to be a member of the 'trusted' group, 
but I yield to anyone who knows more about it.

Rick


--
PHP Development Mailing List http://www.php.net/
To unsubscribe, visit: http://www.php.net/unsub.php