From fcb62fe20f45290bf95703ec3bf4d0b361fa4339 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 27 Jul 2017 11:37:00 +0200 Subject: [PATCH] gpg: Avoid output to the tty during import. * g10/key-check.c (key_check_all_keysigs): Add arg mode and change all output calls to use it. * g10/keyedit.c (keyedit_print_one_sig): Add arg fp and chnage all output calls to use it. (keyedit_menu): Adjust for changes. * g10/gpgcompose.c (keyedit_print_one_sig): Add dummy arg fp. * g10/import.c (import_one): Call key_check_all_keysigs with output to the log stream. -- Fixes-commit: 404fa8211b6188a0abe83ef43a4b44d528c0b035 GnuPG-bug-id: 3288 Signed-off-by: Werner Koch --- g10/gpgcompose.c | 4 +- g10/import.c | 2 +- g10/key-check.c | 117 ++++++++++++++++++++++++++--------------------- g10/key-check.h | 2 +- g10/keyedit.c | 40 ++++++++-------- g10/keyedit.h | 3 +- g10/keylist.c | 2 +- 7 files changed, 96 insertions(+), 74 deletions(-) diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c index f38d75579..2b42bfbf9 100644 --- a/g10/gpgcompose.c +++ b/g10/gpgcompose.c @@ -3065,11 +3065,13 @@ show_basic_key_info (ctrl_t ctrl, KBNODE keyblock) } int -keyedit_print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node, +keyedit_print_one_sig (ctrl_t ctrl, estream_t fp, + int rc, kbnode_t keyblock, kbnode_t node, int *inv_sigs, int *no_key, int *oth_err, int is_selfsig, int print_without_key, int extended) { (void) ctrl; + (void) fp; (void) rc; (void) keyblock; (void) node; diff --git a/g10/import.c b/g10/import.c index 6e8322587..813662537 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1701,7 +1701,7 @@ import_one (ctrl_t ctrl, keystr_from_pk(pk)); if ((options & IMPORT_REPAIR_KEYS)) - key_check_all_keysigs (ctrl, keyblock, 0, 0); + key_check_all_keysigs (ctrl, 1, keyblock, 0, 0); if (chk_self_sigs (ctrl, keyblock, keyid, &non_self)) return 0; /* Invalid keyblock - error already printed. */ diff --git a/g10/key-check.c b/g10/key-check.c index a22394de8..d32067b99 100644 --- a/g10/key-check.c +++ b/g10/key-check.c @@ -33,7 +33,7 @@ #include "key-check.h" /* Order two signatures. The actual ordering isn't important. Our - goal is to ensure that identical signatures occur together. */ + * goal is to ensure that identical signatures occur together. */ static int sig_comparison (const void *av, const void *bv) { @@ -72,28 +72,35 @@ sig_comparison (const void *av, const void *bv) return 0; } + /* Perform a few sanity checks on a keyblock is okay and possibly - repair some damage. Concretely: - - - Detect duplicate signatures and remove them. - - - Detect out of order signatures and relocate them (e.g., a sig - over user id X located under subkey Y). - - Note: this function does not remove signatures that don't belong or - components that are not signed! (Although it would be trivial to - do so.) - - If ONLY_SELFSIGS is true, then this function only reorders self - signatures (it still checks all signatures for duplicates, - however). - - Returns 1 if the keyblock was modified, 0 otherwise. */ + * repair some damage. Concretely: + * + * - Detect duplicate signatures and remove them. + * + * - Detect out of order signatures and relocate them (e.g., a sig + * over user id X located under subkey Y). + * + * Note: this function does not remove signatures that don't belong or + * components that are not signed! (Although it would be trivial to + * do so.) + * + * If ONLY_SELFSIGS is true, then this function only reorders self + * signatures (it still checks all signatures for duplicates, + * however). + * + * Allowed values for MODE are: + * -1 - print to the TTY + * 0 - print to stdout + * 1 - use log_info. + * + * Returns true if the keyblock was modified. */ int -key_check_all_keysigs (ctrl_t ctrl, kbnode_t kb, +key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, int only_selected, int only_selfsigs) { gpg_error_t err; + estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout; PKT_public_key *pk; KBNODE n, n_next, *n_prevp, n2; char *pending_desc = NULL; @@ -329,8 +336,8 @@ key_check_all_keysigs (ctrl_t ctrl, kbnode_t kb, { if (DBG_PACKET && pending_desc) log_debug ("%s", pending_desc); - tty_printf (_("can't check signature with unsupported" - " public-key algorithm (%d): %s.\n"), + log_info (_("can't check signature with unsupported" + " public-key algorithm (%d): %s.\n"), sig->pubkey_algo, gpg_strerror (err)); break; } @@ -338,8 +345,8 @@ key_check_all_keysigs (ctrl_t ctrl, kbnode_t kb, { if (DBG_PACKET && pending_desc) log_debug ("%s", pending_desc); - tty_printf (_("can't check signature with unsupported" - " message-digest algorithm %d: %s.\n"), + log_info (_("can't check signature with unsupported" + " message-digest algorithm %d: %s.\n"), sig->digest_algo, gpg_strerror (err)); break; } @@ -482,32 +489,36 @@ key_check_all_keysigs (ctrl_t ctrl, kbnode_t kb, ; else if (last_printed_component->pkt->pkttype == PKT_USER_ID) { - tty_printf ("uid "); - tty_print_utf8_string (last_printed_component - ->pkt->pkt.user_id->name, - last_printed_component - ->pkt->pkt.user_id->len); + tty_fprintf (fp, "uid "); + tty_print_utf8_string2 (fp, + last_printed_component + ->pkt->pkt.user_id->name, + last_printed_component + ->pkt->pkt.user_id->len, 0); } else if (last_printed_component->pkt->pkttype == PKT_PUBLIC_KEY) - tty_printf ("pub %s", - pk_keyid_str (last_printed_component - ->pkt->pkt.public_key)); + tty_fprintf (fp, "pub %s", + pk_keyid_str (last_printed_component + ->pkt->pkt.public_key)); else - tty_printf ("sub %s", - pk_keyid_str (last_printed_component - ->pkt->pkt.public_key)); + tty_fprintf (fp, "sub %s", + pk_keyid_str (last_printed_component + ->pkt->pkt.public_key)); if (modified) { if (is_reordered) - tty_printf (_(" (reordered signatures follow)")); - tty_printf ("\n"); + tty_fprintf (fp, _(" (reordered signatures follow)")); + if (mode > 0) + log_printf ("\n"); + else + tty_fprintf (fp, "\n"); } } if (modified) - keyedit_print_one_sig (ctrl, rc, kb, n, NULL, NULL, NULL, + keyedit_print_one_sig (ctrl, fp, rc, kb, n, NULL, NULL, NULL, has_selfsig, 0, only_selfsigs); } @@ -524,7 +535,7 @@ key_check_all_keysigs (ctrl_t ctrl, kbnode_t kb, buffer, sizeof (buffer), &len, sig->data[i]); printable = bin2hex (buffer, len, NULL); - log_info (" %d: %s\n", i, printable); + log_debug (" %d: %s\n", i, printable); xfree (printable); } } @@ -614,27 +625,31 @@ key_check_all_keysigs (ctrl_t ctrl, kbnode_t kb, } if (dups || missing_issuer || bad_signature || reordered) - tty_printf (_("key %s:\n"), pk_keyid_str (pk)); + tty_fprintf (fp, _("key %s:\n"), pk_keyid_str (pk)); if (dups) - tty_printf (ngettext ("%d duplicate signature removed\n", - "%d duplicate signatures removed\n", dups), dups); + tty_fprintf (fp, + ngettext ("%d duplicate signature removed\n", + "%d duplicate signatures removed\n", dups), dups); if (missing_issuer) - tty_printf (ngettext ("%d signature not checked due to a missing key\n", - "%d signatures not checked due to missing keys\n", - missing_issuer), missing_issuer); + tty_fprintf (fp, + ngettext ("%d signature not checked due to a missing key\n", + "%d signatures not checked due to missing keys\n", + missing_issuer), missing_issuer); if (bad_signature) - tty_printf (ngettext ("%d bad signature\n", - "%d bad signatures\n", - bad_signature), bad_signature); + tty_fprintf (fp, + ngettext ("%d bad signature\n", + "%d bad signatures\n", + bad_signature), bad_signature); if (reordered) - tty_printf (ngettext ("%d signature reordered\n", - "%d signatures reordered\n", - reordered), reordered); + tty_fprintf (fp, + ngettext ("%d signature reordered\n", + "%d signatures reordered\n", + reordered), reordered); if (only_selfsigs && (bad_signature || reordered)) - tty_printf (_("Warning: errors found and only checked self-signatures," - " run '%s' to check all signatures.\n"), "check"); + tty_fprintf (fp, _("Warning: errors found and only checked self-signatures," + " run '%s' to check all signatures.\n"), "check"); return modified; } diff --git a/g10/key-check.h b/g10/key-check.h index 3e4dd1031..9f7886ca0 100644 --- a/g10/key-check.h +++ b/g10/key-check.h @@ -22,7 +22,7 @@ #include "gpg.h" -int key_check_all_keysigs (ctrl_t ctrl, kbnode_t kb, +int key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb, int only_selected, int only_selfsigs); #endif /* GNUPG_G10_PACKET_TOOLS_H */ diff --git a/g10/keyedit.c b/g10/keyedit.c index 0a90cf5b7..e221b320e 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -193,7 +193,8 @@ print_and_check_one_sig_colon (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node, * always be printed. */ int -keyedit_print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node, +keyedit_print_one_sig (ctrl_t ctrl, estream_t fp, + int rc, kbnode_t keyblock, kbnode_t node, int *inv_sigs, int *no_key, int *oth_err, int is_selfsig, int print_without_key, int extended) { @@ -232,7 +233,7 @@ keyedit_print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node, } if (sigrc != '?' || print_without_key) { - tty_printf ("%s%c%c %c%c%c%c%c%c %s %s", + tty_fprintf (fp, "%s%c%c %c%c%c%c%c%c %s %s", is_rev ? "rev" : "sig", sigrc, (sig->sig_class - 0x10 > 0 && sig->sig_class - 0x10 < @@ -248,38 +249,41 @@ keyedit_print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node, keystr (sig->keyid), datestr_from_sig (sig)); if ((opt.list_options & LIST_SHOW_SIG_EXPIRE) || extended ) - tty_printf (" %s", expirestr_from_sig (sig)); - tty_printf (" "); + tty_fprintf (fp, " %s", expirestr_from_sig (sig)); + tty_fprintf (fp, " "); if (sigrc == '%') - tty_printf ("[%s] ", gpg_strerror (rc)); + tty_fprintf (fp, "[%s] ", gpg_strerror (rc)); else if (sigrc == '?') ; else if (is_selfsig) { - tty_printf (is_rev ? _("[revocation]") : _("[self-signature]")); + tty_fprintf (fp, is_rev ? _("[revocation]") : _("[self-signature]")); if (extended && sig->flags.chosen_selfsig) - tty_printf ("*"); + tty_fprintf (fp, "*"); } else { size_t n; char *p = get_user_id (ctrl, sig->keyid, &n); - tty_print_utf8_string2 (NULL, p, n, + tty_print_utf8_string2 (fp, p, n, opt.screen_columns - keystrlen () - 26 - ((opt. list_options & LIST_SHOW_SIG_EXPIRE) ? 11 : 0)); xfree (p); } - tty_printf ("\n"); + if (fp == log_get_stream ()) + log_printf ("\n"); + else + tty_fprintf (fp, "\n"); if (sig->flags.policy_url && ((opt.list_options & LIST_SHOW_POLICY_URLS) || extended)) - show_policy_url (sig, 3, -1); + show_policy_url (sig, 3, (!fp? -1 : fp == log_get_stream ()? 1 : 0)); if (sig->flags.notation && ((opt.list_options & LIST_SHOW_NOTATIONS) || extended)) - show_notation (sig, 3, -1, + show_notation (sig, 3, (!fp? -1 : fp == log_get_stream ()? 1 : 0), ((opt. list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) + ((opt. @@ -287,7 +291,7 @@ keyedit_print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node, if (sig->flags.pref_ks && ((opt.list_options & LIST_SHOW_KEYSERVER_URLS) || extended)) - show_keyserver_url (sig, 3, -1); + show_keyserver_url (sig, 3, (!fp? -1 : fp == log_get_stream ()? 1 : 0)); if (extended) { @@ -296,12 +300,12 @@ keyedit_print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, kbnode_t node, s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL); if (s && *s) - tty_printf (" [primary]\n"); + tty_fprintf (fp, " [primary]\n"); s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); if (s && buf32_to_u32 (s)) - tty_printf (" [expires: %s]\n", - isotimestamp (pk->timestamp + buf32_to_u32 (s))); + tty_fprintf (fp, " [expires: %s]\n", + isotimestamp (pk->timestamp + buf32_to_u32 (s))); } } @@ -317,7 +321,7 @@ print_and_check_one_sig (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node, int rc; rc = check_key_signature (ctrl, keyblock, node, is_selfsig); - return keyedit_print_one_sig (ctrl, rc, + return keyedit_print_one_sig (ctrl, NULL, rc, keyblock, node, inv_sigs, no_key, oth_err, *is_selfsig, print_without_key, extended); } @@ -1166,7 +1170,7 @@ fix_keyblock (ctrl_t ctrl, kbnode_t *keyblockp) if (collapse_uids (keyblockp)) changed++; - if (key_check_all_keysigs (ctrl, *keyblockp, 0, 1)) + if (key_check_all_keysigs (ctrl, 1, *keyblockp, 0, 1)) changed++; reorder_keyblock (*keyblockp); /* If we modified the keyblock, make sure the flags are right. */ @@ -1613,7 +1617,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, break; case cmdCHECK: - if (key_check_all_keysigs (ctrl, keyblock, + if (key_check_all_keysigs (ctrl, -1, keyblock, count_selected_uids (keyblock), !strcmp (arg_string, "selfsig"))) modified = 1; diff --git a/g10/keyedit.h b/g10/keyedit.h index 23a126bc3..d1f453a6f 100644 --- a/g10/keyedit.h +++ b/g10/keyedit.h @@ -51,7 +51,8 @@ void keyedit_quick_set_expire (ctrl_t ctrl, void keyedit_quick_set_primary (ctrl_t ctrl, const char *username, const char *primaryuid); void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock); -int keyedit_print_one_sig (ctrl_t ctrl, int rc, kbnode_t keyblock, +int keyedit_print_one_sig (ctrl_t ctrl, estream_t fp, + int rc, kbnode_t keyblock, kbnode_t node, int *inv_sigs, int *no_key, int *oth_err, int is_selfsig, int print_without_key, int extended); diff --git a/g10/keylist.c b/g10/keylist.c index 7203d160b..86d1c564f 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -193,7 +193,7 @@ print_seckey_info (ctrl_t ctrl, PKT_public_key *pk) } /* Print information about the public key. With FP passed as NULL, - the tty output interface is used, otherwise output is directted to + the tty output interface is used, otherwise output is directed to the given stream. */ void print_pubkey_info (ctrl_t ctrl, estream_t fp, PKT_public_key *pk)