summaryrefslogtreecommitdiffstats
path: root/crypt-gpgme.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2018-12-03 08:41:56 +0100
committerKevin McCarthy <kevin@8t8.us>2018-12-04 20:03:11 -0800
commit382355a5ddc5fb86bde4e2a376b70c9b0864cc53 (patch)
tree2a8f66cc72ac1f2821dab0f2cba9133b3cef803c /crypt-gpgme.c
parent55c18b7e2fc2b7779beb6cb69d9524a402e9f2ef (diff)
Improve the console output for extract-keys and speed up import.
The listing of imported keys to the console must have stopped working on 2014-12-31 due to a fix for bug #3698, commit bbc5acb6de0ca56d7e8366402d68a1a919ca9b23 which was needed due to a not fully working stub code introduced in 2008 with commit a4b3a60dd63bc7af7927025b2d1344530ca89aa9. The latter commit also introduced a bug in the import code which listed all keys in the keyring to a temporary file and copied that one to stdout. The former commit avoided the output to stdout. The fix here is to use pgp_gpgme_extract_keys only for extracting information about the key and don't re-use the same code for importing keys. We now import the keys directly in pgp_gpgme_invoke_import and we print the fingerprint and status flags for all imported keys. That information available from GPGME for ages (0.3.1 from 2003). The user id is unfortunately not printed; that would require a lookup of the newly imported key. Can be done with another patch.
Diffstat (limited to 'crypt-gpgme.c')
-rw-r--r--crypt-gpgme.c113
1 files changed, 85 insertions, 28 deletions
diff --git a/crypt-gpgme.c b/crypt-gpgme.c
index 515d81b3..f727292b 100644
--- a/crypt-gpgme.c
+++ b/crypt-gpgme.c
@@ -2228,7 +2228,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, int dryrun)
+static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp)
{
/* Before gpgme 1.9.0 and gpg 2.1.14 there was no side-effect free
* way to view key data in GPGME, so we import the key into a
@@ -2257,7 +2257,7 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
tmpctx = create_gpgme_context (0);
- if (dryrun && legacy_api)
+ if (legacy_api)
{
snprintf (tmpdir, sizeof(tmpdir), "%s/mutt-gpgme-XXXXXX", Tempdir);
if (!mkdtemp (tmpdir))
@@ -2284,15 +2284,6 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
}
}
- if (!dryrun || legacy_api)
- {
- if ((err = gpgme_op_import (tmpctx, keydata)) != GPG_ERR_NO_ERROR)
- {
- dprint (1, (debugfile, "Error importing key\n"));
- goto err_tmpdir;
- }
- }
-
mutt_mktemp (tmpfile, sizeof (tmpfile));
*fp = safe_fopen (tmpfile, "w+");
if (!*fp)
@@ -2303,7 +2294,7 @@ static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
unlink (tmpfile);
#if GPGME_VERSION_NUMBER >= 0x010900 /* 1.9.0 */
- if (dryrun && !legacy_api)
+ if (!legacy_api)
err = gpgme_op_keylist_from_data_start (tmpctx, keydata, 0);
else
#endif /* gpgme >= 1.9.0 */
@@ -2351,7 +2342,7 @@ err_fp:
if (rc)
safe_fclose (fp);
err_tmpdir:
- if (dryrun && legacy_api)
+ if (legacy_api)
mutt_rmtree (tmpdir);
err_ctx:
gpgme_release (tmpctx);
@@ -2359,6 +2350,7 @@ err_ctx:
return rc;
}
+
/* Check that 'b' is a complete line containing 'a' followed by either LF or CRLF.
*
* returns:
@@ -2466,37 +2458,102 @@ int pgp_gpgme_check_traditional (FILE *fp, BODY *b, int just_one)
void pgp_gpgme_invoke_import (const char *fname)
{
- gpgme_data_t keydata;
+ gpgme_ctx_t ctx;
+ gpgme_data_t keydata = NULL;
gpgme_error_t err;
- FILE* in;
- FILE* out;
+ FILE *in = NULL;
+ gpgme_import_result_t impres;
+ gpgme_import_status_t st;
+ int any;
+
+ ctx = create_gpgme_context (0);
if (!(in = safe_fopen (fname, "r")))
- return;
+ {
+ mutt_perror (fname);
+ goto leave;
+ }
+
/* Note that the stream, "in", needs to be kept open while the keydata
- * is used.
- */
+ * is used. */
if ((err = gpgme_data_new_from_stream (&keydata, in)) != GPG_ERR_NO_ERROR)
{
- safe_fclose (&in);
mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err));
mutt_sleep (1);
- return;
+ goto leave;
}
- if (pgp_gpgme_extract_keys (keydata, &out, 0))
+ err = gpgme_op_import (ctx, keydata);
+ if (err)
{
- mutt_error (_("Error extracting key data!\n"));
+ mutt_error (_("error importing key: %s\n"), gpgme_strerror (err));
mutt_sleep (1);
+ goto leave;
}
- else
+
+ /* Print infos about the imported keys to stdout. */
+ impres = gpgme_op_import_result (ctx);
+ if (!impres)
{
- fseek (out, 0, SEEK_SET);
- mutt_copy_stream (out, stdout);
+ fputs ("oops: no import result returned\n", stdout);
+ goto leave;
}
+
+ for (st = impres->imports; st; st = st->next)
+ {
+ if (st->result)
+ continue;
+ printf ("key %s imported (", NONULL (st->fpr));
+ /* Note that we use the singular even if it is possible that
+ * several uids etc are new. This simply looks better. */
+ any = 0;
+ if (st->status & GPGME_IMPORT_SECRET)
+ {
+ printf ("secret parts");
+ any = 1;
+ }
+ if ((st->status & GPGME_IMPORT_NEW))
+ {
+ printf ("%snew key", any? ", ":"");
+ any = 1;
+ }
+ if ((st->status & GPGME_IMPORT_UID))
+ {
+ printf ("%snew uid", any? ", ":"");
+ any = 1;
+ }
+ if ((st->status & GPGME_IMPORT_SIG))
+ {
+ printf ("%snew sig", any? ", ":"");
+ any = 1;
+ }
+ if ((st->status & GPGME_IMPORT_SUBKEY))
+ {
+ printf ("%snew subkey", any? ", ":"");
+ any = 1;
+ }
+ printf ("%s)\n", any? "":"not changed");
+ /* Fixme: Should we lookup each imported key and print more infos? */
+ }
+ /* Now print keys which failed the import. Unfortunately in most
+ * cases gpg will bail out early and not tell gpgme about. */
+ /* FIXME: We could instead use the new GPGME_AUDITLOG_DIAG to show
+ * the actual gpg diagnostics. But I fear that would clutter the
+ * output too much. Maybe a dedicated prompt or option to do this
+ * would be helpful. */
+ for (st = impres->imports; st; st = st->next)
+ {
+ if (!st->result)
+ continue;
+ printf ("key %s import failed: %s\n", NONULL (st->fpr),
+ gpgme_strerror (st->result));
+ }
+ fflush (stdout);
+
+ leave:
+ gpgme_release (ctx);
gpgme_data_release (keydata);
safe_fclose (&in);
- safe_fclose (&out);
}
@@ -2641,7 +2698,7 @@ int pgp_gpgme_application_handler (BODY *m, STATE *s)
/* Invoke PGP if needed */
if (pgp_keyblock)
{
- pgp_gpgme_extract_keys (armored_data, &pgpout, 1);
+ pgp_gpgme_extract_keys (armored_data, &pgpout);
}
else if (!clearsign || (s->flags & MUTT_VERIFY))
{