diff options
author | Neal H. Walfield <[email protected]> | 2015-11-03 22:15:27 +0000 |
---|---|---|
committer | Neal H. Walfield <[email protected]> | 2015-11-04 12:19:52 +0000 |
commit | e16d7168c54e5f7bc2f0037806ee4f730930eaf0 (patch) | |
tree | 8cf75fb29648d091e01533506d6377e645451123 /g10/getkey.c | |
parent | scd: Fix error handling with libusb-compat library. (diff) | |
download | gnupg-e16d7168c54e5f7bc2f0037806ee4f730930eaf0.tar.gz gnupg-e16d7168c54e5f7bc2f0037806ee4f730930eaf0.zip |
gpg: Allow multiple --default-key options. Take the last available key.
* g10/getkey.c (parse_def_secret_key): New function.
(get_seckey_default): Add parameter ctrl. Update callers. Use
parse_def_secret_key to get the default secret key, if any.
(getkey_byname): Likewise.
(enum_secret_keys): Likewise.
* g10/options.h (opt): Change def_secret_key's type from a char * to a
strlist_t.
* g10/gpg.c (main): When processing --default-key, add the key to
OPT.DEF_SECRET_KEY.
* g10/gpgv.c (get_session_key): Add parameter ctrl. Update callers.
* g10/mainproc.c (proc_pubkey_enc): Likewise.
(do_proc_packets): Likewise.
* g10/pkclist.c (default_recipient): Likewise.
* g10/pubkey-enc.c (get_session_key): Likewise.
* g10/sign.c (clearsign_file): Likewise.
(sign_symencrypt_file): Likewise.
* g10/skclist.c (build_sk_list): Likewise.
* g10/test-stubs.c (get_session_key): Likewise.
--
Signed-off-by: Neal H. Walield <[email protected]>
GnuPG-bug-id: 806
Diffstat (limited to '')
-rw-r--r-- | g10/getkey.c | 99 |
1 files changed, 89 insertions, 10 deletions
diff --git a/g10/getkey.c b/g10/getkey.c index a5f568956..d3ce7d23f 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1121,17 +1121,93 @@ get_pubkey_byfprint_fast (PKT_public_key * pk, return 0; } +static const char * +parse_def_secret_key (ctrl_t ctrl) +{ + KEYDB_HANDLE hd = NULL; + strlist_t t; + static int warned; + + for (t = opt.def_secret_key; t; t = t->next) + { + gpg_error_t err; + KEYDB_SEARCH_DESC desc; + KBNODE kb; + + err = classify_user_id (t->d, &desc, 1); + if (err) + { + log_error (_("Invalid value ('%s') for --default-key.\n"), + t->d); + continue; + } + + if (! (desc.mode == KEYDB_SEARCH_MODE_LONG_KID + || desc.mode == KEYDB_SEARCH_MODE_FPR16 + || desc.mode == KEYDB_SEARCH_MODE_FPR20 + || desc.mode == KEYDB_SEARCH_MODE_FPR) + && ! warned) + log_info (_("Warning: value '%s' for --default-key" + " should be a long keyid or a fingerprint.\n"), + t->d); + + if (! hd) + hd = keydb_new (); + else + keydb_search_reset (hd); + + err = keydb_search (hd, &desc, 1, NULL); + if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) + continue; + + if (err) + { + log_error (_("Error reading from keyring: %s.\n"), + gpg_strerror (err)); + t = NULL; + break; + } + + err = keydb_get_keyblock (hd, &kb); + if (err) + { + log_error (_("error reading keyblock: %s\n"), + gpg_strerror (err)); + continue; + } + + err = agent_probe_secret_key (ctrl, kb->pkt->pkt.public_key); + release_kbnode (kb); + if (! err) + { + if (! warned) + log_debug (_("Using %s as default secret key.\n"), t->d); + break; + } + } + + warned = 1; + + if (hd) + keydb_release (hd); + + if (t) + return t->d; + return NULL; +} /* For documentation see keydb.h. */ gpg_error_t -get_seckey_default (PKT_public_key *pk) +get_seckey_default (ctrl_t ctrl, PKT_public_key *pk) { gpg_error_t err; strlist_t namelist = NULL; int include_unusable = 1; - if (opt.def_secret_key && *opt.def_secret_key) - add_to_strlist (&namelist, opt.def_secret_key); + + const char *def_secret_key = parse_def_secret_key (ctrl); + if (def_secret_key) + add_to_strlist (&namelist, def_secret_key); else include_unusable = 0; @@ -1154,15 +1230,19 @@ getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk, /* For documentation see keydb.h. */ gpg_error_t -getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk, +getkey_byname (ctrl_t ctrl, getkey_ctx_t *retctx, PKT_public_key *pk, const char *name, int want_secret, kbnode_t *ret_keyblock) { gpg_error_t err; strlist_t namelist = NULL; int with_unusable = 1; + const char *def_secret_key = NULL; + + if (want_secret && !name) + def_secret_key = parse_def_secret_key (ctrl); - if (want_secret && !name && opt.def_secret_key && *opt.def_secret_key) - add_to_strlist (&namelist, opt.def_secret_key); + if (want_secret && !name && def_secret_key) + add_to_strlist (&namelist, def_secret_key); else if (name) add_to_strlist (&namelist, name); else @@ -2737,7 +2817,7 @@ found: /* For documentation see keydb.h. */ gpg_error_t -enum_secret_keys (void **context, PKT_public_key *sk) +enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) { gpg_error_t err = 0; const char *name; @@ -2783,8 +2863,7 @@ enum_secret_keys (void **context, PKT_public_key *sk) switch (c->state) { case 0: /* First try to use the --default-key. */ - if (opt.def_secret_key && *opt.def_secret_key) - name = opt.def_secret_key; + name = parse_def_secret_key (ctrl); c->state = 1; break; @@ -2810,7 +2889,7 @@ enum_secret_keys (void **context, PKT_public_key *sk) } while (!name || !*name); - err = getkey_byname (NULL, NULL, name, 1, &c->keyblock); + err = getkey_byname (ctrl, NULL, NULL, name, 1, &c->keyblock); if (err) { /* getkey_byname might return a keyblock even in the |