]> granicus.if.org Git - neomutt/commitdiff
Add config and data structure for protected header write support
authorKevin McCarthy <kevin@8t8.us>
Sun, 16 Dec 2018 21:15:05 +0000 (13:15 -0800)
committerRichard Russon <rich@flatcap.org>
Mon, 7 Jan 2019 15:09:41 +0000 (15:09 +0000)
Add config vars $crypt_protected_headers_write (unset by default),
and $crypt_protected_headers_subject.

Store the protected headers during mime_protect().

Co-authored-by: Richard Russon <rich@flatcap.org>
globals.h
init.h
ncrypt/crypt.c

index 7ba9f9bd701a495aa2e1afdb3dba62fbc8fe2bd4..8d27f1b55d0865b9e0a827e442b6d1718a614cc9 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -104,6 +104,7 @@ WHERE char *Attribution;                   ///< Config: Message to start a reply
 WHERE char *AttributionLocale;             ///< Config: Locale for dates in the attribution message
 WHERE char *AttachFormat;                  ///< Config: printf-like format string for the attachment menu
 WHERE char *ConfigCharset;                 ///< Config: Character set that the config files are in
+WHERE char *CryptProtectedHeadersSubject;  ///< Config: Use this as the subject for encrypted emails
 WHERE char *DateFormat;                    ///< Config: strftime format string for the `%d` expando
 WHERE char *DsnNotify;                     ///< Config: Request notification for message delivery or delay
 WHERE char *DsnReturn;                     ///< Config: What to send as a notification of message delivery or delay
@@ -272,6 +273,7 @@ WHERE bool CryptUsePka;                    ///< Config: Use GPGME to use PKA (lo
 WHERE bool CryptConfirmhook;               ///< Config: Prompt the user to confirm keys before use
 WHERE bool CryptOpportunisticEncrypt;      ///< Config: Enable encryption when the recipient's key is available
 WHERE bool CryptProtectedHeadersRead;      ///< Config: Display protected headers (Memory Hole) in the pager
+WHERE bool CryptProtectedHeadersWrite;     ///< Config: Generate protected header (Memory Hole) for signed and encrypted emails
 WHERE bool SmimeIsDefault;                 ///< Config: Use SMIME rather than PGP by default
 WHERE bool PgpIgnoreSubkeys;               ///< Config: Only use the principal PGP key
 WHERE bool PgpLongIds;                     ///< Config: Display long PGP key IDs to the user
diff --git a/init.h b/init.h
index f3b361dcafc7dca1c46b231c068e88657c82e6b8..bcfa8a3ee124694a00f41b34c2bfa2dd481113d3 100644 (file)
--- a/init.h
+++ b/init.h
@@ -669,10 +669,40 @@ struct ConfigDef MuttVars[] = {
   ** Protected headers are stored inside the encrypted or signed part of an
   ** an email, to prevent disclosure or tampering.
   ** For more information see https://github.com/autocrypt/memoryhole.
+  ** Currently Mutt only supports the Subject header.
+  ** .pp
+  ** Encrypted messages using protected headers often substitute the exposed
+  ** Subject header with a dummy value (see $$crypt_protected_headers_subject).
+  ** Mutt will update its concept of the correct subject \fBafter\fP the
+  ** message is opened, i.e. via the \fC<display-message>\fP function.
+  ** If you reply to a message before opening it, Mutt will end up using
+  ** the dummy Subject header, so be sure to open such a message first.
+  ** (Crypto only)
+  */
+  { "crypt_protected_headers_write", DT_BOOL, R_NONE, &CryptProtectedHeadersWrite, false },
+  /*
+  ** .pp
+  ** When set, Mutt will generate protected headers ("Memory Hole") for
+  ** signed and encrypted emails.
+  **
+  ** Protected headers are stored inside the encrypted or signed part of an
+  ** an email, to prevent disclosure or tampering.
+  ** For more information see https://github.com/autocrypt/memoryhole.
   **
   ** Currently Mutt only supports the Subject header.
   ** (Crypto only)
   */
+  { "crypt_protected_headers_subject", DT_STRING, R_NONE, &CryptProtectedHeadersSubject, IP "Encrypted subject" },
+  /*
+  ** .pp
+  ** When $$crypt_protected_headers_write is set, and the message is marked
+  ** for encryption, this will be substituted into the Subject field in the
+  ** message headers.
+  **
+  ** To prevent a subject from being substituted, unset this variable, or set it
+  ** to the empty string.
+  ** (Crypto only)
+  */
   { "crypt_replyencrypt",       DT_BOOL, R_NONE, &CryptReplyencrypt, true },
   /*
   ** .pp
index 02b0c23d759a48f62158652265aff80dc797e3ed..417501700e74aaa8b1fb40e223a06da7fd737412 100644 (file)
@@ -265,13 +265,25 @@ int mutt_protect(struct Email *msg, char *keylist)
       mutt_addr_free(&from);
   }
 
+  if (CryptProtectedHeadersWrite)
+  {
+    struct Envelope *protected_headers = mutt_env_new();
+    mutt_str_replace(&protected_headers->subject, msg->env->subject);
+    /* Note: if other headers get added, such as to, cc, then a call to
+     * mutt_env_to_intl() will need to be added here too. */
+    mutt_prepare_envelope(protected_headers, 0);
+
+    mutt_env_free(&msg->content->mime_headers);
+    msg->content->mime_headers = protected_headers;
+  }
+
   if (msg->security & SIGN)
   {
     if (((WithCrypto & APPLICATION_SMIME) != 0) && (msg->security & APPLICATION_SMIME))
     {
       tmp_pbody = crypt_smime_sign_message(msg->content);
       if (!tmp_pbody)
-        return -1;
+        goto bail;
       pbody = tmp_pbody;
       tmp_smime_pbody = tmp_pbody;
     }
@@ -281,7 +293,7 @@ int mutt_protect(struct Email *msg, char *keylist)
     {
       tmp_pbody = crypt_pgp_sign_message(msg->content);
       if (!tmp_pbody)
-        return -1;
+        goto bail;
 
       flags &= ~SIGN;
       pbody = tmp_pbody;
@@ -303,7 +315,7 @@ int mutt_protect(struct Email *msg, char *keylist)
       if (!tmp_pbody)
       {
         /* signed ? free it! */
-        return -1;
+        goto bail;
       }
       /* free tmp_body if messages was signed AND encrypted ... */
       if (tmp_smime_pbody != msg->content && tmp_smime_pbody != tmp_pbody)
@@ -331,7 +343,7 @@ int mutt_protect(struct Email *msg, char *keylist)
           mutt_body_free(&tmp_pgp_pbody->next);
         }
 
-        return -1;
+        goto bail;
       }
 
       /* destroy temporary signature envelope when doing retainable
@@ -347,9 +359,14 @@ int mutt_protect(struct Email *msg, char *keylist)
   }
 
   if (pbody)
+  {
     msg->content = pbody;
+    return 0;
+  }
 
-  return 0;
+bail:
+  mutt_env_free(&msg->content->mime_headers);
+  return -1;
 }
 
 /**