X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=pgp.c;h=7fdd5e9f4d29b834f055a9e889e90b4fc9013177;hp=c0c96c7c88ae802adece3756eb99b8bdd6144fd1;hb=841a368ddea400022328f35dd8c7a3eb6f543892;hpb=df70e07e24add1869bcc9b7af2277d9d0c09a281 diff --git a/pgp.c b/pgp.c index c0c96c7..7fdd5e9 100644 --- a/pgp.c +++ b/pgp.c @@ -1,21 +1,12 @@ /* + * Copyright notice from original mutt: * Copyright (C) 1996,1997 Michael R. Elkins * Copyright (C) 1998,1999 Thomas Roessler * Copyright (C) 2004 g10 Code GmbH * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * This file is part of mutt-ng, see http://www.muttng.org/. + * It's licensed under the GNU General Public License, + * please see the file GPL in the top level source directory. */ /* @@ -35,6 +26,12 @@ #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 #include @@ -62,7 +59,7 @@ #include "mutt_menu.h" -char PgpPass[STRING]; +char PgpPass[LONG_STRING]; time_t PgpExptime = 0; /* when does the cached passphrase expire? */ void pgp_void_passphrase (void) @@ -86,8 +83,8 @@ int pgp_valid_passphrase (void) pgp_void_passphrase (); - if (mutt_get_password - (_("Enter PGP passphrase:"), PgpPass, sizeof (PgpPass)) == 0) { + if (mutt_get_field_unbuffered (_("Enter PGP passphrase:"), PgpPass, + sizeof (PgpPass), M_PASS) == 0) { PgpExptime = time (NULL) + PgpTimeout; return (1); } @@ -144,24 +141,21 @@ static int pgp_copy_checksig (FILE * fpin, FILE * fpout) while ((line = mutt_read_line (line, &linelen, fpin, &lineno)) != NULL) { if (regexec (PgpGoodSign.rx, line, 0, NULL, 0) == 0) { - dprint (2, (debugfile, "pgp_copy_checksig: \"%s\" matches regexp.\n", - line)); + debug_print (2, ("\"%s\" matches regexp.\n", line)); rv = 0; } else - dprint (2, - (debugfile, - "pgp_copy_checksig: \"%s\" doesn't match regexp.\n", line)); + debug_print (2, ("\"%s\" doesn't match regexp.\n", line)); if (strncmp (line, "[GNUPG:] ", 9) == 0) continue; fputs (line, fpout); fputc ('\n', fpout); } - FREE (&line); + mem_free (&line); } else { - dprint (2, (debugfile, "pgp_copy_checksig: No pattern.\n")); + debug_print (2, ("No pattern.\n")); mutt_copy_stream (fpin, fpout); rv = 1; } @@ -202,11 +196,11 @@ static void pgp_copy_clearsigned (FILE * fpin, STATE * s, char *charset) continue; } - if (mutt_strcmp (buf, "-----BEGIN PGP SIGNATURE-----\n") == 0) + if (str_cmp (buf, "-----BEGIN PGP SIGNATURE-----\n") == 0) break; if (armor_header) { - char *p = mutt_skip_whitespace (buf); + char *p = str_skip_initws (buf); if (*p == '\0') armor_header = 0; @@ -258,21 +252,21 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) break; offset = ftell (s->fpin); - bytes -= (offset - last_pos); /* don't rely on mutt_strlen(buf) */ + bytes -= (offset - last_pos); /* don't rely on str_len(buf) */ last_pos = offset; - if (mutt_strncmp ("-----BEGIN PGP ", buf, 15) == 0) { + if (str_ncmp ("-----BEGIN PGP ", buf, 15) == 0) { clearsign = 0; start_pos = last_pos; - if (mutt_strcmp ("MESSAGE-----\n", buf + 15) == 0) + if (str_cmp ("MESSAGE-----\n", buf + 15) == 0) needpass = 1; - else if (mutt_strcmp ("SIGNED MESSAGE-----\n", buf + 15) == 0) { + else if (str_cmp ("SIGNED MESSAGE-----\n", buf + 15) == 0) { clearsign = 1; needpass = 0; } else if (!option (OPTDONTHANDLEPGPKEYS) && - mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) { + str_cmp ("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) { needpass = 0; pgp_keyblock = 1; } @@ -296,16 +290,16 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) 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 mutt_strlen(buf) */ + bytes -= (offset - last_pos); /* don't rely on str_len(buf) */ last_pos = offset; fputs (buf, tmpfp); if ((needpass - && mutt_strcmp ("-----END PGP MESSAGE-----\n", buf) == 0) + && str_cmp ("-----END PGP MESSAGE-----\n", buf) == 0) || (!needpass - && (mutt_strcmp ("-----END PGP SIGNATURE-----\n", buf) == 0 - || mutt_strcmp ("-----END PGP PUBLIC KEY BLOCK-----\n", + && (str_cmp ("-----END PGP SIGNATURE-----\n", buf) == 0 + || str_cmp ("-----END PGP PUBLIC KEY BLOCK-----\n", buf) == 0))) break; } @@ -365,12 +359,17 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) if (rc == -1 || rv) maybe_goodsig = 0; - state_putc ('\n', s); state_attach_puts (_("[-- End of PGP output --]\n\n"), s); } } } + /* treat empty result as sign of failure */ + if (pgpout !=NULL) + if (! ftell(pgpout)) { + mutt_error _("Could not decrypt PGP message"); + goto out; + } /* * Now, copy cleartext to the screen. NOTE - we expect that PGP @@ -406,22 +405,16 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) if (s->flags & M_DISPLAY) { state_putc ('\n', s); - if (needpass) + if (needpass) { state_attach_puts (_("[-- END PGP MESSAGE --]\n"), s); + mutt_message _("PGP message successfully decrypted."); + } else if (pgp_keyblock) state_attach_puts (_("[-- END PGP PUBLIC KEY BLOCK --]\n"), s); else state_attach_puts (_("[-- END PGP SIGNED MESSAGE --]\n"), s); } - if (tmpfp) { - safe_fclose (&tmpfp); - mutt_unlink (tmpfname); - } - if (pgpout) { - safe_fclose (&pgpout); - mutt_unlink (outfile); - } } else { /* XXX - we may wish to recode here */ @@ -431,8 +424,18 @@ void pgp_application_pgp_handler (BODY * m, STATE * s) } } +out: m->goodsig = (maybe_goodsig && have_any_sigs); + if (tmpfp) { + safe_fclose (&tmpfp); + mutt_unlink (tmpfname); + } + if (pgpout) { + safe_fclose (&pgpout); + mutt_unlink (outfile); + } + if (needpass == -1) { state_attach_puts (_ ("[-- Error: could not find beginning of PGP message! --]\n\n"), @@ -470,12 +473,12 @@ static int pgp_check_traditional_one_body (FILE * fp, BODY * b, } while (fgets (buf, sizeof (buf), tfp)) { - if (mutt_strncmp ("-----BEGIN PGP ", buf, 15) == 0) { - if (mutt_strcmp ("MESSAGE-----\n", buf + 15) == 0) + if (str_ncmp ("-----BEGIN PGP ", buf, 15) == 0) { + if (str_cmp ("MESSAGE-----\n", buf + 15) == 0) enc = 1; - else if (mutt_strcmp ("SIGNED MESSAGE-----\n", buf + 15) == 0) + else if (str_cmp ("SIGNED MESSAGE-----\n", buf + 15) == 0) sgn = 1; - else if (mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) + else if (str_cmp ("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) key = 1; } } @@ -566,9 +569,7 @@ int pgp_verify_one (BODY * sigbdy, STATE * s, const char *tempfile) if ((rv = mutt_wait_filter (thepid))) badsig = -1; - dprint (1, - (debugfile, "pgp_verify_one: mutt_wait_filter returned %d.\n", - rv)); + debug_print (1, ("mutt_wait_filter returned %d.\n", rv)); } safe_fclose (&pgperr); @@ -578,7 +579,7 @@ int pgp_verify_one (BODY * sigbdy, STATE * s, const char *tempfile) mutt_unlink (sigfile); mutt_unlink (pgperrfile); - dprint (1, (debugfile, "pgp_verify_one: returning %d.\n", badsig)); + debug_print (1, ("returning %d.\n", badsig)); return badsig; } @@ -700,6 +701,7 @@ BODY *pgp_decrypt_part (BODY * a, STATE * s, FILE * fpout, BODY * p) char pgperrfile[_POSIX_PATH_MAX]; char pgptmpfile[_POSIX_PATH_MAX]; pid_t thepid; + int rv; mutt_mktemp (pgperrfile); if ((pgperr = safe_fopen (pgperrfile, "w+")) == NULL) { @@ -746,21 +748,23 @@ 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 = mutt_strlen (buf); + len = str_len (buf); if (len > 1 && buf[len - 2] == '\r') strcpy (buf + len - 2, "\n"); /* __STRCPY_CHECKED__ */ fputs (buf, fpout); } fclose (pgpout); - mutt_wait_filter (thepid); + rv = mutt_wait_filter (thepid); mutt_unlink (pgptmpfile); if (s->flags & M_DISPLAY) { fflush (pgperr); rewind (pgperr); - if (pgp_copy_checksig (pgperr, s->fpout) == 0 && p) + if (pgp_copy_checksig (pgperr, s->fpout) == 0 && !rv && p) p->goodsig = 1; + else + p->goodsig = 0; state_attach_puts (_("[-- End of PGP output --]\n\n"), s); } fclose (pgperr); @@ -883,7 +887,10 @@ 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 + mutt_error _("Could not decrypt PGP message"); fclose (fpout); mutt_unlink (tempfile); @@ -926,7 +933,7 @@ BODY *pgp_sign_message (BODY * a) if ((thepid = pgp_invoke_sign (&pgpin, &pgpout, &pgperr, -1, -1, -1, signedfile)) == -1) { - mutt_perror _("Can't open PGP subprocess!"); + mutt_perror (_("Can't open PGP subprocess!")); fclose (fp); unlink (sigfile); @@ -944,9 +951,9 @@ BODY *pgp_sign_message (BODY * a) * recommended for future releases of PGP. */ while (fgets (buffer, sizeof (buffer) - 1, pgpout) != NULL) { - if (mutt_strcmp ("-----BEGIN PGP MESSAGE-----\n", buffer) == 0) + if (str_cmp ("-----BEGIN PGP MESSAGE-----\n", buffer) == 0) fputs ("-----BEGIN PGP SIGNATURE-----\n", fp); - else if (mutt_strcmp ("-----END PGP MESSAGE-----\n", buffer) == 0) + else if (str_cmp ("-----END PGP MESSAGE-----\n", buffer) == 0) fputs ("-----END PGP SIGNATURE-----\n", fp); else fputs (buffer, fp); @@ -985,7 +992,7 @@ BODY *pgp_sign_message (BODY * a) t = mutt_new_body (); t->type = TYPEMULTIPART; - t->subtype = safe_strdup ("signed"); + t->subtype = str_dup ("signed"); t->encoding = ENC7BIT; t->use_disp = 0; t->disposition = DISPINLINE; @@ -1000,8 +1007,8 @@ BODY *pgp_sign_message (BODY * a) t->parts->next = mutt_new_body (); t = t->parts->next; t->type = TYPEAPPLICATION; - t->subtype = safe_strdup ("pgp-signature"); - t->filename = safe_strdup (sigfile); + t->subtype = str_dup ("pgp-signature"); + t->filename = str_dup (sigfile); t->use_disp = 0; t->disposition = DISPINLINE; t->encoding = ENC7BIT; @@ -1015,7 +1022,7 @@ static short is_numerical_keyid (const char *s) /* or should we require the "0x"? */ if (strncmp (s, "0x", 2) == 0) s += 2; - if (strlen (s) % 8) + if (str_len (s) % 8) return 0; while (*s) if (strchr ("0123456789ABCDEFabcdef", *s++) == NULL) @@ -1094,7 +1101,7 @@ char *pgp_findKeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc) k_info = pgp_getkeybystr (keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING); } else if (r == -1) { - FREE (&keylist); + mem_free (&keylist); rfc822_free_address (&tmp); rfc822_free_address (&addr); return NULL; @@ -1111,7 +1118,7 @@ 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); + mem_free (&keylist); rfc822_free_address (&tmp); rfc822_free_address (&addr); return NULL; @@ -1123,11 +1130,11 @@ char *pgp_findKeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc) keyID = pgp_keyid (key); bypass_selection: - keylist_size += mutt_strlen (keyID) + 4; - safe_realloc (&keylist, keylist_size); + keylist_size += str_len (keyID) + 4; + mem_realloc (&keylist, keylist_size); sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "", /* __SPRINTF_CHECKED__ */ keyID); - keylist_used = mutt_strlen (keylist); + keylist_used = str_len (keylist); pgp_free_key (&key); rfc822_free_address (&addr); @@ -1223,13 +1230,15 @@ BODY *pgp_encrypt_message (BODY * a, char *keylist, int sign) if (empty) { /* fatal error while trying to encrypt message */ + if (sign) + pgp_void_passphrase (); /* just in case */ unlink (tempfile); return (NULL); } t = mutt_new_body (); t->type = TYPEMULTIPART; - t->subtype = safe_strdup ("encrypted"); + t->subtype = str_dup ("encrypted"); t->encoding = ENC7BIT; t->use_disp = 0; t->disposition = DISPINLINE; @@ -1239,18 +1248,18 @@ BODY *pgp_encrypt_message (BODY * a, char *keylist, int sign) t->parts = mutt_new_body (); t->parts->type = TYPEAPPLICATION; - t->parts->subtype = safe_strdup ("pgp-encrypted"); + t->parts->subtype = str_dup ("pgp-encrypted"); t->parts->encoding = ENC7BIT; t->parts->next = mutt_new_body (); t->parts->next->type = TYPEAPPLICATION; - t->parts->next->subtype = safe_strdup ("octet-stream"); + t->parts->next->subtype = str_dup ("octet-stream"); t->parts->next->encoding = ENC7BIT; - t->parts->next->filename = safe_strdup (tempfile); + t->parts->next->filename = str_dup (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 = safe_strdup ("msg.asc"); /* non pgp/mime can save */ + t->parts->next->d_filename = str_dup ("msg.asc"); /* non pgp/mime can save */ return (t); } @@ -1346,7 +1355,7 @@ BODY *pgp_traditional_encryptsign (BODY * a, int flags, char *keylist) if ((thepid = pgp_invoke_traditional (&pgpin, NULL, NULL, -1, fileno (pgpout), fileno (pgperr), pgpinfile, keylist, flags)) == -1) { - mutt_perror _("Can't invoke PGP"); + mutt_perror (_("Can't invoke PGP")); fclose (pgpout); fclose (pgperr); @@ -1389,6 +1398,8 @@ BODY *pgp_traditional_encryptsign (BODY * a, int flags, char *keylist) mutt_any_key_to_continue (NULL); if (empty) { + if (flags & SIGN) + pgp_void_passphrase (); /* just in case */ unlink (pgpoutfile); return NULL; } @@ -1398,21 +1409,21 @@ BODY *pgp_traditional_encryptsign (BODY * a, int flags, char *keylist) b->encoding = ENC7BIT; b->type = TYPETEXT; - b->subtype = safe_strdup ("plain"); + b->subtype = str_dup ("plain"); mutt_set_parameter ("x-action", flags & ENCRYPT ? "pgp-encrypted" : "pgp-signed", &b->parameter); mutt_set_parameter ("charset", send_charset, &b->parameter); - b->filename = safe_strdup (pgpoutfile); + b->filename = str_dup (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 = safe_strdup ("msg.pgp"); + b->d_filename = str_dup ("msg.pgp"); b->use_disp = 1; #endif @@ -1466,7 +1477,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)); - mutt_str_replace (&PgpSignAs, input_signas); + str_replace (&PgpSignAs, input_signas); pgp_free_key (&p); msg->security |= SIGN;