summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2015-04-21 15:36:30 +0200
committerWerner Koch <wk@gnupg.org>2015-04-21 15:36:30 +0200
commitae0d65f86413a82a40cf68e08aaeca405eee8c78 (patch)
treec51cdde4b074822cce9e4f4ebe3b31f01a93af97 /g10
parentgpg: Update sub-options of --keyserver-options (diff)
downloadgnupg2-ae0d65f86413a82a40cf68e08aaeca405eee8c78.tar.xz
gnupg2-ae0d65f86413a82a40cf68e08aaeca405eee8c78.zip
gpg: Make preferred keyservers work.
* g10/call-dirmngr.c (dirmngr_local_s): Add field set_keyservers_done. (create_context): Move keyserver setting to ... (open_context): here. (clear_context_flags): New. (gpg_dirmngr_ks_get): Add arg override_keyserver. * g10/keyserver.c (keyserver_refresh): Improve diagnostics. (keyserver_get_chunk): Ditto. Pass OVERRIDE_KEYSERVER to ks_get. -- It used to ignore the given server but showed a diagnostics that it will be used.
Diffstat (limited to '')
-rw-r--r--g10/call-dirmngr.c107
-rw-r--r--g10/call-dirmngr.h1
-rw-r--r--g10/keyserver.c30
3 files changed, 102 insertions, 36 deletions
diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
index ef4ca7651..26955abbf 100644
--- a/g10/call-dirmngr.c
+++ b/g10/call-dirmngr.c
@@ -94,6 +94,9 @@ struct dirmngr_local_s
/* The active Assuan context. */
assuan_context_t ctx;
+ /* Flag set when the keyserver names have been send. */
+ int set_keyservers_done;
+
/* Flag set to true while an operation is running on CTX. */
int is_active;
};
@@ -145,32 +148,9 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
}
else if (!err)
{
- keyserver_spec_t ksi;
-
/* Tell the dirmngr that we want to collect audit event. */
/* err = assuan_transact (agent_ctx, "OPTION audit-events=1", */
/* NULL, NULL, NULL, NULL, NULL, NULL); */
-
- /* Set all configured keyservers. We clear existing keyservers
- so that any keyserver configured in GPG overrides keyservers
- possibly still configured in Dirmngr for the session (Note
- that the keyserver list of a session in Dirmngr survives a
- RESET. */
- for (ksi = opt.keyserver; !err && ksi; ksi = ksi->next)
- {
- char *line;
-
- line = xtryasprintf ("KEYSERVER%s %s",
- ksi == opt.keyserver? " --clear":"", ksi->uri);
- if (!line)
- err = gpg_error_from_syserror ();
- else
- {
- err = assuan_transact (ctx, line,
- NULL, NULL, NULL, NULL, NULL, NULL);
- xfree (line);
- }
- }
}
if (err)
@@ -205,7 +185,42 @@ open_context (ctrl_t ctrl, assuan_context_t *r_ctx)
{
/* Found an inactive local session - return that. */
assert (!dml->is_active);
+
+ /* But first do the per session init if not yet done. */
+ if (!dml->set_keyservers_done)
+ {
+ keyserver_spec_t ksi;
+
+ /* Set all configured keyservers. We clear existing
+ keyservers so that any keyserver configured in GPG
+ overrides keyservers possibly still configured in Dirmngr
+ for the session (Note that the keyserver list of a
+ session in Dirmngr survives a RESET. */
+ for (ksi = opt.keyserver; ksi; ksi = ksi->next)
+ {
+ char *line;
+
+ line = xtryasprintf
+ ("KEYSERVER%s %s",
+ ksi == opt.keyserver? " --clear":"", ksi->uri);
+ if (!line)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ err = assuan_transact (dml->ctx, line, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ xfree (line);
+ }
+
+ if (err)
+ return err;
+ }
+
+ dml->set_keyservers_done = 1;
+ }
+
dml->is_active = 1;
+
*r_ctx = dml->ctx;
return 0;
}
@@ -219,6 +234,7 @@ open_context (ctrl_t ctrl, assuan_context_t *r_ctx)
xfree (dml);
return err;
}
+
/* To be on the nPth thread safe site we need to add it to a
list; this is far easier than to have a lock for this
function. It should not happen anyway but the code is free
@@ -253,6 +269,29 @@ close_context (ctrl_t ctrl, assuan_context_t ctx)
}
+/* Clear the set_keyservers_done flag on context CTX. */
+static void
+clear_context_flags (ctrl_t ctrl, assuan_context_t ctx)
+{
+ dirmngr_local_t dml;
+
+ if (!ctx)
+ return;
+
+ for (dml = ctrl->dirmngr_local; dml; dml = dml->next)
+ {
+ if (dml->ctx == ctx)
+ {
+ if (!dml->is_active)
+ log_fatal ("clear_context_flags on inactive dirmngr ctx %p\n", ctx);
+ dml->set_keyservers_done = 0;
+ return;
+ }
+ }
+ log_fatal ("clear_context_flags on unknown dirmngr ctx %p\n", ctx);
+}
+
+
/* Status callback for ks_get and ks_search. */
static gpg_error_t
@@ -453,6 +492,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,
estream_t *r_fp, char **r_source)
{
gpg_error_t err;
@@ -475,6 +515,27 @@ gpg_dirmngr_ks_get (ctrl_t ctrl, char **pattern,
if (err)
return err;
+ /* If we have an override keyserver we first indicate that the next
+ user of the context needs to again setup the global keyservers and
+ them we send the override keyserver. */
+ if (override_keyserver)
+ {
+ clear_context_flags (ctrl, ctx);
+ line = xtryasprintf ("KEYSERVER --clear %s", override_keyserver->uri);
+ if (!line)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ err = assuan_transact (ctx, line, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ if (err)
+ goto leave;
+
+ xfree (line);
+ line = NULL;
+ }
+
/* Lump all patterns into one string. */
init_membuf (&mb, 1024);
put_membuf_str (&mb, "KS_GET --");
diff --git a/g10/call-dirmngr.h b/g10/call-dirmngr.h
index 481b948d9..bae11238c 100644
--- a/g10/call-dirmngr.h
+++ b/g10/call-dirmngr.h
@@ -25,6 +25,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,
estream_t *r_fp, char **r_source);
gpg_error_t gpg_dirmngr_ks_fetch (ctrl_t ctrl,
const char *url, estream_t *r_fp);
diff --git a/g10/keyserver.c b/g10/keyserver.c
index 3aed54bc9..674eb8119 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -112,7 +112,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 *keyserver,
+ struct keyserver_spec *override_keyserver,
unsigned char **r_fpr, size_t *r_fprlen);
static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
struct keyserver_spec *keyserver);
@@ -1394,6 +1394,9 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
{
struct keyserver_spec *keyserver=desc[i].skipfncvalue;
+ if (!opt.quiet)
+ log_info (_("refreshing 1 key from %s\n"), keyserver->uri);
+
/* We use the keyserver structure we parsed out before.
Note that a preferred keyserver without a scheme://
will be interpreted as hkp:// */
@@ -1418,7 +1421,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
if(count>0)
{
- if(opt.keyserver)
+ if(opt.keyserver && !opt.quiet)
{
if(count==1)
log_info(_("refreshing 1 key from %s\n"),opt.keyserver->uri);
@@ -1556,7 +1559,7 @@ static gpg_error_t
keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
int *r_ndesc_used,
void *stats_handle,
- struct keyserver_spec *keyserver,
+ struct keyserver_spec *override_keyserver,
unsigned char **r_fpr, size_t *r_fprlen)
{
@@ -1672,15 +1675,15 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
return err;
}
- if (!quiet && keyserver)
+ if (!quiet && override_keyserver)
{
- if (keyserver->host)
+ if (override_keyserver->host)
log_info (_("requesting key %s from %s server %s\n"),
keystr_from_desc (&desc[idx]),
- keyserver->scheme, keyserver->host);
+ override_keyserver->scheme, override_keyserver->host);
else
log_info (_("requesting key %s from %s\n"),
- keystr_from_desc (&desc[idx]), keyserver->uri);
+ keystr_from_desc (&desc[idx]), override_keyserver->uri);
}
}
@@ -1688,7 +1691,8 @@ 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, &datastream, &source);
+ err = gpg_dirmngr_ks_get (ctrl, pattern, override_keyserver,
+ &datastream, &source);
for (idx=0; idx < npat; idx++)
xfree (pattern[idx]);
xfree (pattern);
@@ -1728,12 +1732,12 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
/* Retrieve a key from a keyserver. The search pattern are in
(DESC,NDESC). Allowed search modes are keyid, fingerprint, and
- exact searches. KEYSERVER gives an optional override keyserver. If
- (R_FPR,R_FPRLEN) are not NULL, they may return the fingerprint of a
- single imported key. */
+ 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. */
static gpg_error_t
keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
- struct keyserver_spec *keyserver,
+ struct keyserver_spec *override_keyserver,
unsigned char **r_fpr, size_t *r_fprlen)
{
gpg_error_t err;
@@ -1746,7 +1750,7 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
for (;;)
{
err = keyserver_get_chunk (ctrl, desc, ndesc, &ndesc_used, stats_handle,
- keyserver, r_fpr, r_fprlen);
+ override_keyserver, r_fpr, r_fprlen);
if (!err)
any_good = 1;
if (err || ndesc_used >= ndesc)