mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-21 14:47:03 +01:00
gpg: Make --auto-key-locate work again with keyservers.
* dirmngr/ks-engine-hkp.c (ks_hkp_get): Allow exact search mode. * g10/keyserver.c (keyserver_import_name): Implement. (keyserver_get): Use exact mode for name based import. (keyserver_get): Add args R_FPR and R_FPRLEN. Change all callers.
This commit is contained in:
parent
1d642d3ca8
commit
1e2e39c575
@ -1040,7 +1040,9 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
|
||||
{
|
||||
gpg_error_t err;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
char kidbuf[40+1];
|
||||
char kidbuf[2+40+1];
|
||||
const char *exactname = NULL;
|
||||
char *searchkey = NULL;
|
||||
char *hostport = NULL;
|
||||
char *request = NULL;
|
||||
estream_t fp = NULL;
|
||||
@ -1060,16 +1062,22 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
|
||||
switch (desc.mode)
|
||||
{
|
||||
case KEYDB_SEARCH_MODE_SHORT_KID:
|
||||
snprintf (kidbuf, sizeof kidbuf, "%08lX", (ulong)desc.u.kid[1]);
|
||||
snprintf (kidbuf, sizeof kidbuf, "0x%08lX", (ulong)desc.u.kid[1]);
|
||||
break;
|
||||
case KEYDB_SEARCH_MODE_LONG_KID:
|
||||
snprintf (kidbuf, sizeof kidbuf, "%08lX%08lX",
|
||||
snprintf (kidbuf, sizeof kidbuf, "0x%08lX%08lX",
|
||||
(ulong)desc.u.kid[0], (ulong)desc.u.kid[1]);
|
||||
break;
|
||||
case KEYDB_SEARCH_MODE_FPR20:
|
||||
case KEYDB_SEARCH_MODE_FPR:
|
||||
/* This is a v4 fingerprint. */
|
||||
bin2hex (desc.u.fpr, 20, kidbuf);
|
||||
kidbuf[0] = '0';
|
||||
kidbuf[1] = 'x';
|
||||
bin2hex (desc.u.fpr, 20, kidbuf+2);
|
||||
break;
|
||||
|
||||
case KEYDB_SEARCH_MODE_EXACT:
|
||||
exactname = desc.u.name;
|
||||
break;
|
||||
|
||||
case KEYDB_SEARCH_MODE_FPR16:
|
||||
@ -1078,6 +1086,14 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
|
||||
return gpg_error (GPG_ERR_INV_USER_ID);
|
||||
}
|
||||
|
||||
searchkey = http_escape_string (exactname? exactname : kidbuf,
|
||||
EXTRA_ESCAPE_CHARS);
|
||||
if (!searchkey)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
|
||||
reselect = 0;
|
||||
again:
|
||||
/* Build the request string. */
|
||||
@ -1092,8 +1108,9 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
|
||||
|
||||
xfree (request);
|
||||
request = strconcat (hostport,
|
||||
"/pks/lookup?op=get&options=mr&search=0x",
|
||||
kidbuf,
|
||||
"/pks/lookup?op=get&options=mr&search=",
|
||||
searchkey,
|
||||
exactname? "&exact=on":"",
|
||||
NULL);
|
||||
if (!request)
|
||||
{
|
||||
@ -1123,6 +1140,7 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
|
||||
es_fclose (fp);
|
||||
xfree (request);
|
||||
xfree (hostport);
|
||||
xfree (searchkey);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1603,7 +1603,8 @@ static const char hlp_ks_get[] =
|
||||
"KS_GET {<pattern>}\n"
|
||||
"\n"
|
||||
"Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
|
||||
"(see command KEYSERVER). Each pattern should be a keyid or a fingerprint";
|
||||
"(see command KEYSERVER). Each pattern should be a keyid, a fingerprint,\n"
|
||||
"or an exact name indicastes by the '=' prefix.";
|
||||
static gpg_error_t
|
||||
cmd_ks_get (assuan_context_t ctx, char *line)
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* keyserver.c - generic keyserver code
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||
* 2009, 2011, 2012 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2014 Werner Koch
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -110,7 +111,8 @@ 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 *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);
|
||||
|
||||
@ -819,7 +821,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);
|
||||
err = keyserver_get (ctrl, selarray, numidx, NULL, NULL, NULL);
|
||||
xfree (selarray);
|
||||
}
|
||||
}
|
||||
@ -1039,6 +1041,7 @@ keyserver_export (ctrl_t ctrl, strlist_t users)
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
keyserver_import (ctrl_t ctrl, strlist_t users)
|
||||
{
|
||||
@ -1071,13 +1074,31 @@ keyserver_import (ctrl_t ctrl, strlist_t users)
|
||||
}
|
||||
|
||||
if(count>0)
|
||||
rc=keyserver_get (ctrl, desc, count, NULL);
|
||||
rc=keyserver_get (ctrl, desc, count, NULL, NULL, NULL);
|
||||
|
||||
xfree(desc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Import all keys that exactly match NAME */
|
||||
int
|
||||
keyserver_import_name (ctrl_t ctrl, const char *name,
|
||||
unsigned char **fpr, size_t *fprlen,
|
||||
struct keyserver_spec *keyserver)
|
||||
{
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
|
||||
memset (&desc, 0, sizeof desc);
|
||||
|
||||
desc.mode = KEYDB_SEARCH_MODE_EXACT;
|
||||
desc.u.name = name;
|
||||
|
||||
return keyserver_get (ctrl, &desc, 1, keyserver, fpr, fprlen);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
@ -1097,7 +1118,7 @@ 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);
|
||||
return keyserver_get (ctrl, &desc, 1, keyserver, NULL, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1112,7 +1133,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);
|
||||
return keyserver_get (ctrl, &desc,1, keyserver, NULL, NULL);
|
||||
}
|
||||
|
||||
/* code mostly stolen from do_export_stream */
|
||||
@ -1316,7 +1337,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:// */
|
||||
rc = keyserver_get (ctrl, &desc[i], 1, keyserver);
|
||||
rc = keyserver_get (ctrl, &desc[i], 1, keyserver, NULL, NULL);
|
||||
if(rc)
|
||||
log_info(_("WARNING: unable to refresh key %s"
|
||||
" via %s: %s\n"),keystr_from_desc(&desc[i]),
|
||||
@ -1346,7 +1367,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
|
||||
count,opt.keyserver->uri);
|
||||
}
|
||||
|
||||
rc=keyserver_get (ctrl, desc, numdesc, NULL);
|
||||
rc=keyserver_get (ctrl, desc, numdesc, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
xfree(desc);
|
||||
@ -1469,21 +1490,15 @@ keyserver_search (ctrl_t ctrl, strlist_t tokens)
|
||||
|
||||
|
||||
|
||||
/* Called using:
|
||||
|
||||
import_name:
|
||||
rc = keyserver_work (ctrl, KS_GETNAME, list, NULL,
|
||||
0, fpr, fpr_len, keyserver);
|
||||
|
||||
import_ldap:
|
||||
rc = keyserver_work (ctrl, KS_GETNAME, list, NULL,
|
||||
0, fpr, fpr_len, keyserver);
|
||||
|
||||
*/
|
||||
|
||||
/* 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, the may retrun the fingerprint of
|
||||
one imported key. */
|
||||
static gpg_error_t
|
||||
keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
|
||||
struct keyserver_spec *keyserver)
|
||||
struct keyserver_spec *keyserver,
|
||||
unsigned char **r_fpr, size_t *r_fprlen)
|
||||
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
@ -1536,10 +1551,12 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
|
||||
}
|
||||
else if(desc[idx].mode == KEYDB_SEARCH_MODE_EXACT)
|
||||
{
|
||||
/* FIXME: We don't need this. It is used as a dummy by
|
||||
keyserver_fetch which passes an entire URL. Better use a
|
||||
separate function here. */
|
||||
pattern[npat] = xtrystrdup ("0x0000000000000000");
|
||||
/* The Dirmngr uses also classify_user_id to detect the type
|
||||
of the search string. By adding the '=' prefix we force
|
||||
Dirmngr's KS_GET to consider this an exact search string.
|
||||
(In gpg 1.4 and gpg 2.0 the keyserver helpers used the
|
||||
KS_GETNAME command to indicate this.) */
|
||||
pattern[npat] = strconcat ("=", desc[idx].u.name, NULL);
|
||||
if (!pattern[npat])
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
@ -1578,7 +1595,7 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
|
||||
for (idx=0; idx < npat; idx++)
|
||||
xfree (pattern[idx]);
|
||||
xfree (pattern);
|
||||
if (opt.verbose)
|
||||
if (opt.verbose && source)
|
||||
log_info ("data source: %s\n", source);
|
||||
|
||||
if (!err)
|
||||
@ -1599,7 +1616,8 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
|
||||
never accept or send them but we better protect against rogue
|
||||
keyservers. */
|
||||
|
||||
import_keys_es_stream (ctrl, datastream, stats_handle, NULL, NULL,
|
||||
import_keys_es_stream (ctrl, datastream, stats_handle,
|
||||
r_fpr, r_fprlen,
|
||||
(opt.keyserver_options.import_options
|
||||
| IMPORT_NO_SECKEY));
|
||||
import_print_stats (stats_handle);
|
||||
@ -1824,31 +1842,18 @@ keyserver_import_pka (ctrl_t ctrl,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Import all keys that match name */
|
||||
int
|
||||
keyserver_import_name (ctrl_t ctrl, const char *name,
|
||||
unsigned char **fpr, size_t *fpr_len,
|
||||
struct keyserver_spec *keyserver)
|
||||
{
|
||||
strlist_t list=NULL;
|
||||
int rc;
|
||||
|
||||
append_to_strlist(&list,name);
|
||||
|
||||
rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); /* FIXME */
|
||||
/* keyserver_work (ctrl, KS_GETNAME, list, NULL, */
|
||||
/* 0, fpr, fpr_len, keyserver); */
|
||||
|
||||
free_strlist(list);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Import a key by name using LDAP */
|
||||
int
|
||||
keyserver_import_ldap (ctrl_t ctrl,
|
||||
const char *name,unsigned char **fpr,size_t *fpr_len)
|
||||
const char *name, unsigned char **fpr, size_t *fprlen)
|
||||
{
|
||||
(void)ctrl;
|
||||
(void)name;
|
||||
(void)fpr;
|
||||
(void)fprlen;
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED); /*FIXME*/
|
||||
#if 0
|
||||
char *domain;
|
||||
struct keyserver_spec *keyserver;
|
||||
strlist_t list=NULL;
|
||||
@ -1919,4 +1924,5 @@ keyserver_import_ldap (ctrl_t ctrl,
|
||||
free_keyserver_spec(keyserver);
|
||||
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user