Source for file Deliver_SMTP.class.php
Documentation is available at Deliver_SMTP.class.php
* SMTP delivery backend for the Deliver class.
* @copyright © 1999-2006 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id: Deliver_SMTP.class.php,v 1.13.2.17 2006/08/01 09:39:36 kink Exp $
/** This of course depends upon Deliver */
require_once(SM_PATH .
'class/deliver/Deliver.class.php');
* Deliver messages using SMTP
if ($s{0} ==
'.') $s =
'.' .
$s;
// TODO merge 1.5.1 changes regarding system wide SMTP username
function initStream($message, $domain, $length=
0, $host=
'', $port=
'', $user=
'', $pass=
'', $authpop=
false) {
$this->authPop($host, '', $username, $pass);
$rfc822_header =
$message->rfc822_header;
$from =
$rfc822_header->from[0];
$to =
$rfc822_header->to;
$cc =
$rfc822_header->cc;
$bcc =
$rfc822_header->bcc;
$content_type =
$rfc822_header->content_type;
// MAIL FROM: <from address> MUST be empty in cae of MDN (RFC2298)
if ($content_type->type0 ==
'multipart' &&
$content_type->type1 ==
'report' &&
isset
($content_type->properties['report-type']) &&
$content_type->properties['report-type']==
'disposition-notification') {
// reinitialize the from object because otherwise the from header somehow
// is affected. This $from var is used for smtp command MAIL FROM which
// is not the same as what we put in the rfc822 header.
$stream =
@fsockopen('tls://' .
$host, $port, $errorNumber, $errorString);
$stream =
@fsockopen($host, $port, $errorNumber, $errorString);
$this->dlv_msg =
$errorString;
$this->dlv_ret_nr =
$errorNumber;
$this->dlv_server_msg =
_("Can't open SMTP stream.");
$tmp =
fgets($stream, 1024);
* If $_SERVER['HTTP_HOST'] is set, use that in our HELO to the SMTP
* server. This should fix the DNS issues some people have had
// optionally trim off port number
if($p =
strrpos($HTTP_HOST, ':')) {
$HTTP_HOST =
substr($HTTP_HOST, 0, $p);
} else { // For some reason, HTTP_HOST is not set - revert to old behavior
/* Lets introduce ourselves */
fputs($stream, "EHLO $helohost\r\n");
$tmp =
fgets($stream,1024);
// fall back to HELO if EHLO is not supported (error 5xx)
if ($this->dlv_ret_nr{0} ==
'5') {
fputs($stream, "HELO $helohost\r\n");
$tmp =
fgets($stream,1024);
if (( $smtp_auth_mech ==
'cram-md5') or ( $smtp_auth_mech ==
'digest-md5' )) {
// Doing some form of non-plain auth
if ($smtp_auth_mech ==
'cram-md5') {
fputs($stream, "AUTH CRAM-MD5\r\n");
} elseif ($smtp_auth_mech ==
'digest-md5') {
fputs($stream, "AUTH DIGEST-MD5\r\n");
$tmp =
fgets($stream,1024);
// At this point, $tmp should hold "334 <challenge string>"
// Depending on mechanism, generate response string
if ($smtp_auth_mech ==
'cram-md5') {
} elseif ($smtp_auth_mech ==
'digest-md5') {
fputs($stream, $response);
// Let's see what the server had to say about that
$tmp =
fgets($stream,1024);
// CRAM-MD5 is done at this point. If DIGEST-MD5, there's a bit more to go
if ($smtp_auth_mech ==
'digest-md5') {
// $tmp contains rspauth, but I don't store that yet. (No need yet)
$tmp =
fgets($stream,1024);
// CRAM-MD5 and DIGEST-MD5 code ends here
} elseif ($smtp_auth_mech ==
'none') {
// No auth at all, just send helo and then send the mail
// We already said hi earlier, nothing more is needed.
} elseif ($smtp_auth_mech ==
'login') {
fputs($stream, "AUTH LOGIN\r\n");
$tmp =
fgets($stream, 1024);
$tmp =
fgets($stream, 1024);
$tmp =
fgets($stream, 1024);
} elseif ($smtp_auth_mech ==
"plain") {
$query =
"AUTH PLAIN\r\n";
$read=
fgets($stream, 1024);
if (substr($read,0,3) ==
'334') { // OK so far..
fputs($stream, "$auth\r\n");
$read =
fgets($stream, 1024);
/* Right here, they've reached an unsupported auth mechanism.
This is the ugliest hack I've ever done, but it'll do till I can fix
things up better tomorrow. So tired... */
if ($this->errorCheck("535 Unable to use this auth type",$stream)) {
/* Ok, who is sending the message? */
$fromaddress =
($from->mailbox &&
$from->host) ?
$from->mailbox.
'@'.
$from->host :
'';
fputs($stream, 'MAIL FROM:<'.
$fromaddress.
">\r\n");
$tmp =
fgets($stream, 1024);
/* send who the recipients are */
for ($i =
0, $cnt =
count($to); $i <
$cnt; $i++
) {
if (!$to[$i]->host) $to[$i]->host =
$domain;
fputs($stream, 'RCPT TO:<'.
$to[$i]->mailbox.
'@'.
$to[$i]->host.
">\r\n");
$tmp =
fgets($stream, 1024);
for ($i =
0, $cnt =
count($cc); $i <
$cnt; $i++
) {
if (!$cc[$i]->host) $cc[$i]->host =
$domain;
fputs($stream, 'RCPT TO:<'.
$cc[$i]->mailbox.
'@'.
$cc[$i]->host.
">\r\n");
$tmp =
fgets($stream, 1024);
for ($i =
0, $cnt =
count($bcc); $i <
$cnt; $i++
) {
if (!$bcc[$i]->host) $bcc[$i]->host =
$domain;
fputs($stream, 'RCPT TO:<'.
$bcc[$i]->mailbox.
'@'.
$bcc[$i]->host.
">\r\n");
$tmp =
fgets($stream, 1024);
/* Lets start sending the actual message */
fputs($stream, "DATA\r\n");
$tmp =
fgets($stream, 1024);
fputs($stream, "\r\n.\r\n"); /* end the DATA part */
$tmp =
fgets($stream, 1024);
if ($this->dlv_ret_nr !=
250) {
fputs($stream, "QUIT\r\n"); /* log off */
/* check if an SMTP reply is an error and set an error message) */
$err_num =
substr($line, 0, 3);
$this->dlv_ret_nr =
$err_num;
$server_msg =
substr($line, 4);
while(substr($line, 0, 4) ==
($err_num.
'-')) {
$line =
fgets($smtpConnection, 1024);
$server_msg .=
substr($line, 4);
if ( ((int)
$err_num{0}) <
4) {
case '421':
$message =
_("Service not available, closing channel");
case '432':
$message =
_("A password transition is needed");
case '450':
$message =
_("Requested mail action not taken: mailbox unavailable");
case '451':
$message =
_("Requested action aborted: error in processing");
case '452':
$message =
_("Requested action not taken: insufficient system storage");
case '454':
$message =
_("Temporary authentication failure");
case '500':
$message =
_("Syntax error; command not recognized");
case '501':
$message =
_("Syntax error in parameters or arguments");
case '502':
$message =
_("Command not implemented");
case '503':
$message =
_("Bad sequence of commands");
case '504':
$message =
_("Command parameter not implemented");
case '530':
$message =
_("Authentication required");
case '534':
$message =
_("Authentication mechanism is too weak");
case '535':
$message =
_("Authentication failed");
case '538':
$message =
_("Encryption required for requested authentication mechanism");
case '550':
$message =
_("Requested action not taken: mailbox unavailable");
case '551':
$message =
_("User not local; please try forwarding");
case '552':
$message =
_("Requested mail action aborted: exceeding storage allocation");
case '553':
$message =
_("Requested action not taken: mailbox name not allowed");
case '554':
$message =
_("Transaction failed");
default:
$message =
_("Unknown response");
$this->dlv_msg =
$message;
function authPop($pop_server=
'', $pop_port=
'', $user, $pass) {
$pop_server =
'localhost';
$popConnection =
fsockopen($pop_server, $pop_port, $err_no, $err_str);
error_log("Error connecting to POP Server ($pop_server:$pop_port)"
.
" $err_no : $err_str");
$tmp =
fgets($popConnection, 1024); /* banner */
if (substr($tmp, 0, 3) !=
'+OK') {
fputs($popConnection, "USER $user\r\n");
$tmp =
fgets($popConnection, 1024);
if (substr($tmp, 0, 3) !=
'+OK') {
fputs($popConnection, 'PASS ' .
$pass .
"\r\n");
$tmp =
fgets($popConnection, 1024);
if (substr($tmp, 0, 3) !=
'+OK') {
fputs($popConnection, "QUIT\r\n"); /* log off */
Documentation generated on Sat, 07 Oct 2006 16:30:57 +0300 by phpDocumentor 1.3.0RC6