diff options
author | Daiki Ueno <ueno@gnu.org> | 2015-08-18 09:57:44 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2016-07-13 18:15:52 +0200 |
commit | 82b90eee100cf1c9680517059b2d35e295dd992a (patch) | |
tree | 02ed9d5f42697b198bdf9411a56f00645d3f336c /g10/getkey.c | |
parent | gpg: Do not print a the short keyid if the high word is zero. (diff) | |
download | gnupg2-82b90eee100cf1c9680517059b2d35e295dd992a.tar.xz gnupg2-82b90eee100cf1c9680517059b2d35e295dd992a.zip |
gpg: Make --try-all-secrets work for hidden recipients
* g10/getkey.c (enum_secret_keys): Really enumerate all secret
keys if --try-all-secrets is specified.
--
GnuPG-bug-id: 1985
Signed-off-by: Daiki Ueno <ueno@gnu.org>
- Add new arg CTRL to getkey_byname call.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'g10/getkey.c')
-rw-r--r-- | g10/getkey.c | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/g10/getkey.c b/g10/getkey.c index 90fd175b4..3fe8274d5 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3555,6 +3555,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) { gpg_error_t err = 0; const char *name; + kbnode_t keyblock; struct { int eof; @@ -3562,6 +3563,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) strlist_t sl; kbnode_t keyblock; kbnode_t node; + getkey_ctx_t ctx; } *c = *context; if (!c) @@ -3577,6 +3579,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) { /* Free the context. */ release_kbnode (c->keyblock); + getkey_end (c->ctx); xfree (c); *context = NULL; return 0; @@ -3594,6 +3597,7 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) do { name = NULL; + keyblock = NULL; switch (c->state) { case 0: /* First try to use the --default-key. */ @@ -3616,24 +3620,60 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) c->state++; break; + case 3: /* Init search context to try all keys. */ + if (opt.try_all_secrets) + { + err = getkey_bynames (&c->ctx, NULL, NULL, 1, &keyblock); + if (err) + { + release_kbnode (keyblock); + keyblock = NULL; + getkey_end (c->ctx); + c->ctx = NULL; + } + } + c->state++; + break; + + case 4: /* Get next item from the context. */ + if (c->ctx) + { + err = getkey_next (c->ctx, NULL, &keyblock); + if (err) + { + release_kbnode (keyblock); + keyblock = NULL; + getkey_end (c->ctx); + c->ctx = NULL; + } + } + else + c->state++; + break; + default: /* No more names to check - stop. */ c->eof = 1; return gpg_error (GPG_ERR_EOF); } } - while (!name || !*name); + while ((!name || !*name) && !keyblock); - err = getkey_byname (ctrl, NULL, NULL, name, 1, &c->keyblock); - if (err) + if (keyblock) + c->node = c->keyblock = keyblock; + else { - /* getkey_byname might return a keyblock even in the - error case - I have not checked. Thus better release - it. */ - release_kbnode (c->keyblock); - c->keyblock = NULL; + err = getkey_byname (ctrl, NULL, NULL, name, 1, &c->keyblock); + if (err) + { + /* getkey_byname might return a keyblock even in the + error case - I have not checked. Thus better release + it. */ + release_kbnode (c->keyblock); + c->keyblock = NULL; + } + else + c->node = c->keyblock; } - else - c->node = c->keyblock; } /* Get the next key from the current keyblock. */ |