From c9f5aa15793b3c05c1b92af401b23ab34d3e6196 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 19 Nov 2015 14:29:36 +0100 Subject: [PATCH] dirmngr: Support hkp server pools using SRV records. * dirmngr/ks-engine-hkp.c (map_host): Handle SRV records. -- Signed-off-by: Justus Winter GnuPG-bug-id: 1788 --- dirmngr/ks-engine-hkp.c | 47 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index be0280b56..3ea3245b7 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -415,6 +415,11 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, int refidx; int is_pool = 0; char *cname; +#ifdef USE_DNS_SRV + char *srvrecord; + struct srventry *srvs; + int srvscount; +#endif /* USE_DNS_SRV */ reftblsize = 100; reftbl = xtrymalloc (reftblsize * sizeof *reftbl); @@ -431,6 +436,45 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, } hi = hosttable[idx]; +#ifdef USE_DNS_SRV + /* Check for SRV records. */ + srvrecord = xtryasprintf ("_hkp._tcp.%s", name); + if (srvrecord == NULL) + { + err = gpg_error_from_syserror (); + xfree (reftbl); + return err; + } + + srvscount = getsrv (srvrecord, &srvs); + xfree (srvrecord); + if (srvscount < 0) + { + err = gpg_error_from_syserror (); + xfree (reftbl); + return err; + } + + if (srvscount > 0) + { + int i; + is_pool = srvscount > 1; + + for (i = 0; i < srvscount; i++) + { + err = resolve_dns_name (srvs[i].target, 0, + AF_UNSPEC, SOCK_STREAM, + &ai, &cname); + if (err) + continue; + dirmngr_tick (ctrl); + add_host (name, ai, is_pool, reftbl, reftblsize, &refidx); + } + + xfree (srvs); + } +#endif /* USE_DNS_SRV */ + /* 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); @@ -446,7 +490,8 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect, the canonical name of the pool as the virtual host along with the IP addresses. If it is not a pool, we use the specified name. */ - is_pool = arecords_is_pool (aibuf); + if (! is_pool) + is_pool = arecords_is_pool (aibuf); if (is_pool && cname) { hi->cname = cname;