mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-02 21:11:05 +01:00
Add code for explicit selection of pooled A records.
To better cope with round robin pooled A records like keys.gnupg.net we need to keep some information on unresponsive hosts etc. What we do now is to resolve the hostnames, remember them and select a random one. If a host is dead it will be marked and a different one selected. This is intended to solve the problem of long timeouts due to unresponsive hosts. The code is not yet finished but selection works.
This commit is contained in:
parent
4206a2bd48
commit
f1e9f510ec
@ -1,3 +1,7 @@
|
||||
2011-04-01 Werner Koch <wk@g10code.com>
|
||||
|
||||
* sysutils.c (get_uint_nonce): New.
|
||||
|
||||
2011-03-03 Werner Koch <wk@g10code.com>
|
||||
|
||||
* estream.c (struct estream_list): Rename to estream_list_s and
|
||||
|
@ -150,6 +150,17 @@ get_session_marker (size_t *rlen)
|
||||
return marker;
|
||||
}
|
||||
|
||||
/* Return a random number in an unsigned int. */
|
||||
unsigned int
|
||||
get_uint_nonce (void)
|
||||
{
|
||||
unsigned int value;
|
||||
|
||||
gcry_create_nonce (&value, sizeof value);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0 /* not yet needed - Note that this will require inclusion of
|
||||
cmacros.am in Makefile.am */
|
||||
|
@ -41,6 +41,7 @@ void trap_unaligned (void);
|
||||
int disable_core_dumps (void);
|
||||
int enable_core_dumps (void);
|
||||
const unsigned char *get_session_marker (size_t *rlen);
|
||||
unsigned int get_uint_nonce (void);
|
||||
/*int check_permissions (const char *path,int extension,int checkonly);*/
|
||||
void gnupg_sleep (unsigned int seconds);
|
||||
int translate_sys2libc_fd (gnupg_fd_t fd, int for_write);
|
||||
|
@ -1,3 +1,13 @@
|
||||
2011-04-12 Werner Koch <wk@g10code.com>
|
||||
|
||||
* ks-engine-hkp.c (ks_hkp_search, ks_hkp_get, ks_hkp_put): Factor
|
||||
code out to ..
|
||||
(make_host_part): new.
|
||||
(hostinfo_s): New.
|
||||
(create_new_hostinfo, find_hostinfo, sort_hostpool)
|
||||
(select_random_host, map_host, mark_host_dead)
|
||||
(ks_hkp_print_hosttable): New.
|
||||
|
||||
2011-02-23 Werner Koch <wk@g10code.com>
|
||||
|
||||
* certcache.c (get_cert_bysubject): Take care of a NULL argument.
|
||||
|
@ -76,7 +76,7 @@ ks_action_help (ctrl_t ctrl, const char *url)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Call all engines to geive them a chance to print a help sting. */
|
||||
/* Call all engines to give them a chance to print a help sting. */
|
||||
err = ks_hkp_help (ctrl, parsed_uri);
|
||||
if (!err)
|
||||
err = ks_http_help (ctrl, parsed_uri);
|
||||
|
@ -17,12 +17,20 @@
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#warning fixme Windows part not yet done
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
# include <windows.h>
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netdb.h>
|
||||
#endif /*!HAVE_W32_SYSTEM*/
|
||||
|
||||
#include "dirmngr.h"
|
||||
#include "misc.h"
|
||||
@ -36,6 +44,359 @@
|
||||
/* How many redirections do we allow. */
|
||||
#define MAX_REDIRECTS 2
|
||||
|
||||
/* Objects used to maintain information about hosts. */
|
||||
struct hostinfo_s;
|
||||
typedef struct hostinfo_s *hostinfo_t;
|
||||
struct hostinfo_s
|
||||
{
|
||||
time_t lastfail; /* Time we tried to connect and failed. */
|
||||
time_t lastused; /* Time of last use. */
|
||||
int *pool; /* A -1 terminated array with indices into
|
||||
HOSTTABLE or NULL if NAME is not a pool
|
||||
name. */
|
||||
int poolidx; /* Index into POOL with the used host. */
|
||||
unsigned int v4:1; /* Host supports AF_INET. */
|
||||
unsigned int v6:1; /* Host supports AF_INET6. */
|
||||
unsigned int dead:1; /* Host is currently unresponsive. */
|
||||
char name[1]; /* The hostname. */
|
||||
};
|
||||
|
||||
|
||||
/* An array of hostinfo_t for all hosts requested by the caller or
|
||||
resolved from a pool name and its allocated size.*/
|
||||
static hostinfo_t *hosttable;
|
||||
static int hosttable_size;
|
||||
|
||||
/* The number of host slots we initally allocate for HOSTTABLE. */
|
||||
#define INITIAL_HOSTTABLE_SIZE 10
|
||||
|
||||
|
||||
/* Create a new hostinfo object, fill in NAME and put it into
|
||||
HOSTTABLE. Return the index into hosttable on success or -1 on
|
||||
error. */
|
||||
static int
|
||||
create_new_hostinfo (const char *name)
|
||||
{
|
||||
hostinfo_t hi, *newtable;
|
||||
int newsize;
|
||||
int idx, rc;
|
||||
|
||||
hi = xtrymalloc (sizeof *hi + strlen (name));
|
||||
if (!hi)
|
||||
return -1;
|
||||
strcpy (hi->name, name);
|
||||
hi->pool = NULL;
|
||||
hi->poolidx = -1;
|
||||
hi->lastused = (time_t)(-1);
|
||||
hi->lastfail = (time_t)(-1);
|
||||
hi->v4 = 0;
|
||||
hi->v6 = 0;
|
||||
|
||||
/* Add it to the hosttable. */
|
||||
for (idx=0; idx < hosttable_size; idx++)
|
||||
if (!hosttable[idx])
|
||||
{
|
||||
hosttable[idx] = hi;
|
||||
return idx;
|
||||
}
|
||||
/* Need to extend the hosttable. */
|
||||
newsize = hosttable_size + INITIAL_HOSTTABLE_SIZE;
|
||||
newtable = xtryrealloc (hosttable, newsize * sizeof *hosttable);
|
||||
if (!newtable)
|
||||
{
|
||||
xfree (hi);
|
||||
return -1;
|
||||
}
|
||||
hosttable = newtable;
|
||||
idx = hosttable_size;
|
||||
hosttable_size = newsize;
|
||||
rc = idx;
|
||||
hosttable[idx++] = hi;
|
||||
while (idx < hosttable_size)
|
||||
hosttable[idx++] = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Find the host NAME in our table. Return the index into the
|
||||
hosttable or -1 if not found. */
|
||||
static int
|
||||
find_hostinfo (const char *name)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx=0; idx < hosttable_size; idx++)
|
||||
if (hosttable[idx] && !ascii_strcasecmp (hosttable[idx]->name, name))
|
||||
return idx;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sort_hostpool (const void *xa, const void *xb)
|
||||
{
|
||||
int a = *(int *)xa;
|
||||
int b = *(int *)xb;
|
||||
|
||||
assert (a >= 0 && a < hosttable_size);
|
||||
assert (b >= 0 && b < hosttable_size);
|
||||
assert (hosttable[a]);
|
||||
assert (hosttable[b]);
|
||||
|
||||
return ascii_strcasecmp (hosttable[a]->name, hosttable[b]->name);
|
||||
}
|
||||
|
||||
|
||||
/* Select a random host. Consult TABLE which indices into the global
|
||||
hosttable. Returns index into TABLE or -1 if no host could be
|
||||
selected. */
|
||||
static int
|
||||
select_random_host (int *table)
|
||||
{
|
||||
int *tbl;
|
||||
size_t tblsize;
|
||||
int pidx, idx;
|
||||
|
||||
/* We create a new table so that we select only from currently alive
|
||||
hosts. */
|
||||
for (idx=0, tblsize=0; (pidx = table[idx]) != -1; idx++)
|
||||
if (hosttable[pidx] && !hosttable[pidx]->dead)
|
||||
tblsize++;
|
||||
if (!tblsize)
|
||||
return -1; /* No hosts. */
|
||||
|
||||
tbl = xtrymalloc (tblsize * sizeof *tbl);
|
||||
if (!tbl)
|
||||
return -1;
|
||||
for (idx=0, tblsize=0; (pidx = table[idx]) != -1; idx++)
|
||||
if (hosttable[pidx] && !hosttable[pidx]->dead)
|
||||
tbl[tblsize++] = pidx;
|
||||
|
||||
if (tblsize == 1) /* Save a get_uint_nonce. */
|
||||
pidx = tbl[0];
|
||||
else
|
||||
pidx = get_uint_nonce () % tblsize;
|
||||
|
||||
xfree (tbl);
|
||||
return pidx;
|
||||
}
|
||||
|
||||
|
||||
/* Map the host name NAME to the actual to be used host name. This
|
||||
allows us to manage round robin DNS names. We use our own strategy
|
||||
to choose one of the hosts. For example we skip those hosts which
|
||||
failed for some time and we stick to one host for a time
|
||||
independent of DNS retry times. */
|
||||
static char *
|
||||
map_host (const char *name)
|
||||
{
|
||||
hostinfo_t hi;
|
||||
int idx;
|
||||
|
||||
/* No hostname means localhost. */
|
||||
if (!name || !*name)
|
||||
return xtrystrdup ("localhost");
|
||||
|
||||
/* See whether the host is in our table. */
|
||||
idx = find_hostinfo (name);
|
||||
if (idx == -1)
|
||||
{
|
||||
/* We never saw this host. Allocate a new entry. */
|
||||
struct addrinfo hints, *aibuf, *ai;
|
||||
int *reftbl;
|
||||
size_t reftblsize;
|
||||
int refidx;
|
||||
|
||||
reftblsize = 100;
|
||||
reftbl = xmalloc (reftblsize * sizeof *reftbl);
|
||||
if (!reftbl)
|
||||
return NULL;
|
||||
refidx = 0;
|
||||
|
||||
idx = create_new_hostinfo (name);
|
||||
if (idx == -1)
|
||||
{
|
||||
xfree (reftbl);
|
||||
return NULL;
|
||||
}
|
||||
hi = hosttable[idx];
|
||||
|
||||
/* Find all A records for this entry and put them into the pool
|
||||
list - if any. */
|
||||
memset (&hints, 0, sizeof (hints));
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
if (!getaddrinfo (name, NULL, &hints, &aibuf))
|
||||
{
|
||||
for (ai = aibuf; ai; ai = ai->ai_next)
|
||||
{
|
||||
char tmphost[NI_MAXHOST];
|
||||
int tmpidx;
|
||||
int ec;
|
||||
int i;
|
||||
|
||||
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
|
||||
continue;
|
||||
|
||||
log_printhex ("getaddrinfo returned", ai->ai_addr,ai->ai_addrlen);
|
||||
if ((ec=getnameinfo (ai->ai_addr, ai->ai_addrlen,
|
||||
tmphost, sizeof tmphost,
|
||||
NULL, 0, NI_NAMEREQD)))
|
||||
log_info ("getnameinfo failed while checking `%s': %s\n",
|
||||
name, gai_strerror (ec));
|
||||
else if (refidx+1 >= reftblsize)
|
||||
{
|
||||
log_error ("getnameinfo returned for `%s': `%s'"
|
||||
" [index table full - ignored]\n", name, tmphost);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if ((tmpidx = find_hostinfo (tmphost)) != -1)
|
||||
{
|
||||
log_info ("getnameinfo returned for `%s': `%s'"
|
||||
" [already known]\n", name, tmphost);
|
||||
if (ai->ai_family == AF_INET)
|
||||
hosttable[tmpidx]->v4 = 1;
|
||||
if (ai->ai_family == AF_INET6)
|
||||
hosttable[tmpidx]->v6 = 1;
|
||||
|
||||
for (i=0; i < refidx; i++)
|
||||
if (reftbl[i] == tmpidx)
|
||||
break;
|
||||
if (!(i < refidx) && tmpidx != idx)
|
||||
reftbl[refidx++] = tmpidx;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info ("getnameinfo returned for `%s': `%s'\n",
|
||||
name, tmphost);
|
||||
/* Create a new entry. */
|
||||
tmpidx = create_new_hostinfo (tmphost);
|
||||
if (tmpidx == -1)
|
||||
log_error ("map_host for `%s' problem: %s - `%s'"
|
||||
" [ignored]\n",
|
||||
name, strerror (errno), tmphost);
|
||||
else
|
||||
{
|
||||
if (ai->ai_family == AF_INET)
|
||||
hosttable[tmpidx]->v4 = 1;
|
||||
if (ai->ai_family == AF_INET6)
|
||||
hosttable[tmpidx]->v6 = 1;
|
||||
|
||||
for (i=0; i < refidx; i++)
|
||||
if (reftbl[i] == tmpidx)
|
||||
break;
|
||||
if (!(i < refidx) && tmpidx != idx)
|
||||
reftbl[refidx++] = tmpidx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reftbl[refidx] = -1;
|
||||
if (refidx)
|
||||
{
|
||||
assert (!hi->pool);
|
||||
hi->pool = xtryrealloc (reftbl, (refidx+1) * sizeof *reftbl);
|
||||
if (!hi->pool)
|
||||
{
|
||||
log_error ("shrinking index table in map_host failed: %s\n",
|
||||
strerror (errno));
|
||||
xfree (reftbl);
|
||||
}
|
||||
qsort (reftbl, refidx, sizeof *reftbl, sort_hostpool);
|
||||
}
|
||||
else
|
||||
xfree (reftbl);
|
||||
}
|
||||
|
||||
hi = hosttable[idx];
|
||||
if (hi->pool)
|
||||
{
|
||||
/* If the currently selected host is now marked dead, force a
|
||||
re-selection . */
|
||||
if (hi->poolidx >= 0 && hi->poolidx < hosttable_size
|
||||
&& hosttable[hi->poolidx] && hosttable[hi->poolidx]->dead)
|
||||
hi->poolidx = -1;
|
||||
|
||||
/* Select a host if needed. */
|
||||
if (hi->poolidx == -1)
|
||||
{
|
||||
hi->poolidx = select_random_host (hi->pool);
|
||||
if (hi->poolidx == -1)
|
||||
{
|
||||
log_error ("no alive host found in pool `%s'\n", name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
assert (hi->poolidx >= 0 && hi->poolidx < hosttable_size);
|
||||
hi = hosttable[hi->poolidx];
|
||||
assert (hi);
|
||||
}
|
||||
|
||||
if (hi->dead)
|
||||
{
|
||||
log_error ("host `%s' marked as dead\n", hi->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return xtrystrdup (hi->name);
|
||||
}
|
||||
|
||||
|
||||
/* Mark the host NAME as dead. */
|
||||
static void
|
||||
mark_host_dead (const char *name)
|
||||
{
|
||||
hostinfo_t hi;
|
||||
int idx;
|
||||
|
||||
if (!name || !*name || !strcmp (name, "localhost"))
|
||||
return;
|
||||
|
||||
idx = find_hostinfo (name);
|
||||
if (idx == -1)
|
||||
return;
|
||||
hi = hosttable[idx];
|
||||
log_info ("marking host `%s' as dead%s\n", hi->name, hi->dead? " (again)":"");
|
||||
hi->dead = 1;
|
||||
}
|
||||
|
||||
|
||||
/* Debug function to print the entire hosttable. */
|
||||
void
|
||||
ks_hkp_print_hosttable (void)
|
||||
{
|
||||
int idx, idx2;
|
||||
hostinfo_t hi;
|
||||
|
||||
for (idx=0; idx < hosttable_size; idx++)
|
||||
if ((hi=hosttable[idx]))
|
||||
{
|
||||
log_info ("hosttable %3d %s %s %s %s\n",
|
||||
idx, hi->v4? "4":" ", hi->v6? "6":" ",
|
||||
hi->dead? "d":" ", hi->name);
|
||||
if (hi->pool)
|
||||
{
|
||||
log_info (" -->");
|
||||
for (idx2=0; hi->pool[idx2] != -1; idx2++)
|
||||
{
|
||||
log_printf (" %d", hi->pool[idx2]);
|
||||
if (hi->poolidx == idx2)
|
||||
log_printf ("*");
|
||||
}
|
||||
log_printf ("\n");
|
||||
/* for (idx2=0; hi->pool[idx2] != -1; idx2++) */
|
||||
/* log_info (" (%s)\n", */
|
||||
/* hosttable[hi->pool[idx2]]->name); */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Print a help output for the schemata supported by this module. */
|
||||
gpg_error_t
|
||||
ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri)
|
||||
@ -57,6 +418,44 @@ ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri)
|
||||
}
|
||||
|
||||
|
||||
/* Build the remote part or the URL from SCHEME, HOST and an optional
|
||||
PORT. Returns an allocated string or NULL on failure and sets
|
||||
ERRNO. */
|
||||
static char *
|
||||
make_host_part (const char *scheme, const char *host, unsigned short port)
|
||||
{
|
||||
char portstr[10];
|
||||
char *hostname;
|
||||
char *hostport;
|
||||
|
||||
/* Map scheme and port. */
|
||||
if (!strcmp (scheme, "hkps") || !strcmp (scheme,"https"))
|
||||
{
|
||||
scheme = "https";
|
||||
strcpy (portstr, "443");
|
||||
}
|
||||
else /* HKP or HTTP. */
|
||||
{
|
||||
scheme = "http";
|
||||
strcpy (portstr, "11371");
|
||||
}
|
||||
if (port)
|
||||
snprintf (portstr, sizeof portstr, "%hu", port);
|
||||
else
|
||||
{
|
||||
/*fixme_do_srv_lookup ()*/
|
||||
}
|
||||
|
||||
hostname = map_host (host);
|
||||
if (!hostname)
|
||||
return NULL;
|
||||
|
||||
hostport = strconcat (scheme, "://", hostname, ":", portstr, NULL);
|
||||
xfree (hostname);
|
||||
return hostport;
|
||||
}
|
||||
|
||||
|
||||
/* Send an HTTP request. On success returns an estream object at
|
||||
R_FP. HOSTPORTSTR is only used for diagnostics. If POST_CB is not
|
||||
NULL a post request is used and that callback is called to allow
|
||||
@ -73,6 +472,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
|
||||
char *request_buffer = NULL;
|
||||
|
||||
*r_fp = NULL;
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
once_more:
|
||||
err = http_open (&http,
|
||||
post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
|
||||
@ -244,8 +644,6 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
|
||||
gpg_error_t err;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
char fprbuf[2+40+1];
|
||||
const char *scheme;
|
||||
char portstr[10];
|
||||
char *hostport = NULL;
|
||||
char *request = NULL;
|
||||
estream_t fp = NULL;
|
||||
@ -289,29 +687,11 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
|
||||
return gpg_error (GPG_ERR_INV_USER_ID);
|
||||
}
|
||||
|
||||
/* Map scheme and port. */
|
||||
if (!strcmp (uri->scheme,"hkps") || !strcmp (uri->scheme,"https"))
|
||||
{
|
||||
scheme = "https";
|
||||
strcpy (portstr, "443");
|
||||
}
|
||||
else /* HKP or HTTP. */
|
||||
{
|
||||
scheme = "http";
|
||||
strcpy (portstr, "11371");
|
||||
}
|
||||
if (uri->port)
|
||||
snprintf (portstr, sizeof portstr, "%hu", uri->port);
|
||||
else
|
||||
{} /*fixme_do_srv_lookup ()*/
|
||||
|
||||
/* Build the request string. */
|
||||
{
|
||||
char *searchkey;
|
||||
|
||||
hostport = strconcat (scheme, "://",
|
||||
*uri->host? uri->host: "localhost",
|
||||
":", portstr, NULL);
|
||||
hostport = make_host_part (uri->scheme, uri->host, uri->port);
|
||||
if (!hostport)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
@ -382,8 +762,6 @@ 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[8+1];
|
||||
const char *scheme;
|
||||
char portstr[10];
|
||||
char *hostport = NULL;
|
||||
char *request = NULL;
|
||||
estream_t fp = NULL;
|
||||
@ -416,43 +794,23 @@ 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);
|
||||
}
|
||||
|
||||
/* Map scheme and port. */
|
||||
if (!strcmp (uri->scheme,"hkps") || !strcmp (uri->scheme,"https"))
|
||||
{
|
||||
scheme = "https";
|
||||
strcpy (portstr, "443");
|
||||
}
|
||||
else /* HKP or HTTP. */
|
||||
{
|
||||
scheme = "http";
|
||||
strcpy (portstr, "11371");
|
||||
}
|
||||
if (uri->port)
|
||||
snprintf (portstr, sizeof portstr, "%hu", uri->port);
|
||||
else
|
||||
{} /*fixme_do_srv_lookup ()*/
|
||||
|
||||
/* Build the request string. */
|
||||
{
|
||||
hostport = strconcat (scheme, "://",
|
||||
*uri->host? uri->host: "localhost",
|
||||
":", portstr, NULL);
|
||||
if (!hostport)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
hostport = make_host_part (uri->scheme, uri->host, uri->port);
|
||||
if (!hostport)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
|
||||
request = strconcat (hostport,
|
||||
"/pks/lookup?op=get&options=mr&search=0x",
|
||||
kidbuf,
|
||||
NULL);
|
||||
if (!request)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
request = strconcat (hostport,
|
||||
"/pks/lookup?op=get&options=mr&search=0x",
|
||||
kidbuf,
|
||||
NULL);
|
||||
if (!request)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Send the request. */
|
||||
err = send_request (ctrl, request, hostport, NULL, NULL, &fp);
|
||||
@ -507,8 +865,6 @@ gpg_error_t
|
||||
ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
|
||||
{
|
||||
gpg_error_t err;
|
||||
const char *scheme;
|
||||
char portstr[10];
|
||||
char *hostport = NULL;
|
||||
char *request = NULL;
|
||||
estream_t fp = NULL;
|
||||
@ -517,22 +873,6 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
|
||||
|
||||
parm.datastring = NULL;
|
||||
|
||||
/* Map scheme and port. */
|
||||
if (!strcmp (uri->scheme,"hkps") || !strcmp (uri->scheme,"https"))
|
||||
{
|
||||
scheme = "https";
|
||||
strcpy (portstr, "443");
|
||||
}
|
||||
else /* HKP or HTTP. */
|
||||
{
|
||||
scheme = "http";
|
||||
strcpy (portstr, "11371");
|
||||
}
|
||||
if (uri->port)
|
||||
snprintf (portstr, sizeof portstr, "%hu", uri->port);
|
||||
else
|
||||
{} /*fixme_do_srv_lookup ()*/
|
||||
|
||||
err = armor_data (&armored, data, datalen);
|
||||
if (err)
|
||||
goto leave;
|
||||
@ -547,9 +887,7 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
|
||||
armored = NULL;
|
||||
|
||||
/* Build the request string. */
|
||||
hostport = strconcat (scheme, "://",
|
||||
*uri->host? uri->host: "localhost",
|
||||
":", portstr, NULL);
|
||||
hostport = make_host_part (uri->scheme, uri->host, uri->port);
|
||||
if (!hostport)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
|
@ -27,6 +27,7 @@
|
||||
gpg_error_t ks_print_help (ctrl_t ctrl, const char *text);
|
||||
|
||||
/*-- ks-engine-hkp.c --*/
|
||||
void ks_hkp_print_hosttable (void);
|
||||
gpg_error_t ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri);
|
||||
gpg_error_t ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
|
||||
estream_t *r_fp);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "misc.h"
|
||||
#include "ldap-wrapper.h"
|
||||
#include "ks-action.h"
|
||||
#include "ks-engine.h" /* (ks_hkp_print_hosttable) */
|
||||
|
||||
/* To avoid DoS attacks we limit the size of a certificate to
|
||||
something reasonable. */
|
||||
@ -1374,12 +1375,13 @@ cmd_keyserver (assuan_context_t ctx, char *line)
|
||||
{
|
||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||
gpg_error_t err;
|
||||
int clear_flag, add_flag, help_flag;
|
||||
int clear_flag, add_flag, help_flag, host_flag;
|
||||
uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
|
||||
is always initialized. */
|
||||
|
||||
clear_flag = has_option (line, "--clear");
|
||||
help_flag = has_option (line, "--help");
|
||||
host_flag = has_option (line, "--print-hosttable");
|
||||
line = skip_options (line);
|
||||
add_flag = !!*line;
|
||||
|
||||
@ -1389,6 +1391,13 @@ cmd_keyserver (assuan_context_t ctx, char *line)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (host_flag)
|
||||
{
|
||||
ks_hkp_print_hosttable ();
|
||||
err = 0;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (add_flag)
|
||||
{
|
||||
item = xtrymalloc (sizeof *item + strlen (line));
|
||||
|
Loading…
x
Reference in New Issue
Block a user