dirmngr: Support hkp server pools using SRV records.
authorJustus Winter <justus@g10code.com>
Thu, 19 Nov 2015 13:29:36 +0000 (14:29 +0100)
committerJustus Winter <justus@g10code.com>
Mon, 23 Nov 2015 13:00:48 +0000 (14:00 +0100)
* dirmngr/ks-engine-hkp.c (map_host): Handle SRV records.
--
Signed-off-by: Justus Winter <justus@g10code.com>
GnuPG-bug-id: 1788

dirmngr/ks-engine-hkp.c

index be0280b..3ea3245 100644 (file)
@@ -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;