+ /**
+ * function prepareRFC822_Header - prepares the RFC822 header string from Rfc822Header object(s)
+ *
+ * This function takes the Rfc822Header object(s) and formats them
+ * into the RFC822Header string to send to the SMTP server as part
+ * of the SMTP message.
+ *
+ * @param Rfc822Header $rfc822_header
+ * @param Rfc822Header $reply_rfc822_header
+ * @param integer &$raw_length length of the message
+ *
+ * @return string $header
+ */
+ function prepareRFC822_Header(&$rfc822_header, $reply_rfc822_header, &$raw_length) {
+ global $domain, $username, $encode_header_key,
+ $edit_identity, $hide_auth_header;
+
+ /* 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;
+ }
+
+ sqGetGlobalVar('REMOTE_ADDR', $REMOTE_ADDR, SQ_SERVER);
+ sqGetGlobalVar('REMOTE_PORT', $REMOTE_PORT, SQ_SERVER);
+ sqGetGlobalVar('REMOTE_HOST', $REMOTE_HOST, SQ_SERVER);
+ sqGetGlobalVar('HTTP_VIA', $HTTP_VIA, SQ_SERVER);
+ sqGetGlobalVar('HTTP_X_FORWARDED_FOR', $HTTP_X_FORWARDED_FOR, SQ_SERVER);
+
+ $rn = "\r\n";
+
+ /* This creates an RFC 822 date */
+ $now = time();
+ $now_date = date('D, j M Y H:i:s ', $now) . $this->timezone();
+ // TODO: Do we really want to preserve possibly old date? Date header should always have "now"... but here is not where this decision should be made -- the caller really should blank out $rfc822_header->date even for drafts being re-edited or sent
+ if (!empty($rfc822_header->date) && $rfc822_header->date != -1)
+ $message_date = date('D, j M Y H:i:s ', $rfc822_header->date) . $this->timezone();
+ else {
+ $message_date = $now_date;
+ $rfc822_header->date = $now;
+ }
+
+ /* Create a message-id */
+ $message_id = 'MESSAGE ID GENERATION ERROR! PLEASE CONTACT SQUIRRELMAIL DEVELOPERS';
+ if (empty($rfc822_header->message_id)) {
+ $message_id = '<'
+ . md5(GenerateRandomString(16, '', 7) . uniqid(mt_rand(),true))
+ . '.squirrel@' . $SERVER_NAME .'>';
+ }
+
+ /* Make an RFC822 Received: line */
+ if (isset($REMOTE_HOST)) {
+ $received_from = "$REMOTE_HOST ([$REMOTE_ADDR])";
+ } else {
+ $received_from = $REMOTE_ADDR;
+ }
+ if (isset($HTTP_VIA) || isset ($HTTP_X_FORWARDED_FOR)) {
+ if (!isset($HTTP_X_FORWARDED_FOR) || $HTTP_X_FORWARDED_FOR == '') {
+ $HTTP_X_FORWARDED_FOR = 'unknown';
+ }
+ $received_from .= " (proxying for $HTTP_X_FORWARDED_FOR)";
+ }
+ $header = array();
+
+ /**
+ * SquirrelMail header
+ *
+ * This Received: header provides information that allows to track
+ * user and machine that was used to send email. Don't remove it
+ * unless you understand all possible forging issues or your
+ * webmail installation does not prevent changes in user's email address.
+ * See SquirrelMail bug tracker #847107 for more details about it.
+ *
+ * Add hide_squirrelmail_header as a candidate for config_local.php
+ * (must be defined as a constant: define('hide_squirrelmail_header', 1);
+ * to allow completely hiding SquirrelMail participation in message
+ * processing; This is dangerous, especially if users can modify their
+ * account information, as it makes mapping a sent message back to the
+ * original sender almost impossible.
+ */
+ $show_sm_header = ( defined('hide_squirrelmail_header') ? ! hide_squirrelmail_header : 1 );
+
+ // FIXME: The following headers may generate slightly differently between the message sent to the destination and that stored in the Sent folder because this code will be called before both actions. This is not necessarily a big problem, but other headers such as Message-ID and Date are preserved between both actions
+ if ( $show_sm_header ) {
+ if (isset($encode_header_key) &&
+ trim($encode_header_key)!='') {
+ // use encoded headers, if encryption key is set and not empty
+ $header[] = 'X-Squirrel-UserHash: '.OneTimePadEncrypt($username,base64_encode($encode_header_key)).$rn;
+ $header[] = 'X-Squirrel-FromHash: '.OneTimePadEncrypt($this->ip2hex($REMOTE_ADDR),base64_encode($encode_header_key)).$rn;
+ if (isset($HTTP_X_FORWARDED_FOR))
+ $header[] = 'X-Squirrel-ProxyHash:'.OneTimePadEncrypt($this->ip2hex($HTTP_X_FORWARDED_FOR),base64_encode($encode_header_key)).$rn;
+ } else {
+ // use default received headers
+ $header[] = "Received: from $received_from" . $rn;
+ if (!isset($hide_auth_header) || !$hide_auth_header)
+ $header[] = " (SquirrelMail authenticated user $username)" . $rn;
+ $header[] = " by $SERVER_NAME with HTTP;" . $rn;
+ $header[] = " $now_date" . $rn;
+ }
+ }
+
+ /* Insert the rest of the header fields */
+
+ if (!empty($rfc822_header->message_id)) {
+ $header[] = 'Message-ID: '. $rfc822_header->message_id . $rn;
+ } else {
+ $header[] = 'Message-ID: '. $message_id . $rn;
+ $rfc822_header->message_id = $message_id;
+ }
+
+ if (is_object($reply_rfc822_header) &&
+ isset($reply_rfc822_header->message_id) &&
+ $reply_rfc822_header->message_id) {
+ $rep_message_id = $reply_rfc822_header->message_id;
+ $header[] = 'In-Reply-To: '.$rep_message_id . $rn;
+ $rfc822_header->in_reply_to = $rep_message_id;
+ $references = $this->calculate_references($reply_rfc822_header);
+ $header[] = 'References: '.$references . $rn;
+ $rfc822_header->references = $references;
+ }
+
+ $header[] = "Date: $message_date" . $rn;
+
+ $header[] = 'Subject: '.encodeHeader($rfc822_header->subject) . $rn;
+ $header[] = 'From: '. $rfc822_header->getAddr_s('from',",$rn ",true) . $rn;
+
+ // folding address list [From|To|Cc|Bcc] happens by using ",$rn<space>"
+ // as delimiter
+ // Do not use foldLine for that.
+
+ // RFC2822 if from contains more then 1 address
+ if (count($rfc822_header->from) > 1) {
+ $header[] = 'Sender: '. $rfc822_header->getAddr_s('sender',',',true) . $rn;
+ }
+ if (count($rfc822_header->to)) {
+ $header[] = 'To: '. $rfc822_header->getAddr_s('to',",$rn ",true) . $rn;
+ }
+ if (count($rfc822_header->cc)) {
+ $header[] = 'Cc: '. $rfc822_header->getAddr_s('cc',",$rn ",true) . $rn;
+ }
+ if (count($rfc822_header->reply_to)) {
+ $header[] = 'Reply-To: '. $rfc822_header->getAddr_s('reply_to',',',true) . $rn;
+ }
+ /* Sendmail should return true. Default = false */
+ $bcc = $this->getBcc();
+ if (count($rfc822_header->bcc)) {
+ $s = 'Bcc: '. $rfc822_header->getAddr_s('bcc',",$rn ",true) . $rn;
+ if (!$bcc) {
+ $raw_length += strlen($s);
+ } else {
+ $header[] = $s;
+ }
+ }
+ /* Identify SquirrelMail */
+ $header[] = 'User-Agent: SquirrelMail/' . SM_VERSION . $rn;
+ /* Do the MIME-stuff */
+ $header[] = 'MIME-Version: 1.0' . $rn;
+ $contenttype = 'Content-Type: '. $rfc822_header->content_type->type0 .'/'.
+ $rfc822_header->content_type->type1;
+ if (count($rfc822_header->content_type->properties)) {
+ foreach ($rfc822_header->content_type->properties as $k => $v) {
+ if ($k && $v) {
+ $contenttype .= ';' .$k.'='.$v;
+ }
+ }
+ }
+ $header[] = $contenttype . $rn;
+ if ($encoding = $rfc822_header->encoding) {
+ $header[] = 'Content-Transfer-Encoding: ' . $encoding . $rn;
+ }
+ if (isset($rfc822_header->dnt) && $rfc822_header->dnt) {
+ $dnt = $rfc822_header->getAddr_s('dnt');
+ /* Pegasus Mail */
+ $header[] = 'X-Confirm-Reading-To: '.$dnt. $rn;
+ /* RFC 2298 */
+ $header[] = 'Disposition-Notification-To: '.$dnt. $rn;
+ }
+ if ($rfc822_header->priority) {
+ switch($rfc822_header->priority)