<<< Date Index >>>     <<< Thread Index >>>

For 1.5.9 - fixed smime-encrypt-self patch



Hi,

the inclusion of the gpgme patch broke the smime-encrypt-self patch by 
Omen Wild (at least if gpgme is enabled). With gpgme, SmimeDefaultKey
holds only a "short key id" and the encrypt-self patch appends SmimeDefaultKey 
to
the list of encryption keys. However, the function gpgme_get_key that the
gpgme module eventually calls in order to retrieve the encryption keys expects
a full fingerprint. Therefore, encryption of the fcc with the own key failed.

I modified the smime-encrypt-self patch such that it expands the short key id
to a full fingerprint if gpgme is used. The patch works for me; but I am
neither familiar with mutt's internals nor with gpgme whence I'd appreciate if
someone who knows mutt's crypto code would review it.

If nobody sees problems with my patch then I request that it is included in
1.5.9. If you are used to keep an fcc of your messages then smime-encrypt-self
patch is a "must have". If you are afraid someone might force you (e.g., with
a subpoena) to decrypt and hand over copies of your communications
then the encrypt self feature can be disabled in .muttrc.

Regards

Christoph
-- 
http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/cludwig.html
LiDIA: http://www.informatik.tu-darmstadt.de/TI/LiDIA/Welcome.html

Index: PATCHES
===================================================================
RCS file: /home/roessler/cvs/mutt/PATCHES,v
retrieving revision 3.6
diff -u -u -r3.6 PATCHES
--- PATCHES     9 Dec 2002 17:44:54 -0000       3.6
+++ PATCHES     17 Feb 2005 15:16:59 -0000
@@ -1,0 +1 @@
+patch-1.5.8-cl.smime-encrypt-self.3
Index: crypt-gpgme.c
===================================================================
RCS file: /home/roessler/cvs/mutt/crypt-gpgme.c,v
retrieving revision 3.2
diff -u -u -r3.2 crypt-gpgme.c
--- crypt-gpgme.c       3 Feb 2005 17:01:42 -0000       3.2
+++ crypt-gpgme.c       17 Feb 2005 15:16:59 -0000
@@ -754,6 +754,48 @@
   state_attach_puts (p, s);
 }
 
+int smime_gpgme_get_full_key_id (char **full_id, char *id)
+{
+  gpgme_error_t err;
+  gpgme_ctx_t listctx;
+  gpgme_key_t key, key2;
+
+  if (!id || !*id)
+    return 0;
+
+  listctx = create_gpgme_context (1);
+  err = gpgme_op_keylist_start (listctx, id, 0);
+  if (!err)
+    err = gpgme_op_keylist_next (listctx, &key);
+  if (err)
+    {
+      gpgme_release (listctx);
+      mutt_error (_("default key `%s' not found: %s\n"),
+                  id, gpgme_strerror (err));
+      return -1;
+    }
+  err = gpgme_op_keylist_next (listctx, &key2);
+  if (!err)
+    {
+      gpgme_key_release (key);
+      gpgme_key_release (key2);
+      gpgme_release (listctx);
+      mutt_error (_("ambiguous specfication of default key `%s'\n"),
+                  id);
+      return -1;
+    }
+  gpgme_op_keylist_end (listctx);
+  gpgme_release (listctx);
+  
+  const char *fpr = "";
+  if (key && key->subkeys && key->subkeys->fpr)
+    fpr = key->subkeys->fpr;
+  *full_id = safe_strdup (fpr);
+  gpgme_key_release (key);
+
+  return 1;
+}
+
 /* 
  * Implementation of `sign_message'.
  */
Index: crypt-gpgme.h
===================================================================
RCS file: /home/roessler/cvs/mutt/crypt-gpgme.h,v
retrieving revision 3.1
diff -u -u -r3.1 crypt-gpgme.h
--- crypt-gpgme.h       28 Jan 2005 13:17:22 -0000      3.1
+++ crypt-gpgme.h       17 Feb 2005 15:16:59 -0000
@@ -27,6 +27,8 @@
 char *pgp_gpgme_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc);
 char *smime_gpgme_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc);
 
+int smime_gpgme_get_full_key_id (char **full_id, char *id);
+
 BODY *pgp_gpgme_encrypt_message (BODY *a, char *keylist, int sign);
 BODY *smime_gpgme_build_smime_entity (BODY *a, char *keylist);
 
Index: crypt-mod-pgp-classic.c
===================================================================
RCS file: /home/roessler/cvs/mutt/crypt-mod-pgp-classic.c,v
retrieving revision 3.2
diff -u -u -r3.2 crypt-mod-pgp-classic.c
--- crypt-mod-pgp-classic.c     3 Feb 2005 17:01:43 -0000       3.2
+++ crypt-mod-pgp-classic.c     17 Feb 2005 15:16:59 -0000
@@ -130,6 +130,7 @@
 
       NULL,                    /* smime_getkeys */
       NULL,                    /* smime_verify_sender */
