]> git.llucax.com Git - software/mutt-debian.git/blobdiff - pgp.c
Merge commit 'upstream/1.5.20'
[software/mutt-debian.git] / pgp.c
diff --git a/pgp.c b/pgp.c
index 66e92948c676add752c9d6be1e8977ae47834aa4..325d47a6650778870f093e7b895c25221f2688bb 100644 (file)
--- a/pgp.c
+++ b/pgp.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 1996,1997 Michael R. Elkins <me@mutt.org>
- * Copyright (C) 1998,1999 Thomas Roessler <roessler@does-not-exist.org>
+ * Copyright (C) 1996-7,2000 Michael R. Elkins <me@mutt.org>
+ * Copyright (C) 1998-2005 Thomas Roessler <roessler@does-not-exist.org>
  * 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);