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);