+      NULL,                     /* smime_get_full_key_id */
       NULL,                    /* smime_build_smime_entity */
       NULL,                    /* smime_invoke_import */
     }
Index: crypt-mod-pgp-gpgme.c
===================================================================
RCS file: /home/roessler/cvs/mutt/crypt-mod-pgp-gpgme.c,v
retrieving revision 3.2
diff -u -u -r3.2 crypt-mod-pgp-gpgme.c
--- crypt-mod-pgp-gpgme.c       3 Feb 2005 17:01:43 -0000       3.2
+++ crypt-mod-pgp-gpgme.c       17 Feb 2005 15:16:59 -0000
@@ -116,6 +116,7 @@
 
       NULL,                    /* smime_getkeys */
       NULL,                    /* smime_verify_sender */
+      NULL,                     /* smime_get_full_key_id */
       NULL,                    /* smime_build_smime_entity */
       NULL,                    /* smime_invoke_import */
     }
Index: crypt-mod-smime-classic.c
===================================================================
RCS file: /home/roessler/cvs/mutt/crypt-mod-smime-classic.c,v
retrieving revision 3.2
diff -u -u -r3.2 crypt-mod-smime-classic.c
--- crypt-mod-smime-classic.c   3 Feb 2005 17:01:43 -0000       3.2
+++ crypt-mod-smime-classic.c   17 Feb 2005 15:16:59 -0000
@@ -111,6 +111,7 @@
       
       crypt_mod_smime_getkeys,
       crypt_mod_smime_verify_sender,
+      NULL,                     /* smime_get_full_key_id */
       crypt_mod_smime_build_smime_entity,
       crypt_mod_smime_invoke_import,
     }
Index: crypt-mod-smime-gpgme.c
===================================================================
RCS file: /home/roessler/cvs/mutt/crypt-mod-smime-gpgme.c,v
retrieving revision 3.2
diff -u -u -r3.2 crypt-mod-smime-gpgme.c
--- crypt-mod-smime-gpgme.c     3 Feb 2005 17:01:43 -0000       3.2
+++ crypt-mod-smime-gpgme.c     17 Feb 2005 15:16:59 -0000
@@ -75,6 +75,11 @@
   return smime_gpgme_send_menu (msg, redraw);
 }
 
+static int crypt_mod_smime_get_full_key_id (char **full_id, char *id)
+{
+  return smime_gpgme_get_full_key_id (full_id, id);
+}
+
 static BODY *crypt_mod_smime_build_smime_entity (BODY *a, char *certlist)
 {
   return smime_gpgme_build_smime_entity (a, certlist);
@@ -109,6 +114,7 @@
       
       NULL,                    /* smime_getkeys */
       crypt_mod_smime_verify_sender,
+      crypt_mod_smime_get_full_key_id,
       crypt_mod_smime_build_smime_entity,
       NULL,                    /* smime_invoke_import */
     }
Index: crypt-mod.h
===================================================================
RCS file: /home/roessler/cvs/mutt/crypt-mod.h,v
retrieving revision 3.1
diff -u -u -r3.1 crypt-mod.h
--- crypt-mod.h 17 Jun 2004 20:36:13 -0000      3.1
+++ crypt-mod.h 17 Feb 2005 15:16:59 -0000
@@ -60,6 +60,8 @@
 typedef void (*crypt_func_smime_getkeys_t) (ENVELOPE *env);
 typedef int (*crypt_func_smime_verify_sender_t) (HEADER *h);
 
+typedef int (*crypt_func_smime_get_full_key_id_t) (char **full_id, char *id);
+
 typedef BODY *(*crypt_func_smime_build_smime_entity_t) (BODY *a,
                                                         char *certlist);
 
@@ -99,6 +101,7 @@
 
   crypt_func_smime_getkeys_t smime_getkeys;
   crypt_func_smime_verify_sender_t smime_verify_sender;
+  crypt_func_smime_get_full_key_id_t smime_get_full_key_id;
   crypt_func_smime_build_smime_entity_t smime_build_smime_entity;
   crypt_func_smime_invoke_import_t smime_invoke_import;
 } crypt_module_functions_t;
Index: crypt.c
===================================================================
RCS file: /home/roessler/cvs/mutt/crypt.c,v
retrieving revision 3.26
diff -u -u -r3.26 crypt.c
--- crypt.c     3 Feb 2005 17:01:43 -0000       3.26
+++ crypt.c     17 Feb 2005 15:16:59 -0000
@@ -127,7 +127,6 @@
 }
 
 
