X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=pgp.c;h=a17b481d1c55ae8029f25c8e4ce1afadcb2016de;hp=5e886dbf5d0ee47eb6cd410fc4e5f7eeafa230b3;hb=a8aba140a61d5b86093cea46afcb613092d4978d;hpb=a8477ebaa09990b3688164cbe5cf661c4189541d diff --git a/pgp.c b/pgp.c index 5e886db..a17b481 100644 --- a/pgp.c +++ b/pgp.c @@ -21,15 +21,22 @@ # include "config.h" #endif +#include +#include +#include +#include +#include + +#include + #include "mutt.h" +#include "enter.h" +#include "handler.h" #include "mutt_curses.h" #include "pgp.h" -#include "mime.h" #include "copy.h" +#include "attach.h" -#include "lib/mem.h" -#include "lib/intl.h" -#include "lib/str.h" #include "lib/debug.h" #include @@ -63,7 +70,7 @@ time_t PgpExptime = 0; /* when does the cached passphrase expire? */ void pgp_void_passphrase (void) { - memset (PgpPass, 0, sizeof (PgpPass)); + p_clear(PgpPass, sizeof(PgpPass)); PgpExptime = 0; } @@ -99,10 +106,16 @@ void pgp_forget_passphrase (void) 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) @@ -151,7 +164,7 @@ static int pgp_copy_checksig (FILE * fpin, FILE * fpout) fputs (line, fpout); fputc ('\n', fpout); } - FREE (&line); + p_delete(&line); } else { debug_print (2, ("No pattern.\n")); @@ -195,11 +208,11 @@ static void pgp_copy_clearsigned (FILE * fpin, STATE * s, char *charset) continue; } - if (str_cmp (buf, "-----BEGIN PGP SIGNATURE-----\n") == 0) + if (m_strcmp(buf, "-----BEGIN PGP SIGNATURE-----\n") == 0) break; if (armor_header) { - char *p = str_skip_initws (buf); + char *p = vskipspaces(buf); if (*p == '\0') armor_header = 0; @@ -221,17 +234,20 @@ static void pgp_copy_clearsigned (FILE * fpin, STATE * s, char *charset) /* 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; + off_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; @@ -243,29 +259,29 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) 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); - bytes -= (offset - last_pos); /* don't rely on str_len(buf) */ + offset = ftello (s->fpin); + bytes -= (offset - last_pos); /* don't rely on m_strlen(buf) */ last_pos = offset; - if (str_ncmp ("-----BEGIN PGP ", buf, 15) == 0) { + if (m_strncmp("-----BEGIN PGP ", buf, 15) == 0) { clearsign = 0; start_pos = last_pos; - if (str_cmp ("MESSAGE-----\n", buf + 15) == 0) + if (m_strcmp("MESSAGE-----\n", buf + 15) == 0) needpass = 1; - else if (str_cmp ("SIGNED MESSAGE-----\n", buf + 15) == 0) { + else if (m_strcmp("SIGNED MESSAGE-----\n", buf + 15) == 0) { clearsign = 1; needpass = 0; } else if (!option (OPTDONTHANDLEPGPKEYS) && - str_cmp ("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) { + m_strcmp("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) { needpass = 0; pgp_keyblock = 1; } @@ -283,22 +299,22 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) 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); - bytes -= (offset - last_pos); /* don't rely on str_len(buf) */ + offset = ftello (s->fpin); + bytes -= (offset - last_pos); /* don't rely on m_strlen(buf) */ last_pos = offset; fputs (buf, tmpfp); if ((needpass - && str_cmp ("-----END PGP MESSAGE-----\n", buf) == 0) + && m_strcmp("-----END PGP MESSAGE-----\n", buf) == 0) || (!needpass - && (str_cmp ("-----END PGP SIGNATURE-----\n", buf) == 0 - || str_cmp ("-----END PGP PUBLIC KEY BLOCK-----\n", + && (m_strcmp("-----END PGP SIGNATURE-----\n", buf) == 0 + || m_strcmp("-----END PGP PUBLIC KEY BLOCK-----\n", buf) == 0))) break; } @@ -312,7 +328,7 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) 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, @@ -349,26 +365,39 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) 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 @@ -406,7 +435,10 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) 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); @@ -423,6 +455,8 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) } } + rc = 0; + out: m->goodsig = (maybe_goodsig && have_any_sigs); @@ -439,8 +473,10 @@ out: 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, @@ -472,12 +508,12 @@ static int pgp_check_traditional_one_body (FILE * fp, BODY * b, } while (fgets (buf, sizeof (buf), tfp)) { - if (str_ncmp ("-----BEGIN PGP ", buf, 15) == 0) { - if (str_cmp ("MESSAGE-----\n", buf + 15) == 0) + if (m_strncmp("-----BEGIN PGP ", buf, 15) == 0) { + if (m_strcmp("MESSAGE-----\n", buf + 15) == 0) enc = 1; - else if (str_cmp ("SIGNED MESSAGE-----\n", buf + 15) == 0) + else if (m_strcmp("SIGNED MESSAGE-----\n", buf + 15) == 0) sgn = 1; - else if (str_cmp ("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) + else if (m_strcmp("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) key = 1; } } @@ -538,7 +574,7 @@ int pgp_verify_one (BODY * sigbdy, STATE * s, const char *tempfile) return -1; } - fseek (s->fpin, sigbdy->offset, 0); + fseeko (s->fpin, sigbdy->offset, 0); mutt_copy_bytes (s->fpin, fp, sigbdy->length); fclose (fp); @@ -653,7 +689,7 @@ static void pgp_extract_keys_from_attachment (FILE * fp, BODY * top) return; } - memset (&s, 0, sizeof (STATE)); + p_clear(&s, 1); s.fpin = fp; s.fpout = tempfp; @@ -720,7 +756,7 @@ BODY *pgp_decrypt_part (BODY * a, STATE * s, FILE * fpout, BODY * p) * 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); @@ -747,7 +783,7 @@ BODY *pgp_decrypt_part (BODY * a, STATE * s, FILE * fpout, BODY * p) * read_mime_header has a hard time parsing the message. */ while (fgets (buf, sizeof (buf) - 1, pgpout) != NULL) { - len = str_len (buf); + len = m_strlen(buf); if (len > 1 && buf[len - 2] == '\r') strcpy (buf + len - 2, "\n"); /* __STRCPY_CHECKED__ */ fputs (buf, fpout); @@ -771,8 +807,11 @@ BODY *pgp_decrypt_part (BODY * a, STATE * s, FILE * fpout, BODY * p) fflush (fpout); rewind (fpout); - if (fgetc (fpout) == EOF) + if (fgetc (fpout) == EOF) { + mutt_error (_("Decryption failed.")); + pgp_void_passphrase (); return NULL; + } rewind (fpout); @@ -805,7 +844,7 @@ int pgp_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur) b = b->parts->next; - memset (&s, 0, sizeof (s)); + p_clear(&s, 1); s.fpin = fpin; mutt_mktemp (tempfile); if ((*fpout = safe_fopen (tempfile, "w+")) == NULL) { @@ -824,12 +863,13 @@ int pgp_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur) 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 || @@ -839,7 +879,7 @@ void pgp_encrypted_handler (BODY * a, STATE * s) if (s->flags & M_DISPLAY) state_attach_puts (_("[-- Error: malformed PGP/MIME message! --]\n\n"), s); - return; + return (-1); } /* @@ -853,7 +893,7 @@ void pgp_encrypted_handler (BODY * a, STATE * s) state_attach_puts (_ ("[-- Error: could not create temporary file! --]\n"), s); - return; + return (-1); } if (s->flags & M_DISPLAY) @@ -867,7 +907,7 @@ void pgp_encrypted_handler (BODY * a, STATE * s) fpin = s->fpin; s->fpin = fpout; - mutt_body_handler (tattach, s); + rc = mutt_body_handler (tattach, s); s->fpin = fpin; /* @@ -888,11 +928,16 @@ void pgp_encrypted_handler (BODY * a, STATE * s) 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); } /* ---------------------------------------------------------------------------- @@ -950,9 +995,9 @@ BODY *pgp_sign_message (BODY * a) * recommended for future releases of PGP. */ while (fgets (buffer, sizeof (buffer) - 1, pgpout) != NULL) { - if (str_cmp ("-----BEGIN PGP MESSAGE-----\n", buffer) == 0) + if (m_strcmp("-----BEGIN PGP MESSAGE-----\n", buffer) == 0) fputs ("-----BEGIN PGP SIGNATURE-----\n", fp); - else if (str_cmp ("-----END PGP MESSAGE-----\n", buffer) == 0) + else if (m_strcmp("-----END PGP MESSAGE-----\n", buffer) == 0) fputs ("-----END PGP SIGNATURE-----\n", fp); else fputs (buffer, fp); @@ -991,7 +1036,7 @@ BODY *pgp_sign_message (BODY * a) t = mutt_new_body (); t->type = TYPEMULTIPART; - t->subtype = str_dup ("signed"); + t->subtype = m_strdup("signed"); t->encoding = ENC7BIT; t->use_disp = 0; t->disposition = DISPINLINE; @@ -1006,8 +1051,8 @@ BODY *pgp_sign_message (BODY * a) t->parts->next = mutt_new_body (); t = t->parts->next; t->type = TYPEAPPLICATION; - t->subtype = str_dup ("pgp-signature"); - t->filename = str_dup (sigfile); + t->subtype = m_strdup("pgp-signature"); + t->filename = m_strdup(sigfile); t->use_disp = 0; t->disposition = DISPINLINE; t->encoding = ENC7BIT; @@ -1021,7 +1066,7 @@ static short is_numerical_keyid (const char *s) /* or should we require the "0x"? */ if (strncmp (s, "0x", 2) == 0) s += 2; - if (str_len (s) % 8) + if (m_strlen(s) % 8) return 0; while (*s) if (strchr ("0123456789ABCDEFabcdef", *s++) == NULL) @@ -1033,14 +1078,14 @@ static short is_numerical_keyid (const char *s) /* This routine attempts to find the keyids of the recipients of a message. * It returns NULL if any of the keys can not be found. */ -char *pgp_findKeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc) +char *pgp_findKeys (address_t * to, address_t * cc, address_t * bcc) { char *keyID, *keylist = NULL, *t; size_t keylist_size = 0; size_t keylist_used = 0; - ADDRESS *tmp = NULL, *addr = NULL; - ADDRESS **last = &tmp; - ADDRESS *p, *q; + address_t *tmp = NULL, *addr = NULL; + address_t **last = &tmp; + address_t *p, *q; int i; pgp_key_t k_info = NULL, key = NULL; @@ -1061,7 +1106,7 @@ char *pgp_findKeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc) abort (); } - *last = rfc822_cpy_adr (p); + *last = address_list_dup (p); while (*last) last = &((*last)->next); } @@ -1100,9 +1145,9 @@ char *pgp_findKeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc) k_info = pgp_getkeybystr (keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING); } else if (r == -1) { - FREE (&keylist); - rfc822_free_address (&tmp); - rfc822_free_address (&addr); + p_delete(&keylist); + address_delete (&tmp); + address_delete (&addr); return NULL; } } @@ -1117,9 +1162,9 @@ char *pgp_findKeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc) if ((key = pgp_ask_for_key (buf, q->mailbox, KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL) { - FREE (&keylist); - rfc822_free_address (&tmp); - rfc822_free_address (&addr); + p_delete(&keylist); + address_delete (&tmp); + address_delete (&addr); return NULL; } } @@ -1129,17 +1174,17 @@ char *pgp_findKeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc) keyID = pgp_keyid (key); bypass_selection: - keylist_size += str_len (keyID) + 4; - safe_realloc (&keylist, keylist_size); + keylist_size += m_strlen(keyID) + 4; + p_realloc(&keylist, keylist_size); sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "", /* __SPRINTF_CHECKED__ */ keyID); - keylist_used = str_len (keylist); + keylist_used = m_strlen(keylist); pgp_free_key (&key); - rfc822_free_address (&addr); + address_delete (&addr); } - rfc822_free_address (&tmp); + address_delete (&tmp); return (keylist); } @@ -1237,7 +1282,7 @@ BODY *pgp_encrypt_message (BODY * a, char *keylist, int sign) t = mutt_new_body (); t->type = TYPEMULTIPART; - t->subtype = str_dup ("encrypted"); + t->subtype = m_strdup("encrypted"); t->encoding = ENC7BIT; t->use_disp = 0; t->disposition = DISPINLINE; @@ -1247,18 +1292,18 @@ BODY *pgp_encrypt_message (BODY * a, char *keylist, int sign) t->parts = mutt_new_body (); t->parts->type = TYPEAPPLICATION; - t->parts->subtype = str_dup ("pgp-encrypted"); + t->parts->subtype = m_strdup("pgp-encrypted"); t->parts->encoding = ENC7BIT; t->parts->next = mutt_new_body (); t->parts->next->type = TYPEAPPLICATION; - t->parts->next->subtype = str_dup ("octet-stream"); + t->parts->next->subtype = m_strdup("octet-stream"); t->parts->next->encoding = ENC7BIT; - t->parts->next->filename = str_dup (tempfile); + t->parts->next->filename = m_strdup(tempfile); t->parts->next->use_disp = 1; t->parts->next->disposition = DISPINLINE; t->parts->next->unlink = 1; /* delete after sending the message */ - t->parts->next->d_filename = str_dup ("msg.asc"); /* non pgp/mime can save */ + t->parts->next->d_filename = m_strdup("msg.asc"); /* non pgp/mime can save */ return (t); } @@ -1408,21 +1453,21 @@ BODY *pgp_traditional_encryptsign (BODY * a, int flags, char *keylist) b->encoding = ENC7BIT; b->type = TYPETEXT; - b->subtype = str_dup ("plain"); + b->subtype = m_strdup("plain"); mutt_set_parameter ("x-action", flags & ENCRYPT ? "pgp-encrypted" : "pgp-signed", &b->parameter); mutt_set_parameter ("charset", send_charset, &b->parameter); - b->filename = str_dup (pgpoutfile); + b->filename = m_strdup(pgpoutfile); #if 0 /* The following is intended to give a clue to some completely brain-dead * "mail environments" which are typically used by large corporations. */ - b->d_filename = str_dup ("msg.pgp"); + b->d_filename = m_strdup("msg.pgp"); b->use_disp = 1; #endif @@ -1476,7 +1521,7 @@ int pgp_send_menu (HEADER * msg, int *redraw) pgp_ask_for_key (_("Sign as: "), NULL, KEYFLAG_CANSIGN, PGP_PUBRING))) { snprintf (input_signas, sizeof (input_signas), "0x%s", pgp_keyid (p)); - str_replace (&PgpSignAs, input_signas); + m_strreplace(&PgpSignAs, input_signas); pgp_free_key (&p); msg->security |= SIGN;