summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2024-05-15 09:56:40 +0200
committerWerner Koch <wk@gnupg.org>2024-05-15 09:56:40 +0200
commitb36e557c5b05ba21942f385c03988f138d57dfb9 (patch)
tree5907245f66f8e4b8922038c4f0a4a4028f0a6dce
parenttpm2d: Use BYTE type to acces TPM2B object. (diff)
downloadgnupg2-b36e557c5b05ba21942f385c03988f138d57dfb9.tar.xz
gnupg2-b36e557c5b05ba21942f385c03988f138d57dfb9.zip
gpg: Terminate key listing on output write error.
* g10/keylist.c (list_all): Handle error from list_keyblock. (list_one): Ditto. (locate_one): Ditto. (list_keyblock): Detect write error, print, and return it. (list_keyblock_direct): Return error from list_keyblock. * g10/import.c (import_one_real): Break on listing error. -- Test by using gpg -k >/dev/full GnuPG-bug-id: 6185
-rw-r--r--g10/import.c4
-rw-r--r--g10/keygen.c5
-rw-r--r--g10/keylist.c53
-rw-r--r--g10/main.h4
4 files changed, 46 insertions, 20 deletions
diff --git a/g10/import.c b/g10/import.c
index ff8847cb6..bbeeebdfe 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -2175,10 +2175,12 @@ import_one_real (ctrl_t ctrl,
merge_keys_done = 1;
/* Note that we do not want to show the validity because the key
* has not yet imported. */
- list_keyblock_direct (ctrl, keyblock, from_sk, 0,
+ err = list_keyblock_direct (ctrl, keyblock, from_sk, 0,
opt.fingerprint || opt.with_fingerprint, 1);
es_fflush (es_stdout);
no_usable_encr_subkeys_warning (keyblock);
+ if (err)
+ goto leave;
}
/* Write the keyblock to the output and do not actually import. */
diff --git a/g10/keygen.c b/g10/keygen.c
index fe9a5d8f2..4bdb9f53a 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -6292,9 +6292,12 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
list_keyblock_direct (ctrl, pub_root, 0, 1,
opt.fingerprint || opt.with_fingerprint,
1);
+ /* Note that we ignore errors from the list function
+ * because that would only be an additional info. It
+ * has already been remarked that the key has been
+ * created. */
}
-
if (!opt.batch
&& (get_parameter_algo (ctrl, para,
pKEYTYPE, NULL) == PUBKEY_ALGO_DSA
diff --git a/g10/keylist.c b/g10/keylist.c
index c6667936d..81d6805a5 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -82,7 +82,7 @@ static estream_t attrib_fp;
-static void list_keyblock (ctrl_t ctrl,
+static gpg_error_t list_keyblock (ctrl_t ctrl,
kbnode_t keyblock, int secret, int has_secret,
int fpr, struct keylist_context *listctx);
@@ -745,6 +745,7 @@ list_all (ctrl_t ctrl, int secret, int mark_secret)
int any_secret;
const char *lastresname, *resname;
struct keylist_context listctx;
+ gpg_error_t listerr = 0;
memset (&listctx, 0, sizeof (listctx));
if (opt.check_sigs)
@@ -802,13 +803,13 @@ list_all (ctrl_t ctrl, int secret, int mark_secret)
}
}
merge_keys_and_selfsig (ctrl, keyblock);
- list_keyblock (ctrl, keyblock, secret, any_secret, opt.fingerprint,
- &listctx);
+ listerr = list_keyblock (ctrl, keyblock, secret, any_secret,
+ opt.fingerprint, &listctx);
}
release_kbnode (keyblock);
keyblock = NULL;
}
- while (!(rc = keydb_search_next (hd)));
+ while (!listerr && !(rc = keydb_search_next (hd)));
es_fflush (es_stdout);
if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
@@ -839,6 +840,7 @@ list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
const char *keyring_str = _("Keyring");
int i;
struct keylist_context listctx;
+ gpg_error_t listerr = 0;
memset (&listctx, 0, sizeof (listctx));
if (!secret && opt.check_sigs)
@@ -887,12 +889,12 @@ list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
es_putc ('-', es_stdout);
es_putc ('\n', es_stdout);
}
- list_keyblock (ctrl, keyblock, secret, any_secret,
- opt.fingerprint, &listctx);
+ listerr = list_keyblock (ctrl, keyblock, secret, any_secret,
+ opt.fingerprint, &listctx);
}
release_kbnode (keyblock);
}
- while (!getkey_next (ctrl, ctx, NULL, &keyblock));
+ while (!listerr && !getkey_next (ctrl, ctx, NULL, &keyblock));
getkey_end (ctrl, ctx);
if (opt.check_sigs && !opt.with_colons)
@@ -910,12 +912,13 @@ locate_one (ctrl_t ctrl, strlist_t names, int no_local)
GETKEY_CTX ctx = NULL;
KBNODE keyblock = NULL;
struct keylist_context listctx;
+ gpg_error_t listerr = 0;
memset (&listctx, 0, sizeof (listctx));
if (opt.check_sigs)
listctx.check_sigs = 1;
- for (sl = names; sl; sl = sl->next)
+ for (sl = names; sl && !listerr; sl = sl->next)
{
rc = get_best_pubkey_byname (ctrl,
no_local? GET_PUBKEY_NO_LOCAL
@@ -933,10 +936,11 @@ locate_one (ctrl_t ctrl, strlist_t names, int no_local)
{
do
{
- list_keyblock (ctrl, keyblock, 0, 0, opt.fingerprint, &listctx);
+ listerr = list_keyblock (ctrl, keyblock, 0, 0,
+ opt.fingerprint, &listctx);
release_kbnode (keyblock);
}
- while (ctx && !getkey_next (ctrl, ctx, NULL, &keyblock));
+ while (!listerr && ctx && !getkey_next (ctrl, ctx, NULL, &keyblock));
getkey_end (ctrl, ctx);
ctx = NULL;
}
@@ -2325,11 +2329,18 @@ reorder_keyblock (KBNODE keyblock)
}
-static void
+/* Note: If this function returns an error the caller is expected to
+ * honor this and stop all further processing. Any error returned
+ * will be a write error (to stdout) and a diagnostics is always
+ * printed using log_error. */
+static gpg_error_t
list_keyblock (ctrl_t ctrl,
KBNODE keyblock, int secret, int has_secret, int fpr,
struct keylist_context *listctx)
{
+ gpg_error_t err = 0;
+
+ es_clearerr (es_stdout);
reorder_keyblock (keyblock);
if (list_filter.selkey)
@@ -2347,7 +2358,7 @@ list_keyblock (ctrl_t ctrl,
}
}
if (!selected)
- return; /* Skip this one. */
+ return 0; /* Skip this one. */
}
if (opt.with_colons)
@@ -2361,24 +2372,34 @@ list_keyblock (ctrl_t ctrl,
else
list_keyblock_print (ctrl, keyblock, secret, fpr, listctx);
- if (secret)
- es_fflush (es_stdout);
+ if (es_ferror (es_stdout))
+ err = gpg_error_from_syserror ();
+
+ if (secret && es_fflush (es_stdout) && !err)
+ err = gpg_error_from_syserror ();
+
+ if (err)
+ log_error (_("error writing to stdout: %s\n"), gpg_strerror (err));
+
+ return err;
}
/* Public function used by keygen to list a keyblock. If NO_VALIDITY
* is set the validity of a key is never shown. */
-void
+gpg_error_t
list_keyblock_direct (ctrl_t ctrl,
kbnode_t keyblock, int secret, int has_secret, int fpr,
int no_validity)
{
struct keylist_context listctx;
+ gpg_error_t err;
memset (&listctx, 0, sizeof (listctx));
listctx.no_validity = !!no_validity;
- list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx);
+ err = list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx);
keylist_context_release (&listctx);
+ return err;
}
diff --git a/g10/main.h b/g10/main.h
index 5123dd03b..2443aa7fe 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -470,8 +470,8 @@ void secret_key_list (ctrl_t ctrl, strlist_t list );
gpg_error_t parse_and_set_list_filter (const char *string);
void print_subpackets_colon(PKT_signature *sig);
void reorder_keyblock (KBNODE keyblock);
-void list_keyblock_direct (ctrl_t ctrl, kbnode_t keyblock, int secret,
- int has_secret, int fpr, int no_validity);
+gpg_error_t list_keyblock_direct (ctrl_t ctrl, kbnode_t keyblock, int secret,
+ int has_secret, int fpr, int no_validity);
int cmp_signodes (const void *av, const void *bv);
void print_fingerprint (ctrl_t ctrl, estream_t fp,
PKT_public_key *pk, int mode);