-
 int mutt_protect (HEADER *msg, char *keylist)
 {
   BODY *pbody = NULL, *tmp_pbody = NULL;
@@ -205,8 +204,29 @@
     if ((WithCrypto & APPLICATION_SMIME)
         && (msg->security & APPLICATION_SMIME))
     {
-      if (!(tmp_pbody = crypt_smime_build_smime_entity (tmp_smime_pbody,
-                                                        keylist)))
+      char *new_keylist = keylist;
+      
+      if (query_quadoption(OPT_SMIMEENCRYPTSELF, _("Encrypt message to S/MIME 
Default Key also?")) == M_YES && SmimeDefaultKey)
+      {
+        char *full_id = NULL;
+        int err = crypt_smime_get_full_key_id (&full_id, SmimeDefaultKey);
+        if (err < 0)
+          return -1;
+        if (err == 0) 
+          full_id = SmimeDefaultKey; /* don't free full_id later on! */
+
+        int size = mutt_strlen(keylist) + mutt_strlen (full_id) + 3; /* +1 for 
NULL, +1 for blank, +1 for \n */
+        new_keylist = safe_malloc(size);
+        snprintf(new_keylist, size, "%s %s\n", keylist, full_id);
+
+        if (err > 0)
+          safe_free((void **)&full_id);
+      }
+      
+      tmp_pbody = crypt_smime_build_smime_entity (tmp_smime_pbody,
+                                                  new_keylist);
+      safe_free((void **)&new_keylist);
+      if (!tmp_pbody)
       {
        /* signed ? free it! */
        return (-1);
Index: cryptglue.c
===================================================================
RCS file: /home/roessler/cvs/mutt/cryptglue.c,v
retrieving revision 3.5
diff -u -u -r3.5 cryptglue.c
--- cryptglue.c 3 Feb 2005 17:01:43 -0000       3.5
+++ cryptglue.c 17 Feb 2005 15:16:59 -0000
@@ -329,6 +329,23 @@
   return NULL;
 }
 
+/* This routine expands the id to a full id. E.g., for the gpgme module it 
+   expands a short id (like 0x27AF75A3) to a full fingerprint. 
+   The expansion is returned in *full_id; the caller is responsible for 
+   deleting *full_id. The default implementation leaves *full_id unchanged, 
+   indicating that no expansion exists. 
+   
+   The return value is negative in case of an error, positive if *full_id holds
+   the expansion, and 0 if *full_id was left unchanged.
+*/
+int crypt_smime_get_full_key_id (char **full_id, char *id)
+{
+  if (CRYPT_MOD_CALL_CHECK (SMIME, smime_get_full_key_id))
+    return (CRYPT_MOD_CALL (SMIME, smime_get_full_key_id)) (full_id, id);
+
+  return 0;  
+}
+
 /* fixme: Needs documentation. */
 BODY *crypt_smime_sign_message (BODY *a)
 {
Index: init.h
===================================================================
RCS file: /home/roessler/cvs/mutt/init.h,v
retrieving revision 3.66
diff -u -u -r3.66 init.h
--- init.h      12 Feb 2005 20:08:19 -0000      3.66
+++ init.h      17 Feb 2005 15:16:59 -0000
@@ -1680,6 +1689,11 @@
   /*
   */
   
+  { "smime_encrypt_self", DT_QUAD, R_NONE, OPT_SMIMEENCRYPTSELF, M_YES },
+  /*
+  ** .pp
+  ** Encrypt the message to smime_default_key too.
+  */
   { "smime_timeout",           DT_NUM,  R_NONE, UL &SmimeTimeout, 300 },
   /*
   ** .pp
Index: mutt.h
===================================================================
RCS file: /home/roessler/cvs/mutt/mutt.h,v
retrieving revision 3.39
diff -u -u -r3.39 mutt.h
--- mutt.h      12 Feb 2005 19:19:25 -0000      3.39
+++ mutt.h      17 Feb 2005 15:16:59 -0000
@@ -294,6 +295,7 @@
 #endif
   OPT_SUBJECT,
   OPT_VERIFYSIG,      /* verify PGP signatures */
+  OPT_SMIMEENCRYPTSELF,
     
   /* THIS MUST BE THE LAST VALUE. */
   OPT_MAX
Index: mutt_crypt.h
===================================================================
RCS file: /home/roessler/cvs/mutt/mutt_crypt.h,v
retrieving revision 3.8
diff -u -u -r3.8 mutt_crypt.h
--- mutt_crypt.h        17 Jun 2004 20:36:13 -0000      3.8
+++ mutt_crypt.h        17 Feb 2005 15:16:59 -0000
@@ -248,6 +248,17 @@
    message.  It returns NULL if any of the keys can not be found.  */
 char *crypt_smime_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc);
 
+/* This routine expands the id to a full id. E.g., for the gpgme module it 
+   expands a short id (like 0x27AF75A3) to a full fingerprint. 
+   The expansion is returned in *full_id; the caller is responsible for 
+   deleting *full_id. The default implementation leaves *full_id unchanged, 
+   indicating that no expansion exists. 
+   
+   The return value is negative in case of an error, positive if *full_id holds
+   the expansion, and 0 if *full_id was left unchanged.
+*/
+int crypt_smime_get_full_key_id (char **full_id, char *id);
+
 /* fixme: Needs documentation. */
 BODY *crypt_smime_sign_message (BODY *a);