]> granicus.if.org Git - mutt/commitdiff
Auto-detect the micalg used with PGP/MIME signatures.
authorThomas Roessler <roessler@does-not-exist.org>
Mon, 12 Feb 2001 17:21:37 +0000 (17:21 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Mon, 12 Feb 2001 17:21:37 +0000 (17:21 +0000)
18 files changed:
Makefile.am
compose.c
configure.in
gnupgparse.c
init.h
mutt.h
pgp.c
pgp.h
pgplib.c
pgplib.h
pgpmicalg.c [new file with mode: 0644]
pgppacket.c [new file with mode: 0644]
pgppacket.h [new file with mode: 0644]
pgppubring.c
postpone.c
protos.h
send.c
sendlib.c

index 4041449060f88aec2e822c105a3afa1e62cfea6b..74e4db932b3e029402a8f66aad6713d5503d4a6c 100644 (file)
@@ -65,16 +65,17 @@ INCLUDES=-I$(top_srcdir) -I. $(IMAP_INCLUDES) \
         -Iintl -I$(includedir)
 
 non_us_sources = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1.c \
-       gnupgparse.c sha1.h \
+       pgpmicalg.c gnupgparse.c sha1.h \
        doc/language.txt doc/language50.txt OPS.PGP doc/PGP-Notes.txt \
        OPS.MIX remailer.c remailer.h pgpewrap  \
        contrib/pgp2.rc contrib/pgp5.rc contrib/gpg.rc \
-       mutt_ssl.c mutt_ssl.h README.SSL mutt_ssl_nss.c
+       mutt_ssl.c mutt_ssl.h README.SSL mutt_ssl_nss.c \
+       pgppacket.c pgppacket.h
 
 EXTRA_mutt_SOURCES = account.c md5c.c mutt_sasl.c mutt_socket.c mutt_ssl.c \
        pop.c pop_auth.c pop_lib.c pgp.c pgpinvoke.c pgpkey.c pgplib.c \
-       sha1.c gnupgparse.c resize.c dotlock.c remailer.c browser.h mbyte.h \
-       remailer.h url.h mutt_ssl_nss.c
+       sha1.c pgpmicalg.c gnupgparse.c resize.c dotlock.c remailer.c browser.h mbyte.h \
+       remailer.h url.h mutt_ssl_nss.c pgppacket.c 
 
 EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h account.h \
        attach.h buffy.h charset.h copy.h dotlock.h functions.h gen_defs \
@@ -86,13 +87,13 @@ EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h account.h \
        _regex.h OPS.MIX README.SECURITY remailer.c remailer.h browser.h \
        mbyte.h lib.h extlib.c pgpewrap pgplib.h Muttrc.head Muttrc \
        makedoc.c stamp-doc-rc README.SSL README.UPGRADE checktypes.c \
-       muttbug
+       muttbug pgppacket.h
 
 mutt_dotlock_SOURCES = mutt_dotlock.c
 mutt_dotlock_LDADD = @LIBOBJS@
 mutt_dotlock_DEPENDENCIES = @LIBOBJS@
 
-pgpring_SOURCES = pgppubring.c pgplib.c lib.c extlib.c sha1.c
+pgpring_SOURCES = pgppubring.c pgplib.c lib.c extlib.c sha1.c pgppacket.c
 pgpring_LDADD = @LIBOBJS@ $(INTLLIBS) 
 pgpring_DEPENDENCIES = @LIBOBJS@ $(INTLDEPS)
 
index 141389ec07d5e26664140ee4ef0508412d2dc579..59ce80fe27e9cbba9497467b545aa6b74ad55646 100644 (file)
--- a/compose.c
+++ b/compose.c
@@ -121,21 +121,16 @@ static void redraw_pgp_lines (int pgp)
   move (HDR_PGPSIGINFO, 0);
   clrtoeol ();
   if (pgp & PGPSIGN)
-  {
     printw ("%s%s", _(" sign as: "), PgpSignAs ? PgpSignAs : _("<default>"));
-    mvprintw (HDR_PGPSIGINFO, 40, "%s%s", _("MIC algorithm: "),
-             NONULL(PgpSignMicalg));
-  }
 }
 
 static int pgp_send_menu (int bits, int *redraw)
 {
   pgp_key_t *p;
   char input_signas[SHORT_STRING];
-  char input_micalg[SHORT_STRING];
 
-  switch (mutt_multi_choice (_("(e)ncrypt, (s)ign, sign (a)s, (b)oth, select (m)ic algorithm, or (f)orget it? "),
-                            _("esabmf")))
+  switch (mutt_multi_choice (_("(e)ncrypt, (s)ign, sign (a)s, (b)oth, or (f)orget it? "),
+                            _("esabf")))
   {
   case 1: /* (e)ncrypt */
     bits |= PGPENCRYPT;
@@ -153,7 +148,6 @@ static int pgp_send_menu (int bits, int *redraw)
     {
       snprintf (input_signas, sizeof (input_signas), "0x%s", pgp_keyid (p));
       mutt_str_replace (&PgpSignAs, input_signas);
-      mutt_str_replace (&PgpSignMicalg, pgp_pkalg_to_mic (p->algorithm));
       pgp_free_key (&p);
       
       bits |= PGPSIGN;
@@ -172,28 +166,7 @@ static int pgp_send_menu (int bits, int *redraw)
     bits = PGPENCRYPT | PGPSIGN;
     break;
 
-  case 5: /* select (m)ic algorithm */
-    if (!(bits & PGPSIGN))
-      mutt_error _("This doesn't make sense if you don't want to sign the message.");
-    else
-    {
-      /* Copy the existing MIC algorithm into place */
-      strfcpy(input_micalg, NONULL (PgpSignMicalg), sizeof (input_micalg));
-
-      if (mutt_get_field (_("MIC algorithm: "), input_micalg, sizeof (input_micalg), 0) == 0)
-      {
-       if (mutt_strcasecmp (input_micalg, "pgp-md5") && mutt_strcasecmp (input_micalg, "pgp-sha1")
-          && mutt_strcasecmp (input_micalg, "pgp-rmd160"))
-       {
-         mutt_error _("Unknown MIC algorithm, valid ones are: pgp-md5, pgp-sha1, pgp-rmd160");
-       }
-       else 
-         mutt_str_replace (&PgpSignMicalg, input_micalg);
-      }
-    }
-    break;
-
-  case 6: /* (f)orget it */
+  case 5: /* (f)orget it */
     bits = 0;
     break;
   }
index bf539ed79df7a4544216b667557754502ee5eefd..82e01d1cdcbd9297e7f10fb84c168585e01c3dd7 100644 (file)
@@ -75,7 +75,7 @@ else
                AC_DEFINE(HAVE_PGP)
                PGPAUX_TARGET=pgpring
                AM_CONDITIONAL(NEEDS_PGPEWRAP, true)
-               MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS pgp.o pgpinvoke.o pgpkey.o pgplib.o gnupgparse.o"
+               MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS pgp.o pgpinvoke.o pgpkey.o pgplib.o gnupgparse.o pgpmicalg.o pgppacket.o"
                OPS="$OPS \$(srcdir)/OPS.PGP"
        fi
 
index c7feca89bce7836eb40ec2b1cc9a2a59b21eb112..88b1716ea872bc13b0d9481ca0cffda4b3443c47 100644 (file)
@@ -252,6 +252,10 @@ static pgp_key_t *parse_pub_line (char *buf, int *is_subkey, pgp_key_t *k)
       {
        if (!pend || !*p)
          break;                        /* empty field or no trailing colon */
+
+       /* ignore user IDs on subkeys */
+       if (!is_uid && (*is_subkey && option (OPTPGPIGNORESUB)))
+         break;
        
        dprint (2, (debugfile, "user ID: %s\n", p));
        
@@ -318,7 +322,7 @@ pgp_key_t *pgp_get_candidates (pgp_ring_t keyring, LIST * hints)
       if (is_sub)
       {
        pgp_uid_t **l;
-
+       
        k->flags  |= KEYFLAG_SUBKEY;
        k->parent  = mainkey;
        for (l = &k->address; *l; l = &(*l)->next)
diff --git a/init.h b/init.h
index 598fd4f2b261aa09305c2f99c28fc30c3d2b6390..3289b403e7704b7ad78b85d774330afbcb5742b5 100644 (file)
--- a/init.h
+++ b/init.h
@@ -1176,20 +1176,6 @@ struct option_t MuttVars[] = {
   ** which of your private keys to use.  It is recommended that you use the
   ** keyid form to specify your key (e.g., ``0x00112233'').
   */
-  { "pgp_sign_micalg", DT_STR,  R_NONE, UL &PgpSignMicalg, UL "pgp-md5" },
-  /*
-  ** .pp
-  ** This variable contains the default message integrity check algorithm.
-  ** Valid values are ``pgp-md5'', ``pgp-sha1'', and ``pgp-rmd160''. If you
-  ** select a signing key using the sign as option on the compose menu,
-  ** mutt will automagically figure out the correct value to insert here,
-  ** but it does not know about the user's default key.
-  ** .pp
-  ** So if you are using an RSA key for signing, set this variable to
-  ** ``pgp-md5'', if you use a PGP 5 DSS key for signing, say ``pgp-sha1''
-  ** here. The value of this variable will show up in the micalg parameter
-  ** of MIME headers when creating RFC 2015 signatures.
-  */
   { "pgp_strict_enc",  DT_BOOL, R_NONE, OPTPGPSTRICTENC, 1 },
   /*
   ** .pp
diff --git a/mutt.h b/mutt.h
index 6b6be1130bf6b59499d94e20f7cf151bf1479820..cde5ecd95f34ec73d194058cb37139f17c7b152e 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -48,6 +48,7 @@
 
 #include "rfc822.h"
 #include "hash.h"
+#include "charset.h"
 
 #ifdef SUBVERSION
 # define MUTT_VERSION (VERSION SUBVERSION)
diff --git a/pgp.c b/pgp.c
index f45f1a6678379570c774de8dff72d6f077274c36..0ec12ed9d3ce4ee269ea6d7a75f34b1edfaa438b 100644 (file)
--- a/pgp.c
+++ b/pgp.c
@@ -1152,7 +1152,7 @@ static BODY *pgp_sign_message (BODY *a)
 
   mutt_generate_boundary (&t->parameter);
   mutt_set_parameter ("protocol", "application/pgp-signature", &t->parameter);
-  mutt_set_parameter ("micalg", PgpSignMicalg, &t->parameter);
+  mutt_set_parameter ("micalg", pgp_micalg (sigfile), &t->parameter);
 
   t->parts = a;
   a = t;
diff --git a/pgp.h b/pgp.h
index 32f2610546614a816ce6c6cbbad4e7558843e34f..05c1a9a864df3501d8153d887e741bf385b7bf2e 100644 (file)
--- a/pgp.h
+++ b/pgp.h
@@ -24,7 +24,6 @@
 WHERE REGEXP PgpGoodSign;
 
 WHERE char *PgpSignAs;
-WHERE char *PgpSignMicalg;
 WHERE short PgpTimeout;
 WHERE char *PgpEntryFormat;
 
@@ -49,6 +48,7 @@ WHERE char *PgpGetkeysCommand;
 
 BODY *pgp_decrypt_part (BODY *, STATE *, FILE *);
 BODY *pgp_make_key_attachment (char *);
+const char *pgp_micalg (const char *fname);
 
 char *_pgp_keyid (pgp_key_t *);
 char *pgp_keyid (pgp_key_t *);
index f22a3db35f59bd0c5663c376d0a31dcb88269b65..dc1fca0f05c1f0d21cd81b17810f1a7a54f241e4 100644 (file)
--- a/pgplib.c
+++ b/pgplib.c
@@ -52,44 +52,6 @@ const char *pgp_pkalgbytype (unsigned char type)
 }
 
 
-static struct
-{
-  char *pkalg;
-  char *micalg;
-}
-pktomic[] =
-{
-  {
-    "RSA", "pgp-md5"
-  }
-  ,
-  {
-    "ElG", "pgp-rmd160"
-  }
-  ,
-  {
-    "DSA", "pgp-sha1"
-  }
-  ,
-  {
-    NULL, "x-unknown"
-  }
-};
-
-
-const char *pgp_pkalg_to_mic (const char *alg)
-{
-  int i;
-
-  for (i = 0; pktomic[i].pkalg; i++)
-  {
-    if (!mutt_strcasecmp (pktomic[i].pkalg, alg))
-      break;
-  }
-
-  return pktomic[i].micalg;
-}
-
 
 /* unused */
 
index 574aa7790eb8b877db464a74a362e4207f2c1852..55ce4050cd7a0eeaeaf1209bff81f2cdc9443baa 100644 (file)
--- a/pgplib.h
+++ b/pgplib.h
@@ -81,7 +81,6 @@ typedef enum pgp_ring pgp_ring_t;
 
 /* prototypes */
 
-const char *pgp_pkalg_to_mic (const char *);
 const char *pgp_pkalgbytype (unsigned char);
 
 pgp_key_t *pgp_remove_key (pgp_key_t **, pgp_key_t *);
diff --git a/pgpmicalg.c b/pgpmicalg.c
new file mode 100644 (file)
index 0000000..6ba7779
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
+ * 
+ * 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 module peeks at a PGP signature and figures out the hash
+ * algorithm.
+ */
+
+#include "mutt.h"
+#include "pgp.h"
+#include "pgppacket.h"
+#include "mime.h"
+#include "charset.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+static struct 
+{
+  short id;
+  const char *name;
+} 
+HashAlgorithms[] = 
+{
+  { 1,         "pgp-md5"               },
+  { 2,         "pgp-sha1"              },
+  { 3,         "pgp-ripemd160"         },
+  { 5,         "pgp-md2"               },
+  { 6,         "pgp-tiger192"          },
+  { 7,         "pgp-haval-5-160"       },
+  { -1,        NULL }
+};
+
+static const char *pgp_hash_to_micalg (short id)
+{
+  int i;
+  
+  for (i = 0; HashAlgorithms[i].id >= 0; i++)
+    if (HashAlgorithms[i].id == id)
+      return HashAlgorithms[i].name;
+  return "x-unknown";
+}
+
+static void pgp_dearmor (FILE *in, FILE *out)
+{
+  char line[HUGE_STRING];
+  long start;
+  long end;
+  char *r;
+
+  STATE state;
+  
+  memset (&state, 0, sizeof (STATE));
+  state.fpin = in;
+  state.fpout = out;
+  
+  /* find the beginning of ASCII armor */
+  
+  while ((r = fgets (line, sizeof (line), in)) != NULL)
+  {
+    if (!strncmp (line, "-----BEGIN", 10))
+      break;
+  }
+  if (r == NULL)
+  {
+    dprint (1, (debugfile, "pgp_dearmor: Can't find begin of ASCII armor.\n"));
+    return;
+  }
+
+  /* skip the armor header */
+  
+  while ((r = fgets (line, sizeof (line), in)) != NULL)
+  {
+    SKIPWS (r);
+    if (!*r) break;
+  }
+  if (r == NULL)
+  {
+    dprint (1, (debugfile, "pgp_dearmor: Armor header doesn't end.\n"));
+    return;
+  }
+  
+  /* actual data starts here */
+  start = ftell (in);
+  
+  /* find the checksum */
+  
+  while ((r = fgets (line, sizeof (line), in)) != NULL)
+  {
+    if (*line == '=' || !strncmp (line, "-----END", 8))
+      break;
+  }
+  if (r == NULL)
+  {
+    dprint (1, (debugfile, "pgp_dearmor: Can't find end of ASCII armor.\n"));
+    return;
+  }
+  
+  if ((end = ftell (in) - strlen (line)) < start)
+  {
+    dprint (1, (debugfile, "pgp_dearmor: end < start???\n"));
+    return;
+  }
+  
+  if (fseek (in, start, SEEK_SET) == -1)
+  {
+    dprint (1, (debugfile, "pgp_dearmor: Can't seekto start.\n"));
+    return;
+  }
+
+  mutt_decode_base64 (&state, end - start, 0, (iconv_t) -1);
+}
+
+static short pgp_mic_from_packet (unsigned char *p, size_t len)
+{
+  /* is signature? */
+  if ((p[0] & 0x3f) != PT_SIG)
+  {
+    dprint (1, (debugfile, "pgp_mic_from_packet: tag = %d, want %d.\n",
+               p[0]&0x3f, PT_SIG));
+    return -1;
+  }
+  
+  if (len >= 18 && p[1] == 3)
+    /* version 3 signature */
+    return (short) p[17];
+  else if (len >= 5 && p[1] == 4)
+    /* version 4 signature */
+    return (short) p[4];
+  else
+  {
+    dprint (1, (debugfile, "pgp_mic_from_packet: Bad signature packet.\n"));
+    return -1;
+  }
+}
+
+static short pgp_find_hash (const char *fname)
+{
+  FILE *in = NULL;
+  FILE *out = NULL;
+  
+  char tempfile[_POSIX_PATH_MAX];
+  
+  unsigned char *p;
+  size_t l;
+  
+  short rv = -1;
+  
+  mutt_mktemp (tempfile);
+  if ((out = safe_fopen (tempfile, "w+")) == NULL)
+  {
+    mutt_perror (tempfile);
+    goto bye;
+  }
+  unlink (tempfile);
+  
+  if ((in = fopen (fname, "r")) == NULL)
+  {
+    mutt_perror (fname);
+    goto bye;
+  }
+  
+  pgp_dearmor (in, out);
+  rewind (out);
+
+  if ((p = pgp_read_packet (out, &l)) != NULL)
+  {
+    rv = pgp_mic_from_packet (p, l);
+  }
+  else
+  {
+    dprint (1, (debugfile, "pgp_find_hash: No packet.\n"));
+  }
+  
+  bye:
+  
+  safe_fclose (&in);
+  safe_fclose (&out);
+  pgp_release_packet ();
+  return rv;
+}
+
+const char *pgp_micalg (const char *fname)
+{
+  return pgp_hash_to_micalg (pgp_find_hash (fname));
+}
+
diff --git a/pgppacket.c b/pgppacket.c
new file mode 100644 (file)
index 0000000..519e70b
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
+ * 
+ * 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.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "sha1.h"
+#include "lib.h"
+#include "pgplib.h"
+#include "pgppacket.h"
+
+#define CHUNKSIZE 1024
+
+static unsigned char *pbuf = NULL;
+static size_t plen = 0;
+
+static int read_material (size_t material, size_t * used, FILE * fp)
+{
+  if (*used + material >= plen)
+  {
+    unsigned char *p;
+    size_t nplen;
+
+    nplen = *used + material + CHUNKSIZE;
+
+    if (!(p = realloc (pbuf, nplen)))  /* __MEM_CHECKED__ */
+    {
+      perror ("realloc");
+      return -1;
+    }
+    plen = nplen;
+    pbuf = p;
+  }
+
+  if (fread (pbuf + *used, 1, material, fp) < material)
+  {
+    perror ("fread");
+    return -1;
+  }
+
+  *used += material;
+  return 0;
+}
+
+unsigned char *pgp_read_packet (FILE * fp, size_t * len)
+{
+  size_t used = 0;
+  long startpos;
+  unsigned char ctb;
+  unsigned char b;
+  size_t material;
+
+  startpos = ftell (fp);
+
+  if (!plen)
+  {
+    plen = CHUNKSIZE;
+    pbuf = safe_malloc (plen);
+  }
+
+  if (fread (&ctb, 1, 1, fp) < 1)
+  {
+    if (!feof (fp))
+      perror ("fread");
+    goto bail;
+  }
+
+  if (!(ctb & 0x80))
+  {
+    goto bail;
+  }
+
+  if (ctb & 0x40)              /* handle PGP 5.0 packets. */
+  {
+    int partial = 0;
+    pbuf[0] = ctb;
+    used++;
+
+    do
+    {
+      if (fread (&b, 1, 1, fp) < 1)
+      {
+       perror ("fread");
+       goto bail;
+      }
+
+      if (b < 192)
+      {
+       material = b;
+       partial = 0;
+       material -= 1;
+      }
+      else if (192 <= b && b <= 223)
+      {
+       material = (b - 192) * 256;
+       if (fread (&b, 1, 1, fp) < 1)
+       {
+         perror ("fread");
+         goto bail;
+       }
+       material += b + 192;
+       partial = 0;
+       material -= 2;
+      }
+      else if (b < 255)
+      {
+       material = 1 << (b & 0x1f);
+       partial = 1;
+       material -= 1;
+      }
+      else
+       /* b == 255 */
+      {
+       unsigned char buf[4];
+       if (fread (buf, 4, 1, fp) < 1)
+       {
+         perror ("fread");
+         goto bail;
+       }
+       /*assert( sizeof(material) >= 4 ); */
+       material = buf[0] << 24;
+       material |= buf[1] << 16;
+       material |= buf[2] << 8;
+       material |= buf[3];
+       partial = 0;
+       material -= 5;
+      }
+
+      if (read_material (material, &used, fp) == -1)
+       goto bail;
+
+    }
+    while (partial);
+  }
+  else
+    /* Old-Style PGP */
+  {
+    int bytes = 0;
+    pbuf[0] = 0x80 | ((ctb >> 2) & 0x0f);
+    used++;
+
+    switch (ctb & 0x03)
+    {
+      case 0:
+      {
+       if (fread (&b, 1, 1, fp) < 1)
+       {
+         perror ("fread");
+         goto bail;
+       }
+
+       material = b;
+       break;
+      }
+
+      case 1:
+      bytes = 2;
+
+      case 2:
+      {
+       int i;
+
+       if (!bytes)
+         bytes = 4;
+
+       material = 0;
+
+       for (i = 0; i < bytes; i++)
+       {
+         if (fread (&b, 1, 1, fp) < 1)
+         {
+           perror ("fread");
+           goto bail;
+         }
+
+         material = (material << 8) + b;
+       }
+       break;
+      }
+
+      default:
+      goto bail;
+    }
+
+    if (read_material (material, &used, fp) == -1)
+      goto bail;
+  }
+
+  if (len)
+    *len = used;
+
+  return pbuf;
+
+bail:
+
+  fseek (fp, startpos, SEEK_SET);
+  return NULL;
+}
+
+void pgp_release_packet (void)
+{
+  plen = 0;
+  free (pbuf);
+  pbuf = NULL;
+}
+
diff --git a/pgppacket.h b/pgppacket.h
new file mode 100644 (file)
index 0000000..4b7fd64
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
+ * 
+ * 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.
+ */
+
+/* 
+ * Definitions for a rudimentary PGP packet parser which is shared
+ * by mutt proper and the PGP public key ring lister.
+ */
+
+#ifndef _PGPPACKET_H
+# define _PGPPACKET_H
+
+enum packet_tags
+{
+  PT_RES0 = 0,                 /* reserved */
+  PT_ESK,                      /* Encrypted Session Key */
+  PT_SIG,                      /* Signature Packet */
+  PT_CESK,                     /* Conventionally Encrypted Session Key Packet */
+  PT_OPS,                      /* One-Pass Signature Packet */
+  PT_SECKEY,                   /* Secret Key Packet */
+  PT_PUBKEY,                   /* Public Key Packet */
+  PT_SUBSECKEY,                        /* Secret Subkey Packet */
+  PT_COMPRESSED,               /* Compressed Data Packet */
+  PT_SKE,                      /* Symmetrically Encrypted Data Packet */
+  PT_MARKER,                   /* Marker Packet */
+  PT_LITERAL,                  /* Literal Data Packet */
+  PT_TRUST,                    /* Trust Packet */
+  PT_NAME,                     /* Name Packet */
+  PT_SUBKEY,                   /* Subkey Packet */
+  PT_RES15,                    /* Reserved */
+  PT_COMMENT                   /* Comment Packet */
+};
+
+unsigned char *pgp_read_packet (FILE * fp, size_t * len);
+void pgp_release_packet (void);
+
+#endif
index aa05822a5cce99ac49a45b60f65c2463e9607247..0181264f3f133e4501eeced014bdeecee3be32ed 100644 (file)
@@ -52,6 +52,8 @@ extern int optind;
 #include "sha1.h"
 #include "lib.h"
 #include "pgplib.h"
+#include "pgppacket.h"
+
 
 #ifdef HAVE_FGETPOS
 #define FGETPOS(fp,pos) fgetpos((fp),&(pos))
@@ -61,10 +63,7 @@ extern int optind;
 #define FSETPOS(fp,pos) fseek((fp),(pos),SEEK_SET)
 #endif
 
-#define CHUNKSIZE 1024
 
-static unsigned char *pbuf = NULL;
-static size_t plen = 0;
 
 static void pgpring_find_candidates (char *ringfile, const char *hints[], int nhints);
 static void pgpring_dump_keyblock (pgp_key_t *p);
@@ -141,243 +140,6 @@ int main (int argc, char * const argv[])
 
 /* The actual key ring parser */
 
-enum packet_tags
-{
-  PT_RES0 = 0,                 /* reserved */
-  PT_ESK,                      /* Encrypted Session Key */
-  PT_SIG,                      /* Signature Packet */
-  PT_CESK,                     /* Conventionally Encrypted Session Key Packet */
-  PT_OPS,                      /* One-Pass Signature Packet */
-  PT_SECKEY,                   /* Secret Key Packet */
-  PT_PUBKEY,                   /* Public Key Packet */
-  PT_SUBSECKEY,                        /* Secret Subkey Packet */
-  PT_COMPRESSED,               /* Compressed Data Packet */
-  PT_SKE,                      /* Symmetrically Encrypted Data Packet */
-  PT_MARKER,                   /* Marker Packet */
-  PT_LITERAL,                  /* Literal Data Packet */
-  PT_TRUST,                    /* Trust Packet */
-  PT_NAME,                     /* Name Packet */
-  PT_SUBKEY,                   /* Subkey Packet */
-  PT_RES15,                    /* Reserved */
-  PT_COMMENT                   /* Comment Packet */
-};
-
-/* 
- * These aren't displayed at all currently, but they may come quite
- * handy for debugging strings.
- * 
- * No need to translate them.
- *
- */
-
-#if 0
-
-const char *pgp_packet_name[] =
-{
-  "reserved",
-  "Encrypted Session Key",
-  "Signature Packet",
-  "Conventionally Encrypted Session Key Packet",
-  "One-Pass Signature Packet",
-  "Secret Key Packet",
-  "Public Key Packet",
-  "Secret Subkey Packet",
-  "Compressed Data Packet",
-  "Symmetrically Encrypted Data Packet",
-  "Marker Packet",
-  "Literal Data Packet",
-  "Trust Packet",
-  "Name Packet",
-  "Subkey Packet",
-  "Reserved",
-  "Comment Packet"
-};
-
-#endif
-
-static int read_material (size_t material, size_t * used, FILE * fp)
-{
-  if (*used + material >= plen)
-  {
-    unsigned char *p;
-    size_t nplen;
-
-    nplen = *used + material + CHUNKSIZE;
-
-    if (!(p = realloc (pbuf, nplen)))  /* __MEM_CHECKED__ */
-    {
-      perror ("realloc");
-      return -1;
-    }
-    plen = nplen;
-    pbuf = p;
-  }
-
-  if (fread (pbuf + *used, 1, material, fp) < material)
-  {
-    perror ("fread");
-    return -1;
-  }
-
-  *used += material;
-  return 0;
-}
-
-static unsigned char *pgp_read_packet (FILE * fp, size_t * len)
-{
-  size_t used = 0;
-  long startpos;
-  unsigned char ctb;
-  unsigned char b;
-  size_t material;
-
-  startpos = ftell (fp);
-
-  if (!plen)
-  {
-    plen = CHUNKSIZE;
-    pbuf = safe_malloc (plen);
-  }
-
-  if (fread (&ctb, 1, 1, fp) < 1)
-  {
-    if (!feof (fp))
-      perror ("fread");
-    goto bail;
-  }
-
-  if (!(ctb & 0x80))
-  {
-    goto bail;
-  }
-
-  if (ctb & 0x40)              /* handle PGP 5.0 packets. */
-  {
-    int partial = 0;
-    pbuf[0] = ctb;
-    used++;
-
-    do
-    {
-      if (fread (&b, 1, 1, fp) < 1)
-      {
-       perror ("fread");
-       goto bail;
-      }
-
-      if (b < 192)
-      {
-       material = b;
-       partial = 0;
-       material -= 1;
-      }
-      else if (192 <= b && b <= 223)
-      {
-       material = (b - 192) * 256;
-       if (fread (&b, 1, 1, fp) < 1)
-       {
-         perror ("fread");
-         goto bail;
-       }
-       material += b + 192;
-       partial = 0;
-       material -= 2;
-      }
-      else if (b < 255)
-      {
-       material = 1 << (b & 0x1f);
-       partial = 1;
-       material -= 1;
-      }
-      else
-       /* b == 255 */
-      {
-       unsigned char buf[4];
-       if (fread (buf, 4, 1, fp) < 1)
-       {
-         perror ("fread");
-         goto bail;
-       }
-       /*assert( sizeof(material) >= 4 ); */
-       material = buf[0] << 24;
-       material |= buf[1] << 16;
-       material |= buf[2] << 8;
-       material |= buf[3];
-       partial = 0;
-       material -= 5;
-      }
-
-      if (read_material (material, &used, fp) == -1)
-       goto bail;
-
-    }
-    while (partial);
-  }
-  else
-    /* Old-Style PGP */
-  {
-    int bytes = 0;
-    pbuf[0] = 0x80 | ((ctb >> 2) & 0x0f);
-    used++;
-
-    switch (ctb & 0x03)
-    {
-      case 0:
-      {
-       if (fread (&b, 1, 1, fp) < 1)
-       {
-         perror ("fread");
-         goto bail;
-       }
-
-       material = b;
-       break;
-      }
-
-      case 1:
-      bytes = 2;
-
-      case 2:
-      {
-       int i;
-
-       if (!bytes)
-         bytes = 4;
-
-       material = 0;
-
-       for (i = 0; i < bytes; i++)
-       {
-         if (fread (&b, 1, 1, fp) < 1)
-         {
-           perror ("fread");
-           goto bail;
-         }
-
-         material = (material << 8) + b;
-       }
-       break;
-      }
-
-      default:
-      goto bail;
-    }
-
-    if (read_material (material, &used, fp) == -1)
-      goto bail;
-  }
-
-  if (len)
-    *len = used;
-
-  return pbuf;
-
-bail:
-
-  fseek (fp, startpos, SEEK_SET);
-  return NULL;
-}
-
 static pgp_key_t *pgp_parse_pgp2_key (unsigned char *buff, size_t l)
 {
   pgp_key_t *p;
index 330f74713cec3302d4a71666181dcee9b096960c..030c83d4b727fc1a36c3304973dc5dda104a938c 100644 (file)
@@ -387,7 +387,6 @@ int mutt_parse_pgp_hdr (char *p, int set_signas)
 {
   int pgp = 0;
   char pgp_sign_as[LONG_STRING] = "\0", *q;
-  char pgp_sign_micalg[LONG_STRING] = "\0";
    
   SKIPWS (p);
   for (; *p; p++)
@@ -422,16 +421,17 @@ int mutt_parse_pgp_hdr (char *p, int set_signas)
         *q = '\0';
         break;
 
+      /* This used to be the micalg parameter.
+       * 
+       * It's no longer needed, so we just skip the parameter in order
+       * to be able to recall old messages.
+       */
       case 'm':
       case 'M':
-       q = pgp_sign_micalg;
-       
         if(*(p+1) == '<')
-       {
-         for(p += 2; *p && *p != '>' && q < pgp_sign_micalg + sizeof(pgp_sign_micalg) - 1;
-             *q++ = *p++)
+        {
+         for (p += 2; *p && *p != '>'; p++)
            ;
-         
          if(*p != '>')
          {
            mutt_error _("Illegal PGP header");
@@ -439,7 +439,6 @@ int mutt_parse_pgp_hdr (char *p, int set_signas)
          }
        }
 
-       *q = '\0';
        break;
          
       default:
@@ -452,10 +451,6 @@ int mutt_parse_pgp_hdr (char *p, int set_signas)
   if (set_signas || *pgp_sign_as)
     mutt_str_replace (&PgpSignAs, pgp_sign_as);
 
-  /* the micalg field must not be empty */
-  if (set_signas && *pgp_sign_micalg)
-    mutt_str_replace (&PgpSignMicalg, pgp_sign_micalg);
-
   return pgp;
 }
 #endif /* HAVE_PGP */
index dc6bab9a1fada57bccf1588780a90403ca14651a..c29e8119a176a6cdb34733804ca8d3cd5ecb1529 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -150,6 +150,7 @@ void mutt_check_rescore (CONTEXT *);
 void mutt_clear_error (void);
 void mutt_create_alias (ENVELOPE *, ADDRESS *);
 void mutt_decode_attachment (BODY *, STATE *);
+void mutt_decode_base64 (STATE *s, long len, int istext, iconv_t cd);
 void mutt_default_save (char *, size_t, HEADER *);
 void mutt_display_address (ENVELOPE *);
 void mutt_display_sanitize (char *);
diff --git a/send.c b/send.c
index b2335e63b87eb79595e972f8718338e32a096044..88b84c6c80129b8fada12ffc5494b4e16160eee0 100644 (file)
--- a/send.c
+++ b/send.c
@@ -1025,7 +1025,6 @@ ci_send_message (int flags,               /* send mode */
   char *pgpkeylist = NULL;
   /* save current value of "pgp_sign_as" */
   char *signas = NULL;
-  char *signmic = NULL;
 #endif
 
   int rv = -1;
@@ -1046,10 +1045,7 @@ ci_send_message (int flags,              /* send mode */
   
 #ifdef HAVE_PGP
   if (flags & SENDPOSTPONED)
-  {
     signas = safe_strdup(PgpSignAs);
-    signmic = safe_strdup(PgpSignMicalg);
-  }
 #endif /* HAVE_PGP */
 
   if (msg)
@@ -1580,12 +1576,6 @@ cleanup:
       safe_free((void **) &PgpSignAs);
       PgpSignAs = signas;
     }
-    
-    if(signmic)
-    {
-      safe_free((void **) &PgpSignMicalg);
-      PgpSignMicalg = signmic;
-    }
   }
 #endif /* HAVE_PGP */
    
index 45ad8aa888d647a1663f7d6c5efe4bf9c321c472..013eab0f1f61aec0982aa4af0bb788cf4c7b318f 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -2304,8 +2304,6 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post,
       fputc ('S', msg->fp);
       if (PgpSignAs && *PgpSignAs)
         fprintf (msg->fp, "<%s>", PgpSignAs);
-      if (*PgpSignMicalg)
-       fprintf (msg->fp, "M<%s>", PgpSignMicalg);
     }
     fputc ('\n', msg->fp);
   }