From a15ed5a1fd5307b3ec1822daf3b138b187db0b5e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 27 Oct 2016 08:44:19 +0200 Subject: [PATCH] gpg: Convey --quick option to dirmngr for --auto-key-retrieve. * g10/call-dirmngr.c (gpg_dirmngr_ks_get): Add arg 'quick'. (gpg_dirmngr_wkd_get): Ditto. * g10/keyserver.c (keyserver_get): Add arg 'quick'. (keyserver_get_chunk): Add arg 'quick'. (keyserver_import_fprint): Ditto. Change callers to pass 0 for it. (keyserver_import_keyid): Ditto. (keyserver_import_wkd): Ditto. * g10/mainproc.c (check_sig_and_print): Call the 3 fucntions with QUICK set. -- Note that this option has not yet been implemented by dirmngr. Dirmngr will simply ignore it for now. Signed-off-by: Werner Koch --- g10/call-dirmngr.c | 14 +++++++------ g10/call-dirmngr.h | 4 ++-- g10/card-util.c | 2 +- g10/getkey.c | 2 +- g10/gpgv.c | 9 +++++--- g10/import.c | 2 +- g10/keyserver-internal.h | 6 +++--- g10/keyserver.c | 44 ++++++++++++++++++++++------------------ g10/mainproc.c | 15 +++++++------- g10/test-stubs.c | 9 +++++--- 10 files changed, 59 insertions(+), 48 deletions(-) diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index 75a7f4650..f7398333c 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -600,6 +600,8 @@ ks_get_data_cb (void *opaque, const void *data, size_t datalen) don't need to escape the patterns before sending them to the server. + If QUICK is set the dirmngr is advised to use a shorter timeout. + If R_SOURCE is not NULL the source of the data is stored as a malloced string there. If a source is not known NULL is stored. @@ -609,7 +611,7 @@ ks_get_data_cb (void *opaque, const void *data, size_t datalen) are able to ask for (1000-10-1)/(2+8+1) = 90 keys at once. */ gpg_error_t gpg_dirmngr_ks_get (ctrl_t ctrl, char **pattern, - keyserver_spec_t override_keyserver, + keyserver_spec_t override_keyserver, int quick, estream_t *r_fp, char **r_source) { gpg_error_t err; @@ -655,7 +657,7 @@ gpg_dirmngr_ks_get (ctrl_t ctrl, char **pattern, /* Lump all patterns into one string. */ init_membuf (&mb, 1024); - put_membuf_str (&mb, "KS_GET --"); + put_membuf_str (&mb, quick? "KS_GET --quick --" : "KS_GET --"); for (idx=0; pattern[idx]; idx++) { put_membuf (&mb, " ", 1); /* Append Delimiter. */ @@ -1289,11 +1291,11 @@ gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid, /* Ask the dirmngr to retrieve a key via the Web Key Directory - * protocol. On success a new estream with the key is stored at - * R_KEY. + * protocol. If QUICK is set the dirmngr is advised to use a shorter + * timeout. On success a new estream with the key is stored at R_KEY. */ gpg_error_t -gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, estream_t *r_key) +gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, int quick, estream_t *r_key) { gpg_error_t err; assuan_context_t ctx; @@ -1306,7 +1308,7 @@ gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, estream_t *r_key) if (err) return err; - line = es_bsprintf ("WKD_GET -- %s", name); + line = es_bsprintf ("WKD_GET%s -- %s", quick?" --quick":"", name); if (!line) { err = gpg_error_from_syserror (); diff --git a/g10/call-dirmngr.h b/g10/call-dirmngr.h index 4dc1e3020..f15459851 100644 --- a/g10/call-dirmngr.h +++ b/g10/call-dirmngr.h @@ -26,7 +26,7 @@ gpg_error_t gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr, gpg_error_t (*cb)(void*, int, char *), void *cb_value); gpg_error_t gpg_dirmngr_ks_get (ctrl_t ctrl, char *pattern[], - keyserver_spec_t override_keyserver, + keyserver_spec_t override_keyserver, int quick, estream_t *r_fp, char **r_source); gpg_error_t gpg_dirmngr_ks_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp); @@ -40,7 +40,7 @@ gpg_error_t gpg_dirmngr_dns_cert (ctrl_t ctrl, gpg_error_t gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid, unsigned char **r_fpr, size_t *r_fprlen, char **r_url); -gpg_error_t gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, +gpg_error_t gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, int quick, estream_t *r_key); diff --git a/g10/card-util.c b/g10/card-util.c index b5fe84bb1..b322a8617 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -758,7 +758,7 @@ fetch_url (ctrl_t ctrl) } else if (info.fpr1valid) { - rc = keyserver_import_fprint (ctrl, info.fpr1, 20, opt.keyserver); + rc = keyserver_import_fprint (ctrl, info.fpr1, 20, opt.keyserver, 0); } } diff --git a/g10/getkey.c b/g10/getkey.c index 8b1759882..7b1c22bd8 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1333,7 +1333,7 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk, case AKL_WKD: mechanism = "WKD"; glo_ctrl.in_auto_key_retrieve++; - rc = keyserver_import_wkd (ctrl, name, &fpr, &fpr_len); + rc = keyserver_import_wkd (ctrl, name, 0, &fpr, &fpr_len); glo_ctrl.in_auto_key_retrieve--; break; diff --git a/g10/gpgv.c b/g10/gpgv.c index 2f34e72f1..01138a054 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -358,21 +358,23 @@ keyserver_any_configured (ctrl_t ctrl) } int -keyserver_import_keyid (u32 *keyid, void *dummy) +keyserver_import_keyid (u32 *keyid, void *dummy, int quick) { (void)keyid; (void)dummy; + (void)quick; return -1; } int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len, - struct keyserver_spec *keyserver) + struct keyserver_spec *keyserver, int quick) { (void)ctrl; (void)fprint; (void)fprint_len; (void)keyserver; + (void)quick; return -1; } @@ -392,11 +394,12 @@ keyserver_import_pka (const char *name,unsigned char *fpr) } gpg_error_t -keyserver_import_wkd (ctrl_t ctrl, const char *name, +keyserver_import_wkd (ctrl_t ctrl, const char *name, int quick, unsigned char **fpr, size_t *fpr_len) { (void)ctrl; (void)name; + (void)quick; (void)fpr; (void)fpr_len; return GPG_ERR_BUG; diff --git a/g10/import.c b/g10/import.c index 8d064578b..d65a7ae4c 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2954,7 +2954,7 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) keyserver_import_fprint (ctrl, sig->revkey[idx].fpr, MAX_FINGERPRINT_LEN, - opt.keyserver); + opt.keyserver, 0); /* Do we have it now? */ rc=get_pubkey_byfprint_fast (NULL, diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h index f57dcaa53..6988ae08c 100644 --- a/g10/keyserver-internal.h +++ b/g10/keyserver-internal.h @@ -35,9 +35,9 @@ int keyserver_any_configured (ctrl_t ctrl); int keyserver_export (ctrl_t ctrl, strlist_t users); int keyserver_import (ctrl_t ctrl, strlist_t users); int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len, - struct keyserver_spec *keyserver); + struct keyserver_spec *keyserver, int quick); int keyserver_import_keyid (ctrl_t ctrl, u32 *keyid, - struct keyserver_spec *keyserver); + struct keyserver_spec *keyserver, int quick); gpg_error_t keyserver_refresh (ctrl_t ctrl, strlist_t users); gpg_error_t keyserver_search (ctrl_t ctrl, strlist_t tokens); int keyserver_fetch (ctrl_t ctrl, strlist_t urilist); @@ -45,7 +45,7 @@ int keyserver_import_cert (ctrl_t ctrl, const char *name, int dane_mode, unsigned char **fpr,size_t *fpr_len); gpg_error_t keyserver_import_pka (ctrl_t ctrl, const char *name, unsigned char **fpr,size_t *fpr_len); -gpg_error_t keyserver_import_wkd (ctrl_t ctrl, const char *name, +gpg_error_t keyserver_import_wkd (ctrl_t ctrl, const char *name, int quick, unsigned char **fpr, size_t *fpr_len); int keyserver_import_name (ctrl_t ctrl, const char *name,unsigned char **fpr,size_t *fpr_len, diff --git a/g10/keyserver.c b/g10/keyserver.c index 4239469f0..d98351cd2 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -108,6 +108,7 @@ static struct parse_options keyserver_opts[]= static gpg_error_t keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, struct keyserver_spec *override_keyserver, + int quick, unsigned char **r_fpr, size_t *r_fprlen); static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs); @@ -793,7 +794,7 @@ show_prompt (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int numdesc, } for (idx = 0; idx < numidx; idx++) selarray[idx] = desc[numarray[idx]-1]; - err = keyserver_get (ctrl, selarray, numidx, NULL, NULL, NULL); + err = keyserver_get (ctrl, selarray, numidx, NULL, 0, NULL, NULL); xfree (selarray); } } @@ -1125,7 +1126,7 @@ keyserver_import (ctrl_t ctrl, strlist_t users) } if(count>0) - rc=keyserver_get (ctrl, desc, count, NULL, NULL, NULL); + rc = keyserver_get (ctrl, desc, count, NULL, 0, NULL, NULL); xfree(desc); @@ -1154,13 +1155,13 @@ keyserver_import_name (ctrl_t ctrl, const char *name, desc.mode = KEYDB_SEARCH_MODE_EXACT; desc.u.name = name; - return keyserver_get (ctrl, &desc, 1, keyserver, fpr, fprlen); + return keyserver_get (ctrl, &desc, 1, keyserver, 0, fpr, fprlen); } int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len, - struct keyserver_spec *keyserver) + struct keyserver_spec *keyserver, int quick) { KEYDB_SEARCH_DESC desc; @@ -1177,12 +1178,12 @@ keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len, /* TODO: Warn here if the fingerprint we got doesn't match the one we asked for? */ - return keyserver_get (ctrl, &desc, 1, keyserver, NULL, NULL); + return keyserver_get (ctrl, &desc, 1, keyserver, quick, NULL, NULL); } int keyserver_import_keyid (ctrl_t ctrl, - u32 *keyid,struct keyserver_spec *keyserver) + u32 *keyid,struct keyserver_spec *keyserver, int quick) { KEYDB_SEARCH_DESC desc; @@ -1192,7 +1193,7 @@ keyserver_import_keyid (ctrl_t ctrl, desc.u.kid[0]=keyid[0]; desc.u.kid[1]=keyid[1]; - return keyserver_get (ctrl, &desc,1, keyserver, NULL, NULL); + return keyserver_get (ctrl, &desc, 1, keyserver, quick, NULL, NULL); } /* code mostly stolen from do_export_stream */ @@ -1422,7 +1423,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users) /* We use the keyserver structure we parsed out before. Note that a preferred keyserver without a scheme:// will be interpreted as hkp:// */ - err = keyserver_get (ctrl, &desc[i], 1, keyserver, NULL, NULL); + err = keyserver_get (ctrl, &desc[i], 1, keyserver, 0, NULL, NULL); if (err) log_info(_("WARNING: unable to refresh key %s" " via %s: %s\n"),keystr_from_desc(&desc[i]), @@ -1456,7 +1457,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users) } xfree (tmpuri); - err = keyserver_get (ctrl, desc, numdesc, NULL, NULL, NULL); + err = keyserver_get (ctrl, desc, numdesc, NULL, 0, NULL, NULL); } } @@ -1581,6 +1582,7 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, int *r_ndesc_used, import_stats_t stats_handle, struct keyserver_spec *override_keyserver, + int quick, unsigned char **r_fpr, size_t *r_fprlen) { @@ -1604,11 +1606,11 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, /* Note that we break the loop as soon as our estimation of the to be used line length reaches the limit. But we do this only if we - have processed at leas one search requests so that an overlong + have processed at least one search requests so that an overlong single request will be rejected only later by gpg_dirmngr_ks_get but we are sure that R_NDESC_USED has been updated. This avoids a possible indefinite loop. */ - linelen = 9; /* "KS_GET --" */ + linelen = 17; /* "KS_GET --quick --" */ for (npat=idx=0; idx < ndesc; idx++) { int quiet = 0; @@ -1712,7 +1714,7 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, this is different from NPAT. */ *r_ndesc_used = idx; - err = gpg_dirmngr_ks_get (ctrl, pattern, override_keyserver, + err = gpg_dirmngr_ks_get (ctrl, pattern, override_keyserver, quick, &datastream, &source); for (idx=0; idx < npat; idx++) xfree (pattern[idx]); @@ -1755,10 +1757,11 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, (DESC,NDESC). Allowed search modes are keyid, fingerprint, and exact searches. OVERRIDE_KEYSERVER gives an optional override keyserver. If (R_FPR,R_FPRLEN) are not NULL, they may return the - fingerprint of a single imported key. */ + fingerprint of a single imported key. If QUICK is set, dirmngr is + advised to use a shorter timeout. */ static gpg_error_t keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, - struct keyserver_spec *override_keyserver, + struct keyserver_spec *override_keyserver, int quick, unsigned char **r_fpr, size_t *r_fprlen) { gpg_error_t err; @@ -1771,7 +1774,7 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, for (;;) { err = keyserver_get_chunk (ctrl, desc, ndesc, &ndesc_used, stats_handle, - override_keyserver, r_fpr, r_fprlen); + override_keyserver, quick, r_fpr, r_fprlen); if (!err) any_good = 1; if (err || ndesc_used >= ndesc) @@ -1946,7 +1949,7 @@ keyserver_import_cert (ctrl_t ctrl, const char *name, int dane_mode, spec = parse_keyserver_uri (url, 1); if(spec) { - err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,spec); + err = keyserver_import_fprint (ctrl, *fpr, *fpr_len, spec, 0); free_keyserver_spec(spec); } } @@ -1955,7 +1958,8 @@ keyserver_import_cert (ctrl_t ctrl, const char *name, int dane_mode, /* If only a fingerprint is provided, try and fetch it from the configured keyserver. */ - err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver); + err = keyserver_import_fprint (ctrl, + *fpr, *fpr_len, opt.keyserver, 0); } else log_info(_("no keyserver known\n")); @@ -1989,7 +1993,7 @@ keyserver_import_pka (ctrl_t ctrl, const char *name, spec = parse_keyserver_uri (url, 1); if (spec) { - err = keyserver_import_fprint (ctrl, *fpr, *fpr_len, spec); + err = keyserver_import_fprint (ctrl, *fpr, *fpr_len, spec, 0); free_keyserver_spec (spec); } } @@ -2008,7 +2012,7 @@ keyserver_import_pka (ctrl_t ctrl, const char *name, /* Import a key using the Web Key Directory protocol. */ gpg_error_t -keyserver_import_wkd (ctrl_t ctrl, const char *name, +keyserver_import_wkd (ctrl_t ctrl, const char *name, int quick, unsigned char **fpr, size_t *fpr_len) { gpg_error_t err; @@ -2026,7 +2030,7 @@ keyserver_import_wkd (ctrl_t ctrl, const char *name, return err; } - err = gpg_dirmngr_wkd_get (ctrl, mbox, &key); + err = gpg_dirmngr_wkd_get (ctrl, mbox, quick, &key); if (err) ; else if (key) diff --git a/g10/mainproc.c b/g10/mainproc.c index f0527bc6e..fbcf316ac 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1803,7 +1803,7 @@ check_sig_and_print (CTX c, kbnode_t node) free_public_key (pk); pk = NULL; glo_ctrl.in_auto_key_retrieve++; - res = keyserver_import_keyid (c->ctrl, sig->keyid,spec); + res = keyserver_import_keyid (c->ctrl, sig->keyid,spec, 1); glo_ctrl.in_auto_key_retrieve--; if (!res) rc = do_check_sig (c, node, NULL, @@ -1838,7 +1838,7 @@ check_sig_and_print (CTX c, kbnode_t node) free_public_key (pk); pk = NULL; glo_ctrl.in_auto_key_retrieve++; - res = keyserver_import_keyid (c->ctrl, sig->keyid, spec); + res = keyserver_import_keyid (c->ctrl, sig->keyid, spec, 1); glo_ctrl.in_auto_key_retrieve--; free_keyserver_spec (spec); if (!res) @@ -1847,12 +1847,11 @@ check_sig_and_print (CTX c, kbnode_t node) } } - /* If the above methods didn't work, our next try is to use locate + /* If the above methods didn't work, our next try is to locate * the key via its fingerprint from a keyserver. This requires * that the signers fingerprint is encoded in the signature. We * favor this over the WKD method (to be tried next), because an - * arbitrary keyserver is less subject to web bug like - * monitoring. */ + * arbitrary keyserver is less subject to web bug like monitoring. */ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY && opt.flags.rfc4880bis && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE) @@ -1869,7 +1868,7 @@ check_sig_and_print (CTX c, kbnode_t node) free_public_key (pk); pk = NULL; glo_ctrl.in_auto_key_retrieve++; - res = keyserver_import_fprint (c->ctrl, p+1, n-1, opt.keyserver); + res = keyserver_import_fprint (c->ctrl, p+1, n-1, opt.keyserver, 1); glo_ctrl.in_auto_key_retrieve--; if (!res) rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey, &pk); @@ -1889,7 +1888,7 @@ check_sig_and_print (CTX c, kbnode_t node) free_public_key (pk); pk = NULL; glo_ctrl.in_auto_key_retrieve++; - res = keyserver_import_wkd (c->ctrl, sig->signers_uid, NULL, NULL); + res = keyserver_import_wkd (c->ctrl, sig->signers_uid, 1, NULL, NULL); glo_ctrl.in_auto_key_retrieve--; /* Fixme: If the fingerprint is embedded in the signature, * compare it to the fingerprint of the returned key. */ @@ -1908,7 +1907,7 @@ check_sig_and_print (CTX c, kbnode_t node) free_public_key (pk); pk = NULL; glo_ctrl.in_auto_key_retrieve++; - res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver ); + res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver, 1); glo_ctrl.in_auto_key_retrieve--; if (!res) rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey, &pk); diff --git a/g10/test-stubs.c b/g10/test-stubs.c index 55351b815..c717cff8c 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -169,21 +169,23 @@ keyserver_any_configured (ctrl_t ctrl) } int -keyserver_import_keyid (u32 *keyid, void *dummy) +keyserver_import_keyid (u32 *keyid, void *dummy, int quick) { (void)keyid; (void)dummy; + (void)quick; return -1; } int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len, - struct keyserver_spec *keyserver) + struct keyserver_spec *keyserver, int quick) { (void)ctrl; (void)fprint; (void)fprint_len; (void)keyserver; + (void)quick; return -1; } @@ -203,11 +205,12 @@ keyserver_import_pka (const char *name,unsigned char *fpr) } gpg_error_t -keyserver_import_wkd (ctrl_t ctrl, const char *name, +keyserver_import_wkd (ctrl_t ctrl, const char *name, int quick, unsigned char **fpr, size_t *fpr_len) { (void)ctrl; (void)name; + (void)quick; (void)fpr; (void)fpr_len; return GPG_ERR_BUG;