#endif
#include "mutt.h"
+#include "enter.h"
+#include "ascii.h"
+#include "handler.h"
#include "mutt_curses.h"
#include "pgp.h"
#include "mime.h"
mutt_message _("PGP passphrase forgotten.");
}
-int pgp_use_gpg_agent (void)
-{
- return option (OPTUSEGPGAGENT) && getenv ("GPG_TTY")
- && getenv ("GPG_AGENT_INFO");
+int pgp_use_gpg_agent (void) {
+ char *tty;
+
+ if (!option (OPTUSEGPGAGENT) || !getenv ("GPG_AGENT_INFO"))
+ return 0;
+
+ if ((tty = ttyname(0)))
+ setenv ("GPG_TTY", tty, 0);
+
+ return 1;
}
char *pgp_keyid (pgp_key_t k)
/* Support for the Application/PGP Content Type. */
-void pgp_application_pgp_handler (BODY * m, STATE * s)
+int pgp_application_pgp_handler (BODY * m, STATE * s)
{
+ int could_not_decrypt = 0;
int needpass = -1, pgp_keyblock = 0;
+ int c = 1;
int clearsign = 0, rv, rc;
long start_pos = 0;
- long bytes, last_pos, offset;
+ long bytes;
+ LOFF_T last_pos, offset;
char buf[HUGE_STRING];
char outfile[_POSIX_PATH_MAX];
char tmpfname[_POSIX_PATH_MAX];
FILE *pgpout = NULL, *pgpin = NULL, *pgperr = NULL;
- FILE *tmpfp;
+ FILE *tmpfp = NULL;
pid_t thepid;
short maybe_goodsig = 1;
rc = 0; /* silence false compiler warning if (s->flags & M_DISPLAY) */
- fseek (s->fpin, m->offset, 0);
+ fseeko (s->fpin, m->offset, 0);
last_pos = m->offset;
for (bytes = m->length; bytes > 0;) {
if (fgets (buf, sizeof (buf), s->fpin) == NULL)
break;
- offset = ftell (s->fpin);
+ offset = ftello (s->fpin);
bytes -= (offset - last_pos); /* don't rely on str_len(buf) */
last_pos = offset;
mutt_mktemp (tmpfname);
if ((tmpfp = safe_fopen (tmpfname, "w+")) == NULL) {
mutt_perror (tmpfname);
- return;
+ return (-1);
}
fputs (buf, tmpfp);
while (bytes > 0 && fgets (buf, sizeof (buf) - 1, s->fpin) != NULL) {
- offset = ftell (s->fpin);
+ offset = ftello (s->fpin);
bytes -= (offset - last_pos); /* don't rely on str_len(buf) */
last_pos = offset;
mutt_mktemp (outfile);
if ((pgpout = safe_fopen (outfile, "w+")) == NULL) {
mutt_perror (tmpfname);
- return;
+ return (-1);
}
if ((thepid = pgp_invoke_decode (&pgpin, NULL, &pgperr, -1,
if (s->flags & M_DISPLAY) {
if (rc == 0)
have_any_sigs = 1;
-/*
- * Sig is bad if
- * gpg_good_sign-pattern did not match || pgp_decode_command returned not 0
- * Sig _is_ correct if
- * gpg_good_sign="" && pgp_decode_command returned 0
- */
+
+ /*
+ * Sig is bad if
+ * gpg_good_sign-pattern did not match || pgp_decode_command returned not 0
+ * Sig _is_ correct if
+ * gpg_good_sign="" && pgp_decode_command returned 0
+ */
if (rc == -1 || rv)
maybe_goodsig = 0;
state_attach_puts (_("[-- End of PGP output --]\n\n"), s);
}
}
- }
- /* treat empty result as sign of failure */
- if (pgpout !=NULL)
- if (! ftell(pgpout)) {
+ /* treat empty result as sign of failure */
+ /* TODO: maybe on failure mutt should include the original undecoded text. */
+ if (pgpout) {
+ rewind (pgpout);
+ c = fgetc (pgpout);
+ ungetc (c, pgpout);
+ }
+ if (!clearsign && (!pgpout || c == EOF)) {
+ could_not_decrypt = 1;
+ pgp_void_passphrase ();
+ }
+
+ if (could_not_decrypt && !(s->flags & M_DISPLAY)) {
mutt_error _("Could not decrypt PGP message");
+ mutt_sleep (1);
+ rc = -1;
goto out;
}
+ }
/*
* Now, copy cleartext to the screen. NOTE - we expect that PGP
state_putc ('\n', s);
if (needpass) {
state_attach_puts (_("[-- END PGP MESSAGE --]\n"), s);
- mutt_message _("PGP message successfully decrypted.");
+ if (could_not_decrypt)
+ mutt_error _("Could not decrypt PGP message.");
+ else
+ mutt_message _("PGP message successfully decrypted.");
}
else if (pgp_keyblock)
state_attach_puts (_("[-- END PGP PUBLIC KEY BLOCK --]\n"), s);
}
}
+ rc = 0;
+
out:
m->goodsig = (maybe_goodsig && have_any_sigs);
state_attach_puts (_
("[-- Error: could not find beginning of PGP message! --]\n\n"),
s);
- return;
+ return (-1);
}
+
+ return (rc);
}
static int pgp_check_traditional_one_body (FILE * fp, BODY * b,
return -1;
}
- fseek (s->fpin, sigbdy->offset, 0);
+ fseeko (s->fpin, sigbdy->offset, 0);
mutt_copy_bytes (s->fpin, fp, sigbdy->length);
fclose (fp);
* the temporary file.
*/
- fseek (s->fpin, a->offset, 0);
+ fseeko (s->fpin, a->offset, 0);
mutt_copy_bytes (s->fpin, pgptmp, a->length);
fclose (pgptmp);
fflush (fpout);
rewind (fpout);
- if (fgetc (fpout) == EOF)
+ if (fgetc (fpout) == EOF) {
+ mutt_error (_("Decryption failed."));
+ pgp_void_passphrase ();
return NULL;
+ }
rewind (fpout);
return (0);
}
-void pgp_encrypted_handler (BODY * a, STATE * s)
+int pgp_encrypted_handler (BODY * a, STATE * s)
{
char tempfile[_POSIX_PATH_MAX];
FILE *fpout, *fpin;
BODY *tattach;
BODY *p = a;
+ int rc = 0;
a = a->parts;
if (!a || a->type != TYPEAPPLICATION || !a->subtype ||
if (s->flags & M_DISPLAY)
state_attach_puts (_("[-- Error: malformed PGP/MIME message! --]\n\n"),
s);
- return;
+ return (-1);
}
/*
state_attach_puts (_
("[-- Error: could not create temporary file! --]\n"),
s);
- return;
+ return (-1);
}
if (s->flags & M_DISPLAY)
fpin = s->fpin;
s->fpin = fpout;
- mutt_body_handler (tattach, s);
+ rc = mutt_body_handler (tattach, s);
s->fpin = fpin;
/*
mutt_free_body (&tattach);
/* clear 'Invoking...' message, since there's no error */
mutt_message _("PGP message successfully decrypted.");
- } else
+ } else {
mutt_error _("Could not decrypt PGP message");
+ pgp_void_passphrase ();
+ rc = -1;
+ }
fclose (fpout);
mutt_unlink (tempfile);
+
+ return (rc);
}
/* ----------------------------------------------------------------------------