From: Kevin McCarthy Date: Thu, 27 Dec 2018 20:05:43 +0000 (-0800) Subject: Add $crypt_protected_headers_save. X-Git-Tag: mutt-1-12-rel~152 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=333312c22e762169500949583755b6e208fc23e5;p=mutt Add $crypt_protected_headers_save. Setting this option will save the protected header back into the clear-text message headers. This improves usability (searching/limiting/replying) when reopening a mailbox without header cache. However, it is a security trade-off, so defaults off and strongly warns about what it is doing in the documentation. --- diff --git a/commands.c b/commands.c index bd09a485..5ec15888 100644 --- a/commands.c +++ b/commands.c @@ -121,6 +121,14 @@ static void update_protected_headers (HEADER *cur) hash_insert (Context->subj_hash, cur->env->real_subj, cur); mx_save_to_header_cache (Context, cur); + + /* Also persist back to the message headers if this is set */ + if (option (OPTCRYPTPROTHDRSSAVE)) + { + cur->env->changed |= MUTT_ENV_CHANGED_SUBJECT; + cur->changed = 1; + Context->changed = 1; + } } } diff --git a/copy.c b/copy.c index fa1240ab..2b0df8a6 100644 --- a/copy.c +++ b/copy.c @@ -111,6 +111,9 @@ mutt_copy_hdr (FILE *in, FILE *out, LOFF_T off_start, LOFF_T off_end, int flags, if ((flags & CH_UPDATE_LABEL) && ascii_strncasecmp ("X-Label:", buf, 8) == 0) continue; + if ((flags & CH_UPDATE_SUBJECT) && + ascii_strncasecmp ("Subject:", buf, 8) == 0) + continue; ignore = 0; } @@ -221,6 +224,9 @@ mutt_copy_hdr (FILE *in, FILE *out, LOFF_T off_start, LOFF_T off_end, int flags, if ((flags & CH_UPDATE_LABEL) && ascii_strncasecmp ("X-Label:", buf, 8) == 0) continue; + if ((flags & CH_UPDATE_SUBJECT) && + ascii_strncasecmp ("Subject:", buf, 8) == 0) + continue; /* Find x -- the array entry where this header is to be saved */ if (flags & CH_REORDER) @@ -357,7 +363,8 @@ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix) if (h->env) flags |= ((h->env->changed & MUTT_ENV_CHANGED_IRT) ? CH_UPDATE_IRT : 0) | ((h->env->changed & MUTT_ENV_CHANGED_REFS) ? CH_UPDATE_REFS : 0) - | ((h->env->changed & MUTT_ENV_CHANGED_XLABEL) ? CH_UPDATE_LABEL : 0); + | ((h->env->changed & MUTT_ENV_CHANGED_XLABEL) ? CH_UPDATE_LABEL : 0) + | ((h->env->changed & MUTT_ENV_CHANGED_SUBJECT) ? CH_UPDATE_SUBJECT : 0); if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1) return -1; @@ -444,6 +451,25 @@ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix) FREE (&temp_hdr); } + if ((flags & CH_UPDATE_SUBJECT) && h->env->subject) + { + temp_hdr = h->env->subject; + /* env->subject is directly referenced in Context->subj_hash, so we + * have to be careful not to encode (and thus free) that memory. */ + if (!(flags & CH_DECODE)) + { + temp_hdr = safe_strdup (temp_hdr); + rfc2047_encode_string (&temp_hdr); + } + if (mutt_write_one_header (out, "Subject", temp_hdr, + flags & CH_PREFIX ? prefix : 0, + mutt_window_wrap_cols (MuttIndexWindow, Wrap), + flags) == -1) + return -1; + if (!(flags & CH_DECODE)) + FREE (&temp_hdr); + } + if ((flags & CH_NONEWLINE) == 0) { if (flags & CH_PREFIX) diff --git a/copy.h b/copy.h index 2ba54143..11ade381 100644 --- a/copy.h +++ b/copy.h @@ -54,6 +54,7 @@ #define CH_UPDATE_REFS (1<<17) /* update References: */ #define CH_DISPLAY (1<<18) /* display result to user */ #define CH_UPDATE_LABEL (1<<19) /* update X-Label: from hdr->env->x_label? */ +#define CH_UPDATE_SUBJECT (1<<20) /* update Subject: protected header update */ int mutt_copy_hdr (FILE *, FILE *, LOFF_T, LOFF_T, int, const char *); diff --git a/init.h b/init.h index a3deea71..35c1ec75 100644 --- a/init.h +++ b/init.h @@ -605,6 +605,30 @@ struct option_t MuttVars[] = { ** message is opened, i.e. via the \fC\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_save", DT_BOOL, R_NONE, OPTCRYPTPROTHDRSSAVE, 0 }, + /* + ** .pp + ** When $$crypt_protected_headers_read is set, and a message with a + ** protected Subject is opened, Mutt will save the updated Subject + ** into the header cache by default. This allows searching/limiting + ** based on the protected Subject header if the mailbox is + ** re-opened, without having to re-open the message each time. + ** However, for mbox/mh mailbox types, or if header caching is not + ** set up, you would need to re-open the message each time the + ** mailbox was reopened before you could see or search/limit on the + ** protected subject again. + ** .pp + ** When this variable is set, Mutt additionally saves the protected + ** Subject back \fBin the clear-text message headers\fP. This + ** provides better usability, but with the tradeoff of reduced + ** security. The protected Subject header, which may have + ** previously been encrypted, is now stored in clear-text in the + ** message headers. Copying the message elsewhere, via Mutt or + ** external tools, could expose this previously encrypted data. + ** Please make sure you understand the consequences of this before + ** you enable this variable. ** (Crypto only) */ { "crypt_protected_headers_write", DT_BOOL, R_NONE, OPTCRYPTPROTHDRSWRITE, 0 }, diff --git a/mutt.h b/mutt.h index 3457156f..91c3b67b 100644 --- a/mutt.h +++ b/mutt.h @@ -542,6 +542,7 @@ enum OPTCRYPTCONFIRMHOOK, OPTCRYPTOPPORTUNISTICENCRYPT, OPTCRYPTPROTHDRSREAD, + OPTCRYPTPROTHDRSSAVE, OPTCRYPTPROTHDRSWRITE, OPTCRYPTREPLYENCRYPT, OPTCRYPTREPLYSIGN, @@ -659,6 +660,7 @@ typedef struct alias #define MUTT_ENV_CHANGED_IRT (1<<0) /* In-Reply-To changed to link/break threads */ #define MUTT_ENV_CHANGED_REFS (1<<1) /* References changed to break thread */ #define MUTT_ENV_CHANGED_XLABEL (1<<2) /* X-Label edited */ +#define MUTT_ENV_CHANGED_SUBJECT (1<<3) /* Protected header update */ typedef struct envelope {