X-Git-Url: https://git.llucax.com/software/mutt-debian.git/blobdiff_plain/14c29200cb58d3c4a0830265f2433849781858d0..6c6f0d10745f764586b8689fecfbea955ba501dc:/pgp.c diff --git a/pgp.c b/pgp.c index 66e9294..325d47a 100644 --- a/pgp.c +++ b/pgp.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 1996,1997 Michael R. Elkins - * Copyright (C) 1998,1999 Thomas Roessler + * Copyright (C) 1996-7,2000 Michael R. Elkins + * Copyright (C) 1998-2005 Thomas Roessler * Copyright (C) 2004 g10 Code GmbH * * This program is free software; you can redistribute it and/or modify @@ -151,7 +151,7 @@ static int pgp_copy_checksig (FILE *fpin, FILE *fpout) int lineno = 0; size_t linelen; - while ((line = mutt_read_line (line, &linelen, fpin, &lineno)) != NULL) + while ((line = mutt_read_line (line, &linelen, fpin, &lineno, 0)) != NULL) { if (regexec (PgpGoodSign.rx, line, 0, NULL, 0) == 0) { @@ -264,6 +264,7 @@ int pgp_application_pgp_handler (BODY *m, STATE *s) short maybe_goodsig = 1; short have_any_sigs = 0; + char *gpgcharset = NULL; char body_charset[STRING]; mutt_get_body_charset (body_charset, sizeof (body_charset), m); @@ -293,11 +294,10 @@ int pgp_application_pgp_handler (BODY *m, STATE *s) clearsign = 1; needpass = 0; } - else if (!option (OPTDONTHANDLEPGPKEYS) && - mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15) == 0) + else if (!mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15)) { needpass = 0; - pgp_keyblock =1; + pgp_keyblock = 1; } else { @@ -332,6 +332,16 @@ int pgp_application_pgp_handler (BODY *m, STATE *s) && (mutt_strcmp ("-----END PGP SIGNATURE-----\n", buf) == 0 || mutt_strcmp ("-----END PGP PUBLIC KEY BLOCK-----\n",buf) == 0))) break; + /* remember optional Charset: armor header as defined by RfC4880 */ + if (mutt_strncmp ("Charset: ", buf, 9) == 0) + { + size_t l = 0; + gpgcharset = safe_strdup (buf + 9); + if ((l = mutt_strlen (gpgcharset)) > 0 && gpgcharset[l-1] == '\n') + gpgcharset[l-1] = 0; + if (mutt_check_charset (gpgcharset, 0) < 0) + mutt_str_replace (&gpgcharset, "UTF-8"); + } } /* leave tmpfp open in case we still need it - but flush it! */ @@ -391,6 +401,8 @@ int pgp_application_pgp_handler (BODY *m, STATE *s) state_attach_puts (_("[-- End of PGP output --]\n\n"), s); } + if (pgp_use_gpg_agent()) + mutt_need_hard_redraw (); } /* treat empty result as sign of failure */ @@ -417,9 +429,7 @@ int pgp_application_pgp_handler (BODY *m, STATE *s) } /* - * Now, copy cleartext to the screen. NOTE - we expect that PGP - * outputs utf-8 cleartext. This may not always be true, but it - * seems to be a reasonable guess. + * Now, copy cleartext to the screen. */ if(s->flags & M_DISPLAY) @@ -442,9 +452,14 @@ int pgp_application_pgp_handler (BODY *m, STATE *s) { FGETCONV *fc; int c; + char *expected_charset = gpgcharset && *gpgcharset ? gpgcharset : "utf-8"; + + dprint(4,(debugfile,"pgp: recoding inline from [%s] to [%s]\n", + expected_charset, Charset)); + rewind (pgpout); state_set_prefix (s); - fc = fgetconv_open (pgpout, "utf-8", Charset, 0); + fc = fgetconv_open (pgpout, expected_charset, Charset, M_ICONV_HOOK_FROM); while ((c = fgetconv (fc)) != EOF) state_prefix_putc (c, s); fgetconv_close (&fc); @@ -467,13 +482,16 @@ int pgp_application_pgp_handler (BODY *m, STATE *s) state_attach_puts (_("[-- END PGP SIGNED MESSAGE --]\n"), s); } } +#if 0 else { + /* why would we want to display this at all? */ /* XXX - we may wish to recode here */ if (s->prefix) state_puts (s->prefix, s); state_puts (buf, s); } +#endif } rc = 0; @@ -491,7 +509,9 @@ out: safe_fclose (&pgpout); mutt_unlink (outfile); } - + + FREE(&gpgcharset); + if (needpass == -1) { state_attach_puts (_("[-- Error: could not find beginning of PGP message! --]\n\n"), s); @@ -603,7 +623,7 @@ int pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempfile) fseeko (s->fpin, sigbdy->offset, 0); mutt_copy_bytes (s->fpin, fp, sigbdy->length); - fclose (fp); + safe_fclose (&fp); mutt_mktemp(pgperrfile); if(!(pgperr = safe_fopen(pgperrfile, "w+"))) @@ -683,7 +703,7 @@ void pgp_extract_keys_from_messages (HEADER *h) if (Context->hdrs[Context->v2r[i]]->security & PGPENCRYPT && !pgp_valid_passphrase()) { - fclose (fpout); + safe_fclose (&fpout); goto bailout; } mutt_copy_message (fpout, Context, Context->hdrs[Context->v2r[i]], @@ -696,13 +716,13 @@ void pgp_extract_keys_from_messages (HEADER *h) mutt_parse_mime_message (Context, h); if (h->security & PGPENCRYPT && !pgp_valid_passphrase()) { - fclose (fpout); + safe_fclose (&fpout); goto bailout; } mutt_copy_message (fpout, Context, h, M_CM_DECODE|M_CM_CHARCONV, 0); } - fclose (fpout); + safe_fclose (&fpout); mutt_endwin (NULL); pgp_invoke_import (tempfname); mutt_any_key_to_continue (NULL); @@ -734,7 +754,7 @@ static void pgp_extract_keys_from_attachment (FILE *fp, BODY *top) mutt_body_handler (top, &s); - fclose (tempfp); + safe_fclose (&tempfp); pgp_invoke_import (tempfname); mutt_any_key_to_continue (NULL); @@ -789,7 +809,7 @@ BODY *pgp_decrypt_part (BODY *a, STATE *s, FILE *fpout, BODY *p) if((pgptmp = safe_fopen (pgptmpfile, "w")) == NULL) { mutt_perror (pgptmpfile); - fclose(pgperr); + safe_fclose (&pgperr); return NULL; } @@ -799,12 +819,12 @@ BODY *pgp_decrypt_part (BODY *a, STATE *s, FILE *fpout, BODY *p) fseeko (s->fpin, a->offset, 0); mutt_copy_bytes (s->fpin, pgptmp, a->length); - fclose (pgptmp); + safe_fclose (&pgptmp); if ((thepid = pgp_invoke_decrypt (&pgpin, &pgpout, NULL, -1, -1, fileno (pgperr), pgptmpfile)) == -1) { - fclose (pgperr); + safe_fclose (&pgperr); unlink (pgptmpfile); if (s->flags & M_DISPLAY) state_attach_puts (_("[-- Error: could not create a PGP subprocess! --]\n\n"), s); @@ -817,7 +837,7 @@ BODY *pgp_decrypt_part (BODY *a, STATE *s, FILE *fpout, BODY *p) if (!pgp_use_gpg_agent()) fputs (PgpPass, pgpin); fputc ('\n', pgpin); - fclose(pgpin); + safe_fclose (&pgpin); /* Read the output from PGP, and make sure to change CRLF to LF, otherwise * read_mime_header has a hard time parsing the message. @@ -830,7 +850,7 @@ BODY *pgp_decrypt_part (BODY *a, STATE *s, FILE *fpout, BODY *p) fputs (buf, fpout); } - fclose (pgpout); + safe_fclose (&pgpout); rv = mutt_wait_filter (thepid); mutt_unlink(pgptmpfile); @@ -844,11 +864,14 @@ BODY *pgp_decrypt_part (BODY *a, STATE *s, FILE *fpout, BODY *p) p->goodsig = 0; state_attach_puts (_("[-- End of PGP output --]\n\n"), s); } - fclose (pgperr); + safe_fclose (&pgperr); fflush (fpout); rewind (fpout); - + + if (pgp_use_gpg_agent()) + mutt_need_hard_redraw (); + if (fgetc (fpout) == EOF) { mutt_error _("Decryption failed"); @@ -980,7 +1003,7 @@ int pgp_encrypted_handler (BODY *a, STATE *s) rc = -1; } - fclose (fpout); + safe_fclose (&fpout); mutt_unlink(tempfile); return rc; @@ -1013,7 +1036,7 @@ BODY *pgp_sign_message (BODY *a) if ((sfp = safe_fopen(signedfile, "w")) == NULL) { mutt_perror(signedfile); - fclose(fp); + safe_fclose (&fp); unlink(sigfile); return NULL; } @@ -1021,13 +1044,13 @@ BODY *pgp_sign_message (BODY *a) mutt_write_mime_header (a, sfp); fputc ('\n', sfp); mutt_write_mime_body (a, sfp); - fclose(sfp); + safe_fclose (&sfp); if ((thepid = pgp_invoke_sign (&pgpin, &pgpout, &pgperr, -1, -1, -1, signedfile)) == -1) { mutt_perror _("Can't open PGP subprocess!"); - fclose(fp); + safe_fclose (&fp); unlink(sigfile); unlink(signedfile); return NULL; @@ -1036,7 +1059,7 @@ BODY *pgp_sign_message (BODY *a) if (!pgp_use_gpg_agent()) fputs(PgpPass, pgpin); fputc('\n', pgpin); - fclose(pgpin); + safe_fclose (&pgpin); /* * Read back the PGP signature. Also, change MESSAGE=>SIGNATURE as @@ -1064,8 +1087,8 @@ BODY *pgp_sign_message (BODY *a) if(mutt_wait_filter (thepid) && option(OPTPGPCHECKEXIT)) empty=1; - fclose (pgperr); - fclose (pgpout); + safe_fclose (&pgperr); + safe_fclose (&pgpout); unlink (signedfile); if (fclose (fp) != 0) @@ -1131,7 +1154,7 @@ static short is_numerical_keyid (const char *s) */ char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) { - char *keyID, *keylist = NULL, *t; + char *keyID, *keylist = NULL; size_t keylist_size = 0; size_t keylist_used = 0; ADDRESS *tmp = NULL, *addr = NULL; @@ -1152,7 +1175,7 @@ char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) default: abort (); } - *last = rfc822_cpy_adr (p); + *last = rfc822_cpy_adr (p, 0); while (*last) last = &((*last)->next); } @@ -1183,7 +1206,7 @@ char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) } /* check for e-mail address */ - if ((t = strchr (keyID, '@')) && + if (strchr (keyID, '@') && (addr = rfc822_parse_adrlist (NULL, keyID))) { if (fqdn) rfc822_qualify (addr, fqdn); @@ -1263,7 +1286,7 @@ BODY *pgp_encrypt_message (BODY *a, char *keylist, int sign) { mutt_perror (pgperrfile); unlink(tempfile); - fclose(fpout); + safe_fclose (&fpout); return NULL; } unlink (pgperrfile); @@ -1273,8 +1296,8 @@ BODY *pgp_encrypt_message (BODY *a, char *keylist, int sign) { mutt_perror(pgpinfile); unlink(tempfile); - fclose(fpout); - fclose(pgperr); + safe_fclose (&fpout); + safe_fclose (&pgperr); return NULL; } @@ -1284,13 +1307,13 @@ BODY *pgp_encrypt_message (BODY *a, char *keylist, int sign) mutt_write_mime_header (a, fptmp); fputc ('\n', fptmp); mutt_write_mime_body (a, fptmp); - fclose(fptmp); + safe_fclose (&fptmp); if ((thepid = pgp_invoke_encrypt (&pgpin, NULL, NULL, -1, fileno (fpout), fileno (pgperr), pgpinfile, keylist, sign)) == -1) { - fclose (pgperr); + safe_fclose (&pgperr); unlink(pgpinfile); return (NULL); } @@ -1301,7 +1324,7 @@ BODY *pgp_encrypt_message (BODY *a, char *keylist, int sign) fputs (PgpPass, pgpin); fputc ('\n', pgpin); } - fclose(pgpin); + safe_fclose (&pgpin); if(mutt_wait_filter (thepid) && option(OPTPGPCHECKEXIT)) empty=1; @@ -1312,7 +1335,7 @@ BODY *pgp_encrypt_message (BODY *a, char *keylist, int sign) rewind (fpout); if(!empty) empty = (fgetc (fpout) == EOF); - fclose (fpout); + safe_fclose (&fpout); fflush (pgperr); rewind (pgperr); @@ -1321,7 +1344,7 @@ BODY *pgp_encrypt_message (BODY *a, char *keylist, int sign) err = 1; fputs (buf, stdout); } - fclose (pgperr); + safe_fclose (&pgperr); /* pause if there is any error output from PGP */ if (err) @@ -1401,7 +1424,7 @@ BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist) if ((pgpin = safe_fopen (pgpinfile, "w")) == NULL) { mutt_perror (pgpinfile); - fclose (fp); + safe_fclose (&fp); return NULL; } @@ -1440,7 +1463,7 @@ BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist) mutt_copy_stream (fp, pgpin); } safe_fclose (&fp); - fclose (pgpin); + safe_fclose (&pgpin); mutt_mktemp (pgpoutfile); mutt_mktemp (pgperrfile); @@ -1451,7 +1474,7 @@ BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist) unlink (pgpinfile); if (pgpout) { - fclose (pgpout); + safe_fclose (&pgpout); unlink (pgpoutfile); } return NULL; @@ -1464,8 +1487,8 @@ BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist) pgpinfile, keylist, flags)) == -1) { mutt_perror _("Can't invoke PGP"); - fclose (pgpout); - fclose (pgperr); + safe_fclose (&pgpout); + safe_fclose (&pgperr); mutt_unlink (pgpinfile); unlink (pgpoutfile); return NULL; @@ -1475,7 +1498,7 @@ BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist) *PgpPass = 0; if (flags & SIGN) fprintf (pgpin, "%s\n", PgpPass); - fclose (pgpin); + safe_fclose (&pgpin); if(mutt_wait_filter (thepid) && option(OPTPGPCHECKEXIT)) empty=1; @@ -1490,7 +1513,7 @@ BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist) if(!empty) empty = (fgetc (pgpout) == EOF); - fclose (pgpout); + safe_fclose (&pgpout); err = 0; @@ -1500,7 +1523,7 @@ BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist) fputs (buff, stdout); } - fclose (pgperr); + safe_fclose (&pgperr); if (err) mutt_any_key_to_continue (NULL);