Remove personal data from Message ID seed. (#880029/847107)
[squirrelmail.git] / class / deliver / Deliver.class.php
index 80f62976291e16d4635d665ebf063169f3b7b67c..fb085cb5f353b4e4e9e27d3b6c0189e95abc877b 100644 (file)
@@ -7,7 +7,7 @@
  * a delivery backend.
  *
  * @author Marc Groot Koerkamp
- * @copyright © 1999-2007 The SquirrelMail Project Team
+ * @copyright © 1999-2009 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
@@ -282,17 +282,52 @@ class Deliver {
                 global $username, $attachment_dir;
                 $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
                 $filename = $message->att_local_name;
+
+                // inspect attached file for lines longer than allowed by RFC,
+                // in which case we'll be using base64 encoding (so we can split
+                // the lines up without corrupting them) instead of 8bit unencoded...
+                // (see RFC 2822/2.1.1)
+                //
+                // using 990 because someone somewhere is folding lines at
+                // 990 instead of 998 and I'm too lazy to find who it is
+                //
+                $file_has_long_lines = file_has_long_lines($hashed_attachment_dir
+                                                           . '/' . $filename, 990);
+
                 $file = fopen ($hashed_attachment_dir . '/' . $filename, 'rb');
-                while ($body_part = fgets($file, 4096)) {
-                    // remove NUL characters
-                    $body_part = str_replace("\0",'',$body_part);
-                    $length += $this->clean_crlf($body_part);
-                    if ($stream) {
-                        $this->preWriteToStream($body_part);
-                        $this->writeToStream($stream, $body_part);
+
+                // long lines were found, need to use base64 encoding
+                //
+                if ($file_has_long_lines) {
+                    while ($tmp = fread($file, 570)) {
+                        $body_part = chunk_split(base64_encode($tmp));
+                        // Up to 4.3.10 chunk_split always appends a newline,
+                        // while in 4.3.11 it doesn't if the string to split
+                        // is shorter than the chunk length.
+                        if( substr($body_part, -1 , 1 ) != "\n" )
+                            $body_part .= "\n";
+                        $length += $this->clean_crlf($body_part);
+                        if ($stream) {
+                            $this->writeToStream($stream, $body_part);
+                        }
                     }
-                    $last = $body_part;
                 }
+
+                // no excessively long lines - normal 8bit
+                //
+                else {
+                    while ($body_part = fgets($file, 4096)) {
+                        // remove NUL characters
+                        $body_part = str_replace("\0",'',$body_part);
+                        $length += $this->clean_crlf($body_part);
+                        if ($stream) {
+                            $this->preWriteToStream($body_part);
+                            $this->writeToStream($stream, $body_part);
+                        }
+                        $last = $body_part;
+                    }
+                }
+
                 fclose($file);
             }
             break;
@@ -461,10 +496,29 @@ class Deliver {
         if ($mime_header->encoding) {
             $header[] = 'Content-Transfer-Encoding: ' . $mime_header->encoding . $rn;
         } else {
-            if ($mime_header->type0 == 'text' || $mime_header->type0 == 'message') {
-                $header[] = 'Content-Transfer-Encoding: 8bit' .  $rn;
-            } else if ($mime_header->type0 == 'multipart' || $mime_header->type0 == 'alternative') {
+
+            // inspect attached file for lines longer than allowed by RFC,
+            // in which case we'll be using base64 encoding (so we can split
+            // the lines up without corrupting them) instead of 8bit unencoded...
+            // (see RFC 2822/2.1.1)
+            //
+            if (!empty($message->att_local_name)) { // is this redundant? I have no idea
+                global $username, $attachment_dir;
+                $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
+                $filename = $hashed_attachment_dir . '/' . $message->att_local_name;
+
+                // using 990 because someone somewhere is folding lines at
+                // 990 instead of 998 and I'm too lazy to find who it is
+                //
+                $file_has_long_lines = file_has_long_lines($filename, 990);
+            } else
+                $file_has_long_lines = FALSE;
+
+            if ($mime_header->type0 == 'multipart' || $mime_header->type0 == 'alternative') {
                 /* no-op; no encoding needed */
+            } else if (($mime_header->type0 == 'text' || $mime_header->type0 == 'message')
+                    && !$file_has_long_lines) {
+                $header[] = 'Content-Transfer-Encoding: 8bit' .  $rn;
             } else {
                 $header[] = 'Content-Transfer-Encoding: base64' .  $rn;
             }
@@ -536,15 +590,9 @@ class Deliver {
         /* Create a message-id */
         $message_id = 'MESSAGE ID GENERATION ERROR! PLEASE CONTACT SQUIRRELMAIL DEVELOPERS';
         if (empty($rfc822_header->message_id)) {
-            $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 .'>';
+            $message_id = '<'
+                        . md5(GenerateRandomString(16, '', 7) . uniqid(mt_rand(),true))
+                        . '.squirrel@' . $SERVER_NAME .'>';
         }
 
         /* Make an RFC822 Received: line */