X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=class%2Fdeliver%2FDeliver.class.php;h=2f8e6a3153c666d2cdbd11def8e2be5668ceb008;hb=49c7f4111d0e0bf2e8e5eb661fc869006c2db2e1;hp=45ed6ab8375faaa5033d7f57d713ed9e8f137991;hpb=0fdb0aa1fadc8a897622a53ca3338a704cb66588;p=squirrelmail.git diff --git a/class/deliver/Deliver.class.php b/class/deliver/Deliver.class.php index 45ed6ab8..2f8e6a31 100644 --- a/class/deliver/Deliver.class.php +++ b/class/deliver/Deliver.class.php @@ -28,11 +28,23 @@ */ class Deliver { + /** + * Most recently calculated Message-ID + * External code should NEVER access this directly! + * @var string + */ + var $message_id; + /** * function mail - send the message parts to the SMTP stream * * @param Message $message Message object to send * @param resource $stream Handle to the SMTP stream + * (when FALSE, nothing will be + * written to the stream; this can + * be used to determine the actual + * number of bytes that will be + * written to the stream) * @param string $reply_id Identifies message being replied to * (OPTIONAL; caller should ONLY specify * a value for this when the message @@ -42,10 +54,21 @@ class Deliver { * message inside another (OPTIONAL; caller * should ONLY specify a value for this * when the message being sent is a reply) + * @param mixed $extra Any implementation-specific variables + * can be passed in here and used in + * an overloaded version of this method + * if needed. + * + * @return array An array containing at least these elements in this order: + * - The number of bytes written (or that would have been + * written) to the output stream + * - The message ID (WARNING: if $stream is FALSE, this + * may not be supplied, or may not be accurate) * - * @return integer $raw_length */ - function mail($message, $stream=false, $reply_id=0, $reply_ent_id=0) { + function mail($message, $stream=false, $reply_id=0, $reply_ent_id=0, + $extra=NULL) { + $rfc822_header = $message->rfc822_header; if (count($message->entities)) { $boundary = $this->mimeBoundary(); @@ -61,7 +84,8 @@ class Deliver { if ($reply_id) { global $imapConnection, $username, $imapServerAddress, $imapPort, $mailbox; - if (!$imapConnection) + + if (!is_resource($imapConnection)) $imapConnection = sqimap_login($username, FALSE, $imapServerAddress, $imapPort, 0); @@ -81,20 +105,52 @@ class Deliver { } else { $orig_header = $reply_message->rfc822_header; } + $message->reply_rfc822_header = $orig_header; } - $message->reply_rfc822_header = $orig_header; $reply_rfc822_header = (isset($message->reply_rfc822_header) ? $message->reply_rfc822_header : ''); $header = $this->prepareRFC822_Header($rfc822_header, $reply_rfc822_header, $raw_length); + $this->send_mail($message, $header, $boundary, $stream, $raw_length, $extra); + + return array($raw_length, $this->message_id); + } + + /** + * function send_mail - send the message parts to the IMAP stream + * + * @param Message $message Message object to send + * @param string $header Headers ready to send + * @param string $boundary Message parts boundary + * @param resource $stream Handle to the SMTP stream + * (when FALSE, nothing will be + * written to the stream; this can + * be used to determine the actual + * number of bytes that will be + * written to the stream) + * @param int &$raw_length The number of bytes written (or that + * would have been written) to the + * output stream - NOTE that this is + * passed by reference + * @param mixed $extra Any implementation-specific variables + * can be passed in here and used in + * an overloaded version of this method + * if needed. + * + * @return void + * + */ + function send_mail($message, $header, $boundary, $stream=false, + &$raw_length, $extra=NULL) { + + if ($stream) { $this->preWriteToStream($header); $this->writeToStream($stream, $header); } $this->writeBody($message, $stream, $raw_length, $boundary); - return $raw_length; } /** @@ -105,6 +161,11 @@ class Deliver { * * @param Message $message Message object to transform * @param resource $stream SMTP output stream + * (when FALSE, nothing will be + * written to the stream; this can + * be used to determine the actual + * number of bytes that will be + * written to the stream) * @param integer &$length_raw raw length of the message (part) * as returned by mail fn * @param string $boundary custom boundary to call, usually for subparts @@ -163,6 +224,11 @@ class Deliver { * * @param Message $message Message object to transform * @param resource $stream SMTP output stream + * (when FALSE, nothing will be + * written to the stream; this can + * be used to determine the actual + * number of bytes that will be + * written to the stream) * @param integer &$length length of the message part * as returned by mail fn * @@ -425,8 +491,10 @@ class Deliver { global $domain, $username, $encode_header_key, $edit_identity, $hide_auth_header; - /* if server var SERVER_NAME not available, use $domain */ - if(!sqGetGlobalVar('SERVER_NAME', $SERVER_NAME, SQ_SERVER)) { + /* if server var SERVER_NAME not available, or contains + ":" (e.g. IPv6) which is illegal in a Message-ID, use $domain */ + if(!sqGetGlobalVar('SERVER_NAME', $SERVER_NAME, SQ_SERVER) || + strpos($SERVER_NAME,':') !== FALSE) { $SERVER_NAME = $domain; } @@ -440,15 +508,19 @@ class Deliver { /* This creates an RFC 822 date */ $date = date('D, j M Y H:i:s ', time()) . $this->timezone(); + /* Create a message-id */ - $message_id = '<' . $REMOTE_PORT . '.'; - if (isset($encode_header_key) && trim($encode_header_key)!='') { - // use encrypted form of remote address - $message_id.= OneTimePadEncrypt($this->ip2hex($REMOTE_ADDR),base64_encode($encode_header_key)); - } else { - $message_id.= $REMOTE_ADDR; - } - $message_id .= '.' . time() . '.squirrel@' . $SERVER_NAME .'>'; + $message_id = '<'; + /* user-specifc data to decrease collision chance */ + $seed_data = $username . '.'; + $seed_data .= (!empty($REMOTE_PORT) ? $REMOTE_PORT . '.' : ''); + $seed_data .= (!empty($REMOTE_ADDR) ? $REMOTE_ADDR . '.' : ''); + /* add the current time in milliseconds and randomness */ + $seed_data .= uniqid(mt_rand(),true); + /* put it through one-way hash and add it to the ID */ + $message_id .= md5($seed_data) . '.squirrel@' . $SERVER_NAME .'>'; + $this->message_id = $message_id; + /* Make an RFC822 Received: line */ if (isset($REMOTE_HOST)) { $received_from = "$REMOTE_HOST ([$REMOTE_ADDR])";