diff options
author | Kevin McCarthy <kevin@8t8.us> | 2016-02-15 19:44:23 -0800 |
---|---|---|
committer | Kevin McCarthy <kevin@8t8.us> | 2016-02-15 19:44:23 -0800 |
commit | 6f4be2b2ac3b8630e49c75b9053819db7fbe1140 (patch) | |
tree | b04a57b475962b9a6798d09beb3445dcff941418 /pgp.c | |
parent | 6bedbdc0bc02a11800b562e519c4d8a3245f862e (diff) |
Add $pgp_decryption_okay to verify multipart/encrypted are actually encrypted. (closes #3770)
In pgp classic mode, if the $pgp_decrypt_command generated output, it
assumed the content was encrypted. However, gpg will generate output
even if the block is simply signed and armored text. The problem is
that mutt was then printing mime headers labelling the output as
encrypted text in the ui.
Add a new option, and suggested value of:
set pgp_decryption_okay="^\\[GNUPG:\\] DECRYPTION_OKAY"
If set, the output from the decrypt command will be scanned for this
regexp to confirm an actual decryption occurred.
Note that gpgme already correctly rejects this form of spoofed message.
Diffstat (limited to 'pgp.c')
-rw-r--r-- | pgp.c | 52 |
1 files changed, 50 insertions, 2 deletions
@@ -224,6 +224,45 @@ static int pgp_copy_checksig (FILE *fpin, FILE *fpout) return rv; } +/* Checks PGP output messages to look for the $pgp_decryption_okay message. + * This protects against messages with multipart/encrypted headers + * but which aren't actually encrypted. See ticket #3770 + */ +static int pgp_check_decryption_okay (FILE *fpin) +{ + int rv = -1; + + if (PgpDecryptionOkay.pattern) + { + char *line = NULL; + int lineno = 0; + size_t linelen; + + while ((line = mutt_read_line (line, &linelen, fpin, &lineno, 0)) != NULL) + { + if (regexec (PgpDecryptionOkay.rx, line, 0, NULL, 0) == 0) + { + dprint (2, (debugfile, "pgp_check_decryption_okay: \"%s\" matches regexp.\n", + line)); + rv = 0; + break; + } + else + dprint (2, (debugfile, "pgp_check_decryption_okay: \"%s\" doesn't match regexp.\n", + line)); + } + FREE (&line); + } + else + { + dprint (2, (debugfile, "pgp_check_decryption_okay: No pattern.\n")); + rv = 1; + } + + return rv; +} + + /* * Copy a clearsigned message, and strip the signature and PGP's * dash-escaping. @@ -905,10 +944,18 @@ BODY *pgp_decrypt_part (BODY *a, STATE *s, FILE *fpout, BODY *p) safe_fclose (&pgpout); rv = mutt_wait_filter (thepid); mutt_unlink(pgptmpfile); - + + fflush (pgperr); + rewind (pgperr); + if (pgp_check_decryption_okay (pgperr) < 0) + { + mutt_error _("Decryption failed"); + pgp_void_passphrase (); + return NULL; + } + if (s->flags & M_DISPLAY) { - fflush (pgperr); rewind (pgperr); if (pgp_copy_checksig (pgperr, s->fpout) == 0 && !rv && p) p->goodsig = 1; @@ -1080,6 +1127,7 @@ int pgp_encrypted_handler (BODY *a, STATE *s) else { mutt_error _("Could not decrypt PGP message"); + mutt_sleep (2); /* void the passphrase, even if it's not necessarily the problem */ pgp_void_passphrase (); rc = -1; |