From 60f015c33b9431577771bdeddd3a20401c6f4334 Mon Sep 17 00:00:00 2001 From: Brendan Cully Date: Tue, 1 Jul 2008 17:57:37 -0700 Subject: [PATCH] Stub in a gpgme version of extract-keys. It doesn't currently work right because apparently while gpg on the command line can parse a whole message, we'll have to do it for gpgme. I really wonder about the 'ME' part of GPGME sometimes. --- ChangeLog | 13 ++++++- crypt-gpgme.c | 91 ++++++++++++++++++++++++++++++------------- crypt-gpgme.h | 1 + crypt-mod-pgp-gpgme.c | 7 +++- 4 files changed, 82 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index f37b82afc..12dfe6d4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,15 @@ -2008-07-01 13:32 -0700 Brendan Cully (17525e17fa7b) +2008-07-01 17:20 -0700 Brendan Cully (8e2438ec5909) + + * crypt-gpgme.c, lib.c, lib.h: Support displaying application/pgp-keys + with GPGME. This was pretty convoluted because GPGME provides no way + to examine a key block without importing it. This code creates a + temporary GPG home in which to import the key in order to display + it. + + * crypt-gpgme.c, handler.c, pgp.c: Handle DONTHANDLEPGPKEYS in + handler instead of crypto modules. This lets gpgme and classic pgp + share a bit of logic, and unbreaks key extraction at least for + classic PGP. * copy.c: Bail out of copy if decryption is requested but the desired engine is missing. This closes #2684, but handling of mixed crypto diff --git a/crypt-gpgme.c b/crypt-gpgme.c index 9f696d292..670be1687 100644 --- a/crypt-gpgme.c +++ b/crypt-gpgme.c @@ -1838,7 +1838,7 @@ int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur) return *cur? 0:-1; } -static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp) +static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun) { /* there's no side-effect free way to view key data in GPGME, * so we import the key into a temporary keyring */ @@ -1856,40 +1856,43 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp) int more; int rc = -1; - snprintf (tmpdir, sizeof(tmpdir), "%s/mutt-gpgme-XXXXXX", Tempdir); - if (!mkdtemp (tmpdir)) - { - dprint (1, (debugfile, "Error creating temporary GPGME home\n")); - return rc; - } - if ((err = gpgme_new (&tmpctx)) != GPG_ERR_NO_ERROR) { dprint (1, (debugfile, "Error creating GPGME context\n")); - goto err_tmpdir; - } - - engineinfo = gpgme_ctx_get_engine_info (tmpctx); - while (engineinfo && engineinfo->protocol != GPGME_PROTOCOL_OpenPGP) - engineinfo = engineinfo->next; - if (!engineinfo) - { - dprint (1, (debugfile, "Error finding GPGME PGP engine\n")); - goto err_ctx; + return rc; } - err = gpgme_ctx_set_engine_info (tmpctx, GPGME_PROTOCOL_OpenPGP, - engineinfo->file_name, tmpdir); - if (err != GPG_ERR_NO_ERROR) + if (dryrun) { - dprint (1, (debugfile, "Error setting GPGME context home\n")); - goto err_ctx; + snprintf (tmpdir, sizeof(tmpdir), "%s/mutt-gpgme-XXXXXX", Tempdir); + if (!mkdtemp (tmpdir)) + { + dprint (1, (debugfile, "Error creating temporary GPGME home\n")); + goto err_ctx; + } + + engineinfo = gpgme_ctx_get_engine_info (tmpctx); + while (engineinfo && engineinfo->protocol != GPGME_PROTOCOL_OpenPGP) + engineinfo = engineinfo->next; + if (!engineinfo) + { + dprint (1, (debugfile, "Error finding GPGME PGP engine\n")); + goto err_tmpdir; + } + + err = gpgme_ctx_set_engine_info (tmpctx, GPGME_PROTOCOL_OpenPGP, + engineinfo->file_name, tmpdir); + if (err != GPG_ERR_NO_ERROR) + { + dprint (1, (debugfile, "Error setting GPGME context home\n")); + goto err_tmpdir; + } } if ((err = gpgme_op_import (tmpctx, keydata)) != GPG_ERR_NO_ERROR) { dprint (1, (debugfile, "Error importing key\n")); - goto err_ctx; + goto err_tmpdir; } mutt_mktemp (tmpfile); @@ -1897,7 +1900,7 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp) if (!*fp) { mutt_perror (tmpfile); - goto err_ctx; + goto err_tmpdir; } unlink (tmpfile); @@ -1944,10 +1947,11 @@ err_fp: fclose (*fp); *fp = NULL; } +err_tmpdir: + if (dryrun) + mutt_rmtree (tmpdir); err_ctx: gpgme_release (tmpctx); -err_tmpdir: - mutt_rmtree (tmpdir); return rc; } @@ -2034,6 +2038,37 @@ int pgp_gpgme_check_traditional (FILE *fp, BODY *b, int tagged_only) return rv; } +/* TODO: looks like this won't work and we'll have to fully parse the + * message file. GPGME makes life hard yet again. */ +void pgp_gpgme_invoke_import (const char *fname) +{ + gpgme_data_t keydata; + gpgme_error_t err; + FILE* in; + FILE* out; + long outlen; + + if (!(in = safe_fopen (fname, "r"))) + return; + if ((err = gpgme_data_new_from_stream (&keydata, in)) != GPG_ERR_NO_ERROR) + { + dprint (1, (debugfile, "error converting key file into data object\n")); + return; + } + fclose (in); + + if (!pgp_gpgme_extract_keys (keydata, &out, 0)) + { + /* display import results */ + outlen = ftell (out); + fseek (out, 0, SEEK_SET); + mutt_copy_bytes (out, stdout, outlen); + fclose (out); + } + else + printf (_("Error extracting key data!\n")); +} + /* * Implementation of `application_handler'. @@ -2179,7 +2214,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s) /* Invoke PGP if needed */ if (pgp_keyblock) { - pgp_gpgme_extract_keys (armored_data, &pgpout); + pgp_gpgme_extract_keys (armored_data, &pgpout, 1); } else if (!clearsign || (s->flags & M_VERIFY)) { diff --git a/crypt-gpgme.h b/crypt-gpgme.h index d0da2bb56..400d4a7f7 100644 --- a/crypt-gpgme.h +++ b/crypt-gpgme.h @@ -34,6 +34,7 @@ int pgp_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur); int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur); int pgp_gpgme_check_traditional (FILE *fp, BODY *b, int tagged_only); +void pgp_gpgme_invoke_import (const char* fname); int pgp_gpgme_application_handler (BODY *m, STATE *s); int smime_gpgme_application_handler (BODY *a, STATE *s); diff --git a/crypt-mod-pgp-gpgme.c b/crypt-mod-pgp-gpgme.c index 290adf710..388056fd8 100644 --- a/crypt-mod-pgp-gpgme.c +++ b/crypt-mod-pgp-gpgme.c @@ -65,6 +65,11 @@ static int crypt_mod_pgp_check_traditional (FILE *fp, BODY *b, int tagged_only) return pgp_gpgme_check_traditional (fp, b, tagged_only); } +static void crypt_mod_pgp_invoke_import (const char *fname) +{ + pgp_gpgme_invoke_import (fname); +} + static char *crypt_mod_pgp_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) { return pgp_gpgme_findkeys (to, cc, bcc); @@ -117,7 +122,7 @@ struct crypt_module_specs crypt_mod_pgp_gpgme = crypt_mod_pgp_check_traditional, NULL, /* pgp_traditional_encryptsign */ NULL, /* pgp_invoke_getkeys */ - NULL, /* pgp_invoke_import */ + crypt_mod_pgp_invoke_import, NULL, /* pgp_extract_keys_from_attachment_list */ NULL, /* smime_getkeys */ -- 2.40.0