# HG changeset patch
# Parent a9d426e01d37d2a72fcfeb8cd63242982d04adb2
# User Sukhbir Singh <sukhbir.in@gmail.com>
Prevent local timestamp disclosure via Date and Message-ID header fields.


diff --git a/mailnews/compose/src/nsMsgCompUtils.cpp b/mailnews/compose/src/nsMsgCompUtils.cpp
--- a/mailnews/compose/src/nsMsgCompUtils.cpp
+++ b/mailnews/compose/src/nsMsgCompUtils.cpp
@@ -364,36 +364,42 @@ mime_generate_headers (nsMsgCompFields *
     if (deliver_mode == MSG_SaveAsTemplate) {
       const char *pStr = fields->GetTemplateName();
       pStr = pStr ? pStr : "";
       ENCODE_AND_PUSH("X-Template: ", false, pStr, charset, usemime);
     }
 #endif /* SUPPORT_X_TEMPLATE_NAME */
   }
 
-  PRExplodedTime now;
-  PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &now);
-  int gmtoffset = (now.tm_params.tp_gmt_offset + now.tm_params.tp_dst_offset) / 60;
+  bool local_date_header = true;
+  prefs->GetBoolPref("mailnews.local_date_header_generation", &local_date_header);
 
-  /* Use PR_FormatTimeUSEnglish() to format the date in US English format,
-     then figure out what our local GMT offset is, and append it (since
-     PR_FormatTimeUSEnglish() can't do that.) Generate four digit years as
-     per RFC 1123 (superceding RFC 822.)
-   */
-  PR_FormatTimeUSEnglish(buffer_tail, 100,
-               "Date: %a, %d %b %Y %H:%M:%S ",
-               &now);
+  if (local_date_header)
+  {
+    PRExplodedTime now;
+    PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &now);
+    int gmtoffset = (now.tm_params.tp_gmt_offset + now.tm_params.tp_dst_offset) / 60;
 
-  buffer_tail += PL_strlen (buffer_tail);
-  PR_snprintf(buffer_tail, buffer + size - buffer_tail,
-        "%c%02d%02d" CRLF,
-        (gmtoffset >= 0 ? '+' : '-'),
-        ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) / 60),
-        ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) % 60));
-  buffer_tail += PL_strlen (buffer_tail);
+    /* Use PR_FormatTimeUSEnglish() to format the date in US English format,
+       then figure out what our local GMT offset is, and append it (since
+       PR_FormatTimeUSEnglish() can't do that.) Generate four digit years as
+       per RFC 1123 (superceding RFC 822.)
+     */
+    PR_FormatTimeUSEnglish(buffer_tail, 100,
+                 "Date: %a, %d %b %Y %H:%M:%S ",
+                 &now);
+
+    buffer_tail += PL_strlen (buffer_tail);
+    PR_snprintf(buffer_tail, buffer + size - buffer_tail,
+          "%c%02d%02d" CRLF,
+          (gmtoffset >= 0 ? '+' : '-'),
+          ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) / 60),
+          ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) % 60));
+    buffer_tail += PL_strlen (buffer_tail);
+  }
 
   if (pFrom && *pFrom)
   {
     ENCODE_AND_PUSH("From: ", true, pFrom, charset, usemime);
   }
 
   if (pReplyTo && *pReplyTo)
   {
@@ -1109,19 +1115,36 @@ msg_generate_message_id (nsIMsgIdentity 
       ++host;
   }
 
   if (!isValidHost(host))
   /* If we couldn't find a valid host name to use, we can't generate a
      valid message ID, so bail, and let NNTP and SMTP generate them. */
     return 0;
 
-  GenerateGlobalRandomBytes((unsigned char *) &salt, sizeof(salt));
-  return PR_smprintf("<%lX.%lX@%s>",
-           (unsigned long) now, (unsigned long) salt, host);
+  bool custom_message_id = false;
+  nsCString message_id;
+
+  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+  if (NS_SUCCEEDED(rv)) {
+    prefs->GetBoolPref("mailnews.custom_message_id", &custom_message_id);
+    prefs->GetCharPref("mailnews.header.custom_message_id", getter_Copies(message_id));
+  }
+
+  if (!custom_message_id)
+  {
+    GenerateGlobalRandomBytes((unsigned char *) &salt, sizeof(salt));
+    return PR_smprintf("<%lX.%lX@%s>",
+             (unsigned long) now, (unsigned long) salt, host);
+  }
+  else
+  {
+    return PR_smprintf("<%s@%s>",
+             message_id.get(), host);
+  }
 }
 
 
 inline static bool is7bitCharset(const nsCString& charset)
 {
   // charset name is canonical (no worry about case-sensitivity)
   return charset.EqualsLiteral("HZ-GB-2312") ||
          Substring(charset, 0, 8).EqualsLiteral("ISO-2022-");
diff --git a/mailnews/mailnews.js b/mailnews/mailnews.js
--- a/mailnews/mailnews.js
+++ b/mailnews/mailnews.js
@@ -821,8 +821,16 @@ pref("mail.smtp.qos", 0);
 pref("mail.nntp.qos", 0);
 
 // default value for IMAP4
 // in a DSCP environment this should be 56 (0x38, or AF13), ibid.
 pref("mail.imap.qos", 0);
 
 // PgpMime Addon
 pref("mail.pgpmime.addon_url", "https://addons.mozilla.org/addon/enigmail/");
+
+// Send emails with the Date header.
+// If set to false, the Date header will be inserted by the MSA (RFC 4409/RFC 6409).
+pref("mailnews.local_date_header_generation", true);
+
+// Allow a custom message-ID to be set through an extension.
+pref("mailnews.custom_message_id", false);
+pref("mailnews.header.custom_message_id", "");
