]> granicus.if.org Git - mutt/commitdiff
This is the sequel to the crypto modularization changes I did on
authorMoritz Schulte <moritz@g10code.com>
Thu, 17 Jun 2004 20:36:13 +0000 (20:36 +0000)
committerMoritz Schulte <moritz@g10code.com>
Thu, 17 Jun 2004 20:36:13 +0000 (20:36 +0000)
2003-01-21.  Moritz added another abstraction layer which cleans up
the code and allows the crypto modules to use their own option menu.
Everything should work as it used to but is now in a really good
shape for part III, the Return of the GnuPG Easy Makers. -wk

* crypt-mod-pgp-classic.c, crypt-mod-smime-classic.c, crypt-mod.c,
crypt-mod.h: New files.

* smime.c (smime_valid_passphrase, smime_send_menu): New functions.
* smime.h: Removed macro: smime_valid_passphrase.
Declared: smime_valid_passphrase, smime_send_menu.
* pgp.c: Include "mutt_menu.h".
(pgp_valid_passphrase, pgp_send_menu): New functions.
* pgp.h: Removed macro: pgp_valid_passphrase.
Declared: pgp_valid_passphrase, pgp_send_menu.
* mutt_curses.h: Declare: mutt_need_hard_redraw.
* mutt_crypt.h: Declare: crypt_pgp_valid_passphrase,
crypt_pgp_send_menu, crypt_smime_valid_passphrase,
crypt_smime_send_menu, crypt_init.
Adjust WithCrypto definition since the GPGME backend does not
exclude anymore the other `classic' backends.
(KEYFLAG_ISX509): New symbol.
* mutt.h (enum): New symbol: OPTCRYPTUSEGPGME.
(struct body): New member: is_signed_data, warnsig.
* main.c (main): Call crypt_init.
* keymap.c (km_get_table): Support for MENU_KEY_SELECT_PGP and
MENU_KEY_SELECT_SMIME.
(Menus): Added entries fuer MENU_KEY_SELECT_PGP and
MENU_KEY_SELECT_SMIME.
(km_init): Create bindings for MENU_KEY_SELECT_PGP and
MENU_KEY_SELECT_SMIME.
* keymap.h (enum): New enum symbols: MENU_KEY_SELECT_PGP,
MENU_KEY_SELECT_SMIME.
* init.h: New configuration variable: crypt_use_gpgme.
* compose.c (pgp_send_menu, smime_send_menu): Removed functions,
they are now contained in the crypto backend modules.
(mutt_compose_menu): Use crypt_pgp_send_menu and
crypt_smime_send_menu instead pgp_send_menu and smime_send_menu.
* cryptglue.c: Slightly rewritten in order to make use of the
module mechanism used to access crypto backends.
* curs_lib.c (mutt_need_hard_redraw): New function.
* crypt.c (crypt_forget_passphrase): Adjust for new crypto backend
interface.
(crypt_valid_passphrase): Stripped, use calls to
crypt_pgp_valid_passphrase and crypt_smime_valid_passphrase.

21 files changed:
Makefile.am
compose.c
configure.in
crypt-mod-pgp-classic.c [new file with mode: 0644]
crypt-mod-smime-classic.c [new file with mode: 0644]
crypt-mod.c [new file with mode: 0644]
crypt-mod.h [new file with mode: 0644]
crypt.c
cryptglue.c
curs_lib.c
init.h
keymap.c
keymap.h
main.c
mutt.h
mutt_crypt.h
mutt_curses.h
pgp.c
pgp.h
smime.c
smime.h

index 66ce4135e7b10db0576bd78822374e86d6ccdd43..38499f7f83bfb041d3b9ccd6130ee6cbd2f586d4 100644 (file)
@@ -28,10 +28,10 @@ mutt_SOURCES = $(BUILT_SOURCES) \
        score.c send.c sendlib.c signal.c sort.c \
        status.c system.c thread.c charset.c history.c lib.c \
        muttlib.c editmsg.c utf8.c mbyte.c wcwidth.c \
-       url.c ascii.c mutt_idna.c
+       url.c ascii.c mutt_idna.c crypt-mod.c crypt-mod.h
 
 mutt_LDADD = @MUTT_LIB_OBJECTS@ @LIBOBJS@ $(LIBIMAP) $(MUTTLIBS) \
-       $(INTLLIBS) $(LIBICONV)
+       $(INTLLIBS) $(LIBICONV) 
 
 mutt_DEPENDENCIES = @MUTT_LIB_OBJECTS@ @LIBOBJS@ $(LIBIMAPDEPS) \
        $(INTLDEPS)
@@ -55,13 +55,14 @@ DEFS=-DPKGDATADIR=\"$(pkgdatadir)\" -DSYSCONFDIR=\"$(sysconfdir)\" \
 
 INCLUDES=-I. -I$(top_srcdir) $(IMAP_INCLUDES) -Iintl
 
-CPPFLAGS=@CPPFLAGS@ -I$(includedir)
+CPPFLAGS=@CPPFLAGS@ -I$(includedir) -D_FILE_OFFSET_BITS=64
 
 
 EXTRA_mutt_SOURCES = account.c md5c.c mutt_sasl.c mutt_socket.c mutt_ssl.c \
        mutt_tunnel.c pop.c pop_auth.c pop_lib.c smime.c pgp.c pgpinvoke.c pgpkey.c \
        pgplib.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 \
+       crypt-mod-pgp-classic.c crypt-mod-smime-classic.c \
        pgppacket.c mutt_idna.h
 
 EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP OPS.CRYPT OPS.SMIME TODO \
index bed25df71a28e168509a419202189b801ebc9055..8bd93b01c99fedaef6bc6909e145876d5ee4dbcc 100644 (file)
--- a/compose.c
+++ b/compose.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
+ * 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
@@ -162,167 +163,6 @@ static void redraw_crypt_lines (HEADER *msg)
 }
 
 
-
-static int pgp_send_menu (HEADER *msg, int *redraw)
-{
-  pgp_key_t p;
-  char input_signas[SHORT_STRING];
-
-  if (!(WithCrypto & APPLICATION_PGP))
-    return msg->security;
-
-  switch (mutt_multi_choice (_("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, (i)nline, or (f)orget it? "),
-                            _("esabif")))
-  {
-  case 1: /* (e)ncrypt */
-    msg->security ^= ENCRYPT;
-    break;
-
-  case 2: /* (s)ign */
-    msg->security ^= SIGN;
-    break;
-
-  case 3: /* sign (a)s */
-    unset_option(OPTPGPCHECKTRUST);
-
-    if ((p = crypt_pgp_ask_for_key (_("Sign as: "), NULL,
-                                    KEYFLAG_CANSIGN, PGP_PUBRING)))
-    {
-      snprintf (input_signas, sizeof (input_signas), "0x%s",
-                crypt_pgp_keyid (p));
-      mutt_str_replace (&PgpSignAs, input_signas);
-      crypt_pgp_free_key (&p);
-      
-      msg->security |= SIGN;
-       
-      crypt_pgp_void_passphrase ();  /* probably need a different passphrase */
-    }
-    else
-    {
-      msg->security &= ~SIGN;
-    }
-
-    *redraw = REDRAW_FULL;
-    break;
-
-  case 4: /* (b)oth */
-    if ((msg->security & (ENCRYPT | SIGN)) == (ENCRYPT | SIGN))
-      msg->security = 0;
-    else
-      msg->security |= (ENCRYPT | SIGN);
-    break;
-
-  case 5: /* (i)nline */
-    if ((msg->security & (ENCRYPT | SIGN)))
-      msg->security ^= INLINE;
-    else
-      msg->security &= ~INLINE;
-    break;
-
-  case 6: /* (f)orget it */
-    msg->security = 0;
-    break;
-  }
-
-  if (msg->security)
-  {
-    if (! (msg->security & (ENCRYPT | SIGN)))
-      msg->security = 0;
-    else
-      msg->security |= APPLICATION_PGP;
-  }
-
-  if(*redraw)
-      redraw_crypt_lines (msg);
-  return (msg->security);
-}
-
-
-
-static int smime_send_menu (HEADER *msg, int *redraw)
-{
-  char *p;
-
-  if (!(WithCrypto & APPLICATION_SMIME))
-    return msg->security;
-
-  switch (mutt_multi_choice (_("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, or (f)orget it? "),
-                            _("eswabf")))
-  {
-  case 1: /* (e)ncrypt */
-    msg->security |= ENCRYPT;
-    break;
-
-  case 3: /* encrypt (w)ith */
-    msg->security |= ENCRYPT;
-    switch (mutt_multi_choice (_("1: DES, 2: Triple-DES, 3: RC2-40,"
-                                " 4: RC2-64, 5: RC2-128, or (f)orget it? "),
-                              _("12345f"))) {
-    case 1:
-       mutt_str_replace (&SmimeCryptAlg, "des");
-       break;
-    case 2:
-       mutt_str_replace (&SmimeCryptAlg, "des3");
-       break;
-    case 3:
-       mutt_str_replace (&SmimeCryptAlg, "rc2-40");
-       break;
-    case 4:
-       mutt_str_replace (&SmimeCryptAlg, "rc2-64");
-       break;
-    case 5:
-       mutt_str_replace (&SmimeCryptAlg, "rc2-128");
-       break;
-    case 6: /* forget it */
-       break;
-    }
-    break;
-
-  case 2: /* (s)ign */
-      
-    if(!SmimeDefaultKey)
-       mutt_message("Can\'t sign: No key specified. use sign(as).");
-    else
-       msg->security |= SIGN;
-    break;
-
-  case 4: /* sign (a)s */
-
-    if ((p = crypt_smime_ask_for_key (_("Sign as: "), NULL, 0))) {
-      p[mutt_strlen (p)-1] = '\0';
-      mutt_str_replace (&SmimeDefaultKey, p);
-       
-      msg->security |= SIGN;
-
-      /* probably need a different passphrase */
-      crypt_smime_void_passphrase ();
-    }
-    else
-      msg->security &= ~SIGN;
-
-    *redraw = REDRAW_FULL;
-    break;
-
-  case 5: /* (b)oth */
-    msg->security = ENCRYPT | SIGN;
-    break;
-
-  case 6: /* (f)orget it */
-    msg->security = 0;
-    break;
-  }
-
-  if (msg->security && msg->security != APPLICATION_SMIME)
-    msg->security |= APPLICATION_SMIME;
-  else
-    msg->security = 0;
-
-  if(*redraw)
-      redraw_crypt_lines (msg);
-  return (msg->security);
-}
-
-
 #ifdef MIXMASTER
 
 static void redraw_mix_line (LIST *chain)
@@ -1344,7 +1184,7 @@ int mutt_compose_menu (HEADER *msg,   /* structure for new message */
          }
          msg->security = 0;
        }
-       msg->security = pgp_send_menu (msg, &menu->redraw);
+       msg->security = crypt_pgp_send_menu (msg, &menu->redraw);
        redraw_crypt_lines (msg);
        break;
 
@@ -1369,7 +1209,7 @@ int mutt_compose_menu (HEADER *msg,   /* structure for new message */
          }
          msg->security = 0;
        }
-       msg->security = smime_send_menu(msg, &menu->redraw);
+       msg->security = crypt_smime_send_menu(msg, &menu->redraw);
        redraw_crypt_lines (msg);
        break;
 
index 892f2f608bab80f8eee7b7083d81fb5726df6be8..5ce55a95cafd48f41890bbf7256843438b4f1031 100644 (file)
@@ -105,7 +105,7 @@ else
                 AC_DEFINE(CRYPT_BACKEND_CLASSIC_PGP,1,
                     [ Define if you want classic PGP support. ])
                 PGPAUX_TARGET="pgpring pgpewrap"
-                MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS pgp.o pgpinvoke.o pgpkey.o pgplib.o gnupgparse.o pgpmicalg.o pgppacket.o"
+                MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS pgp.o pgpinvoke.o pgpkey.o pgplib.o gnupgparse.o pgpmicalg.o pgppacket.o crypt-mod-pgp-classic.o"
         fi
 
        AC_ARG_ENABLE(smime, [  --disable-smime            Disable SMIME support],
@@ -117,7 +117,7 @@ else
        if test x$have_smime != xno ; then
                AC_DEFINE(CRYPT_BACKEND_CLASSIC_SMIME,1,
                   [ Define if you want clasic S/MIME support. ])
-               MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS smime.o "
+               MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS smime.o crypt-mod-smime-classic.o"
                SMIMEAUX_TARGET="smime_keys"
        fi
   
diff --git a/crypt-mod-pgp-classic.c b/crypt-mod-pgp-classic.c
new file mode 100644 (file)
index 0000000..083a82f
--- /dev/null
@@ -0,0 +1,132 @@
+/* 
+ * 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 is a crytpo module wrapping the classic pgp code.
+ */
+
+#include "crypt-mod.h"
+#include "pgp.h"
+
+static void crypt_mod_pgp_void_passphrase (void)
+{
+  pgp_void_passphrase ();
+}
+
+static int crypt_mod_pgp_valid_passphrase (void)
+{
+  return pgp_valid_passphrase ();
+}
+
+static int crypt_mod_pgp_decrypt_mime (FILE *a, FILE **b, BODY *c, BODY **d)
+{
+  return pgp_decrypt_mime (a, b, c, d);
+}
+static void crypt_mod_pgp_application_handler (BODY *m, STATE *s)
+{
+  pgp_application_pgp_handler (m, s);
+}
+
+static char *crypt_mod_pgp_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
+{
+  return pgp_findKeys (to, cc, bcc);
+}
+
+static BODY *crypt_mod_pgp_sign_message (BODY *a)
+{
+  return pgp_sign_message (a);
+}
+
+static int crypt_mod_pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
+{
+  return pgp_verify_one (sigbdy, s, tempf);
+}
+
+static int crypt_mod_pgp_send_menu (HEADER *msg, int *redraw)
+{
+  return pgp_send_menu (msg, redraw);
+}
+
+static BODY *crypt_mod_pgp_encrypt_message (BODY *a, char *keylist, int sign)
+{
+  return pgp_encrypt_message (a, keylist, sign);
+}
+
+static BODY *crypt_mod_pgp_make_key_attachment (char *tempf)
+{
+  return pgp_make_key_attachment (tempf);
+}
+
+static int crypt_mod_pgp_check_traditional (FILE *fp, BODY *b, int tagged_only)
+{
+  return pgp_check_traditional (fp, b, tagged_only);
+}
+
+static BODY *crypt_mod_pgp_traditional_encryptsign (BODY *a, int flags, char *keylist)
+{
+  return pgp_traditional_encryptsign (a, flags, keylist);
+}
+
+static void crypt_mod_pgp_encrypted_handler (BODY *m, STATE *s)
+{
+  pgp_encrypted_handler (m, s);
+}
+
+static void crypt_mod_pgp_invoke_getkeys (ADDRESS *addr)
+{
+  pgp_invoke_getkeys (addr);
+}
+
+static void crypt_mod_pgp_invoke_import (const char *fname)
+{
+  pgp_invoke_import (fname);
+}
+
+static void crypt_mod_pgp_extract_keys_from_attachment_list (FILE *fp, int tag, BODY *top)
+{
+  pgp_extract_keys_from_attachment_list (fp, tag, top);
+}
+
+struct crypt_module_specs crypt_mod_pgp_classic =
+  { APPLICATION_PGP,
+    {
+      NULL,                    /* init */
+      crypt_mod_pgp_void_passphrase,
+      crypt_mod_pgp_valid_passphrase,
+      crypt_mod_pgp_decrypt_mime,
+      crypt_mod_pgp_application_handler,
+      crypt_mod_pgp_encrypted_handler,
+      crypt_mod_pgp_findkeys,
+      crypt_mod_pgp_sign_message,
+      crypt_mod_pgp_verify_one,
+      crypt_mod_pgp_send_menu,
+
+      crypt_mod_pgp_encrypt_message,
+      crypt_mod_pgp_make_key_attachment,
+      crypt_mod_pgp_check_traditional,
+      crypt_mod_pgp_traditional_encryptsign,
+      crypt_mod_pgp_invoke_getkeys,
+      crypt_mod_pgp_invoke_import,
+      crypt_mod_pgp_extract_keys_from_attachment_list,
+
+      NULL,                    /* smime_getkeys */
+      NULL,                    /* smime_verify_sender */
+      NULL,                    /* smime_build_smime_entity */
+      NULL,                    /* smime_invoke_import */
+    }
+  };
diff --git a/crypt-mod-smime-classic.c b/crypt-mod-smime-classic.c
new file mode 100644 (file)
index 0000000..e6ab753
--- /dev/null
@@ -0,0 +1,113 @@
+/* 
+ * 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 is a crytpo module wrapping the classic smime code.
+ */
+
+#include "crypt-mod.h"
+#include "smime.h"
+
+static void crypt_mod_smime_void_passphrase (void)
+{
+  smime_void_passphrase ();
+}
+
+static int crypt_mod_smime_valid_passphrase (void)
+{
+  return smime_valid_passphrase ();
+}
+
+static int crypt_mod_smime_decrypt_mime (FILE *a, FILE **b, BODY *c, BODY **d)
+{
+  return smime_decrypt_mime (a, b, c, d);
+}
+static void crypt_mod_smime_application_handler (BODY *m, STATE *s)
+{
+  smime_application_smime_handler (m, s);
+}
+
+static char *crypt_mod_smime_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
+{
+  return smime_findKeys (to, cc, bcc);
+}
+
+static BODY *crypt_mod_smime_sign_message (BODY *a)
+{
+  return smime_sign_message (a);
+}
+
+static int crypt_mod_smime_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
+{
+  return smime_verify_one (sigbdy, s, tempf);
+}
+
+static int crypt_mod_smime_send_menu (HEADER *msg, int *redraw)
+{
+  return smime_send_menu (msg, redraw);
+}
+
+static void crypt_mod_smime_getkeys (ENVELOPE *env)
+{
+  smime_getkeys (env);
+}
+
+static int crypt_mod_smime_verify_sender (HEADER *h)
+{
+  return smime_verify_sender (h);
+}
+
+static BODY *crypt_mod_smime_build_smime_entity (BODY *a, char *certlist)
+{
+  return smime_build_smime_entity (a, certlist);
+}
+
+static void crypt_mod_smime_invoke_import (char *infile, char *mailbox)
+{
+  smime_invoke_import (infile, mailbox);
+}
+
+
+struct crypt_module_specs crypt_mod_smime_classic =
+  { APPLICATION_SMIME,
+    {
+      NULL,                    /* init */
+      crypt_mod_smime_void_passphrase,
+      crypt_mod_smime_valid_passphrase,
+      crypt_mod_smime_decrypt_mime,
+      crypt_mod_smime_application_handler,
+      NULL,                    /* encrypted_handler */
+      crypt_mod_smime_findkeys,
+      crypt_mod_smime_sign_message,
+      crypt_mod_smime_verify_one,
+      crypt_mod_smime_send_menu,
+
+      NULL,                    /* pgp_encrypt_message */
+      NULL,                    /* pgp_make_key_attachment */
+      NULL,                    /* pgp_check_traditional */
+      NULL,                    /* pgp_traditional_encryptsign */
+      NULL,                    /* pgp_invoke_getkeys */
+      NULL,                    /* pgp_invoke_import */
+      NULL,                    /* pgp_extract_keys_from_attachment_list */
+      
+      crypt_mod_smime_getkeys,
+      crypt_mod_smime_verify_sender,
+      crypt_mod_smime_build_smime_entity,
+      crypt_mod_smime_invoke_import,
+    }
+  };
diff --git a/crypt-mod.c b/crypt-mod.c
new file mode 100644 (file)
index 0000000..356e3e9
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#include "crypt-mod.h"
+
+/* A type an a variable to keep track of registered crypto modules. */
+typedef struct crypt_module *crypt_module_t;
+
+struct crypt_module
+{
+  crypt_module_specs_t specs;
+  crypt_module_t next, *prevp;
+};
+
+static crypt_module_t modules;
+
+/* Register a new crypto module. */
+void crypto_module_register (crypt_module_specs_t specs)
+{
+  crypt_module_t module_new = safe_malloc (sizeof (*module_new));
+
+  module_new->specs = specs;
+  module_new->next = modules;
+  if (modules)
+    modules->prevp = &module_new->next;
+  modules = module_new;
+}
+
+/* Return the crypto module specs for IDENTIFIER.  This function is
+   usually used via the CRYPT_MOD_CALL[_CHECK] macros. */
+crypt_module_specs_t crypto_module_lookup (int identifier)
+{
+  crypt_module_t module = modules;
+
+  while (module && (module->specs->identifier != identifier))
+    module = module->next;
+
+  return module ? module->specs : NULL;
+}
diff --git a/crypt-mod.h b/crypt-mod.h
new file mode 100644 (file)
index 0000000..4f69c3e
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+#ifndef CRYPTOGRAPHY_H
+#define CRYPTOGRAPHY_H
+
+#include "mutt.h"
+#include "mutt_crypt.h"
+
+#define CRYPTO_SUPPORT(identifier) (WithCrypto & APPLICATION_ ## identifier)
+
+
+/* 
+    Type defintions for crypto module functions.
+ */
+typedef void (*crypt_func_void_passphrase_t) (void);
+typedef int (*crypt_func_valid_passphrase_t)  (void);
+
+typedef int (*crypt_func_decrypt_mime_t) (FILE *a, FILE **b,
+                                          BODY *c, BODY **d);
+
+typedef void (*crypt_func_application_handler_t) (BODY *m, STATE *s);
+typedef void (*crypt_func_encrypted_handler_t) (BODY *m, STATE *s);
+
+typedef void (*crypt_func_pgp_invoke_getkeys_t) (ADDRESS *addr);
+typedef int (*crypt_func_pgp_check_traditional_t) (FILE *fp, BODY *b,
+                                                   int tagged_only);
+typedef BODY *(*crypt_func_pgp_traditional_encryptsign_t) (BODY *a, int flags,
+                                                           char *keylist);
+typedef BODY *(*crypt_func_pgp_make_key_attachment_t) (char *tempf);
+typedef char *(*crypt_func_findkeys_t) (ADDRESS *to,
+                                        ADDRESS *cc, ADDRESS *bcc);
+typedef BODY *(*crypt_func_sign_message_t) (BODY *a);
+typedef BODY *(*crypt_func_pgp_encrypt_message_t) (BODY *a, char *keylist,
+                                                   int sign);
+typedef void (*crypt_func_pgp_invoke_import_t) (const char *fname);
+typedef int (*crypt_func_verify_one_t) (BODY *sigbdy, STATE *s,
+                                        const char *tempf);
+typedef void (*crypt_func_pgp_extract_keys_from_attachment_list_t) 
+                                           (FILE *fp, int tag, BODY *top);
+
+typedef int (*crypt_func_send_menu_t) (HEADER *msg, int *redraw);
+
+ /* (SMIME) */
+typedef void (*crypt_func_smime_getkeys_t) (ENVELOPE *env);
+typedef int (*crypt_func_smime_verify_sender_t) (HEADER *h);
+
+typedef BODY *(*crypt_func_smime_build_smime_entity_t) (BODY *a,
+                                                        char *certlist);
+
+typedef void (*crypt_func_smime_invoke_import_t) (char *infile, char *mailbox);
+
+typedef void (*crypt_func_init_t) (void);
+
+
+/*
+   A structure to keep all crypto module fucntions together.
+ */
+typedef struct crypt_module_functions
+{
+  /* Common/General functions.  */
+  crypt_func_init_t init;
+  crypt_func_void_passphrase_t void_passphrase;
+  crypt_func_valid_passphrase_t valid_passphrase;
+  crypt_func_decrypt_mime_t decrypt_mime;
+  crypt_func_application_handler_t application_handler;
+  crypt_func_encrypted_handler_t encrypted_handler;
+  crypt_func_findkeys_t findkeys;
+  crypt_func_sign_message_t sign_message;
+  crypt_func_verify_one_t verify_one;
+  crypt_func_send_menu_t send_menu;
+
+  /* PGP specific functions.  */
+  crypt_func_pgp_encrypt_message_t pgp_encrypt_message;
+  crypt_func_pgp_make_key_attachment_t pgp_make_key_attachment;
+  crypt_func_pgp_check_traditional_t pgp_check_traditional;
+  crypt_func_pgp_traditional_encryptsign_t pgp_traditional_encryptsign;
+  crypt_func_pgp_invoke_getkeys_t pgp_invoke_getkeys;
+  crypt_func_pgp_invoke_import_t pgp_invoke_import;
+  crypt_func_pgp_extract_keys_from_attachment_list_t
+                                 pgp_extract_keys_from_attachment_list;
+
+  /* S/MIME specific functions.  */
+
+  crypt_func_smime_getkeys_t smime_getkeys;
+  crypt_func_smime_verify_sender_t smime_verify_sender;
+  crypt_func_smime_build_smime_entity_t smime_build_smime_entity;
+  crypt_func_smime_invoke_import_t smime_invoke_import;
+} crypt_module_functions_t;
+
+
+/*
+   A structure to decribe a crypto module. 
+ */
+typedef struct crypt_module_specs
+{
+  int identifier;                      /* Identifying bit.  */
+  crypt_module_functions_t functions;
+} *crypt_module_specs_t;
+
+
+
+/* 
+   High Level crypto module interface. 
+ */
+
+void crypto_module_register (crypt_module_specs_t specs);
+crypt_module_specs_t crypto_module_lookup (int identifier);
+
+/* If the crypto module identifier by IDENTIFIER has been registered,
+   call its function FUNC.  Do nothing else.  This may be used as an
+   expression. */
+#define CRYPT_MOD_CALL_CHECK(identifier, func) \
+  (crypto_module_lookup (APPLICATION_ ## identifier) \
+   && (crypto_module_lookup (APPLICATION_ ## identifier))->functions.func)
+
+/* Call the function FUNC in the crypto module identified by
+   IDENTIFIER. This may be used as an expression. */
+#define CRYPT_MOD_CALL(identifier, func) \
+  *(crypto_module_lookup (APPLICATION_ ## identifier))->functions.func
+
+#endif
diff --git a/crypt.c b/crypt.c
index fe5dc2c4de70ea365123f0518c07fba19056716e..dfb097411edd48f8387a0e22de7dbb6917a722aa 100644 (file)
--- a/crypt.c
+++ b/crypt.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2001  Thomas Roessler <roessler@does-not-exist.org>
  *                     Oliver Ehli <elmy@acm.org>
  * Copyright (C) 2003  Werner Koch <wk@gnupg.org>
+ * Copyright (C) 2004 g10code 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
@@ -107,54 +108,19 @@ static void disable_coredumps (void)
 int crypt_valid_passphrase(int flags)
 {
   time_t now = time (NULL);
+  int ret = 0;
 
 # if defined(HAVE_SETRLIMIT) &&(!defined(DEBUG))
   disable_coredumps ();
 # endif
 
   if ((WithCrypto & APPLICATION_PGP) && (flags & APPLICATION_PGP))
-  {
-    extern char PgpPass[STRING];
-    extern time_t PgpExptime;
-
-    if (pgp_use_gpg_agent())
-    {
-      *PgpPass = 0;
-      return 1; /* handled by gpg-agent */
-    }
-
-    if (now < PgpExptime) return 1; /* just use the cached copy. */
-    crypt_pgp_void_passphrase ();
-      
-    if (mutt_get_password (_("Enter PGP passphrase:"),
-                           PgpPass, sizeof (PgpPass)) == 0)
-    {
-      PgpExptime = time (NULL) + PgpTimeout;
-      return (1);
-    }
-    else
-      PgpExptime = 0;
-    }
+    ret = crypt_pgp_valid_passphrase ();
 
   if ((WithCrypto & APPLICATION_SMIME) && (flags & APPLICATION_SMIME))
-  {
-    extern char SmimePass[STRING];
-    extern time_t SmimeExptime;
-
-    if (now < SmimeExptime) return (1);
-    crypt_smime_void_passphrase ();
-      
-    if (mutt_get_password (_("Enter SMIME passphrase:"), SmimePass,
-                          sizeof (SmimePass)) == 0)
-    {
-      SmimeExptime = time (NULL) + SmimeTimeout;
-      return (1);
-    }
-    else
-      SmimeExptime = 0;
-  }
+    ret = crypt_smime_valid_passphrase ();
 
-  return (0);
+  return ret;
 }
 
 
@@ -275,6 +241,7 @@ int mutt_protect (HEADER *msg, char *keylist)
 
       /* destroy temporary signature envelope when doing retainable 
        * signatures.
+
        */
       if (flags != msg->security)
       {
index ce81860313ae42608c918dcb79697abb542c121d..f8ff4793a6130f58835f207e357cf79c7ba33422 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003  Werner Koch <wk@gnupg.org>
+ * 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
  */
 
 /*
-   This file dispatches the generic crytpo functions to the implemented
-   backend or provides dummy stubs.  Note, that some generic functions are
-   handled in crypt.c.
+   This file dispatches the generic crypto functions to the
+   implemented backend or provides dummy stubs.  Note, that some
+   generic functions are handled in crypt.c.
 */
 
+/* Note: This file has been changed to make use of the new module
+   system.  Consequently there's a 1:1 mapping between the functions
+   contained in this file and the functions implemented by the crypto
+   modules.  */
+
 #include "mutt.h"
 #include "mutt_crypt.h"
 
-/* Make sure those macros are not defined. */
-#undef BFNC_PGP_VOID_PASSPHRASE     
-#undef BFNC_PGP_DECRYPT_MIME           
-#undef BFNC_PGP_APPLICATION_PGP_HANDLER
-#undef BFNC_PGP_ENCRYPTED_HANDLER
-#undef BFNC_PGP_INVOKE_GETKEYS
-#undef BFNC_PGP_ASK_FOR_KEY
-#undef BNFC_PGP_CHECK_TRADITIONAL
-#undef BFNC_PGP_TRADITIONAL_ENCRYPTSIGN  
-#undef BFNC_PGP_FREE_KEY
-#undef BFNC_PGP_MAKE_KEY_ATTACHMENT 
-#undef BFNC_PGP_FINDKEYS
-#undef BFNC_PGP_SIGN_MESSAGE
-#undef BFNC_PGP_ENCRYPT_MESSAGE
-#undef BFNC_PGP_INVOKE_IMPORT
-#undef BFNC_PGP_VERIFY_ONE
-#undef BFNC_PGP_KEYID
-#undef BFNC_PGP_EXTRACT_KEYS_FROM_ATTACHMENT_LIST
-
-#undef BFNC_SMIME_VOID_PASSPHRASE 
-#undef BFNC_SMIME_DECRYPT_MIME    
-#undef BFNC_SMIME_APPLICATION_SMIME_HANDLER 
-#undef BFNC_SMIME_GETKEYS  
-#undef BFNC_SMIME_VERIFY_SENDER
-#undef BFNC_SMIME_ASK_FOR_KEY
-#undef BFNC_SMIME_FINDKEYS
-#undef BFNC_SMIME_SIGN_MESSAGE
-#undef BFNC_SMIME_BUILD_SMIME_ENTITY
-#undef BFNC_SMIME_INVOKE_IMPORT
-#undef BFNC_SMIME_VERIFY_ONE
-
-
-/* The PGP backend */
-#if defined (CRYPT_BACKEND_CLASSIC_PGP)
-# include "pgp.h"
-# define BFNC_PGP_VOID_PASSPHRASE         pgp_void_passphrase
-# define BFNC_PGP_DECRYPT_MIME            pgp_decrypt_mime
-# define BFNC_PGP_APPLICATION_PGP_HANDLER pgp_application_pgp_handler
-# define BFNC_PGP_ENCRYPTED_HANDLER       pgp_encrypted_handler
-# define BFNC_PGP_INVOKE_GETKEYS          pgp_invoke_getkeys
-# define BFNC_PGP_ASK_FOR_KEY             pgp_ask_for_key
-# define BNFC_PGP_CHECK_TRADITIONAL       pgp_check_traditional
-# define BFNC_PGP_TRADITIONAL_ENCRYPTSIGN pgp_traditional_encryptsign 
-# define BFNC_PGP_FREE_KEY                pgp_free_key
-# define BFNC_PGP_MAKE_KEY_ATTACHMENT     pgp_make_key_attachment
-# define BFNC_PGP_FINDKEYS                pgp_findKeys
-# define BFNC_PGP_SIGN_MESSAGE            pgp_sign_message
-# define BFNC_PGP_ENCRYPT_MESSAGE         pgp_encrypt_message
-# define BFNC_PGP_INVOKE_IMPORT           pgp_invoke_import
-# define BFNC_PGP_VERIFY_ONE              pgp_verify_one
-# define BFNC_PGP_KEYID                   pgp_keyid
-# define BFNC_PGP_EXTRACT_KEYS_FROM_ATTACHMENT_LIST \
-                                       pgp_extract_keys_from_attachment_list
-
-
-#elif defined (CRYPT_BACKEND_GPGME)
-# include "crypt-gpgme.h"
-# define BFNC_PGP_VOID_PASSPHRASE NULL /* not required */
-# define BFNC_PGP_DECRYPT_MIME     gpg_pgp_decrypt_mime
-
-#endif /* PGP backend */
-
-
-/* The SMIME backend */
-#ifdef CRYPT_BACKEND_CLASSIC_SMIME
-# include "smime.h"
-# define BFNC_SMIME_VOID_PASSPHRASE           smime_void_passphrase
-# define BFNC_SMIME_DECRYPT_MIME              smime_decrypt_mime
-# define BFNC_SMIME_APPLICATION_SMIME_HANDLER smime_application_smime_handler
-# define BFNC_SMIME_GETKEYS                   smime_getkeys
-# define BFNC_SMIME_VERIFY_SENDER             smime_verify_sender
-# define BFNC_SMIME_ASK_FOR_KEY               smime_ask_for_key
-# define BFNC_SMIME_FINDKEYS                  smime_findKeys
-# define BFNC_SMIME_SIGN_MESSAGE              smime_sign_message
-# define BFNC_SMIME_BUILD_SMIME_ENTITY        smime_build_smime_entity
-# define BFNC_SMIME_INVOKE_IMPORT             smime_invoke_import
-# define BFNC_SMIME_VERIFY_ONE            smime_verify_one
-
-#elif defined (CRYPT_BACKEND_GPGME)
-  /* Already included above (gpgme supports both). */ 
-# define BFNC_SMIME_VOID_PASSPHRASE NULL /* not required */
-
-#endif /* SMIME backend */
+#include "crypt-mod.h"
 
-\f
 /*
     
     Generic
 
 */
 
+#ifdef CRYPT_BACKEND_CLASSIC_PGP
+extern struct crypt_module_specs crypt_mod_pgp_classic;
+#endif
+
+#ifdef CRYPT_BACKEND_CLASSIC_SMIME
+extern struct crypt_module_specs crypt_mod_smime_classic;
+#endif
+
+#ifdef CRYPT_BACKEND_GPGME
+extern struct crypt_module_specs crypt_mod_pgp_gpgme;
+extern struct crypt_module_specs crypt_mod_smime_gpgme;
+#endif
+
+void crypt_init (void)
+{
+#ifdef CRYPT_BACKEND_CLASSIC_PGP
+  if (
+#ifdef CRYPT_BACKEND_GPGME
+      (! option (OPTCRYPTUSEGPGME))
+#else
+       1
+#endif
+      )
+    crypto_module_register (&crypt_mod_pgp_classic);
+#endif
+
+#ifdef CRYPT_BACKEND_CLASSIC_SMIME
+  if (
+#ifdef CRYPT_BACKEND_GPGME
+      (! option (OPTCRYPTUSEGPGME))
+#else
+       1
+#endif
+      )
+    crypto_module_register (&crypt_mod_smime_classic);
+#endif
+
+  if (option (OPTCRYPTUSEGPGME))
+    {
+#ifdef CRYPT_BACKEND_GPGME
+      crypto_module_register (&crypt_mod_pgp_gpgme);
+      crypto_module_register (&crypt_mod_smime_gpgme);
+#else
+      mutt_message (_("\"crypt_use_gpgme\" set"
+                      " but not build with GPGME support."));
+#endif
+    }
+
+#if defined CRYPT_BACKEND_CLASSIG_PGP || defined CRYPT_BACKEND_CLASSIG_SMIME || defined CRYPT_BACKEND_GPGME
+  if (CRYPT_MOD_CALL_CHECK (PGP, init))
+    (CRYPT_MOD_CALL (PGP, init)) ();
+
+  if (CRYPT_MOD_CALL_CHECK (SMIME, init))
+    (CRYPT_MOD_CALL (SMIME, init)) ();
+#endif
+}
+
+
 /* Show a message that a backend will be invoked. */
 void crypt_invoke_message (int type)
 {
-#if defined (CRYPT_BACKEND_CLASSIC_PGP) || defined(CRYPT_BACKEND_CLASSIC_SMIME)
-  if ((type & APPLICATION_PGP))
+  if ((WithCrypto & APPLICATION_PGP) && (type & APPLICATION_PGP))
     mutt_message _("Invoking PGP...");
-  if ((type & APPLICATION_SMIME))
-    mutt_message _("Invoking OpenSSL...");
-#elif defined (CRYPT_BACKEND_GPGME)
-  if ((type & APPLICATION_PGP) || (type & APPLICATION_SMIME) )
-    mutt_message _("Invoking GnuPG...");
-#endif
+  else if ((WithCrypto & APPLICATION_SMIME) && (type & APPLICATION_SMIME))
+    mutt_message _("Invoking SMIME...");
 }
 
 
@@ -142,163 +118,136 @@ void crypt_invoke_message (int type)
 /* Reset a PGP passphrase */
 void crypt_pgp_void_passphrase (void)
 {
-#ifdef BFNC_PGP_VOID_PASSPHRASE
-  BFNC_PGP_VOID_PASSPHRASE ();
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, void_passphrase))
+    (CRYPT_MOD_CALL (PGP, void_passphrase)) ();
 }
 
+int crypt_pgp_valid_passphrase (void)
+{
+  if (CRYPT_MOD_CALL_CHECK (PGP, valid_passphrase))
+    return (CRYPT_MOD_CALL (PGP, valid_passphrase)) ();
+
+  return 0;
+}
+
+
 /* Decrypt a PGP/MIME message. */
 int crypt_pgp_decrypt_mime (FILE *a, FILE **b, BODY *c, BODY **d)
 {
-#ifdef BFNC_PGP_DECRYPT_MIME
-  return BFNC_PGP_DECRYPT_MIME (a, b, c, d);
-#else
-  return -1; /* error */
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, decrypt_mime))
+    return (CRYPT_MOD_CALL (PGP, decrypt_mime)) (a, b, c, d);
+
+  return -1;
 }
 
 /* MIME handler for the application/pgp content-type. */
 void crypt_pgp_application_pgp_handler (BODY *m, STATE *s)
 {
-#ifdef BFNC_PGP_APPLICATION_PGP_HANDLER
-  BFNC_PGP_APPLICATION_PGP_HANDLER (m, s);
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, application_handler))
+    (CRYPT_MOD_CALL (PGP, application_handler)) (m, s);
 }
 
 /* MIME handler for an PGP/MIME encrypted message. */
 void crypt_pgp_encrypted_handler (BODY *a, STATE *s)
 {
-#ifdef BFNC_PGP_ENCRYPTED_HANDLER
-  BFNC_PGP_ENCRYPTED_HANDLER (a, s);
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, encrypted_handler))
+    (CRYPT_MOD_CALL (PGP, encrypted_handler)) (a, s);
 }
 
 /* fixme: needs documentation. */
 void crypt_pgp_invoke_getkeys (ADDRESS *addr)
 {
-#ifdef BFNC_PGP_INVOKE_GETKEYS
-  BFNC_PGP_INVOKE_GETKEYS (addr);
-#endif
-}
-
-/* Ask for a PGP key. */
-pgp_key_t crypt_pgp_ask_for_key (char *tag, char *whatfor,
-                                 short abilities, pgp_ring_t keyring)
-{
-#ifdef BFNC_PGP_ASK_FOR_KEY
-  return BFNC_PGP_ASK_FOR_KEY (tag, whatfor, abilities, keyring);
-#else
-  return NULL;
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, pgp_invoke_getkeys))
+    (CRYPT_MOD_CALL (PGP, pgp_invoke_getkeys)) (addr);
 }
 
-
 /* Check for a traditional PGP message in body B. */
 int crypt_pgp_check_traditional (FILE *fp, BODY *b, int tagged_only)
 {
-#ifdef BNFC_PGP_CHECK_TRADITIONAL
-  return BNFC_PGP_CHECK_TRADITIONAL (fp, b, tagged_only);
-#else
-  return 0; /* no */
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, pgp_check_traditional))
+    return (CRYPT_MOD_CALL (PGP, pgp_check_traditional)) (fp, b, tagged_only);
+
+  return 0;
 }
 
 /* fixme: needs documentation. */
 BODY *crypt_pgp_traditional_encryptsign (BODY *a, int flags, char *keylist)
 {
-#ifdef BFNC_PGP_TRADITIONAL_ENCRYPTSIGN  
-  return BFNC_PGP_TRADITIONAL_ENCRYPTSIGN (a, flags, keylist);
-#else
-  return NULL;
-#endif
-}
+  if (CRYPT_MOD_CALL_CHECK (PGP, pgp_traditional_encryptsign))
+    return (CRYPT_MOD_CALL (PGP, pgp_traditional_encryptsign)) (a, flags, keylist);
 
-/* Release pgp key KPP. */
-void crypt_pgp_free_key (pgp_key_t *kpp)
-{
-#ifdef BFNC_PGP_FREE_KEY
-  BFNC_PGP_FREE_KEY (kpp);
-#endif
+  return NULL;
 }
 
-
 /* Generate a PGP public key attachment. */
 BODY *crypt_pgp_make_key_attachment (char *tempf)
 {
-#ifdef BFNC_PGP_MAKE_KEY_ATTACHMENT 
-  return BFNC_PGP_MAKE_KEY_ATTACHMENT (tempf);
-#else
-  return NULL; /* error */ 
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, pgp_make_key_attachment))
+    return (CRYPT_MOD_CALL (PGP, pgp_make_key_attachment)) (tempf);
+
+  return NULL;
 }
 
 /* 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 *crypt_pgp_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
 {
-#ifdef BFNC_PGP_FINDKEYS
-  return BFNC_PGP_FINDKEYS (to, cc, bcc);
-#else
+  if (CRYPT_MOD_CALL_CHECK (PGP, findkeys))
+    return (CRYPT_MOD_CALL (PGP, findkeys)) (to, cc, bcc);
+
   return NULL;
-#endif
 }
 
 /* Create a new body with a PGP signed message from A. */
 BODY *crypt_pgp_sign_message (BODY *a)
 {
-#ifdef BFNC_PGP_SIGN_MESSAGE
-  return BFNC_PGP_SIGN_MESSAGE (a);
-#else
+  if (CRYPT_MOD_CALL_CHECK (PGP, sign_message))
+    return (CRYPT_MOD_CALL (PGP, sign_message)) (a);
+
   return NULL;
-#endif
 }
 
 /* Warning: A is no longer freed in this routine, you need to free it
    later.  This is necessary for $fcc_attach. */
 BODY *crypt_pgp_encrypt_message (BODY *a, char *keylist, int sign)
 {
-#ifdef BFNC_PGP_ENCRYPT_MESSAGE
-  return BFNC_PGP_ENCRYPT_MESSAGE (a, keylist, sign);
-#else
+  if (CRYPT_MOD_CALL_CHECK (PGP, pgp_encrypt_message))
+    return (CRYPT_MOD_CALL (PGP, pgp_encrypt_message)) (a, keylist, sign);
+
   return NULL;
-#endif
 }
 
 /* Invoke the PGP command to import a key. */
 void crypt_pgp_invoke_import (const char *fname)
 {
-#ifdef BFNC_PGP_INVOKE_IMPORT
-  BFNC_PGP_INVOKE_IMPORT (fname);
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, pgp_invoke_import))
+    (CRYPT_MOD_CALL (PGP, pgp_invoke_import)) (fname);
 }
 
 /* fixme: needs documentation */
 int crypt_pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
 {
-#ifdef BFNC_PGP_VERIFY_ONE
-  return BFNC_PGP_VERIFY_ONE (sigbdy, s, tempf);
-#else
+  if (CRYPT_MOD_CALL_CHECK (PGP, verify_one))
+    return (CRYPT_MOD_CALL (PGP, verify_one)) (sigbdy, s, tempf);
+
   return -1;
-#endif
 }
 
 
-/* Access the keyID in K. */
-char *crypt_pgp_keyid (pgp_key_t k)
+int crypt_pgp_send_menu (HEADER *msg, int *redraw)
 {
-#ifdef BFNC_PGP_KEYID
-  return pgp_keyid (k);
-#else
-  return "?";
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, send_menu))
+    return (CRYPT_MOD_CALL (PGP, send_menu)) (msg, redraw);
+
+  return 0;
 }
 
+
 /* fixme: needs documentation */
 void crypt_pgp_extract_keys_from_attachment_list (FILE *fp, int tag, BODY *top)
 {
-#ifdef BFNC_PGP_EXTRACT_KEYS_FROM_ATTACHMENT_LIST
-  BFNC_PGP_EXTRACT_KEYS_FROM_ATTACHMENT_LIST (fp, tag, top);
-#endif
+  if (CRYPT_MOD_CALL_CHECK (PGP, pgp_extract_keys_from_attachment_list))
+    (CRYPT_MOD_CALL (PGP, pgp_extract_keys_from_attachment_list)) (fp, tag, top);
 }
 
 
@@ -313,104 +262,105 @@ void crypt_pgp_extract_keys_from_attachment_list (FILE *fp, int tag, BODY *top)
 /* Reset an SMIME passphrase */
 void crypt_smime_void_passphrase (void)
 {
-#ifdef BFNC_SMIME_VOID_PASSPHRASE
-  BFNC_SMIME_VOID_PASSPHRASE ();
-#endif
+  if (CRYPT_MOD_CALL_CHECK (SMIME, void_passphrase))
+    (CRYPT_MOD_CALL (SMIME, void_passphrase)) ();
 }
 
+int crypt_smime_valid_passphrase (void)
+{
+  if (CRYPT_MOD_CALL_CHECK (SMIME, valid_passphrase))
+    return (CRYPT_MOD_CALL (SMIME, valid_passphrase)) ();
+
+  return 0;
+}
 
 /* Decrypt am S/MIME message. */
 int crypt_smime_decrypt_mime (FILE *a, FILE **b, BODY *c, BODY **d)
 {
-#ifdef BFNC_SMIME_DECRYPT_MIME
-  return BFNC_SMIME_DECRYPT_MIME (a, b, c, d);
-#else
-  return -1; /* error */
-#endif
+  if (CRYPT_MOD_CALL_CHECK (SMIME, decrypt_mime))
+    return (CRYPT_MOD_CALL (SMIME, decrypt_mime)) (a, b, c, d);
+
+  return -1;
 }
 
 /* MIME handler for the application/smime content-type. */
 void crypt_smime_application_smime_handler (BODY *m, STATE *s)
 {
-#ifdef BFNC_SMIME_APPLICATION_SMIME_HANDLER
-  BFNC_SMIME_APPLICATION_SMIME_HANDLER (m, s);
-#endif
+  if (CRYPT_MOD_CALL_CHECK (SMIME, application_handler))
+    (CRYPT_MOD_CALL (SMIME, application_handler)) (m, s);
+}
+
+/* MIME handler for an PGP/MIME encrypted message. */
+void crypt_smime_encrypted_handler (BODY *a, STATE *s)
+{
+  if (CRYPT_MOD_CALL_CHECK (SMIME, encrypted_handler))
+    (CRYPT_MOD_CALL (SMIME, encrypted_handler)) (a, s);
 }
 
 /* fixme: Needs documentation. */
 void crypt_smime_getkeys (ENVELOPE *env)
 {
-#ifdef BFNC_SMIME_GETKEYS  
-  BFNC_SMIME_GETKEYS (env);
-#endif
+  if (CRYPT_MOD_CALL_CHECK (SMIME, smime_getkeys))
+    (CRYPT_MOD_CALL (SMIME, smime_getkeys)) (env);
 }
 
 /* Check that the sender matches. */
 int crypt_smime_verify_sender(HEADER *h)
 {
-#ifdef BFNC_SMIME_VERIFY_SENDER
-  return BFNC_SMIME_VERIFY_SENDER (h);
-#else
-  return 1; /* yes */
-#endif
-}
+  if (CRYPT_MOD_CALL_CHECK (SMIME, smime_verify_sender))
+    return (CRYPT_MOD_CALL (SMIME, smime_verify_sender)) (h);
 
-/* Ask for an SMIME key. */
-char *crypt_smime_ask_for_key (char *prompt, char *mailbox, short public)
-{
-#ifdef BFNC_SMIME_ASK_FOR_KEY
-  return BFNC_SMIME_ASK_FOR_KEY (prompt, mailbox, public);
-#else
-  return NULL; /* error */
-#endif
+  return 1;
 }
 
-
 /* 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 *crypt_smime_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
 {
-#ifdef BFNC_SMIME_FINDKEYS
-  return BFNC_SMIME_FINDKEYS (to, cc, bcc);
-#else
+  if (CRYPT_MOD_CALL_CHECK (SMIME, findkeys))
+    return (CRYPT_MOD_CALL (SMIME, findkeys)) (to, cc, bcc);
+
   return NULL;
-#endif
 }
 
 /* fixme: Needs documentation. */
 BODY *crypt_smime_sign_message (BODY *a)
 {
-#ifdef BFNC_SMIME_SIGN_MESSAGE
-  return BFNC_SMIME_SIGN_MESSAGE (a);
-#else
+  if (CRYPT_MOD_CALL_CHECK (SMIME, sign_message))
+    return (CRYPT_MOD_CALL (SMIME, sign_message)) (a);
+
   return NULL;
-#endif
 }
 
 /* fixme: needs documentation. */
 BODY *crypt_smime_build_smime_entity (BODY *a, char *certlist)
 {
-#ifdef BFNC_SMIME_BUILD_SMIME_ENTITY
-  return BFNC_SMIME_BUILD_SMIME_ENTITY (a, certlist);
-#else
+  if (CRYPT_MOD_CALL_CHECK (SMIME, smime_build_smime_entity))
+    return (CRYPT_MOD_CALL (SMIME, smime_build_smime_entity)) (a, certlist);
+
   return NULL;
-#endif
 }
 
 /* Add a certificate and update index file (externally). */
 void crypt_smime_invoke_import (char *infile, char *mailbox)
 {
-#ifdef BFNC_SMIME_INVOKE_IMPORT
-  BFNC_SMIME_INVOKE_IMPORT (infile, mailbox);
-#endif
+  if (CRYPT_MOD_CALL_CHECK (SMIME, smime_invoke_import))
+    (CRYPT_MOD_CALL (SMIME, smime_invoke_import)) (infile, mailbox);
 }
 
 /* fixme: needs documentation */
 int crypt_smime_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
 {
-#ifdef BFNC_SMIME_VERIFY_ONE
-  return BFNC_SMIME_VERIFY_ONE (sigbdy, s, tempf);
-#else
+  if (CRYPT_MOD_CALL_CHECK (SMIME, verify_one))
+    return (CRYPT_MOD_CALL (SMIME, verify_one)) (sigbdy, s, tempf);
+
   return -1;
-#endif
+}
+
+int crypt_smime_send_menu (HEADER *msg, int *redraw)
+{
+  if (CRYPT_MOD_CALL_CHECK (SMIME, send_menu))
+    return (CRYPT_MOD_CALL (SMIME, send_menu)) (msg, redraw);
+
+  return 0;
 }
index 28fd0ae72325ce0c69d79722f28ac362ddca08a9..d546182ecd9e2796de25bc6075f2fb04b3a91a7c 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>
+ * 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
@@ -57,6 +58,20 @@ void mutt_refresh (void)
   refresh ();
 }
 
+/* Make sure that the next refresh does a full refresh.  This could be
+   optmized by not doing it at all if DISPLAY is set as this might
+   indicate that a GUI based pinentry was used.  Having an option to
+   customize this is of course the Mutt way.  */
+void mutt_need_hard_redraw (void)
+{
+  if (!getenv ("DISPLAY"))
+  {
+    keypad (stdscr, TRUE);
+    clearok (stdscr, TRUE);
+    set_option (OPTNEEDREDRAW);
+  }
+}
+
 event_t mutt_getch (void)
 {
   int ch;
diff --git a/init.h b/init.h
index 781dbcd5d2a1fe9eea4b6eb6e68ed74ba85b1901..8a67a1532355fb0cabece471ef2bdc7aea099c49 100644 (file)
--- a/init.h
+++ b/init.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>
+ * 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
@@ -359,6 +360,17 @@ struct option_t MuttVars[] = {
   ** will be saved for later references.  Also see ``$$record'',
   ** ``$$save_name'', ``$$force_name'' and ``$fcc-hook''.
   */
+  
+  { "crypt_use_gpgme",  DT_BOOL, R_NONE, OPTCRYPTUSEGPGME, 0 },
+  /*
+  ** .pp
+  ** This variable controls the use the GPGME enabled crypto backends.
+  ** If it is set and Mutt was build with gpgme support, the gpgme code for
+  ** S/MIME and PGP will be used instead of the classic code.  Note, that
+  ** you need to use this option in .muttrc as it won't have any effect when 
+  ** used interactively.
+  */
+  
   { "crypt_autopgp",   DT_BOOL, R_NONE, OPTCRYPTAUTOPGP, 1 },
   /*
   ** .pp
index 828aa5ef64d398731e37e134230673e8807a296b..de0169da687df397554996b611ce5a4c36b0199f 100644 (file)
--- a/keymap.c
+++ b/keymap.c
@@ -40,7 +40,11 @@ struct mapping_t Menus[] = {
  { "postpone", MENU_POST },
  { "pgp",      MENU_PGP },
  { "smime",    MENU_SMIME },
+#ifdef HAVE_GPGME
+ { "key_select_pgp",   MENU_KEY_SELECT_PGP },
+ { "key_select_smime", MENU_KEY_SELECT_SMIME },
+#endif
+
 #ifdef MIXMASTER
   { "mix",     MENU_MIX },
 #endif
@@ -557,6 +561,11 @@ void km_init (void)
   if ((WithCrypto & APPLICATION_SMIME))
     create_bindings (OpSmime, MENU_SMIME);
 
+#ifdef CRYPT_BACKEND_GPGME
+  create_bindings (OpPgp, MENU_KEY_SELECT_PGP);
+  create_bindings (OpSmime, MENU_KEY_SELECT_SMIME);
+#endif
+
 #ifdef MIXMASTER
   create_bindings (OpMix, MENU_MIX);
   
@@ -781,6 +790,13 @@ struct binding_t *km_get_table (int menu)
     case MENU_PGP:
       return (WithCrypto & APPLICATION_PGP)? OpPgp:NULL;
 
+#ifdef CRYPT_BACKEND_GPGME
+    case MENU_KEY_SELECT_PGP:
+      return OpPgp;
+    case MENU_KEY_SELECT_SMIME:
+      return OpSmime;
+#endif
+
 #ifdef MIXMASTER
     case MENU_MIX:
       return OpMix;
index a88bbf46167a812b375297f37a608b4dbcbe69fa..4a75c6a162feed6f54ebabb065b3198cd6bd9a8e 100644 (file)
--- a/keymap.h
+++ b/keymap.h
@@ -65,9 +65,13 @@ enum
 
   
   MENU_PGP,
-
   MENU_SMIME,
 
+#ifdef CRYPT_BACKEND_GPGME
+  MENU_KEY_SELECT_PGP,
+  MENU_KEY_SELECT_SMIME,
+#endif
+  
 #ifdef MIXMASTER
   MENU_MIX,
 #endif
diff --git a/main.c b/main.c
index 81062f862d7669510d614d26bb23ddc561905415..5341f2ac7af5937ddb017ceb63ac74c90a787257 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>
  * Copyright (C) 1999-2002 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
  *     it under the terms of the GNU General Public License as published by
@@ -653,6 +654,9 @@ int main (int argc, char **argv)
   mutt_init (flags & M_NOSYSRC, commands);
   mutt_free_list (&commands);
 
+  /* Initialize crypto backends.  */
+  crypt_init ();
+
   if (queries)
     return mutt_query_variables (queries);
 
diff --git a/mutt.h b/mutt.h
index 3dfe27d67485b46c7902b8275e6a38d66f4ccad9..45597ece2b28b4385a9c8b8f19ca000ce45cf73c 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -1,6 +1,7 @@
 
 /*
  * Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>
+ * 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
@@ -429,6 +430,8 @@ enum
   OPTWRITEBCC,         /* write out a bcc header? */
   OPTXMAILER,
 
+  OPTCRYPTUSEGPGME,
+
   /* PGP options */
   
   OPTCRYPTAUTOSIGN,
@@ -633,8 +636,20 @@ typedef struct body
                                /* send mode: don't adjust the character
                                 * set when in send-mode.
                                 */
+  unsigned int is_signed_data : 1; /* A lot of MUAs don't indicate
+                                      S/MIME signed-data correctly,
+                                      e.g. they use foo.p7m even for
+                                      the name of signed data.  This
+                                      flag is used to keep track of
+                                      the actual message type.  It
+                                      gets set during the verification
+                                      (which is done if the encryption
+                                      try failed) and check by the
+                                      function to figure the type of
+                                      the message. */
 
   unsigned int goodsig : 1;    /* good cryptographic signature */
+  unsigned int warnsig : 1;     /* maybe good signature */
   unsigned int badsig : 1;     /* bad cryptographic signature (needed to check encrypted s/mime-signatures) */
 
   unsigned int collapsed : 1;  /* used by recvattach */
index f63c8d0d59d51f24c814321d201e99a0efd26118..6b57382ec03433b8ca5116b6bec1b3ffbc337ff4 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003 Werner Koch <wk@gnupg.org>
+ * Copyright (C) 2004 g10code 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
    effectively as a conditional compile directive. It is set to false
    if no crypto backend is configures or to a bit vector denoting the
    configured backends. */
-#if defined(CRYPT_BACKEND_CLASSIC_PGP) && defined(CRYPT_BACKEND_CLASSIC_SMIME)
+#if (defined(CRYPT_BACKEND_CLASSIC_PGP) && defined(CRYPT_BACKEND_CLASSIC_SMIME)) || defined (CRYPT_BACKEND_GPGME)
 # define WithCrypto (APPLICATION_PGP | APPLICATION_SMIME)
 #elif defined(CRYPT_BACKEND_CLASSIC_PGP)
 # define WithCrypto  APPLICATION_PGP
 #elif defined(CRYPT_BACKEND_CLASSIC_SMIME)
 # define WithCrypto  APPLICATION_SMIME
-#elif defined(CRYPT_BACKEND_GPGME)
-# define WithCrypto  (APPLICATION_PGP | APPLICATION_SMIME)
 #else
 # define WithCrypto 0
 #endif
@@ -78,6 +77,7 @@
 
 #define KEYFLAG_CANSIGN                (1 <<  0)
 #define KEYFLAG_CANENCRYPT             (1 <<  1)
+#define KEYFLAG_ISX509                  (1 <<  2)
 #define KEYFLAG_SECRET                 (1 <<  7)
 #define KEYFLAG_EXPIRED                (1 <<  8)
 #define KEYFLAG_REVOKED                (1 <<  9)
@@ -164,6 +164,9 @@ void crypt_invoke_message (int type);
 /* Silently forget about a passphrase. */
 void crypt_pgp_void_passphrase (void);
 
+int crypt_pgp_valid_passphrase (void);
+
+
 /* Decrypt a PGP/MIME message. */
 int crypt_pgp_decrypt_mime (FILE *a, FILE **b, BODY *c, BODY **d);
 
@@ -206,6 +209,8 @@ BODY *crypt_pgp_encrypt_message (BODY *a, char *keylist, int sign);
 /* Invoke the PGP command to import a key. */
 void crypt_pgp_invoke_import (const char *fname);
 
+int crypt_pgp_send_menu (HEADER *msg, int *redraw);
+
 /* fixme: needs documentation */
 int crypt_pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempf);
 
@@ -222,6 +227,8 @@ void crypt_pgp_extract_keys_from_attachment_list (FILE *fp, int tag,BODY *top);
 /* Silently forget about a passphrase. */
 void crypt_smime_void_passphrase (void);
 
+int crypt_smime_valid_passphrase (void);
+
 /* Decrypt an S/MIME message. */
 int crypt_smime_decrypt_mime (FILE *a, FILE **b, BODY *c, BODY **d);
 
@@ -250,8 +257,11 @@ BODY *crypt_smime_build_smime_entity (BODY *a, char *certlist);
 /* Add a certificate and update index file (externally). */
 void crypt_smime_invoke_import (char *infile, char *mailbox);
 
+int crypt_smime_send_menu (HEADER *msg, int *redraw);
+
 /* fixme: needs documentation */
 int crypt_smime_verify_one (BODY *sigbdy, STATE *s, const char *tempf);
 
+void crypt_init (void);
 
 #endif /*MUTT_CRYPT_H*/
index b7b1a828950e35a3cf330b7de3f93ad14b5447a5..0b354ca5b1d4ac58b33d17c4f90096b6dd0e470b 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
+ * 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
@@ -94,6 +95,7 @@ void mutt_flushinp (void);
 void mutt_refresh (void);
 void mutt_resize_screen (void);
 void mutt_ungetch (int, int);
+void mutt_need_hard_redraw (void);
 
 /* ----------------------------------------------------------------------------
  * Support for color
diff --git a/pgp.c b/pgp.c
index 9fcdd3d3ff7f72443a6c1b22c57d6df4056b39c2..ccc8e38ccd13971e7bfc3e135a8be79f0e5c568a 100644 (file)
--- a/pgp.c
+++ b/pgp.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 1996,1997 Michael R. Elkins <me@mutt.org>
  * Copyright (c) 1998,1999 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
  *     it under the terms of the GNU General Public License as published by
@@ -54,7 +55,7 @@
 #ifdef CRYPT_BACKEND_CLASSIC_PGP
 
 #include "mutt_crypt.h"
-
+#include "mutt_menu.h"
 
 
 char PgpPass[STRING];
@@ -66,6 +67,24 @@ void pgp_void_passphrase (void)
   PgpExptime = 0;
 }
 
+int pgp_valid_passphrase (void)
+{
+  time_t now = time (NULL);
+
+  if (now < PgpExptime)
+    /* Use cached copy.  */
+    return 1;
+
+  if (mutt_get_password (_("Enter PGP passphrase:"), PgpPass, sizeof (PgpPass)) == 0)
+    {
+      PgpExptime = time (NULL) + PgpTimeout;
+      return (1);
+    }
+  else
+    PgpExptime = 0;
+
+  return 0;
+}
 
 void pgp_forget_passphrase (void)
 {
@@ -1023,7 +1042,7 @@ char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
   pgp_key_t k_info = NULL, key = NULL;
 
   const char *fqdn = mutt_fqdn (1);
-  
+
   for (i = 0; i < 3; i++) 
   {
     switch (i)
@@ -1425,4 +1444,76 @@ BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist)
   return b;
 }
 
+int pgp_send_menu (HEADER *msg, int *redraw)
+{
+  pgp_key_t p;
+  char input_signas[SHORT_STRING];
+
+  if (!(WithCrypto & APPLICATION_PGP))
+    return msg->security;
+
+  switch (mutt_multi_choice (_("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, (i)nline, or (f)orget it? "),
+                            _("esabif")))
+  {
+  case 1: /* (e)ncrypt */
+    msg->security ^= ENCRYPT;
+    break;
+
+  case 2: /* (s)ign */
+    msg->security ^= SIGN;
+    break;
+
+  case 3: /* sign (a)s */
+    unset_option(OPTPGPCHECKTRUST);
+
+    if ((p = 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);
+      pgp_free_key (&p);
+      
+      msg->security |= SIGN;
+       
+      crypt_pgp_void_passphrase ();  /* probably need a different passphrase */
+    }
+    else
+    {
+      msg->security &= ~SIGN;
+    }
+
+    *redraw = REDRAW_FULL;
+    break;
+
+  case 4: /* (b)oth */
+    if ((msg->security & (ENCRYPT | SIGN)) == (ENCRYPT | SIGN))
+      msg->security = 0;
+    else
+      msg->security |= (ENCRYPT | SIGN);
+    break;
+
+  case 5: /* (i)nline */
+    if ((msg->security & (ENCRYPT | SIGN)))
+      msg->security ^= INLINE;
+    else
+      msg->security &= ~INLINE;
+    break;
+
+  case 6: /* (f)orget it */
+    msg->security = 0;
+    break;
+  }
+
+  if (msg->security)
+  {
+    if (! (msg->security & (ENCRYPT | SIGN)))
+      msg->security = 0;
+    else
+      msg->security |= APPLICATION_PGP;
+  }
+
+  return (msg->security);
+}
+
+
 #endif /* CRYPT_BACKEND_CLASSIC_PGP */
diff --git a/pgp.h b/pgp.h
index 5c696651e178bc59f22f2dd48767b24d8cb6daee..31718720d072cd10e4dc2515b004419a7d2fc8d8 100644 (file)
--- a/pgp.h
+++ b/pgp.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 1996,1997 Michael R. Elkins <me@mutt.org>
  * Copyright (C) 1999-2000 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
  *     it under the terms of the GNU General Public License as published by
@@ -42,8 +43,6 @@ int pgp_decrypt_mime (FILE *, FILE **, BODY *, BODY **);
 
 /* int pgp_string_matches_hint (const char *s, LIST * hints); */
 
-#define pgp_valid_passphrase() crypt_valid_passphrase(APPLICATION_PGP)
-
 /* pgp_key_t gpg_get_candidates (struct pgp_vinfo *, pgp_ring_t, LIST *); */
 pgp_key_t pgp_ask_for_key (char *, char *, short, pgp_ring_t);
 pgp_key_t pgp_get_candidates (pgp_ring_t, LIST *);
@@ -57,8 +56,7 @@ void pgp_application_pgp_handler (BODY *, STATE *);
 void pgp_encrypted_handler (BODY *, STATE *);
 void pgp_extract_keys_from_attachment_list (FILE * fp, int tag, BODY * top);
 void pgp_void_passphrase (void);
-
-
+int pgp_valid_passphrase (void);
 
 
 /* The PGP invocation interface - not really beautiful. */
@@ -102,5 +100,6 @@ BODY *pgp_traditional_encryptsign (BODY *, int, char *);
 BODY *pgp_encrypt_message (BODY *, char *, int);
 BODY *pgp_sign_message (BODY *);
 
+int pgp_send_menu (HEADER *msg, int *redraw);
 
 #endif /* CRYPT_BACKEND_CLASSIC_PGP */
diff --git a/smime.c b/smime.c
index fda19e957975e0a076c9675147b40fcd31bb7f6c..a510ed1e67f0ce53decde7fca9ab4de679b12978 100644 (file)
--- a/smime.c
+++ b/smime.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2001,2002 Oliver Ehli <elmy@acm.org>
  * Copyright (C) 2002 Mike Schiraldi <raldi@research.netsol.com>
+ * 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
@@ -48,7 +49,6 @@
 
 #include "mutt_crypt.h"
 
-
 struct smime_command_context {
   const char *key;                 /* %k */
   const char *cryptalg;                    /* %a */
@@ -94,9 +94,24 @@ void smime_void_passphrase (void)
   SmimeExptime = 0;
 }
 
+int smime_valid_passphrase (void)
+{
+  time_t now = time (NULL);
 
+  if (now < SmimeExptime)
+    /* Use cached copy.  */
+    return 1;
 
+  if (mutt_get_password (_("Enter SMIME passphrase:"), SmimePass, sizeof (SmimePass)) == 0)
+    {
+      SmimeExptime = time (NULL) + SmimeTimeout;
+      return (1);
+    }
+  else
+    SmimeExptime = 0;
 
+  return 0;
+}
 
 
 /*
@@ -1917,4 +1932,87 @@ void smime_application_smime_handler (BODY *m, STATE *s)
     smime_handle_entity (m, s, NULL);
 
 }
+
+int smime_send_menu (HEADER *msg, int *redraw)
+{
+  char *p;
+
+  if (!(WithCrypto & APPLICATION_SMIME))
+    return msg->security;
+
+  switch (mutt_multi_choice (_("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, or (f)orget it? "),
+                            _("eswabf")))
+  {
+  case 1: /* (e)ncrypt */
+    msg->security |= ENCRYPT;
+    break;
+
+  case 3: /* encrypt (w)ith */
+    msg->security |= ENCRYPT;
+    switch (mutt_multi_choice (_("1: DES, 2: Triple-DES, 3: RC2-40,"
+                                " 4: RC2-64, 5: RC2-128, or (f)orget it? "),
+                              _("12345f"))) {
+    case 1:
+       mutt_str_replace (&SmimeCryptAlg, "des");
+       break;
+    case 2:
+       mutt_str_replace (&SmimeCryptAlg, "des3");
+       break;
+    case 3:
+       mutt_str_replace (&SmimeCryptAlg, "rc2-40");
+       break;
+    case 4:
+       mutt_str_replace (&SmimeCryptAlg, "rc2-64");
+       break;
+    case 5:
+       mutt_str_replace (&SmimeCryptAlg, "rc2-128");
+       break;
+    case 6: /* forget it */
+       break;
+    }
+    break;
+
+  case 2: /* (s)ign */
+      
+    if(!SmimeDefaultKey)
+       mutt_message("Can\'t sign: No key specified. use sign(as).");
+    else
+       msg->security |= SIGN;
+    break;
+
+  case 4: /* sign (a)s */
+
+    if ((p = smime_ask_for_key (_("Sign as: "), NULL, 0))) {
+      p[mutt_strlen (p)-1] = '\0';
+      mutt_str_replace (&SmimeDefaultKey, p);
+       
+      msg->security |= SIGN;
+
+      /* probably need a different passphrase */
+      crypt_smime_void_passphrase ();
+    }
+    else
+      msg->security &= ~SIGN;
+
+    *redraw = REDRAW_FULL;
+    break;
+
+  case 5: /* (b)oth */
+    msg->security = ENCRYPT | SIGN;
+    break;
+
+  case 6: /* (f)orget it */
+    msg->security = 0;
+    break;
+  }
+
+  if (msg->security && msg->security != APPLICATION_SMIME)
+    msg->security |= APPLICATION_SMIME;
+  else
+    msg->security = 0;
+
+  return (msg->security);
+}
+
+
 #endif /* CRYPT_BACKEND_CLASSIC_SMIME */
diff --git a/smime.h b/smime.h
index 360ecd8a8c1b9bb695c2f3771167d789fd77ba25..dba0a0fc4ff3c928180602b7287568333fcffb35 100644 (file)
--- a/smime.h
+++ b/smime.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2001,2002 Oliver Ehli <elmy@acm.org>
+ * 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
@@ -25,9 +26,8 @@
 
 
 
-#define smime_valid_passphrase() crypt_valid_passphrase(APPLICATION_SMIME)
-
 void smime_void_passphrase (void);
+int smime_valid_passphrase (void);
 
 int   smime_decrypt_mime (FILE *, FILE **, BODY *, BODY **);
 
@@ -54,6 +54,8 @@ char *smime_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc);
 
 void  smime_invoke_import (char *, char *);
 
+int smime_send_menu (HEADER *msg, int *redraw);
+
 #endif