** subprocess failed.
** (PGP only)
*/
+ { "pgp_check_gpg_decrypt_status_fd", DT_BOOL, R_NONE, OPTPGPCHECKGPGDECRYPTSTATUSFD, 1 },
+ /*
+ ** .pp
+ ** If \fIset\fP, mutt will check the status file descriptor output
+ ** of $$pgp_decrypt_command for GnuPG status codes indicating
+ ** successful decryption. This will check for the presence of
+ ** DECRYPTION_OKAY, absence of DECRYPTION_FAILED, and that all
+ ** PLAINTEXT occurs between the BEGIN_DECRYPTION and END_DECRYPTION
+ ** status codes.
+ ** .pp
+ ** If \fIunset\fP, mutt will instead match the status fd output
+ ** against $$pgp_decryption_okay.
+ ** (PGP only)
+ */
{ "pgp_clearsign_command", DT_STR, R_NONE, UL &PgpClearSignCommand, 0 },
/*
** .pp
** protect against a spoofed encrypted message, with multipart/encrypted
** headers but containing a block that is not actually encrypted.
** (e.g. simply signed and ascii armored text).
+ ** .pp
+ ** Note that if $$pgp_check_gpg_decrypt_status_fd is set, this variable
+ ** is ignored.
** (PGP only)
*/
{ "pgp_self_encrypt_as", DT_SYN, R_NONE, UL "pgp_default_key", 0 },
* 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)
+static int pgp_check_pgp_decryption_okay_regexp (FILE *fpin)
{
int rv = -1;
{
if (regexec (PgpDecryptionOkay.rx, line, 0, NULL, 0) == 0)
{
- dprint (2, (debugfile, "pgp_check_decryption_okay: \"%s\" matches regexp.\n",
+ dprint (2, (debugfile, "pgp_check_pgp_decryption_okay_regexp: \"%s\" matches regexp.\n",
line));
rv = 0;
break;
}
else
- dprint (2, (debugfile, "pgp_check_decryption_okay: \"%s\" doesn't match regexp.\n",
+ dprint (2, (debugfile, "pgp_check_pgp_decryption_okay_regexp: \"%s\" doesn't match regexp.\n",
line));
}
FREE (&line);
}
else
{
- dprint (2, (debugfile, "pgp_check_decryption_okay: No pattern.\n"));
+ dprint (2, (debugfile, "pgp_check_pgp_decryption_okay_regexp: No pattern.\n"));
rv = 1;
}
return rv;
}
+/* Checks GnuPGP status fd output for various status codes indicating
+ * an issue. If $pgp_check_gpg_decrypt_status_fd is unset, it falls
+ * back to the old behavior of just scanning for $pgp_decryption_okay.
+ */
+static int pgp_check_decryption_okay (FILE *fpin)
+{
+ int rv = -1;
+ char *line = NULL, *s;
+ int lineno = 0;
+ size_t linelen;
+ int inside_decrypt = 0;
+
+ if (!option (OPTPGPCHECKGPGDECRYPTSTATUSFD))
+ return pgp_check_pgp_decryption_okay_regexp (fpin);
+
+ while ((line = mutt_read_line (line, &linelen, fpin, &lineno, 0)) != NULL)
+ {
+ if (strncmp (line, "[GNUPG:] ", 9) != 0)
+ continue;
+ s = line + 9;
+ dprint (2, (debugfile, "pgp_check_decryption_okay: checking \"%s\".\n",
+ line));
+ if (mutt_strncmp (s, "BEGIN_DECRYPTION", 16) == 0)
+ inside_decrypt = 1;
+ else if (mutt_strncmp (s, "END_DECRYPTION", 14) == 0)
+ inside_decrypt = 0;
+ else if (mutt_strncmp (s, "PLAINTEXT", 9) == 0)
+ {
+ if (!inside_decrypt)
+ {
+ dprint (2, (debugfile, "\tPLAINTEXT encountered outside of DECRYPTION. Failure.\n"));
+ rv = -1;
+ break;
+ }
+ }
+ else if (mutt_strncmp (s, "DECRYPTION_FAILED", 17) == 0)
+ {
+ dprint (2, (debugfile, "\tDECRYPTION_FAILED encountered. Failure.\n"));
+ rv = -1;
+ break;
+ }
+ else if (mutt_strncmp (s, "DECRYPTION_OKAY", 15) == 0)
+ {
+ /* Don't break out because we still have to check for
+ * PLAINTEXT outside of the decryption boundaries. */
+ dprint (2, (debugfile, "\tDECRYPTION_OKAY encountered.\n"));
+ rv = 0;
+ }
+ }
+ FREE (&line);
+
+ return rv;
+}
/*
* Copy a clearsigned message, and strip the signature and PGP's