modifing PEAR Mail so we can use return paths

From: Date: Tue, 27 May 2003 01:39:23 +0000
Subject: modifing PEAR Mail so we can use return paths
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-16735@lists.php.net to get a copy of this message
hello everyone... Perhaps this has already been suggested (or perhaps im going down the wrong path.....?), however I couldnt find anything on the dev mailing list.. I think that there can be changes made to the PEAR's Mail class(s) that would allow people to define the Return-Path properly without it being overwritten as the From path as currently happens. For example if I set the headers as follows; $hdrs = array('To' => 'Alex Hayes <alex@alution.com>', 'Return-Path' => 'bounce.processor@alution.com', 'From' => 'MY NEWS STUF... <alexhayes@alution.com>', 'Subject' => 'Hello'); The Return-Path doesnt get used properly. This is because the implementation of the mail classes IE. Mail/sendmail.php overwrite the return path by using the -f argument, as follows... $mail = popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w'); As most will realise, the -f$from will overwrite the return path to whatever $from is equal to. I believe that it would be more sensible to use the return path that was defined by the header. This is also the same for some other mail backends, such as qmail. I realise that it is possible to send on non bounces to human addresses in most mta's, however I think that it would make more sense, if the return-path specified in the header was actually the return-path used.... This will not effect backwards compatibility as we can do the following in Mail.php... Hopefully someone can notice my changes... il put /* CHANGE */ /* / CHANGE */ around them... >> (...)----------------------------- function prepareHeaders($headers) { // Look out for the From: value to use along the way. $text_headers = ''; // text representation of headers $from = null; foreach ($headers as $key => $val) { if ($key == 'From') { include_once 'Mail/RFC822.php'; $from_arr = Mail_RFC822::parseAddressList($val, 'localhost', false); $from = $from_arr[0]->mailbox . '@' . $from_arr[0]->host; if (strstr($from, ' ')) { // Reject outright envelope From addresses with spaces. return false; } $text_headers .= $key . ': ' . $val . "\n"; } else if ($key == 'Received') { // put Received: headers at the top, since Receieved: // after Subject: in the header order is somtimes used // as a spam trap. $text_headers = $key . ': ' . $val . "\n" . $text_headers; /* CHANGE */ } else if ($key == 'Return-Path') { // NOTE: we now try and get the Return-Path, so that if we need to we can // bounce the message back to the Return-Path rather than the from address // which can be useful. If there is no Return-Path specified however, // the Return-Path should default to the From address. include_once 'Mail/RFC822.php'; $return_path_arr = Mail_RFC822::parseAddressList($val, 'localhost', false); $return_path = $return_path_arr[0]->mailbox . '@' . $return_path_arr[0]->host; if (strstr($return_path, ' ')) { // Reject outright envelope From addresses with spaces. return false; } $text_headers .= $key . ': ' . $val . "\n"; /* / CHANGE */ } else { $text_headers .= $key . ': ' . $val . "\n"; } } /* CHANGE */ // If there is no return path set, defaults to the From address. if(!is_set($return_path)) { $return_path = $from; } return array($from, $text_headers, $return_path); /* /CHANGE */ -----------------------------(...)<< Then with our sendmail implementation of the mail class we can do the following... >> (...)----------------------------- function send($recipients, $headers, $body) { $recipients = escapeShellCmd(implode(' ', $this->parseRecipients($recipients))); /* CHANGE */ list($from, $text_headers, $return_path) = $this->prepareHeaders($headers); /* / CHANGE */ if (!isset($from)) { return new PEAR_Error('No from address given.'); } elseif (strstr($from, ' ') || strstr($from, ';') || strstr($from, '&') || strstr($from, '`')) { return new PEAR_Error('From address specified with dangerous characters.'); } $result = 0; if (@is_executable($this->sendmail_path)) { $from = escapeShellCmd($from); /* CHANGE */ $return_path = escapeShellCmd($return_path); $mail = popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$return_path -- $recipients", 'w'); /* /CHANGE */ fputs($mail, $text_headers); fputs($mail, "\n"); // newline to end the headers section fputs($mail, $body); $result = pclose($mail) >> 8 & 0xFF; // need to shift the pclose result to get the exit code } else { return new PEAR_Error('sendmail [' . $this->sendmail_path . '] not executable'); } if ($result != 0) { return new PEAR_Error('sendmail returned error code ' . $result); } return true; } -----------------------------(...)<< If this was done for a reason then that is fine... maybe i totally missed the point.... Also in question is whether or not we should check for dangerous characters in the return-path, as is done with the from path... any suggestions? thanks alex

« previous php.pear.dev (#16735) next »