aboutsummaryrefslogtreecommitdiffstats
path: root/dirmngr
diff options
context:
space:
mode:
Diffstat (limited to 'dirmngr')
-rw-r--r--dirmngr/Makefile.am4
-rw-r--r--dirmngr/cdb.h2
-rw-r--r--dirmngr/cdblib.c6
-rw-r--r--dirmngr/crlcache.c8
-rw-r--r--dirmngr/dirmngr-status.h39
-rw-r--r--dirmngr/dirmngr.c13
-rw-r--r--dirmngr/dirmngr.h10
-rw-r--r--dirmngr/dirmngr_ldap.c4
-rw-r--r--dirmngr/dns-stuff.c101
-rw-r--r--dirmngr/dns-stuff.h14
-rw-r--r--dirmngr/dns.c4
-rw-r--r--dirmngr/domaininfo.c2
-rw-r--r--dirmngr/http-ntbtls.c2
-rw-r--r--dirmngr/http.c36
-rw-r--r--dirmngr/http.h6
-rw-r--r--dirmngr/ks-action.c2
-rw-r--r--dirmngr/ks-engine-finger.c2
-rw-r--r--dirmngr/ks-engine-hkp.c110
-rw-r--r--dirmngr/ks-engine-http.c2
-rw-r--r--dirmngr/ks-engine-ldap.c33
-rw-r--r--dirmngr/ldap.c2
-rw-r--r--dirmngr/misc.c4
-rw-r--r--dirmngr/ocsp.c35
-rw-r--r--dirmngr/server.c134
-rw-r--r--dirmngr/t-dns-stuff.c12
-rw-r--r--dirmngr/t-http.c4
-rw-r--r--dirmngr/t-support.c43
-rw-r--r--dirmngr/workqueue.c2
28 files changed, 451 insertions, 185 deletions
diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am
index 43f59bd45..22b8c1a3a 100644
--- a/dirmngr/Makefile.am
+++ b/dirmngr/Makefile.am
@@ -62,7 +62,7 @@ dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \
domaininfo.c \
workqueue.c \
loadswdb.c \
- cdb.h cdblib.c misc.c dirmngr-err.h \
+ cdb.h cdblib.c misc.c dirmngr-err.h dirmngr-status.h \
ocsp.c ocsp.h validate.c validate.h \
dns-stuff.c dns-stuff.h \
http.c http.h http-common.c http-common.h http-ntbtls.c \
@@ -111,7 +111,7 @@ dirmngr_client_LDADD = $(libcommon) \
dirmngr_client_LDFLAGS = $(extra_bin_ldflags)
-t_common_src = t-support.h
+t_common_src = t-support.h t-support.c
if USE_LIBDNS
t_common_src += dns.c dns.h
endif
diff --git a/dirmngr/cdb.h b/dirmngr/cdb.h
index 0c0d2702a..5d46f6956 100644
--- a/dirmngr/cdb.h
+++ b/dirmngr/cdb.h
@@ -85,7 +85,7 @@ int cdb_make_put(struct cdb_make *cdbmp,
const void *key, cdbi_t klen,
const void *val, cdbi_t vlen,
int flag);
-#define CDB_PUT_ADD 0 /* add unconditionnaly, like cdb_make_add() */
+#define CDB_PUT_ADD 0 /* add unconditionally, like cdb_make_add() */
#define CDB_PUT_REPLACE 1 /* replace: do not place to index OLD record */
#define CDB_PUT_INSERT 2 /* add only if not already exists */
#define CDB_PUT_WARN 3 /* add unconditionally but ret. 1 if exists */
diff --git a/dirmngr/cdblib.c b/dirmngr/cdblib.c
index 827399f7e..c40126396 100644
--- a/dirmngr/cdblib.c
+++ b/dirmngr/cdblib.c
@@ -19,7 +19,7 @@
length, meaning that corresponding hash table is empty.
Right after toc section, data section follows without any
- alingment. It consists of series of records, each is a key length,
+ alignment. It consists of series of records, each is a key length,
value (data) length, key and value. Again, key and value length
are 4-byte unsigned integers. Each next record follows previous
without any special alignment.
@@ -52,7 +52,7 @@
beginning of a table). When hash value in question is found in
hash table, look to key of corresponding record, comparing it with
key in question. If them of the same length and equals to each
- other, then record is found, overwise, repeat with next hash table
+ other, then record is found, otherwise, repeat with next hash table
slot. Note that there may be several records with the same key.
*/
@@ -245,7 +245,7 @@ cdb_find(struct cdb *cdbp, const void *key, cdbi_t klen)
pos = cdb_unpack(htp); /* htab position */
if (n > (cdbp->cdb_fsize >> 3) /* overflow of httodo ? */
|| pos > cdbp->cdb_fsize /* htab start within file ? */
- || httodo > cdbp->cdb_fsize - pos) /* entrie htab within file ? */
+ || httodo > cdbp->cdb_fsize - pos) /* htab entry within file ? */
{
gpg_err_set_errno (EPROTO);
return -1;
diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c
index fbe3beea1..c9e5ca68f 100644
--- a/dirmngr/crlcache.c
+++ b/dirmngr/crlcache.c
@@ -1250,13 +1250,15 @@ crl_cache_deinit (void)
}
-/* Delete the cache from disk. Return 0 on success.*/
+/* Delete the cache from disk and memory. Return 0 on success.*/
int
crl_cache_flush (void)
{
int rc;
+ crl_cache_deinit ();
rc = cleanup_cache_dir (0)? -1 : 0;
+ crl_cache_init ();
return rc;
}
@@ -1782,7 +1784,7 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
ksba_sexp_t keyid;
/* We need to look for the issuer only after having read
- all items. The issuer itselfs comes before the items
+ all items. The issuer itself comes before the items
but the optional authorityKeyIdentifier comes after the
items. */
err = ksba_crl_get_issuer (crl, &crlissuer);
@@ -1907,7 +1909,7 @@ get_crl_number (ksba_crl_t crl)
/* Return the authorityKeyIdentifier or NULL if it is not available.
- The issuer name may consists of several parts - they are delimted by
+ The issuer name may consists of several parts - they are delimited by
0x01. */
static char *
get_auth_key_id (ksba_crl_t crl, char **serialno)
diff --git a/dirmngr/dirmngr-status.h b/dirmngr/dirmngr-status.h
new file mode 100644
index 000000000..2c3fd78a3
--- /dev/null
+++ b/dirmngr/dirmngr-status.h
@@ -0,0 +1,39 @@
+/* dirmngr-status.h - Status code helper functions for dirmnmgr.
+ * Copyright (C) 2004, 2014, 2015, 2018 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0+
+ */
+
+/* We keep them separate so that we don't always need to include the
+ * entire dirmngr.h */
+
+#ifndef DIRMNGR_STATUS_H
+#define DIRMNGR_STATUS_H
+
+
+/*-- server.c --*/
+gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...);
+gpg_error_t dirmngr_status_help (ctrl_t ctrl, const char *text);
+gpg_error_t dirmngr_status_helpf (ctrl_t ctrl, const char *format,
+ ...) GPGRT_ATTR_PRINTF(2,3);
+gpg_error_t dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
+ const char *format,
+ ...) GPGRT_ATTR_PRINTF(3,4);
+
+
+#endif /* DIRMNGR_STATUS_H */
diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
index 6fdfe36c2..80fb13476 100644
--- a/dirmngr/dirmngr.c
+++ b/dirmngr/dirmngr.c
@@ -338,7 +338,7 @@ static int active_connections;
* thread to run background network tasks. */
static int network_activity_seen;
-/* A list of filenames registred with --hkp-cacert. */
+/* A list of filenames registered with --hkp-cacert. */
static strlist_t hkp_cacert_filenames;
@@ -411,7 +411,7 @@ my_strusage( int level )
/* Callback from libksba to hash a provided buffer. Our current
implementation does only allow SHA-1 for hashing. This may be
- extended by mapping the name, testing for algorithm availibility
+ extended by mapping the name, testing for algorithm availability
and adjust the length checks accordingly. */
static gpg_error_t
my_ksba_hash_buffer (void *arg, const char *oid,
@@ -520,7 +520,7 @@ set_tor_mode (void)
{
if (dirmngr_use_tor ())
{
- /* Enable Tor mode and when called again force a new curcuit
+ /* Enable Tor mode and when called again force a new circuit
* (e.g. on SIGHUP). */
enable_dns_tormode (1);
if (assuan_sock_set_flag (ASSUAN_INVALID_FD, "tor-mode", 1))
@@ -752,7 +752,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
}
-/* This fucntion is called after option parsing to adjust some values
+/* This function is called after option parsing to adjust some values
* and call option setup functions. */
static void
post_option_parsing (void)
@@ -1143,6 +1143,7 @@ main (int argc, char **argv)
thread_init ();
cert_cache_init (hkp_cacert_filenames);
crl_cache_init ();
+ ks_hkp_init ();
http_register_netactivity_cb (netactivity_action);
start_command_handler (ASSUAN_INVALID_FD, 0);
shutdown_reaper ();
@@ -1178,6 +1179,7 @@ main (int argc, char **argv)
thread_init ();
cert_cache_init (hkp_cacert_filenames);
crl_cache_init ();
+ ks_hkp_init ();
http_register_netactivity_cb (netactivity_action);
handle_connections (3);
shutdown_reaper ();
@@ -1399,6 +1401,7 @@ main (int argc, char **argv)
thread_init ();
cert_cache_init (hkp_cacert_filenames);
crl_cache_init ();
+ ks_hkp_init ();
http_register_netactivity_cb (netactivity_action);
handle_connections (fd);
shutdown_reaper ();
@@ -1421,6 +1424,7 @@ main (int argc, char **argv)
thread_init ();
cert_cache_init (hkp_cacert_filenames);
crl_cache_init ();
+ ks_hkp_init ();
if (!argc)
rc = crl_cache_load (&ctrlbuf, NULL);
else
@@ -1444,6 +1448,7 @@ main (int argc, char **argv)
thread_init ();
cert_cache_init (hkp_cacert_filenames);
crl_cache_init ();
+ ks_hkp_init ();
rc = crl_fetch (&ctrlbuf, argv[0], &reader);
if (rc)
log_error (_("fetching CRL from '%s' failed: %s\n"),
diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
index 5189f93b1..9c26c09e6 100644
--- a/dirmngr/dirmngr.h
+++ b/dirmngr/dirmngr.h
@@ -36,6 +36,7 @@
#include "../common/sysutils.h" /* (gnupg_fd_t) */
#include "../common/asshelp.h" /* (assuan_context_t) */
#include "../common/i18n.h"
+#include "dirmngr-status.h"
#include "http.h" /* (parsed_uri_t) */
/* This objects keeps information about a particular LDAP server and
@@ -217,7 +218,7 @@ int dirmngr_use_tor (void);
/*-- Various housekeeping functions. --*/
void ks_hkp_housekeeping (time_t curtime);
void ks_hkp_reload (void);
-
+void ks_hkp_init (void);
/*-- server.c --*/
ldap_server_t get_ldapservers_from_ctrl (ctrl_t ctrl);
@@ -229,13 +230,6 @@ gpg_error_t get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr);
int dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
const char *msg);
void start_command_handler (gnupg_fd_t fd, unsigned int session_id);
-gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...);
-gpg_error_t dirmngr_status_help (ctrl_t ctrl, const char *text);
-gpg_error_t dirmngr_status_helpf (ctrl_t ctrl, const char *format,
- ...) GPGRT_ATTR_PRINTF(2,3);
-gpg_error_t dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
- const char *format,
- ...) GPGRT_ATTR_PRINTF(3,4);
gpg_error_t dirmngr_tick (ctrl_t ctrl);
/*-- http-ntbtls.c --*/
diff --git a/dirmngr/dirmngr_ldap.c b/dirmngr/dirmngr_ldap.c
index 8452c3ba0..dd7e4bda5 100644
--- a/dirmngr/dirmngr_ldap.c
+++ b/dirmngr/dirmngr_ldap.c
@@ -417,9 +417,9 @@ set_timeout (my_opt_t myopt)
sec_attr.nLength = sizeof sec_attr;
sec_attr.bInheritHandle = FALSE;
- /* Create a manual resetable timer. */
+ /* Create a manual resettable timer. */
timer = CreateWaitableTimer (NULL, TRUE, NULL);
- /* Intially set the timer. */
+ /* Initially set the timer. */
SetWaitableTimer (timer, &due_time, 0, NULL, NULL, 0);
if (CreateThread (&sec_attr, 0, alarm_thread, timer, 0, &tid))
diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
index ffac816f9..7aa07c716 100644
--- a/dirmngr/dns-stuff.c
+++ b/dirmngr/dns-stuff.c
@@ -73,6 +73,7 @@
#include "./dirmngr-err.h"
#include "../common/util.h"
#include "../common/host2net.h"
+#include "dirmngr-status.h"
#include "dns-stuff.h"
#ifdef USE_NPTH
@@ -150,7 +151,7 @@ static char tor_socks_password[20];
#ifdef USE_LIBDNS
-/* Libdns gobal data. */
+/* Libdns global data. */
struct libdns_s
{
struct dns_resolv_conf *resolv_conf;
@@ -433,12 +434,13 @@ resolv_conf_changed_p (void)
/* Initialize libdns. Returns 0 on success; prints a diagnostic and
* returns an error code on failure. */
static gpg_error_t
-libdns_init (void)
+libdns_init (ctrl_t ctrl)
{
gpg_error_t err;
struct libdns_s ld;
int derr;
char *cfgstr = NULL;
+ const char *fname = NULL;
if (libdns.resolv_conf)
return 0; /* Already initialized. */
@@ -532,7 +534,6 @@ libdns_init (void)
xfree (ninfo);
#else /* Unix */
- const char *fname;
fname = RESOLV_CONF_NAME;
resolv_conf_changed_p (); /* Reset timestamp. */
@@ -622,6 +623,7 @@ libdns_init (void)
{
err = libdns_error_to_gpg_error (derr);
log_error ("failed to load DNS hints: %s\n", gpg_strerror (err));
+ fname = "[dns hints]";
goto leave;
}
@@ -632,6 +634,14 @@ libdns_init (void)
log_debug ("dns: libdns initialized%s\n", tor_mode?" (tor mode)":"");
leave:
+ if (!fname)
+ fname = cfgstr;
+ if (err && fname)
+ dirmngr_status_printf (ctrl, "WARNING",
+ "dns_config_problem %u"
+ " error accessing '%s': %s <%s>",
+ err, fname, gpg_strerror (err), gpg_strsource (err));
+
xfree (cfgstr);
return err;
}
@@ -686,7 +696,7 @@ reload_dns_stuff (int force)
* failure an error code is returned and NULL stored at R_RES.
*/
static gpg_error_t
-libdns_res_open (struct dns_resolver **r_res)
+libdns_res_open (ctrl_t ctrl, struct dns_resolver **r_res)
{
gpg_error_t err;
struct dns_resolver *res;
@@ -708,7 +718,7 @@ libdns_res_open (struct dns_resolver **r_res)
libdns_deinit ();
}
- err = libdns_init ();
+ err = libdns_init (ctrl);
if (err)
return err;
@@ -790,7 +800,7 @@ libdns_res_wait (struct dns_resolver *res)
#ifdef USE_LIBDNS
static gpg_error_t
-resolve_name_libdns (const char *name, unsigned short port,
+resolve_name_libdns (ctrl_t ctrl, const char *name, unsigned short port,
int want_family, int want_socktype,
dns_addrinfo_t *r_dai, char **r_canonname)
{
@@ -823,7 +833,7 @@ resolve_name_libdns (const char *name, unsigned short port,
portstr = portstr_;
}
- err = libdns_res_open (&res);
+ err = libdns_res_open (ctrl, &res);
if (err)
goto leave;
@@ -935,7 +945,7 @@ resolve_name_libdns (const char *name, unsigned short port,
/* Resolve a name using the standard system function. */
static gpg_error_t
-resolve_name_standard (const char *name, unsigned short port,
+resolve_name_standard (ctrl_t ctrl, const char *name, unsigned short port,
int want_family, int want_socktype,
dns_addrinfo_t *r_dai, char **r_canonname)
{
@@ -981,7 +991,7 @@ resolve_name_standard (const char *name, unsigned short port,
CNAME redirection again. */
char *cname;
- if (get_dns_cname (name, &cname))
+ if (get_dns_cname (ctrl, name, &cname))
goto leave; /* Still no success. */
ret = getaddrinfo (cname, *portstr? portstr : NULL, &hints, &aibuf);
@@ -1046,18 +1056,19 @@ resolve_name_standard (const char *name, unsigned short port,
/* This a wrapper around getaddrinfo with slightly different semantics.
- NAME is the name to resolve.
- PORT is the requested port or 0.
- WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4.
- WANT_SOCKETTYPE is either SOCK_STREAM or SOCK_DGRAM.
-
- On success the result is stored in a linked list with the head
- stored at the address R_AI; the caller must call gpg_addrinfo_free
- on this. If R_CANONNAME is not NULL the official name of the host
- is stored there as a malloced string; if that name is not available
- NULL is stored. */
+ * NAME is the name to resolve.
+ * PORT is the requested port or 0.
+ * WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4.
+ * WANT_SOCKETTYPE is either 0 for any socket type
+ * or SOCK_STREAM or SOCK_DGRAM.
+ *
+ * On success the result is stored in a linked list with the head
+ * stored at the address R_AI; the caller must call free_dns_addrinfo
+ * on this. If R_CANONNAME is not NULL the official name of the host
+ * is stored there as a malloced string; if that name is not available
+ * NULL is stored. */
gpg_error_t
-resolve_dns_name (const char *name, unsigned short port,
+resolve_dns_name (ctrl_t ctrl, const char *name, unsigned short port,
int want_family, int want_socktype,
dns_addrinfo_t *r_ai, char **r_canonname)
{
@@ -1066,15 +1077,15 @@ resolve_dns_name (const char *name, unsigned short port,
#ifdef USE_LIBDNS
if (!standard_resolver)
{
- err = resolve_name_libdns (name, port, want_family, want_socktype,
+ err = resolve_name_libdns (ctrl, name, port, want_family, want_socktype,
r_ai, r_canonname);
if (err && libdns_switch_port_p (err))
- err = resolve_name_libdns (name, port, want_family, want_socktype,
+ err = resolve_name_libdns (ctrl, name, port, want_family, want_socktype,
r_ai, r_canonname);
}
else
#endif /*USE_LIBDNS*/
- err = resolve_name_standard (name, port, want_family, want_socktype,
+ err = resolve_name_standard (ctrl, name, port, want_family, want_socktype,
r_ai, r_canonname);
if (opt_debug)
log_debug ("dns: resolve_dns_name(%s): %s\n", name, gpg_strerror (err));
@@ -1085,7 +1096,8 @@ resolve_dns_name (const char *name, unsigned short port,
#ifdef USE_LIBDNS
/* Resolve an address using libdns. */
static gpg_error_t
-resolve_addr_libdns (const struct sockaddr_storage *addr, int addrlen,
+resolve_addr_libdns (ctrl_t ctrl,
+ const struct sockaddr_storage *addr, int addrlen,
unsigned int flags, char **r_name)
{
gpg_error_t err;
@@ -1117,7 +1129,7 @@ resolve_addr_libdns (const struct sockaddr_storage *addr, int addrlen,
goto leave;
- err = libdns_res_open (&res);
+ err = libdns_res_open (ctrl, &res);
if (err)
goto leave;
@@ -1281,7 +1293,8 @@ resolve_addr_standard (const struct sockaddr_storage *addr, int addrlen,
/* A wrapper around getnameinfo. */
gpg_error_t
-resolve_dns_addr (const struct sockaddr_storage *addr, int addrlen,
+resolve_dns_addr (ctrl_t ctrl,
+ const struct sockaddr_storage *addr, int addrlen,
unsigned int flags, char **r_name)
{
gpg_error_t err;
@@ -1290,9 +1303,9 @@ resolve_dns_addr (const struct sockaddr_storage *addr, int addrlen,
/* Note that we divert to the standard resolver for NUMERICHOST. */
if (!standard_resolver && !(flags & DNS_NUMERICHOST))
{
- err = resolve_addr_libdns (addr, addrlen, flags, r_name);
+ err = resolve_addr_libdns (ctrl, addr, addrlen, flags, r_name);
if (err && libdns_switch_port_p (err))
- err = resolve_addr_libdns (addr, addrlen, flags, r_name);
+ err = resolve_addr_libdns (ctrl, addr, addrlen, flags, r_name);
}
else
#endif /*USE_LIBDNS*/
@@ -1390,7 +1403,7 @@ is_onion_address (const char *name)
/* libdns version of get_dns_cert. */
#ifdef USE_LIBDNS
static gpg_error_t
-get_dns_cert_libdns (const char *name, int want_certtype,
+get_dns_cert_libdns (ctrl_t ctrl, const char *name, int want_certtype,
void **r_key, size_t *r_keylen,
unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
{
@@ -1410,7 +1423,7 @@ get_dns_cert_libdns (const char *name, int want_certtype,
: (want_certtype - DNS_CERTTYPE_RRBASE));
- err = libdns_res_open (&res);
+ err = libdns_res_open (ctrl, &res);
if (err)
goto leave;
@@ -1776,7 +1789,7 @@ get_dns_cert_standard (const char *name, int want_certtype,
supported certtypes only records with this certtype are considered
and the first found is returned. (R_KEY,R_KEYLEN) are optional. */
gpg_error_t
-get_dns_cert (const char *name, int want_certtype,
+get_dns_cert (ctrl_t ctrl, const char *name, int want_certtype,
void **r_key, size_t *r_keylen,
unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
{
@@ -1793,10 +1806,10 @@ get_dns_cert (const char *name, int want_certtype,
#ifdef USE_LIBDNS
if (!standard_resolver)
{
- err = get_dns_cert_libdns (name, want_certtype, r_key, r_keylen,
+ err = get_dns_cert_libdns (ctrl, name, want_certtype, r_key, r_keylen,
r_fpr, r_fprlen, r_url);
if (err && libdns_switch_port_p (err))
- err = get_dns_cert_libdns (name, want_certtype, r_key, r_keylen,
+ err = get_dns_cert_libdns (ctrl, name, want_certtype, r_key, r_keylen,
r_fpr, r_fprlen, r_url);
}
else
@@ -1828,7 +1841,8 @@ priosort(const void *a,const void *b)
* R_COUNT. */
#ifdef USE_LIBDNS
static gpg_error_t
-getsrv_libdns (const char *name, struct srventry **list, unsigned int *r_count)
+getsrv_libdns (ctrl_t ctrl,
+ const char *name, struct srventry **list, unsigned int *r_count)
{
gpg_error_t err;
struct dns_resolver *res = NULL;
@@ -1839,7 +1853,7 @@ getsrv_libdns (const char *name, struct srventry **list, unsigned int *r_count)
int derr;
unsigned int srvcount = 0;
- err = libdns_res_open (&res);
+ err = libdns_res_open (ctrl, &res);
if (err)
goto leave;
@@ -2058,7 +2072,8 @@ getsrv_standard (const char *name,
* we do not return NONAME but simply store 0 at R_COUNT. On error an
* error code is returned and 0 stored at R_COUNT. */
gpg_error_t
-get_dns_srv (const char *name, const char *service, const char *proto,
+get_dns_srv (ctrl_t ctrl,
+ const char *name, const char *service, const char *proto,
struct srventry **list, unsigned int *r_count)
{
gpg_error_t err;
@@ -2087,9 +2102,9 @@ get_dns_srv (const char *name, const char *service, const char *proto,
#ifdef USE_LIBDNS
if (!standard_resolver)
{
- err = getsrv_libdns (name, list, &srvcount);
+ err = getsrv_libdns (ctrl, name, list, &srvcount);
if (err && libdns_switch_port_p (err))
- err = getsrv_libdns (name, list, &srvcount);
+ err = getsrv_libdns (ctrl, name, list, &srvcount);
}
else
#endif /*USE_LIBDNS*/
@@ -2194,7 +2209,7 @@ get_dns_srv (const char *name, const char *service, const char *proto,
#ifdef USE_LIBDNS
/* libdns version of get_dns_cname. */
gpg_error_t
-get_dns_cname_libdns (const char *name, char **r_cname)
+get_dns_cname_libdns (ctrl_t ctrl, const char *name, char **r_cname)
{
gpg_error_t err;
struct dns_resolver *res;
@@ -2202,7 +2217,7 @@ get_dns_cname_libdns (const char *name, char **r_cname)
struct dns_cname cname;
int derr;
- err = libdns_res_open (&res);
+ err = libdns_res_open (ctrl, &res);
if (err)
goto leave;
@@ -2347,7 +2362,7 @@ get_dns_cname_standard (const char *name, char **r_cname)
gpg_error_t
-get_dns_cname (const char *name, char **r_cname)
+get_dns_cname (ctrl_t ctrl, const char *name, char **r_cname)
{
gpg_error_t err;
@@ -2356,9 +2371,9 @@ get_dns_cname (const char *name, char **r_cname)
#ifdef USE_LIBDNS
if (!standard_resolver)
{
- err = get_dns_cname_libdns (name, r_cname);
+ err = get_dns_cname_libdns (ctrl, name, r_cname);
if (err && libdns_switch_port_p (err))
- err = get_dns_cname_libdns (name, r_cname);
+ err = get_dns_cname_libdns (ctrl, name, r_cname);
return err;
}
#endif /*USE_LIBDNS*/
diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
index 612b2e5f5..06a43122a 100644
--- a/dirmngr/dns-stuff.h
+++ b/dirmngr/dns-stuff.h
@@ -137,12 +137,14 @@ void reload_dns_stuff (int force);
void free_dns_addrinfo (dns_addrinfo_t ai);
/* Function similar to getaddrinfo. */
-gpg_error_t resolve_dns_name (const char *name, unsigned short port,
+gpg_error_t resolve_dns_name (ctrl_t ctrl,
+ const char *name, unsigned short port,
int want_family, int want_socktype,
dns_addrinfo_t *r_dai, char **r_canonname);
/* Function similar to getnameinfo. */
-gpg_error_t resolve_dns_addr (const struct sockaddr_storage *addr, int addrlen,
+gpg_error_t resolve_dns_addr (ctrl_t ctrl,
+ const struct sockaddr_storage *addr, int addrlen,
unsigned int flags, char **r_name);
/* Return true if NAME is a numerical IP address. */
@@ -152,16 +154,18 @@ int is_ip_address (const char *name);
int is_onion_address (const char *name);
/* Get the canonical name for NAME. */
-gpg_error_t get_dns_cname (const char *name, char **r_cname);
+gpg_error_t get_dns_cname (ctrl_t ctrl, const char *name, char **r_cname);
/* Return a CERT record or an arbitrary RR. */
-gpg_error_t get_dns_cert (const char *name, int want_certtype,
+gpg_error_t get_dns_cert (ctrl_t ctrl,
+ const char *name, int want_certtype,
void **r_key, size_t *r_keylen,
unsigned char **r_fpr, size_t *r_fprlen,
char **r_url);
/* Return an array of SRV records. */
-gpg_error_t get_dns_srv (const char *name,
+gpg_error_t get_dns_srv (ctrl_t ctrl,
+ const char *name,
const char *service, const char *proto,
struct srventry **list, unsigned int *r_count);
diff --git a/dirmngr/dns.c b/dirmngr/dns.c
index 77f83f437..596e81fc9 100644
--- a/dirmngr/dns.c
+++ b/dirmngr/dns.c
@@ -1832,7 +1832,7 @@ static void dns_p_free(struct dns_packet *P) {
} /* dns_p_free() */
-/* convience routine to free any existing packet before storing new packet */
+/* convenience routine to free any existing packet before storing new packet */
static struct dns_packet *dns_p_setptr(struct dns_packet **dst, struct dns_packet *src) {
dns_p_free(*dst);
@@ -7634,7 +7634,7 @@ retry:
goto udp_connect_retry;
} else if (error == ECONNREFUSED)
/* Error for previous socket operation may
- be reserverd asynchronously. */
+ be reserverd(?) asynchronously. */
goto udp_connect_retry;
if (error)
diff --git a/dirmngr/domaininfo.c b/dirmngr/domaininfo.c
index a2effffef..f6263b06d 100644
--- a/dirmngr/domaininfo.c
+++ b/dirmngr/domaininfo.c
@@ -119,7 +119,7 @@ domaininfo_print_stats (void)
}
-/* Return true if DOMAIN definitely does not support WKD. Noet that
+/* Return true if DOMAIN definitely does not support WKD. Note that
* DOMAIN is expected to be lowercase. */
int
domaininfo_is_wkd_not_supported (const char *domain)
diff --git a/dirmngr/http-ntbtls.c b/dirmngr/http-ntbtls.c
index ed4cdd496..924b8b25f 100644
--- a/dirmngr/http-ntbtls.c
+++ b/dirmngr/http-ntbtls.c
@@ -55,7 +55,7 @@ gnupg_http_tls_verify_cb (void *opaque,
log_assert (ctrl && ctrl->magic == SERVER_CONTROL_MAGIC);
log_assert (!ntbtls_check_context (tls));
- /* Get the peer's certs fron ntbtls. */
+ /* Get the peer's certs from ntbtls. */
for (idx = 0;
(cert = ntbtls_x509_get_peer_cert (tls, idx)); idx++)
{
diff --git a/dirmngr/http.c b/dirmngr/http.c
index 049aefc29..5fb7eed04 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -2,7 +2,7 @@
* Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010,
* 2011 Free Software Foundation, Inc.
* Copyright (C) 2014 Werner Koch
- * Copyright (C) 2015-2017 g10 Code GmbH
+ * Copyright (C) 2015-2018 g10 Code GmbH
*
* This file is part of GnuPG.
*
@@ -152,14 +152,15 @@ static int remove_escapes (char *string);
static int insert_escapes (char *buffer, const char *string,
const char *special);
static uri_tuple_t parse_tuple (char *string);
-static gpg_error_t send_request (http_t hd, const char *httphost,
+static gpg_error_t send_request (ctrl_t ctrl, http_t hd, const char *httphost,
const char *auth,const char *proxy,
const char *srvtag, unsigned int timeout,
strlist_t headers);
static char *build_rel_path (parsed_uri_t uri);
static gpg_error_t parse_response (http_t hd);
-static gpg_error_t connect_server (const char *server, unsigned short port,
+static gpg_error_t connect_server (ctrl_t ctrl,
+ const char *server, unsigned short port,
unsigned int flags, const char *srvtag,
unsigned int timeout, assuan_fd_t *r_sock);
static gpgrt_ssize_t read_server (assuan_fd_t sock, void *buffer, size_t size);
@@ -937,7 +938,7 @@ http_session_set_timeout (http_session_t sess, unsigned int timeout)
If HTTPHOST is not NULL it is used for the Host header instead of a
Host header derived from the URL. */
gpg_error_t
-http_open (http_t *r_hd, http_req_t reqtype, const char *url,
+http_open (ctrl_t ctrl, http_t *r_hd, http_req_t reqtype, const char *url,
const char *httphost,
const char *auth, unsigned int flags, const char *proxy,
http_session_t session, const char *srvtag, strlist_t headers)
@@ -961,7 +962,7 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
if (!err)
- err = send_request (hd, httphost, auth, proxy, srvtag,
+ err = send_request (ctrl, hd, httphost, auth, proxy, srvtag,
hd->session? hd->session->connect_timeout : 0,
headers);
@@ -985,7 +986,8 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
this http abstraction layer. This has the advantage of providing
service tags and an estream interface. TIMEOUT is in milliseconds. */
gpg_error_t
-http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
+http_raw_connect (ctrl_t ctrl, http_t *r_hd,
+ const char *server, unsigned short port,
unsigned int flags, const char *srvtag, unsigned int timeout)
{
gpg_error_t err = 0;
@@ -1021,7 +1023,8 @@ http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
{
assuan_fd_t sock;
- err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
+ err = connect_server (ctrl, server, port,
+ hd->flags, srvtag, timeout, &sock);
if (err)
{
xfree (hd);
@@ -1174,14 +1177,14 @@ http_wait_response (http_t hd)
be used as an HTTP proxy and any enabled $http_proxy gets
ignored. */
gpg_error_t
-http_open_document (http_t *r_hd, const char *document,
+http_open_document (ctrl_t ctrl, http_t *r_hd, const char *document,
const char *auth, unsigned int flags, const char *proxy,
http_session_t session,
const char *srvtag, strlist_t headers)
{
gpg_error_t err;
- err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
+ err = http_open (ctrl, r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
proxy, session, srvtag, headers);
if (err)
return err;
@@ -1712,7 +1715,7 @@ is_hostname_port (const char *string)
* Returns 0 if the request was successful
*/
static gpg_error_t
-send_request (http_t hd, const char *httphost, const char *auth,
+send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth,
const char *proxy, const char *srvtag, unsigned int timeout,
strlist_t headers)
{
@@ -1859,14 +1862,16 @@ send_request (http_t hd, const char *httphost, const char *auth,
}
}
- err = connect_server (*uri->host ? uri->host : "localhost",
+ err = connect_server (ctrl,
+ *uri->host ? uri->host : "localhost",
uri->port ? uri->port : 80,
hd->flags, NULL, timeout, &sock);
http_release_parsed_uri (uri);
}
else
{
- err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
+ err = connect_server (ctrl,
+ server, port, hd->flags, srvtag, timeout, &sock);
}
if (err)
@@ -2870,7 +2875,7 @@ connect_with_timeout (assuan_fd_t sock,
* function tries to connect to all known addresses and the timeout is
* for each one. */
static gpg_error_t
-connect_server (const char *server, unsigned short port,
+connect_server (ctrl_t ctrl, const char *server, unsigned short port,
unsigned int flags, const char *srvtag, unsigned int timeout,
assuan_fd_t *r_sock)
{
@@ -2923,7 +2928,7 @@ connect_server (const char *server, unsigned short port,
/* Do the SRV thing */
if (srvtag)
{
- err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount);
+ err = get_dns_srv (ctrl, server, srvtag, NULL, &serverlist, &srvcount);
if (err)
log_info ("getting '%s' SRV for '%s' failed: %s\n",
srvtag, server, gpg_strerror (err));
@@ -2953,7 +2958,8 @@ connect_server (const char *server, unsigned short port,
if (opt_debug)
log_debug ("http.c:connect_server: trying name='%s' port=%hu\n",
serverlist[srv].target, port);
- err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
+ err = resolve_dns_name (ctrl,
+ serverlist[srv].target, port, 0, SOCK_STREAM,
&aibuf, NULL);
if (err)
{
diff --git a/dirmngr/http.h b/dirmngr/http.h
index 4cfb4c890..a86abbee7 100644
--- a/dirmngr/http.h
+++ b/dirmngr/http.h
@@ -135,12 +135,12 @@ gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
void http_release_parsed_uri (parsed_uri_t uri);
-gpg_error_t http_raw_connect (http_t *r_hd,
+gpg_error_t http_raw_connect (ctrl_t ctrl, http_t *r_hd,
const char *server, unsigned short port,
unsigned int flags, const char *srvtag,
unsigned int timeout);
-gpg_error_t http_open (http_t *r_hd, http_req_t reqtype,
+gpg_error_t http_open (ctrl_t ctrl, http_t *r_hd, http_req_t reqtype,
const char *url,
const char *httphost,
const char *auth,
@@ -156,7 +156,7 @@ gpg_error_t http_wait_response (http_t hd);
void http_close (http_t hd, int keep_read_stream);
-gpg_error_t http_open_document (http_t *r_hd,
+gpg_error_t http_open_document (ctrl_t ctrl, http_t *r_hd,
const char *document,
const char *auth,
unsigned int flags,
diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c
index c1ecafb58..3651ca7db 100644
--- a/dirmngr/ks-action.c
+++ b/dirmngr/ks-action.c
@@ -88,7 +88,7 @@ ks_action_help (ctrl_t ctrl, const char *url)
return err;
}
- /* Call all engines to give them a chance to print a help sting. */
+ /* Call all engines to give them a chance to print a help string. */
err = ks_hkp_help (ctrl, parsed_uri);
if (!err)
err = ks_http_help (ctrl, parsed_uri);
diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c
index e53a0ee78..30ede1573 100644
--- a/dirmngr/ks-engine-finger.c
+++ b/dirmngr/ks-engine-finger.c
@@ -82,7 +82,7 @@ ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp)
}
*server++ = 0;
- err = http_raw_connect (&http, server, 79,
+ err = http_raw_connect (ctrl, &http, server, 79,
((dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR : 0)
| (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
| (opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)),
diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
index 32840e68e..790a8b1c5 100644
--- a/dirmngr/ks-engine-hkp.c
+++ b/dirmngr/ks-engine-hkp.c
@@ -35,6 +35,7 @@
# include <netdb.h>
#endif /*!HAVE_W32_SYSTEM*/
+#include <npth.h>
#include "dirmngr.h"
#include "misc.h"
#include "../common/userids.h"
@@ -108,6 +109,8 @@ struct hostinfo_s
resolved from a pool name and its allocated size.*/
static hostinfo_t *hosttable;
static int hosttable_size;
+/* A mutex used to serialize access to the hosttable. */
+static npth_mutex_t hosttable_lock;
/* The number of host slots we initially allocate for HOSTTABLE. */
#define INITIAL_HOSTTABLE_SIZE 50
@@ -304,7 +307,7 @@ tor_not_running_p (ctrl_t ctrl)
PROTOCOL. If NAME specifies a pool (as indicated by IS_POOL),
update the given reference table accordingly. */
static void
-add_host (const char *name, int is_pool,
+add_host (ctrl_t ctrl, const char *name, int is_pool,
const dns_addrinfo_t ai,
enum ks_protocol protocol, unsigned short port)
{
@@ -320,7 +323,7 @@ add_host (const char *name, int is_pool,
if (is_pool)
{
/* For a pool immediately convert the address to a string. */
- tmperr = resolve_dns_addr (ai->addr, ai->addrlen,
+ tmperr = resolve_dns_addr (ctrl, ai->addr, ai->addrlen,
(DNS_NUMERICHOST | DNS_WITHBRACKET), &tmphost);
}
else if (!is_ip_address (name))
@@ -337,7 +340,7 @@ add_host (const char *name, int is_pool,
{
/* Do a PTR lookup on AI. If a name was not found the function
* returns the numeric address (with brackets). */
- tmperr = resolve_dns_addr (ai->addr, ai->addrlen,
+ tmperr = resolve_dns_addr (ctrl, ai->addr, ai->addrlen,
DNS_WITHBRACKET, &tmphost);
}
@@ -498,7 +501,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
unsigned int srvscount;
/* Check for SRV records. */
- err = get_dns_srv (name, srvtag, NULL, &srvs, &srvscount);
+ err = get_dns_srv (ctrl, name, srvtag, NULL, &srvs, &srvscount);
if (err)
{
if (gpg_err_code (err) == GPG_ERR_ECONNREFUSED)
@@ -514,13 +517,13 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
for (i = 0; i < srvscount; i++)
{
- err = resolve_dns_name (srvs[i].target, 0,
+ err = resolve_dns_name (ctrl, srvs[i].target, 0,
AF_UNSPEC, SOCK_STREAM,
&ai, &cname);
if (err)
continue;
dirmngr_tick (ctrl);
- add_host (name, is_pool, ai, protocol, srvs[i].port);
+ add_host (ctrl, name, is_pool, ai, protocol, srvs[i].port);
new_hosts = 1;
}
@@ -535,7 +538,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
{
/* Find all A records for this entry and put them into the pool
list - if any. */
- err = resolve_dns_name (name, 0, 0, SOCK_STREAM, &aibuf, &cname);
+ err = resolve_dns_name (ctrl, name, 0, 0, SOCK_STREAM, &aibuf, &cname);
if (err)
{
log_error ("resolving '%s' failed: %s\n", name, gpg_strerror (err));
@@ -566,7 +569,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
continue;
dirmngr_tick (ctrl);
- add_host (name, is_pool, ai, 0, 0);
+ add_host (ctrl, name, is_pool, ai, 0, 0);
new_hosts = 1;
}
@@ -624,7 +627,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
* hosttable. */
char *host;
- err = resolve_dns_name (hi->name, 0, 0, SOCK_STREAM, &aibuf, NULL);
+ err = resolve_dns_name (ctrl, hi->name, 0, 0, SOCK_STREAM, &aibuf, NULL);
if (!err)
{
for (ai = aibuf; ai; ai = ai->next)
@@ -632,7 +635,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
if ((!opt.disable_ipv6 && ai->family == AF_INET6)
|| (!opt.disable_ipv4 && ai->family == AF_INET))
{
- err = resolve_dns_addr (ai->addr, ai->addrlen, 0, &host);
+ err = resolve_dns_addr (ctrl,
+ ai->addr, ai->addrlen, 0, &host);
if (!err)
{
/* Okay, we return the first found name. */
@@ -755,9 +759,15 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
if (!name || !*name || !strcmp (name, "localhost"))
return 0;
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
idx = find_hostinfo (name);
if (idx == -1)
- return gpg_error (GPG_ERR_NOT_FOUND);
+ {
+ err = gpg_error (GPG_ERR_NOT_FOUND);
+ goto leave;
+ }
hi = hosttable[idx];
if (alive && hi->dead)
@@ -816,6 +826,10 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
}
}
+ leave:
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
+
return err;
}
@@ -836,7 +850,9 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
if (err)
return err;
- /* FIXME: We need a lock for the hosttable. */
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
curtime = gnupg_get_time ();
for (idx=0; idx < hosttable_size; idx++)
if ((hi=hosttable[idx]))
@@ -865,7 +881,7 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
/* Turn the numerical IP address string into an AI and
* then do a DNS PTR lookup. */
- if (!resolve_dns_name (hi->name, 0, 0,
+ if (!resolve_dns_name (ctrl, hi->name, 0, 0,
SOCK_STREAM,
&aibuf, &canon))
{
@@ -876,7 +892,7 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
}
for (ai = aibuf; !canon && ai; ai = ai->next)
{
- resolve_dns_addr (ai->addr, ai->addrlen,
+ resolve_dns_addr (ctrl, ai->addr, ai->addrlen,
DNS_WITHBRACKET, &canon);
if (canon && is_ip_address (canon))
{
@@ -896,14 +912,14 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
/* Get the IP address as a string from a name. Note
* that resolve_dns_addr allocates CANON on success
* and thus terminates the loop. */
- if (!resolve_dns_name (hi->name, 0,
+ if (!resolve_dns_name (ctrl, hi->name, 0,
hi->v6? AF_INET6 : AF_INET,
SOCK_STREAM,
&aibuf, NULL))
{
for (ai = aibuf; !canon && ai; ai = ai->next)
{
- resolve_dns_addr (ai->addr, ai->addrlen,
+ resolve_dns_addr (ctrl, ai->addr, ai->addrlen,
DNS_NUMERICHOST|DNS_WITHBRACKET,
&canon);
}
@@ -929,12 +945,12 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
diedstr? ")":"" );
xfree (died);
if (err)
- return err;
+ goto leave;
if (hi->cname)
err = ks_printf_help (ctrl, " . %s", hi->cname);
if (err)
- return err;
+ goto leave;
if (hi->pool)
{
@@ -949,14 +965,21 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
put_membuf( &mb, "", 1);
p = get_membuf (&mb, NULL);
if (!p)
- return gpg_error_from_syserror ();
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
err = ks_print_help (ctrl, p);
xfree (p);
if (err)
- return err;
+ goto leave;
}
}
- return 0;
+
+ leave:
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
+ return err;
}
@@ -1025,9 +1048,16 @@ make_host_part (ctrl_t ctrl,
protocol = KS_PROTOCOL_HKP;
}
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
portstr[0] = 0;
err = map_host (ctrl, host, srvtag, force_reselect, protocol,
&hostname, portstr, r_httpflags, r_httphost);
+
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
+
if (err)
return err;
@@ -1101,6 +1131,9 @@ ks_hkp_housekeeping (time_t curtime)
int idx;
hostinfo_t hi;
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
for (idx=0; idx < hosttable_size; idx++)
{
hi = hosttable[idx];
@@ -1117,6 +1150,9 @@ ks_hkp_housekeeping (time_t curtime)
log_info ("resurrected host '%s'", hi->name);
}
}
+
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
}
@@ -1128,6 +1164,9 @@ ks_hkp_reload (void)
int idx, count;
hostinfo_t hi;
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
for (idx=count=0; idx < hosttable_size; idx++)
{
hi = hosttable[idx];
@@ -1141,6 +1180,9 @@ ks_hkp_reload (void)
}
if (count)
log_info ("number of resurrected hosts: %d", count);
+
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
}
@@ -1182,7 +1224,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
http_session_set_timeout (session, ctrl->timeout);
once_more:
- err = http_open (&http,
+ err = http_open (ctrl, &http,
post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
request,
httphost,
@@ -1339,7 +1381,7 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
int retry = 0;
/* Fixme: Should we disable all hosts of a protocol family if a
- * request for an address of that familiy returned ENETDOWN? */
+ * request for an address of that family returned ENETDOWN? */
switch (gpg_err_code (err))
{
@@ -1493,7 +1535,11 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
goto again;
}
if (err)
- goto leave;
+ {
+ if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+ dirmngr_status (ctrl, "SOURCE", hostport, NULL);
+ goto leave;
+ }
err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
if (err)
@@ -1628,7 +1674,11 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
goto again;
}
if (err)
- goto leave;
+ {
+ if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+ dirmngr_status (ctrl, "SOURCE", hostport, NULL);
+ goto leave;
+ }
err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
if (err)
@@ -1748,3 +1798,13 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
xfree (httphost);
return err;
}
+
+void
+ks_hkp_init (void)
+{
+ int err;
+
+ err = npth_mutex_init (&hosttable_lock, NULL);
+ if (err)
+ log_fatal ("error initializing mutex: %s\n", strerror (err));
+}
diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
index 946c92769..9e6b9e1f5 100644
--- a/dirmngr/ks-engine-http.c
+++ b/dirmngr/ks-engine-http.c
@@ -103,7 +103,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags,
http_session_set_timeout (session, ctrl->timeout);
*r_fp = NULL;
- err = http_open (&http,
+ err = http_open (ctrl, &http,
HTTP_REQ_GET,
url,
/* httphost */ NULL,
diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c
index f50ba50d0..d94bd5e25 100644
--- a/dirmngr/ks-engine-ldap.c
+++ b/dirmngr/ks-engine-ldap.c
@@ -1694,26 +1694,16 @@ extract_attributes (LDAPMod ***modlist, char *line)
if (is_pub || is_sub)
{
- char *size = fields[2];
- int val = atoi (size);
- size = NULL;
+ char padded[6];
+ int val;
- if (val > 0)
- {
- /* We zero pad this on the left to make PGP happy. */
- char padded[6];
- if (val < 99999 && val > 0)
- {
- snprintf (padded, sizeof padded, "%05u", val);
- size = padded;
- }
- }
-
- if (size)
- {
- if (is_pub || is_sub)
- modlist_add (modlist, "pgpKeySize", size);
- }
+ val = atoi (fields[2]);
+ if (val < 99999 && val > 0)
+ {
+ /* We zero pad this on the left to make PGP happy. */
+ snprintf (padded, sizeof padded, "%05u", val);
+ modlist_add (modlist, "pgpKeySize", padded);
+ }
}
if (is_pub)
@@ -1736,10 +1726,7 @@ extract_attributes (LDAPMod ***modlist, char *line)
}
if (algo)
- {
- if (is_pub)
- modlist_add (modlist, "pgpKeyType", algo);
- }
+ modlist_add (modlist, "pgpKeyType", algo);
}
if (is_pub || is_sub || is_sig)
diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c
index cb3c0b763..a04bb97a2 100644
--- a/dirmngr/ldap.c
+++ b/dirmngr/ldap.c
@@ -388,7 +388,7 @@ parse_one_pattern (const char *pattern)
}
/* Take the string STRING and escape it according to the URL rules.
- Retun a newly allocated string. */
+ Return a newly allocated string. */
static char *
escape4url (const char *string)
{
diff --git a/dirmngr/misc.c b/dirmngr/misc.c
index 1270b834d..9cedf911c 100644
--- a/dirmngr/misc.c
+++ b/dirmngr/misc.c
@@ -515,7 +515,7 @@ host_and_port_from_url (const char *url, int *port)
if ((p = strchr (buf, '/')))
*p++ = 0;
strlwr (buf);
- if ((p = strchr (p, ':')))
+ if ((p = strchr (buf, ':')))
{
*p++ = 0;
*port = atoi (p);
@@ -637,7 +637,7 @@ armor_data (char **r_string, const void *data, size_t datalen)
}
-/* Copy all data from IN to OUT. OUT may be NULL to use this fucntion
+/* Copy all data from IN to OUT. OUT may be NULL to use this function
* as a dummy reader. */
gpg_error_t
copy_stream (estream_t in, estream_t out)
diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
index 22391c32d..79c252d87 100644
--- a/dirmngr/ocsp.c
+++ b/dirmngr/ocsp.c
@@ -172,7 +172,7 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
}
once_more:
- err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL,
+ err = http_open (ctrl, &http, HTTP_REQ_POST, url, NULL, NULL,
((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
| (dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
| (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
@@ -343,7 +343,7 @@ validate_responder_cert (ctrl_t ctrl, ksba_cert_t cert,
Note, that in theory we could simply ask the client via an
inquire to validate a certificate but this might involve
- calling DirMngr again recursivly - we can't do that as of now
+ calling DirMngr again recursively - we can't do that as of now
(neither DirMngr nor gpgsm have the ability for concurrent
access to DirMngr. */
@@ -391,7 +391,7 @@ check_signature_core (ctrl_t ctrl, ksba_cert_t cert, gcry_sexp_t s_sig,
}
-/* Check the signature of an OCSP repsonse. OCSP is the context,
+/* Check the signature of an OCSP response. OCSP is the context,
S_SIG the signature value and MD the handle of the hash we used for
the response. This function automagically finds the correct public
key. If SIGNER_FPR_LIST is not NULL, the default OCSP reponder has been
@@ -653,6 +653,33 @@ ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr,
if (err)
goto leave;
+ /* It is sometimes useful to know the responder ID. */
+ if (opt.verbose)
+ {
+ char *resp_name;
+ ksba_sexp_t resp_keyid;
+
+ err = ksba_ocsp_get_responder_id (ocsp, &resp_name, &resp_keyid);
+ if (err)
+ log_info (_("error getting responder ID: %s\n"), gpg_strerror (err));
+ else
+ {
+ log_info ("responder id: ");
+ if (resp_name)
+ log_printf ("'/%s' ", resp_name);
+ if (resp_keyid)
+ {
+ log_printf ("{");
+ dump_serial (resp_keyid);
+ log_printf ("} ");
+ }
+ log_printf ("\n");
+ }
+ ksba_free (resp_name);
+ ksba_free (resp_keyid);
+ err = 0;
+ }
+
/* We got a useful answer, check that the answer has a valid signature. */
sigval = ksba_ocsp_get_sig_val (ocsp, produced_at);
if (!sigval || !*produced_at)
@@ -761,7 +788,7 @@ ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr,
err = gpg_error (GPG_ERR_TIME_CONFLICT);
}
- /* Check that we are not beyound NEXT_UPDATE (plus some extra time). */
+ /* Check that we are not beyond NEXT_UPDATE (plus some extra time). */
if (*next_update)
{
gnupg_copy_time (tmp_time, next_update);
diff --git a/dirmngr/server.c b/dirmngr/server.c
index b7cdb24c9..4a242539b 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -666,7 +666,7 @@ static const char hlp_dns_cert[] =
static gpg_error_t
cmd_dns_cert (assuan_context_t ctx, char *line)
{
- /* ctrl_t ctrl = assuan_get_pointer (ctx); */
+ ctrl_t ctrl = assuan_get_pointer (ctx);
gpg_error_t err = 0;
int pka_mode, dane_mode;
char *mbox = NULL;
@@ -731,7 +731,7 @@ cmd_dns_cert (assuan_context_t ctx, char *line)
/* We lowercase ascii characters but the DANE I-D does not allow
this. FIXME: Check after the release of the RFC whether to
change this. */
- mbox = mailbox_from_userid (line);
+ mbox = mailbox_from_userid (line, 0);
if (!mbox || !(domain = strchr (mbox, '@')))
{
err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
@@ -782,7 +782,7 @@ cmd_dns_cert (assuan_context_t ctx, char *line)
else
name = line;
- err = get_dns_cert (name, certtype, &key, &keylen, &fpr, &fprlen, &url);
+ err = get_dns_cert (ctrl, name, certtype, &key, &keylen, &fpr, &fprlen, &url);
if (err)
goto leave;
@@ -837,8 +837,11 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
gpg_error_t err = 0;
char *mbox = NULL;
char *domainbuf = NULL;
- char *domain; /* Points to mbox or domainbuf. */
- char *domain_orig;/* Points to mbox. */
+ char *domain; /* Points to mbox or domainbuf. This is used to
+ * connect to the host. */
+ char *domain_orig;/* Points to mbox. This is the used for the
+ * query; i.e. the domain part of the
+ * addrspec. */
char sha1buf[20];
char *uri = NULL;
char *encodedhash = NULL;
@@ -847,6 +850,7 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
int is_wkd_query; /* True if this is a real WKD query. */
int no_log = 0;
char portstr[20] = { 0 };
+ int subdomain_mode = 0;
opt_submission_addr = has_option (line, "--submission-address");
opt_policy_flags = has_option (line, "--policy-flags");
@@ -855,7 +859,7 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
line = skip_options (line);
is_wkd_query = !(opt_policy_flags || opt_submission_addr);
- mbox = mailbox_from_userid (line);
+ mbox = mailbox_from_userid (line, 0);
if (!mbox || !(domain = strchr (mbox, '@')))
{
err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
@@ -864,7 +868,8 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
*domain++ = 0;
domain_orig = domain;
- /* First check whether we already know that the domain does not
+
+ /* Let's check whether we already know that the domain does not
* support WKD. */
if (is_wkd_query)
{
@@ -875,18 +880,63 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
}
}
- /* Check for SRV records. */
- if (1)
+
+ /* First try the new "openpgp" subdomain. We check that the domain
+ * is valid because it is later used as an unescaped filename part
+ * of the URI. */
+ if (is_valid_domain_name (domain_orig))
+ {
+ dns_addrinfo_t aibuf;
+
+ domainbuf = strconcat ( "openpgpkey.", domain_orig, NULL);
+ if (!domainbuf)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ /* FIXME: We should put a cache into dns-stuff because the same
+ * query (with a different port and socket type, though) will be
+ * done later by http function. */
+ err = resolve_dns_name (ctrl, domainbuf, 0, 0, 0, &aibuf, NULL);
+ if (err)
+ {
+ err = 0;
+ xfree (domainbuf);
+ domainbuf = NULL;
+ }
+ else /* Got a subdomain. */
+ {
+ free_dns_addrinfo (aibuf);
+ subdomain_mode = 1;
+ domain = domainbuf;
+ }
+ }
+
+ /* Check for SRV records unless we have a subdomain. */
+ if (!subdomain_mode)
{
struct srventry *srvs;
unsigned int srvscount;
size_t domainlen, targetlen;
int i;
- err = get_dns_srv (domain, "openpgpkey", NULL, &srvs, &srvscount);
+ err = get_dns_srv (ctrl, domain, "openpgpkey", NULL, &srvs, &srvscount);
if (err)
goto leave;
+ /* Check for rogue DNS names. */
+ for (i = 0; i < srvscount; i++)
+ {
+ if (!is_valid_domain_name (srvs[i].target))
+ {
+ err = gpg_error (GPG_ERR_DNS_ADDRESS);
+ log_error ("rogue openpgpkey SRV record for '%s'\n", domain);
+ xfree (srvs);
+ goto leave;
+ }
+ }
+
/* Find the first target which also ends in DOMAIN or is equal
* to DOMAIN. */
domainlen = strlen (domain);
@@ -919,6 +969,7 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
xfree (srvs);
}
+ /* Prepare the hash of the local part. */
gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
encodedhash = zb32_encode (sha1buf, 8*20);
if (!encodedhash)
@@ -932,7 +983,10 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
uri = strconcat ("https://",
domain,
portstr,
- "/.well-known/openpgpkey/submission-address",
+ "/.well-known/openpgpkey/",
+ subdomain_mode? domain_orig : "",
+ subdomain_mode? "/" : "",
+ "submission-address",
NULL);
}
else if (opt_policy_flags)
@@ -940,24 +994,39 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
uri = strconcat ("https://",
domain,
portstr,
- "/.well-known/openpgpkey/policy",
+ "/.well-known/openpgpkey/",
+ subdomain_mode? domain_orig : "",
+ subdomain_mode? "/" : "",
+ "policy",
NULL);
}
else
{
- uri = strconcat ("https://",
- domain,
- portstr,
- "/.well-known/openpgpkey/hu/",
- encodedhash,
- NULL);
- no_log = 1;
- if (uri)
+ char *escapedmbox;
+
+ escapedmbox = http_escape_string (mbox, "%;?&=");
+ if (escapedmbox)
{
- err = dirmngr_status_printf (ctrl, "SOURCE", "https://%s%s",
- domain, portstr);
- if (err)
- goto leave;
+ uri = strconcat ("https://",
+ domain,
+ portstr,
+ "/.well-known/openpgpkey/",
+ subdomain_mode? domain_orig : "",
+ subdomain_mode? "/" : "",
+ "hu/",
+ encodedhash,
+ "?l=",
+ escapedmbox,
+ NULL);
+ xfree (escapedmbox);
+ no_log = 1;
+ if (uri)
+ {
+ err = dirmngr_status_printf (ctrl, "SOURCE", "https://%s%s",
+ domain, portstr);
+ if (err)
+ goto leave;
+ }
}
}
if (!uri)
@@ -2668,6 +2737,20 @@ cmd_reloaddirmngr (assuan_context_t ctx, char *line)
}
+static const char hlp_flushcrls[] =
+ "FLUSHCRLS\n"
+ "\n"
+ "Remove all cached CRLs from memory and\n"
+ "the file system.";
+static gpg_error_t
+cmd_flushcrls (assuan_context_t ctx, char *line)
+{
+ (void)line;
+
+ return leave_cmd (ctx, crl_cache_flush () ? GPG_ERR_GENERAL : 0);
+}
+
+
/* Tell the assuan library about our commands. */
static int
@@ -2698,6 +2781,7 @@ register_commands (assuan_context_t ctx)
{ "LOADSWDB", cmd_loadswdb, hlp_loadswdb },
{ "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
{ "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
+ { "FLUSHCRLS", cmd_flushcrls, hlp_flushcrls },
{ NULL, NULL }
};
int i, j, rc;
@@ -2977,7 +3061,7 @@ dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
va_list arg_ptr;
assuan_context_t ctx;
- if (!ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
+ if (!ctrl || !ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
return 0;
va_start (arg_ptr, format);
diff --git a/dirmngr/t-dns-stuff.c b/dirmngr/t-dns-stuff.c
index 5a3ede15b..6d52160bc 100644
--- a/dirmngr/t-dns-stuff.c
+++ b/dirmngr/t-dns-stuff.c
@@ -178,7 +178,7 @@ main (int argc, char **argv)
if (verbose || any_options)
printf ("CERT lookup on '%s'\n", name);
- err = get_dns_cert (name, DNS_CERTTYPE_ANY, &key, &keylen,
+ err = get_dns_cert (NULL, name, DNS_CERTTYPE_ANY, &key, &keylen,
&fpr, &fpr_len, &url);
if (err)
printf ("get_dns_cert failed: %s <%s>\n",
@@ -218,7 +218,7 @@ main (int argc, char **argv)
char *cname;
printf ("CNAME lookup on '%s'\n", name);
- err = get_dns_cname (name, &cname);
+ err = get_dns_cname (NULL, name, &cname);
if (err)
printf ("get_dns_cname failed: %s <%s>\n",
gpg_strerror (err), gpg_strsource (err));
@@ -234,7 +234,7 @@ main (int argc, char **argv)
unsigned int count;
int i;
- err = get_dns_srv (name? name : "_hkp._tcp.wwwkeys.pgp.net",
+ err = get_dns_srv (NULL, name? name : "_hkp._tcp.wwwkeys.pgp.net",
NULL, NULL, &srv, &count);
if (err)
printf ("get_dns_srv failed: %s <%s>\n",
@@ -261,7 +261,7 @@ main (int argc, char **argv)
printf ("Lookup on '%s'\n", name);
- err = resolve_dns_name (name, 0, 0, SOCK_STREAM, &aibuf, &cname);
+ err = resolve_dns_name (NULL, name, 0, 0, SOCK_STREAM, &aibuf, &cname);
if (err)
{
fprintf (stderr, PGM": resolving '%s' failed: %s\n",
@@ -278,7 +278,7 @@ main (int argc, char **argv)
ai->family == AF_INET? "inet4" : "? ",
ai->socktype, ai->protocol);
- err = resolve_dns_addr (ai->addr, ai->addrlen,
+ err = resolve_dns_addr (NULL, ai->addr, ai->addrlen,
(DNS_NUMERICHOST
| (opt_bracket? DNS_WITHBRACKET:0)),
&host);
@@ -290,7 +290,7 @@ main (int argc, char **argv)
xfree (host);
}
- err = resolve_dns_addr (ai->addr, ai->addrlen,
+ err = resolve_dns_addr (NULL, ai->addr, ai->addrlen,
(opt_bracket? DNS_WITHBRACKET:0),
&host);
if (err)
diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c
index 440633db4..8b32613b6 100644
--- a/dirmngr/t-http.c
+++ b/dirmngr/t-http.c
@@ -137,7 +137,7 @@ my_http_tls_verify_cb (void *opaque,
(void)session;
(void)http_flags;
- /* Get the peer's certs fron ntbtls. */
+ /* Get the peer's certs from ntbtls. */
for (idx = 0;
(cert = ntbtls_x509_get_peer_cert (tls_context, idx)); idx++)
{
@@ -438,7 +438,7 @@ main (int argc, char **argv)
if (session)
http_session_set_timeout (session, timeout);
- rc = http_open_document (&hd, *argv, NULL, my_http_flags,
+ rc = http_open_document (NULL, &hd, *argv, NULL, my_http_flags,
NULL, session, NULL, NULL);
if (rc)
{
diff --git a/dirmngr/t-support.c b/dirmngr/t-support.c
new file mode 100644
index 000000000..fc9546a7d
--- /dev/null
+++ b/dirmngr/t-support.c
@@ -0,0 +1,43 @@
+/* t-support.c - Module test support (stubs etc).
+ * Copyright (C) 2018 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-3.0+
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+
+#include "../common/util.h"
+#include "dirmngr-status.h"
+#include "t-support.h"
+
+
+
+/* Stub for testing. See server.c for the real implementation. */
+gpg_error_t
+dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
+ const char *format, ...)
+{
+ (void)ctrl;
+ (void)keyword;
+ (void)format;
+
+ return 0;
+}
diff --git a/dirmngr/workqueue.c b/dirmngr/workqueue.c
index 2cb8573e8..a47cdebc8 100644
--- a/dirmngr/workqueue.c
+++ b/dirmngr/workqueue.c
@@ -116,7 +116,7 @@ workqueue_add_task (wqtask_t func, const char *args, unsigned int session_id,
/* Run the task described by ITEM. ITEM must have been detached from
- * the workqueue; its ownership is transferred to this fucntion. */
+ * the workqueue; its ownership is transferred to this function. */
static void
run_a_task (ctrl_t ctrl, wqitem_t item)
{