po: Update Japanese Translation.
[gnupg.git] / dirmngr / dns-stuff.c
1 /* dns-stuff.c - DNS related code including CERT RR (rfc-4398)
2  * Copyright (C) 2003, 2005, 2006, 2009 Free Software Foundation, Inc.
3  * Copyright (C) 2005, 2006, 2009, 2015. 2016 Werner Koch
4  *
5  * This file is part of GnuPG.
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of either
9  *
10  *   - the GNU Lesser General Public License as published by the Free
11  *     Software Foundation; either version 3 of the License, or (at
12  *     your option) any later version.
13  *
14  * or
15  *
16  *   - the GNU General Public License as published by the Free
17  *     Software Foundation; either version 2 of the License, or (at
18  *     your option) any later version.
19  *
20  * or both in parallel, as here.
21  *
22  * This file is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, see <https://www.gnu.org/licenses/>.
29  */
30
31 #include <config.h>
32 #include <sys/types.h>
33 #ifdef HAVE_W32_SYSTEM
34 # define WIN32_LEAN_AND_MEAN
35 # ifdef HAVE_WINSOCK2_H
36 #  include <winsock2.h>
37 # endif
38 # include <windows.h>
39 # include <iphlpapi.h>
40 #else
41 # if HAVE_SYSTEM_RESOLVER
42 #  include <netinet/in.h>
43 #  include <arpa/nameser.h>
44 #  include <resolv.h>
45 # endif
46 # include <netdb.h>
47 #endif
48 #ifdef HAVE_STAT
49 # include <sys/stat.h>
50 #endif
51 #include <string.h>
52 #include <unistd.h>
53
54
55 /* William Ahern's DNS library, included as a source copy.  */
56 #ifdef USE_LIBDNS
57 # include "dns.h"
58 #endif
59
60 /* dns.c has a dns_p_free but it is not exported.  We use our own
61  * wrapper here so that we do not accidentally use xfree which would
62  * be wrong for dns.c allocated data.  */
63 #define dns_free(a)  free ((a))
64
65
66 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
67 # undef USE_NPTH
68 #endif
69 #ifdef USE_NPTH
70 # include <npth.h>
71 #endif
72
73 #include "./dirmngr-err.h"
74 #include "../common/util.h"
75 #include "../common/host2net.h"
76 #include "dirmngr-status.h"
77 #include "dns-stuff.h"
78
79 #ifdef USE_NPTH
80 # define my_unprotect()        npth_unprotect ()
81 # define my_protect()          npth_protect ()
82 #else
83 # define my_unprotect()        do { } while(0)
84 # define my_protect()          do { } while(0)
85 #endif
86
87 /* We allow the use of 0 instead of AF_UNSPEC - check this assumption.  */
88 #if AF_UNSPEC != 0
89 # error AF_UNSPEC does not have the value 0
90 #endif
91
92 /* Windows does not support the AI_ADDRCONFIG flag - use zero instead.  */
93 #ifndef AI_ADDRCONFIG
94 # define AI_ADDRCONFIG 0
95 #endif
96
97 /* Not every installation has gotten around to supporting SRVs or
98    CERTs yet... */
99 #ifndef T_SRV
100 #define T_SRV 33
101 #endif
102 #undef T_CERT
103 #define T_CERT 37
104
105 /* The standard SOCKS and TOR ports.  */
106 #define SOCKS_PORT 1080
107 #define TOR_PORT   9050
108 #define TOR_PORT2  9150   /* (Used by the Tor browser) */
109
110
111 /* The default nameserver used in Tor mode.  */
112 #define DEFAULT_NAMESERVER "8.8.8.8"
113
114 /* The default timeout in seconds for libdns requests.  */
115 #define DEFAULT_TIMEOUT 30
116
117
118 #define RESOLV_CONF_NAME "/etc/resolv.conf"
119
120 /* Two flags to enable verbose and debug mode.  */
121 static int opt_verbose;
122 static int opt_debug;
123
124 /* The timeout in seconds for libdns requests.  */
125 static int opt_timeout;
126
127 /* The flag to disable IPv4 access - right now this only skips
128  * returned A records.  */
129 static int opt_disable_ipv4;
130
131 /* The flag to disable IPv6 access - right now this only skips
132  * returned AAAA records.  */
133 static int opt_disable_ipv6;
134
135 /* If set force the use of the standard resolver.  */
136 static int standard_resolver;
137
138 /* If set use recursive resolver when available. */
139 static int recursive_resolver;
140
141 /* If set Tor mode shall be used.  */
142 static int tor_mode;
143
144 /* A string with the nameserver IP address used with Tor.
145   (40 should be sufficient for v6 but we add some extra for a scope.) */
146 static char tor_nameserver[40+20];
147
148 /* Two strings to hold the credentials presented to Tor.  */
149 static char tor_socks_user[30];
150 static char tor_socks_password[20];
151
152
153 #ifdef USE_LIBDNS
154 /* Libdns global data.  */
155 struct libdns_s
156 {
157   struct dns_resolv_conf *resolv_conf;
158   struct dns_hosts *hosts;
159   struct dns_hints *hints;
160
161   struct sockaddr_storage socks_host;
162 } libdns;
163
164 /* If this flag is set, libdns shall be reinited for the next use.  */
165 static int libdns_reinit_pending;
166
167 /* The Tor port to be used.  */
168 static int libdns_tor_port;
169
170 #endif /*USE_LIBDNS*/
171
172
173 /* Calling this function with YES set to True forces the use of the
174  * standard resolver even if dirmngr has been built with support for
175  * an alternative resolver.  */
176 void
177 enable_standard_resolver (int yes)
178 {
179   standard_resolver = yes;
180 }
181
182
183 /* Return true if the standard resolver is used.  */
184 int
185 standard_resolver_p (void)
186 {
187   return standard_resolver;
188 }
189
190
191 /* Calling this function with YES switches libdns into recursive mode.
192  * It has no effect on the standard resolver.  */
193 void
194 enable_recursive_resolver (int yes)
195 {
196   recursive_resolver = yes;
197 #ifdef USE_LIBDNS
198   libdns_reinit_pending = 1;
199 #endif
200 }
201
202
203 /* Return true iff the recursive resolver is used.  */
204 int
205 recursive_resolver_p (void)
206 {
207 #if USE_LIBDNS
208   return !standard_resolver && recursive_resolver;
209 #else
210   return 0;
211 #endif
212 }
213
214
215 /* Puts this module eternally into Tor mode.  When called agained with
216  * NEW_CIRCUIT request a new TOR circuit for the next DNS query.  */
217 void
218 enable_dns_tormode (int new_circuit)
219 {
220   if (!*tor_socks_user || new_circuit)
221     {
222       static unsigned int counter;
223
224       gpgrt_snprintf (tor_socks_user, sizeof tor_socks_user,
225                       "dirmngr-%lu", (unsigned long)getpid ());
226       gpgrt_snprintf (tor_socks_password, sizeof tor_socks_password,
227                       "p%u", counter);
228       counter++;
229     }
230   tor_mode = 1;
231 }
232
233
234 /* Disable tor mode.  */
235 void
236 disable_dns_tormode (void)
237 {
238   tor_mode = 0;
239 }
240
241
242 /* Set verbosity and debug mode for this module. */
243 void
244 set_dns_verbose (int verbose, int debug)
245 {
246   opt_verbose = verbose;
247   opt_debug = debug;
248 }
249
250
251 /* Set the Disable-IPv4 flag so that the name resolver does not return
252  * A addresses.  */
253 void
254 set_dns_disable_ipv4 (int yes)
255 {
256   opt_disable_ipv4 = !!yes;
257 }
258
259
260 /* Set the Disable-IPv6 flag so that the name resolver does not return
261  * AAAA addresses.  */
262 void
263 set_dns_disable_ipv6 (int yes)
264 {
265   opt_disable_ipv6 = !!yes;
266 }
267
268
269 /* Set the timeout for libdns requests to SECONDS.  A value of 0 sets
270  * the default timeout and values are capped at 10 minutes.  */
271 void
272 set_dns_timeout (int seconds)
273 {
274   if (!seconds)
275     seconds = DEFAULT_TIMEOUT;
276   else if (seconds < 1)
277     seconds = 1;
278   else if (seconds > 600)
279     seconds = 600;
280
281   opt_timeout = seconds;
282 }
283
284
285 /* Change the default IP address of the nameserver to IPADDR.  The
286    address needs to be a numerical IP address and will be used for the
287    next DNS query.  Note that this is only used in Tor mode.  */
288 void
289 set_dns_nameserver (const char *ipaddr)
290 {
291   strncpy (tor_nameserver, ipaddr? ipaddr : DEFAULT_NAMESERVER,
292            sizeof tor_nameserver -1);
293   tor_nameserver[sizeof tor_nameserver -1] = 0;
294 #ifdef USE_LIBDNS
295   libdns_reinit_pending = 1;
296   libdns_tor_port = 0;  /* Start again with the default port.  */
297 #endif
298 }
299
300
301 /* Free an addressinfo linked list as returned by resolve_dns_name.  */
302 void
303 free_dns_addrinfo (dns_addrinfo_t ai)
304 {
305   while (ai)
306     {
307       dns_addrinfo_t next = ai->next;
308       xfree (ai);
309       ai = next;
310     }
311 }
312
313
314 #ifndef HAVE_W32_SYSTEM
315 /* Return H_ERRNO mapped to a gpg-error code.  Will never return 0. */
316 static gpg_error_t
317 get_h_errno_as_gpg_error (void)
318 {
319   gpg_err_code_t ec;
320
321   switch (h_errno)
322     {
323     case HOST_NOT_FOUND: ec = GPG_ERR_NO_NAME; break;
324     case TRY_AGAIN:      ec = GPG_ERR_TRY_LATER; break;
325     case NO_RECOVERY:    ec = GPG_ERR_SERVER_FAILED; break;
326     case NO_DATA:        ec = GPG_ERR_NO_DATA; break;
327     default:             ec = GPG_ERR_UNKNOWN_ERRNO; break;
328     }
329   return gpg_error (ec);
330 }
331 #endif /*!HAVE_W32_SYSTEM*/
332
333 static gpg_error_t
334 map_eai_to_gpg_error (int ec)
335 {
336   gpg_error_t err;
337
338   switch (ec)
339     {
340     case EAI_AGAIN:     err = gpg_error (GPG_ERR_EAGAIN); break;
341     case EAI_BADFLAGS:  err = gpg_error (GPG_ERR_INV_FLAG); break;
342     case EAI_FAIL:      err = gpg_error (GPG_ERR_SERVER_FAILED); break;
343     case EAI_MEMORY:    err = gpg_error (GPG_ERR_ENOMEM); break;
344 #ifdef EAI_NODATA
345     case EAI_NODATA:    err = gpg_error (GPG_ERR_NO_DATA); break;
346 #endif
347     case EAI_NONAME:    err = gpg_error (GPG_ERR_NO_NAME); break;
348     case EAI_SERVICE:   err = gpg_error (GPG_ERR_NOT_SUPPORTED); break;
349     case EAI_FAMILY:    err = gpg_error (GPG_ERR_EAFNOSUPPORT); break;
350     case EAI_SOCKTYPE:  err = gpg_error (GPG_ERR_ESOCKTNOSUPPORT); break;
351 #ifndef HAVE_W32_SYSTEM
352 # ifdef EAI_ADDRFAMILY
353     case EAI_ADDRFAMILY:err = gpg_error (GPG_ERR_EADDRNOTAVAIL); break;
354 # endif
355     case EAI_SYSTEM:    err = gpg_error_from_syserror (); break;
356 #endif
357     default:            err = gpg_error (GPG_ERR_UNKNOWN_ERRNO); break;
358     }
359   return err;
360 }
361
362
363 #ifdef USE_LIBDNS
364 static gpg_error_t
365 libdns_error_to_gpg_error (int serr)
366 {
367   gpg_err_code_t ec;
368
369   switch (serr)
370     {
371     case 0: ec = 0; break;
372
373     case DNS_ENOBUFS:  ec = GPG_ERR_BUFFER_TOO_SHORT; break;
374     case DNS_EILLEGAL: ec = GPG_ERR_INV_OBJ; break;
375     case DNS_EORDER:   ec = GPG_ERR_INV_ORDER; break;
376     case DNS_ESECTION: ec = GPG_ERR_DNS_SECTION; break;
377     case DNS_EUNKNOWN: ec = GPG_ERR_DNS_UNKNOWN; break;
378     case DNS_EADDRESS: ec = GPG_ERR_DNS_ADDRESS; break;
379     case DNS_ENOQUERY: ec = GPG_ERR_DNS_NO_QUERY; break;
380     case DNS_ENOANSWER:ec = GPG_ERR_DNS_NO_ANSWER; break;
381     case DNS_EFETCHED: ec = GPG_ERR_ALREADY_FETCHED; break;
382     case DNS_ESERVICE: ec = GPG_ERR_NOT_SUPPORTED; break;
383     case DNS_ENONAME:  ec = GPG_ERR_NO_NAME; break;
384     case DNS_EFAIL:    ec = GPG_ERR_SERVER_FAILED; break;
385     case DNS_ECONNFIN: ec = GPG_ERR_DNS_CLOSED; break;
386     case DNS_EVERIFY:  ec = GPG_ERR_DNS_VERIFY; break;
387
388     default:
389       if (serr >= 0)
390         ec = gpg_err_code_from_errno (serr);
391       else
392         ec = GPG_ERR_DNS_UNKNOWN;
393       break;
394     }
395   return gpg_error (ec);
396 }
397 #endif /*USE_LIBDNS*/
398
399
400 /* Return true if resolve.conf changed since it was last loaded.  */
401 #ifdef USE_LIBDNS
402 static int
403 resolv_conf_changed_p (void)
404 {
405 #if defined(HAVE_W32_SYSTEM) || !defined(HAVE_STAT)
406   return 0;
407 #else
408   static time_t last_mtime;
409   const char *fname = RESOLV_CONF_NAME;
410   struct stat statbuf;
411   int changed = 0;
412
413   if (stat (fname, &statbuf))
414     {
415       log_error ("stat'ing '%s' failed: %s\n",
416                  fname, gpg_strerror (gpg_error_from_syserror ()));
417       last_mtime = 1; /* Force a "changed" result the next time stat
418                        * works.  */
419     }
420   else if (!last_mtime)
421     last_mtime = statbuf.st_mtime;
422   else if (last_mtime != statbuf.st_mtime)
423     {
424       changed = 1;
425       last_mtime = statbuf.st_mtime;
426     }
427
428   return changed;
429 #endif
430 }
431 #endif /*USE_LIBDNS*/
432
433 #ifdef USE_LIBDNS
434 /* Initialize libdns.  Returns 0 on success; prints a diagnostic and
435  * returns an error code on failure.  */
436 static gpg_error_t
437 libdns_init (ctrl_t ctrl)
438 {
439   gpg_error_t err;
440   struct libdns_s ld;
441   int derr;
442   char *cfgstr = NULL;
443   const char *fname = NULL;
444
445   if (libdns.resolv_conf)
446     return 0; /* Already initialized.  */
447
448   memset (&ld, 0, sizeof ld);
449
450   ld.resolv_conf = dns_resconf_open (&derr);
451   if (!ld.resolv_conf)
452     {
453       err = libdns_error_to_gpg_error (derr);
454       log_error ("failed to allocate DNS resconf object: %s\n",
455                  gpg_strerror (err));
456       goto leave;
457     }
458
459   if (tor_mode)
460     {
461       if (!*tor_nameserver)
462         set_dns_nameserver (NULL);
463
464       if (!libdns_tor_port)
465         libdns_tor_port = TOR_PORT;
466
467       cfgstr = xtryasprintf ("[%s]:53", tor_nameserver);
468       if (!cfgstr)
469         err = gpg_error_from_syserror ();
470       else
471         err = libdns_error_to_gpg_error
472           (dns_resconf_pton (&ld.resolv_conf->nameserver[0], cfgstr));
473       if (err)
474         log_error ("failed to set nameserver '%s': %s\n",
475                    cfgstr, gpg_strerror (err));
476       if (err)
477         goto leave;
478
479       ld.resolv_conf->options.tcp = DNS_RESCONF_TCP_SOCKS;
480
481       xfree (cfgstr);
482       cfgstr = xtryasprintf ("[%s]:%d", "127.0.0.1", libdns_tor_port);
483       if (!cfgstr)
484         err = gpg_error_from_syserror ();
485       else
486         err = libdns_error_to_gpg_error
487           (dns_resconf_pton (&ld.socks_host, cfgstr));
488       if (err)
489         {
490           log_error ("failed to set socks server '%s': %s\n",
491                      cfgstr, gpg_strerror (err));
492           goto leave;
493         }
494     }
495   else
496     {
497 #ifdef HAVE_W32_SYSTEM
498       ULONG ninfo_len;
499       PFIXED_INFO ninfo;
500       PIP_ADDR_STRING pip;
501       int idx;
502
503       ninfo_len = 2048;
504       ninfo = xtrymalloc (ninfo_len);
505       if (!ninfo)
506         {
507           err = gpg_error_from_syserror ();
508           goto leave;
509         }
510
511       if (GetNetworkParams (ninfo, &ninfo_len))
512         {
513           log_error ("GetNetworkParms failed: %s\n", w32_strerror (-1));
514           err = gpg_error (GPG_ERR_GENERAL);
515           xfree (ninfo);
516           goto leave;
517         }
518
519       for (idx=0, pip = &(ninfo->DnsServerList);
520            pip && idx < DIM (ld.resolv_conf->nameserver);
521            pip = pip->Next)
522         {
523           if (opt_debug)
524             log_debug ("dns: dnsserver[%d] '%s'\n", idx, pip->IpAddress.String);
525           err = libdns_error_to_gpg_error
526             (dns_resconf_pton (&ld.resolv_conf->nameserver[idx],
527                                pip->IpAddress.String));
528           if (err)
529             log_error ("failed to set nameserver[%d] '%s': %s\n",
530                        idx, pip->IpAddress.String, gpg_strerror (err));
531           else
532             idx++;
533         }
534       xfree (ninfo);
535
536 #else /* Unix */
537
538       fname = RESOLV_CONF_NAME;
539       resolv_conf_changed_p (); /* Reset timestamp.  */
540       err = libdns_error_to_gpg_error
541         (dns_resconf_loadpath (ld.resolv_conf, fname));
542       if (err)
543         {
544           log_error ("failed to load '%s': %s\n", fname, gpg_strerror (err));
545           goto leave;
546         }
547
548       fname = "/etc/nsswitch.conf";
549       err = libdns_error_to_gpg_error
550         (dns_nssconf_loadpath (ld.resolv_conf, fname));
551       if (err)
552         {
553           /* This is not a fatal error: nsswitch.conf is not used on
554            * all systems; assume classic behavior instead.  */
555           if (gpg_err_code (err) != GPG_ERR_ENOENT)
556             log_error ("failed to load '%s': %s\n", fname, gpg_strerror (err));
557           if (opt_debug)
558             log_debug ("dns: fallback resolution order, files then DNS\n");
559           ld.resolv_conf->lookup[0] = 'f';
560           ld.resolv_conf->lookup[1] = 'b';
561           ld.resolv_conf->lookup[2] = '\0';
562           err = GPG_ERR_NO_ERROR;
563         }
564       else if (!strchr (ld.resolv_conf->lookup, 'b'))
565         {
566           /* No DNS resolution type found in the list.  This might be
567            * due to systemd based systems which allow for custom
568            * keywords which are not known to us and thus we do not
569            * know whether DNS is wanted or not.  Because DNS is
570            * important for our infrastructure, we forcefully append
571            * DNS to the end of the list.  */
572           if (strlen (ld.resolv_conf->lookup)+2 < sizeof ld.resolv_conf->lookup)
573             {
574               if (opt_debug)
575                 log_debug ("dns: appending DNS to resolution order\n");
576               strcat (ld.resolv_conf->lookup, "b");
577             }
578           else
579             log_error ("failed to append DNS to resolution order\n");
580         }
581
582 #endif /* Unix */
583     }
584
585   ld.hosts = dns_hosts_open (&derr);
586   if (!ld.hosts)
587     {
588       err = libdns_error_to_gpg_error (derr);
589       log_error ("failed to initialize hosts file: %s\n", gpg_strerror (err));
590       goto leave;
591     }
592
593   {
594 #if HAVE_W32_SYSTEM
595     char *hosts_path = xtryasprintf ("%s\\System32\\drivers\\etc\\hosts",
596                                      getenv ("SystemRoot"));
597     if (! hosts_path)
598       {
599         err = gpg_error_from_syserror ();
600         goto leave;
601       }
602
603     derr = dns_hosts_loadpath (ld.hosts, hosts_path);
604     xfree (hosts_path);
605 #else
606     derr = dns_hosts_loadpath (ld.hosts, "/etc/hosts");
607 #endif
608     if (derr)
609       {
610         err = libdns_error_to_gpg_error (derr);
611         log_error ("failed to load hosts file: %s\n", gpg_strerror (err));
612         err = 0; /* Do not bail out - having no /etc/hosts is legal.  */
613       }
614   }
615
616   ld.resolv_conf->options.recurse = recursive_resolver_p ();
617
618   /* dns_hints_local for stub mode, dns_hints_root for recursive.  */
619   ld.hints = (recursive_resolver
620               ? dns_hints_root  (ld.resolv_conf, &derr)
621               : dns_hints_local (ld.resolv_conf, &derr));
622   if (!ld.hints)
623     {
624       err = libdns_error_to_gpg_error (derr);
625       log_error ("failed to load DNS hints: %s\n", gpg_strerror (err));
626       fname = "[dns hints]";
627       goto leave;
628     }
629
630   /* All fine.  Make the data global.  */
631   libdns = ld;
632
633   if (opt_debug)
634     log_debug ("dns: libdns initialized%s\n", tor_mode?" (tor mode)":"");
635
636  leave:
637   if (!fname)
638     fname = cfgstr;
639   if (err && fname)
640     dirmngr_status_printf (ctrl, "WARNING",
641                            "dns_config_problem %u"
642                            " error accessing '%s': %s <%s>",
643                            err, fname, gpg_strerror (err), gpg_strsource (err));
644
645   xfree (cfgstr);
646   return err;
647 }
648 #endif /*USE_LIBDNS*/
649
650
651 #ifdef USE_LIBDNS
652 /* Deinitialize libdns.  */
653 static void
654 libdns_deinit (void)
655 {
656   struct libdns_s ld;
657
658   if (!libdns.resolv_conf)
659     return; /* Not initialized.  */
660
661   ld = libdns;
662   memset (&libdns, 0, sizeof libdns);
663   dns_hints_close (ld.hints);
664   dns_hosts_close (ld.hosts);
665   dns_resconf_close (ld.resolv_conf);
666 }
667 #endif /*USE_LIBDNS*/
668
669
670 /* SIGHUP action handler for this module.  With FORCE set objects are
671  * all immediately released. */
672 void
673 reload_dns_stuff (int force)
674 {
675 #ifdef USE_LIBDNS
676   if (force)
677     {
678       libdns_deinit ();
679       libdns_reinit_pending = 0;
680     }
681   else
682     {
683       libdns_reinit_pending = 1;
684       libdns_tor_port = 0;  /* Start again with the default port.  */
685     }
686 #else
687   (void)force;
688 #endif
689 }
690
691
692 #ifdef USE_LIBDNS
693 /*
694  * Initialize libdns if needed and open a dns_resolver context.
695  * Returns 0 on success and stores the new context at R_RES.  On
696  * failure an error code is returned and NULL stored at R_RES.
697  */
698 static gpg_error_t
699 libdns_res_open (ctrl_t ctrl, struct dns_resolver **r_res)
700 {
701   gpg_error_t err;
702   struct dns_resolver *res;
703   int derr;
704   struct dns_options opts = { 0 };
705
706   opts.socks_host     = &libdns.socks_host;
707   opts.socks_user     = tor_socks_user;
708   opts.socks_password = tor_socks_password;
709
710   *r_res = NULL;
711
712   /* Force a reload if resolv.conf has changed.  */
713   if (resolv_conf_changed_p ())
714     {
715       if (opt_debug)
716         log_debug ("dns: resolv.conf changed - forcing reload\n");
717       libdns_reinit_pending = 1;
718     }
719
720   if (libdns_reinit_pending)
721     {
722       libdns_reinit_pending = 0;
723       libdns_deinit ();
724     }
725
726   err = libdns_init (ctrl);
727   if (err)
728     return err;
729
730   if (!opt_timeout)
731     set_dns_timeout (0);
732
733   res = dns_res_open (libdns.resolv_conf, libdns.hosts, libdns.hints, NULL,
734                       &opts, &derr);
735   if (!res)
736     return libdns_error_to_gpg_error (derr);
737
738   *r_res = res;
739   return 0;
740 }
741 #endif /*USE_LIBDNS*/
742
743
744 #ifdef USE_LIBDNS
745 /* Helper to test whether we need to try again after having switched
746  * the Tor port.  */
747 static int
748 libdns_switch_port_p (gpg_error_t err)
749 {
750   if (tor_mode && gpg_err_code (err) == GPG_ERR_ECONNREFUSED
751       && libdns_tor_port == TOR_PORT)
752     {
753       /* Switch port and try again.  */
754       if (opt_debug)
755         log_debug ("dns: switching from SOCKS port %d to %d\n",
756                    TOR_PORT, TOR_PORT2);
757       libdns_tor_port = TOR_PORT2;
758       libdns_reinit_pending = 1;
759       return 1;
760     }
761   return 0;
762 }
763 #endif /*USE_LIBDNS*/
764
765
766 #ifdef USE_LIBDNS
767 /* Wrapper around dns_res_submit.  */
768 static gpg_error_t
769 libdns_res_submit (struct dns_resolver *res, const char *qname,
770                    enum dns_type qtype, enum dns_class qclass)
771 {
772   return libdns_error_to_gpg_error (dns_res_submit (res, qname, qtype, qclass));
773 }
774 #endif /*USE_LIBDNS*/
775
776
777 #ifdef USE_LIBDNS
778 /* Standard event handling loop.  */
779 gpg_error_t
780 libdns_res_wait (struct dns_resolver *res)
781 {
782   gpg_error_t err;
783
784   while ((err = libdns_error_to_gpg_error (dns_res_check (res)))
785          && gpg_err_code (err) == GPG_ERR_EAGAIN)
786     {
787       if (dns_res_elapsed (res) > opt_timeout)
788         {
789           err = gpg_error (GPG_ERR_DNS_TIMEOUT);
790           break;
791         }
792
793       my_unprotect ();
794       dns_res_poll (res, 1);
795       my_protect ();
796     }
797
798   return err;
799 }
800 #endif /*USE_LIBDNS*/
801
802
803 #ifdef USE_LIBDNS
804 static gpg_error_t
805 resolve_name_libdns (ctrl_t ctrl, const char *name, unsigned short port,
806                      int want_family, int want_socktype,
807                      dns_addrinfo_t *r_dai, char **r_canonname)
808 {
809   gpg_error_t err;
810   dns_addrinfo_t daihead = NULL;
811   dns_addrinfo_t dai;
812   struct dns_resolver *res = NULL;
813   struct dns_addrinfo *ai = NULL;
814   struct addrinfo hints;
815   struct addrinfo *ent;
816   char portstr_[21];
817   char *portstr = NULL;
818   char *namebuf = NULL;
819   int derr;
820
821   *r_dai = NULL;
822   if (r_canonname)
823     *r_canonname = NULL;
824
825   memset (&hints, 0, sizeof hints);
826   hints.ai_family = want_family;
827   hints.ai_socktype = want_socktype;
828   hints.ai_flags = AI_ADDRCONFIG;
829   if (r_canonname)
830     hints.ai_flags |= AI_CANONNAME;
831
832   if (port)
833     {
834       snprintf (portstr_, sizeof portstr_, "%hu", port);
835       portstr = portstr_;
836     }
837
838   err = libdns_res_open (ctrl, &res);
839   if (err)
840     goto leave;
841
842
843   if (is_ip_address (name))
844     {
845       hints.ai_flags |= AI_NUMERICHOST;
846       /* libdns does not grok brackets - remove them.  */
847       if (*name == '[' && name[strlen(name)-1] == ']')
848         {
849           namebuf = xtrymalloc (strlen (name));
850           if (!namebuf)
851             {
852               err = gpg_error_from_syserror ();
853               goto leave;
854             }
855           strcpy (namebuf, name+1);
856           namebuf[strlen (namebuf)-1] = 0;
857           name = namebuf;
858         }
859     }
860
861   ai = dns_ai_open (name, portstr, 0, &hints, res, &derr);
862   if (!ai)
863     {
864       err = libdns_error_to_gpg_error (derr);
865       goto leave;
866     }
867
868   /* Loop over all records.  */
869   for (;;)
870     {
871       err = libdns_error_to_gpg_error (dns_ai_nextent (&ent, ai));
872       if (gpg_err_code (err) == GPG_ERR_ENOENT)
873         {
874           if (daihead)
875             err = 0; /* We got some results, we're good.  */
876           break; /* Ready.  */
877         }
878       if (gpg_err_code (err) == GPG_ERR_EAGAIN)
879         {
880           if (dns_ai_elapsed (ai) > opt_timeout)
881             {
882               err = gpg_error (GPG_ERR_DNS_TIMEOUT);
883               goto leave;
884             }
885
886           my_unprotect ();
887           dns_ai_poll (ai, 1);
888           my_protect ();
889           continue;
890         }
891       if (err)
892         goto leave;
893
894       if (r_canonname && ! *r_canonname && ent && ent->ai_canonname)
895         {
896           *r_canonname = xtrystrdup (ent->ai_canonname);
897           if (!*r_canonname)
898             {
899               err = gpg_error_from_syserror ();
900               goto leave;
901             }
902           /* Libdns appends the root zone part which is problematic
903            * for most other functions - strip it.  */
904           if (**r_canonname && (*r_canonname)[strlen (*r_canonname)-1] == '.')
905             (*r_canonname)[strlen (*r_canonname)-1] = 0;
906         }
907
908       dai = xtrymalloc (sizeof *dai);
909       if (dai == NULL)
910         {
911           err = gpg_error_from_syserror ();
912           goto leave;
913         }
914
915       dai->family = ent->ai_family;
916       dai->socktype = ent->ai_socktype;
917       dai->protocol = ent->ai_protocol;
918       dai->addrlen = ent->ai_addrlen;
919       memcpy (dai->addr, ent->ai_addr, ent->ai_addrlen);
920       dai->next = daihead;
921       daihead = dai;
922
923       xfree (ent);
924   }
925
926  leave:
927   dns_ai_close (ai);
928   dns_res_close (res);
929
930   if (err)
931     {
932       if (r_canonname)
933         {
934           xfree (*r_canonname);
935           *r_canonname = NULL;
936         }
937       free_dns_addrinfo (daihead);
938     }
939   else
940     *r_dai = daihead;
941
942   xfree (namebuf);
943   return err;
944 }
945 #endif /*USE_LIBDNS*/
946
947
948 /* Resolve a name using the standard system function.  */
949 static gpg_error_t
950 resolve_name_standard (ctrl_t ctrl, const char *name, unsigned short port,
951                        int want_family, int want_socktype,
952                        dns_addrinfo_t *r_dai, char **r_canonname)
953 {
954   gpg_error_t err = 0;
955   dns_addrinfo_t daihead = NULL;
956   dns_addrinfo_t dai;
957   struct addrinfo *aibuf = NULL;
958   struct addrinfo hints, *ai;
959   char portstr[21];
960   int ret;
961
962   *r_dai = NULL;
963   if (r_canonname)
964     *r_canonname = NULL;
965
966   memset (&hints, 0, sizeof hints);
967   hints.ai_family = want_family;
968   hints.ai_socktype = want_socktype;
969   hints.ai_flags = AI_ADDRCONFIG;
970   if (r_canonname)
971     hints.ai_flags |= AI_CANONNAME;
972   if (is_ip_address (name))
973     hints.ai_flags |= AI_NUMERICHOST;
974
975   if (port)
976     snprintf (portstr, sizeof portstr, "%hu", port);
977   else
978     *portstr = 0;
979
980   /* We can't use the AI_IDN flag because that does the conversion
981      using the current locale.  However, GnuPG always used UTF-8.  To
982      support IDN we would need to make use of the libidn API.  */
983   ret = getaddrinfo (name, *portstr? portstr : NULL, &hints, &aibuf);
984   if (ret)
985     {
986       aibuf = NULL;
987       err = map_eai_to_gpg_error (ret);
988       if (gpg_err_code (err) == GPG_ERR_NO_NAME)
989         {
990           /* There seems to be a bug in the glibc getaddrinfo function
991              if the CNAME points to a long list of A and AAAA records
992              in which case the function return NO_NAME.  Let's do the
993              CNAME redirection again.  */
994           char *cname;
995
996           if (get_dns_cname (ctrl, name, &cname))
997             goto leave; /* Still no success.  */
998
999           ret = getaddrinfo (cname, *portstr? portstr : NULL, &hints, &aibuf);
1000           xfree (cname);
1001           if (ret)
1002             {
1003               aibuf = NULL;
1004               err = map_eai_to_gpg_error (ret);
1005               goto leave;
1006             }
1007           err = 0; /* Yep, now it worked.  */
1008         }
1009       else
1010         goto leave;
1011     }
1012
1013   if (r_canonname && aibuf && aibuf->ai_canonname)
1014     {
1015       *r_canonname = xtrystrdup (aibuf->ai_canonname);
1016       if (!*r_canonname)
1017         {
1018           err = gpg_error_from_syserror ();
1019           goto leave;
1020         }
1021     }
1022
1023   for (ai = aibuf; ai; ai = ai->ai_next)
1024     {
1025       if (ai->ai_family != AF_INET6 && ai->ai_family != AF_INET)
1026         continue;
1027       if (opt_disable_ipv4 && ai->ai_family == AF_INET)
1028         continue;
1029       if (opt_disable_ipv6 && ai->ai_family == AF_INET6)
1030         continue;
1031
1032       dai = xtrymalloc (sizeof *dai);
1033       dai->family = ai->ai_family;
1034       dai->socktype = ai->ai_socktype;
1035       dai->protocol = ai->ai_protocol;
1036       dai->addrlen = ai->ai_addrlen;
1037       memcpy (dai->addr, ai->ai_addr, ai->ai_addrlen);
1038       dai->next = daihead;
1039       daihead = dai;
1040     }
1041
1042  leave:
1043   if (aibuf)
1044     freeaddrinfo (aibuf);
1045   if (err)
1046     {
1047       if (r_canonname)
1048         {
1049           xfree (*r_canonname);
1050           *r_canonname = NULL;
1051         }
1052       free_dns_addrinfo (daihead);
1053     }
1054   else
1055     *r_dai = daihead;
1056   return err;
1057 }
1058
1059
1060 /* This a wrapper around getaddrinfo with slightly different semantics.
1061  * NAME is the name to resolve.
1062  * PORT is the requested port or 0.
1063  * WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4.
1064  * WANT_SOCKETTYPE is either 0 for any socket type
1065  *                 or SOCK_STREAM or SOCK_DGRAM.
1066  *
1067  * On success the result is stored in a linked list with the head
1068  * stored at the address R_AI; the caller must call free_dns_addrinfo
1069  * on this.  If R_CANONNAME is not NULL the official name of the host
1070  * is stored there as a malloced string; if that name is not available
1071  * NULL is stored.  */
1072 gpg_error_t
1073 resolve_dns_name (ctrl_t ctrl, const char *name, unsigned short port,
1074                   int want_family, int want_socktype,
1075                   dns_addrinfo_t *r_ai, char **r_canonname)
1076 {
1077   gpg_error_t err;
1078
1079 #ifdef USE_LIBDNS
1080   if (!standard_resolver)
1081     {
1082       err = resolve_name_libdns (ctrl, name, port, want_family, want_socktype,
1083                                   r_ai, r_canonname);
1084       if (err && libdns_switch_port_p (err))
1085         err = resolve_name_libdns (ctrl, name, port, want_family, want_socktype,
1086                                    r_ai, r_canonname);
1087     }
1088   else
1089 #endif /*USE_LIBDNS*/
1090     err = resolve_name_standard (ctrl, name, port, want_family, want_socktype,
1091                                  r_ai, r_canonname);
1092   if (opt_debug)
1093     log_debug ("dns: resolve_dns_name(%s): %s\n", name, gpg_strerror (err));
1094   return err;
1095 }
1096
1097
1098 #ifdef USE_LIBDNS
1099 /* Resolve an address using libdns.  */
1100 static gpg_error_t
1101 resolve_addr_libdns (ctrl_t ctrl,
1102                      const struct sockaddr_storage *addr, int addrlen,
1103                      unsigned int flags, char **r_name)
1104 {
1105   gpg_error_t err;
1106   char host[DNS_D_MAXNAME + 1];
1107   struct dns_resolver *res = NULL;
1108   struct dns_packet *ans = NULL;
1109   struct dns_ptr ptr;
1110   int derr;
1111
1112   *r_name = NULL;
1113
1114   /* First we turn ADDR into a DNS name (with ".arpa" suffix).  */
1115   err = 0;
1116   if (addr->ss_family == AF_INET6)
1117     {
1118       const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)addr;
1119       if (!dns_aaaa_arpa (host, sizeof host, (void*)&a6->sin6_addr))
1120         err = gpg_error (GPG_ERR_INV_OBJ);
1121     }
1122   else if (addr->ss_family == AF_INET)
1123     {
1124       const struct sockaddr_in *a4 = (const struct sockaddr_in *)addr;
1125       if (!dns_a_arpa (host, sizeof host, (void*)&a4->sin_addr))
1126         err = gpg_error (GPG_ERR_INV_OBJ);
1127     }
1128   else
1129     err = gpg_error (GPG_ERR_EAFNOSUPPORT);
1130   if (err)
1131     goto leave;
1132
1133
1134   err = libdns_res_open (ctrl, &res);
1135   if (err)
1136     goto leave;
1137
1138   err = libdns_res_submit (res, host, DNS_T_PTR, DNS_C_IN);
1139   if (err)
1140     goto leave;
1141
1142   err = libdns_res_wait (res);
1143   if (err)
1144     goto leave;
1145
1146   ans = dns_res_fetch (res, &derr);
1147   if (!ans)
1148     {
1149       err = libdns_error_to_gpg_error (derr);
1150       goto leave;
1151     }
1152
1153   /* Check the rcode.  */
1154   switch (dns_p_rcode (ans))
1155     {
1156     case DNS_RC_NOERROR:
1157       break;
1158     case DNS_RC_NXDOMAIN:
1159       err = gpg_error (GPG_ERR_NO_NAME);
1160       break;
1161     default:
1162       err = GPG_ERR_SERVER_FAILED;
1163       goto leave;
1164     }
1165
1166   /* Parse the result.  */
1167   if (!err)
1168     {
1169       struct dns_rr rr;
1170       struct dns_rr_i rri;
1171
1172       memset (&rri, 0, sizeof rri);
1173       dns_rr_i_init (&rri);
1174       rri.section = DNS_S_ALL & ~DNS_S_QD;
1175       rri.name    = host;
1176       rri.type    = DNS_T_PTR;
1177
1178       if (!dns_rr_grep (&rr, 1, &rri, ans, &derr))
1179         {
1180           err = gpg_error (GPG_ERR_NOT_FOUND);
1181           goto leave;
1182         }
1183
1184       err = libdns_error_to_gpg_error (dns_ptr_parse (&ptr, &rr, ans));
1185       if (err)
1186         goto leave;
1187
1188       /* Copy result.  */
1189       *r_name = xtrystrdup (ptr.host);
1190       if (!*r_name)
1191         {
1192           err = gpg_error_from_syserror ();
1193           goto leave;
1194         }
1195       /* Libdns appends the root zone part which is problematic
1196        * for most other functions - strip it.  */
1197       if (**r_name && (*r_name)[strlen (*r_name)-1] == '.')
1198         (*r_name)[strlen (*r_name)-1] = 0;
1199     }
1200   else /* GPG_ERR_NO_NAME */
1201     {
1202       char *buffer, *p;
1203       int buflen;
1204       int ec;
1205
1206       buffer = ptr.host;
1207       buflen = sizeof ptr.host;
1208
1209       p = buffer;
1210       if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
1211         {
1212           *p++ = '[';
1213           buflen -= 2;
1214         }
1215       ec = getnameinfo ((const struct sockaddr *)addr,
1216                         addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
1217       if (ec)
1218         {
1219           err = map_eai_to_gpg_error (ec);
1220           goto leave;
1221         }
1222       if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
1223         strcat (buffer, "]");
1224     }
1225
1226  leave:
1227   dns_free (ans);
1228   dns_res_close (res);
1229   return err;
1230 }
1231 #endif /*USE_LIBDNS*/
1232
1233
1234 /* Resolve an address using the standard system function.  */
1235 static gpg_error_t
1236 resolve_addr_standard (const struct sockaddr_storage *addr, int addrlen,
1237                        unsigned int flags, char **r_name)
1238 {
1239   gpg_error_t err;
1240   int ec;
1241   char *buffer, *p;
1242   int buflen;
1243
1244   *r_name = NULL;
1245
1246   buflen = NI_MAXHOST;
1247   buffer = xtrymalloc (buflen + 2 + 1);
1248   if (!buffer)
1249     return gpg_error_from_syserror ();
1250
1251   if ((flags & DNS_NUMERICHOST) || tor_mode)
1252     ec = EAI_NONAME;
1253   else
1254     ec = getnameinfo ((const struct sockaddr *)addr,
1255                       addrlen, buffer, buflen, NULL, 0, NI_NAMEREQD);
1256
1257   if (!ec && *buffer == '[')
1258     ec = EAI_FAIL;  /* A name may never start with a bracket.  */
1259   else if (ec == EAI_NONAME)
1260     {
1261       p = buffer;
1262       if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
1263         {
1264           *p++ = '[';
1265           buflen -= 2;
1266         }
1267       ec = getnameinfo ((const struct sockaddr *)addr,
1268                         addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
1269       if (!ec && addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
1270         strcat (buffer, "]");
1271     }
1272
1273   if (ec)
1274     err = map_eai_to_gpg_error (ec);
1275   else
1276     {
1277       p = xtryrealloc (buffer, strlen (buffer)+1);
1278       if (!p)
1279         err = gpg_error_from_syserror ();
1280       else
1281         {
1282           buffer = p;
1283           err = 0;
1284         }
1285     }
1286
1287   if (err)
1288     xfree (buffer);
1289   else
1290     *r_name = buffer;
1291
1292   return err;
1293 }
1294
1295
1296 /* A wrapper around getnameinfo.  */
1297 gpg_error_t
1298 resolve_dns_addr (ctrl_t ctrl,
1299                   const struct sockaddr_storage *addr, int addrlen,
1300                   unsigned int flags, char **r_name)
1301 {
1302   gpg_error_t err;
1303
1304 #ifdef USE_LIBDNS
1305   /* Note that we divert to the standard resolver for NUMERICHOST.  */
1306   if (!standard_resolver && !(flags & DNS_NUMERICHOST))
1307     {
1308       err = resolve_addr_libdns (ctrl, addr, addrlen, flags, r_name);
1309       if (err && libdns_switch_port_p (err))
1310         err = resolve_addr_libdns (ctrl, addr, addrlen, flags, r_name);
1311     }
1312   else
1313 #endif /*USE_LIBDNS*/
1314     err = resolve_addr_standard (addr, addrlen, flags, r_name);
1315
1316   if (opt_debug)
1317     log_debug ("dns: resolve_dns_addr(): %s\n", gpg_strerror (err));
1318   return err;
1319 }
1320
1321
1322 /* Check whether NAME is an IP address.  Returns a true if it is
1323  * either an IPv6 or a IPv4 numerical address.  The actual return
1324  * values can also be used to identify whether it is v4 or v6: The
1325  * true value will surprisingly be 4 for IPv4 and 6 for IPv6.  */
1326 int
1327 is_ip_address (const char *name)
1328 {
1329   const char *s;
1330   int ndots, dblcol, n;
1331
1332   if (*name == '[')
1333     return 6; /* yes: A legal DNS name may not contain this character;
1334                  this must be bracketed v6 address.  */
1335   if (*name == '.')
1336     return 0; /* No.  A leading dot is not a valid IP address.  */
1337
1338   /* Check whether this is a v6 address.  */
1339   ndots = n = dblcol = 0;
1340   for (s=name; *s; s++)
1341     {
1342       if (*s == ':')
1343         {
1344           ndots++;
1345           if (s[1] == ':')
1346             {
1347               ndots++;
1348               if (dblcol)
1349                 return 0; /* No: Only one "::" allowed.  */
1350               dblcol++;
1351               if (s[1])
1352                 s++;
1353             }
1354           n = 0;
1355         }
1356       else if (*s == '.')
1357         goto legacy;
1358       else if (!strchr ("0123456789abcdefABCDEF", *s))
1359         return 0; /* No: Not a hex digit.  */
1360       else if (++n > 4)
1361         return 0; /* To many digits in a group.  */
1362     }
1363   if (ndots > 7)
1364     return 0; /* No: Too many colons.  */
1365   else if (ndots > 1)
1366     return 6; /* Yes: At least 2 colons indicate an v6 address.  */
1367
1368  legacy:
1369   /* Check whether it is legacy IP address.  */
1370   ndots = n = 0;
1371   for (s=name; *s; s++)
1372     {
1373       if (*s == '.')
1374         {
1375           if (s[1] == '.')
1376             return 0; /* No:  Double dot. */
1377           if (atoi (s+1) > 255)
1378             return 0; /* No:  Ipv4 byte value too large.  */
1379           ndots++;
1380           n = 0;
1381         }
1382       else if (!strchr ("0123456789", *s))
1383         return 0; /* No: Not a digit.  */
1384       else if (++n > 3)
1385         return 0; /* No: More than 3 digits.  */
1386     }
1387   return (ndots == 3)? 4 : 0;
1388 }
1389
1390
1391 /* Return true if NAME is an onion address.  */
1392 int
1393 is_onion_address (const char *name)
1394 {
1395   size_t len;
1396
1397   len = name? strlen (name) : 0;
1398   if (len < 8 || strcmp (name + len - 6, ".onion"))
1399     return 0;
1400   /* Note that we require at least 2 characters before the suffix.  */
1401   return 1;  /* Yes.  */
1402 }
1403
1404
1405 /* libdns version of get_dns_cert.  */
1406 #ifdef USE_LIBDNS
1407 static gpg_error_t
1408 get_dns_cert_libdns (ctrl_t ctrl, const char *name, int want_certtype,
1409                      void **r_key, size_t *r_keylen,
1410                      unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
1411 {
1412   gpg_error_t err;
1413   struct dns_resolver *res = NULL;
1414   struct dns_packet *ans = NULL;
1415   struct dns_rr rr;
1416   struct dns_rr_i rri;
1417   char host[DNS_D_MAXNAME + 1];
1418   int derr;
1419   int qtype;
1420
1421   /* Get the query type from WANT_CERTTYPE (which in general indicates
1422    * the subtype we want). */
1423   qtype = (want_certtype < DNS_CERTTYPE_RRBASE
1424            ? T_CERT
1425            : (want_certtype - DNS_CERTTYPE_RRBASE));
1426
1427
1428   err = libdns_res_open (ctrl, &res);
1429   if (err)
1430     goto leave;
1431
1432   if (dns_d_anchor (host, sizeof host, name, strlen (name)) >= sizeof host)
1433     {
1434       err = gpg_error (GPG_ERR_ENAMETOOLONG);
1435       goto leave;
1436     }
1437
1438   err = libdns_res_submit (res, name, qtype, DNS_C_IN);
1439   if (err)
1440     goto leave;
1441
1442   err = libdns_res_wait (res);
1443   if (err)
1444     goto leave;
1445
1446   ans = dns_res_fetch (res, &derr);
1447   if (!ans)
1448     {
1449       err = libdns_error_to_gpg_error (derr);
1450       goto leave;
1451     }
1452
1453   /* Check the rcode.  */
1454   switch (dns_p_rcode (ans))
1455     {
1456     case DNS_RC_NOERROR: break;
1457     case DNS_RC_NXDOMAIN: err = gpg_error (GPG_ERR_NO_NAME); break;
1458     default: err = GPG_ERR_SERVER_FAILED; break;
1459     }
1460   if (err)
1461     goto leave;
1462
1463   memset (&rri, 0, sizeof rri);
1464   dns_rr_i_init (&rri);
1465   rri.section = DNS_S_ALL & ~DNS_S_QD;
1466   rri.name    = host;
1467   rri.type    = qtype;
1468
1469   err = gpg_error (GPG_ERR_NOT_FOUND);
1470   while (dns_rr_grep (&rr, 1, &rri, ans, &derr))
1471     {
1472       unsigned char *rp  = ans->data + rr.rd.p;
1473       unsigned short len = rr.rd.len;
1474       u16 subtype;
1475
1476        if (!len)
1477         {
1478           /* Definitely too short - skip.  */
1479         }
1480       else if (want_certtype >= DNS_CERTTYPE_RRBASE
1481           && rr.type == (want_certtype - DNS_CERTTYPE_RRBASE)
1482           && r_key)
1483         {
1484           *r_key = xtrymalloc (len);
1485           if (!*r_key)
1486             err = gpg_error_from_syserror ();
1487           else
1488             {
1489               memcpy (*r_key, rp, len);
1490               *r_keylen = len;
1491               err = 0;
1492             }
1493           goto leave;
1494         }
1495       else if (want_certtype >= DNS_CERTTYPE_RRBASE)
1496         {
1497           /* We did not found the requested RR - skip. */
1498         }
1499       else if (rr.type == T_CERT && len > 5)
1500         {
1501           /* We got a CERT type.   */
1502           subtype = buf16_to_u16 (rp);
1503           rp += 2; len -= 2;
1504
1505           /* Skip the CERT key tag and algo which we don't need.  */
1506           rp += 3; len -= 3;
1507
1508           if (want_certtype && want_certtype != subtype)
1509             ; /* Not the requested subtype - skip.  */
1510           else if (subtype == DNS_CERTTYPE_PGP && len && r_key && r_keylen)
1511             {
1512               /* PGP subtype */
1513               *r_key = xtrymalloc (len);
1514               if (!*r_key)
1515                 err = gpg_error_from_syserror ();
1516               else
1517                 {
1518                   memcpy (*r_key, rp, len);
1519                   *r_keylen = len;
1520                   err = 0;
1521                 }
1522               goto leave;
1523             }
1524           else if (subtype == DNS_CERTTYPE_IPGP
1525                    && len && len < 1023 && len >= rp[0] + 1)
1526             {
1527               /* IPGP type */
1528               *r_fprlen = rp[0];
1529               if (*r_fprlen)
1530                 {
1531                   *r_fpr = xtrymalloc (*r_fprlen);
1532                   if (!*r_fpr)
1533                     {
1534                       err = gpg_error_from_syserror ();
1535                       goto leave;
1536                     }
1537                   memcpy (*r_fpr, rp+1, *r_fprlen);
1538                 }
1539               else
1540                 *r_fpr = NULL;
1541
1542               if (len > *r_fprlen + 1)
1543                 {
1544                   *r_url = xtrymalloc (len - (*r_fprlen + 1) + 1);
1545                   if (!*r_url)
1546                     {
1547                       err = gpg_error_from_syserror ();
1548                       xfree (*r_fpr);
1549                       *r_fpr = NULL;
1550                       goto leave;
1551                     }
1552                   memcpy (*r_url, rp + *r_fprlen + 1, len - (*r_fprlen + 1));
1553                   (*r_url)[len - (*r_fprlen + 1)] = 0;
1554                 }
1555               else
1556                 *r_url = NULL;
1557
1558               err = 0;
1559               goto leave;
1560             }
1561           else
1562             {
1563               /* Unknown subtype or record too short - skip.  */
1564             }
1565         }
1566       else
1567         {
1568           /* Not a requested type - skip.  */
1569         }
1570     }
1571
1572  leave:
1573   dns_free (ans);
1574   dns_res_close (res);
1575   return err;
1576 }
1577 #endif /*USE_LIBDNS*/
1578
1579
1580 /* Standard resolver version of get_dns_cert.  */
1581 static gpg_error_t
1582 get_dns_cert_standard (const char *name, int want_certtype,
1583                        void **r_key, size_t *r_keylen,
1584                        unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
1585 {
1586 #ifdef HAVE_SYSTEM_RESOLVER
1587   gpg_error_t err;
1588   unsigned char *answer;
1589   int r;
1590   u16 count;
1591
1592   /* Allocate a 64k buffer which is the limit for an DNS response.  */
1593   answer = xtrymalloc (65536);
1594   if (!answer)
1595     return gpg_error_from_syserror ();
1596
1597   err = gpg_error (GPG_ERR_NOT_FOUND);
1598   r = res_query (name, C_IN,
1599                  (want_certtype < DNS_CERTTYPE_RRBASE
1600                   ? T_CERT
1601                   : (want_certtype - DNS_CERTTYPE_RRBASE)),
1602                  answer, 65536);
1603   /* Not too big, not too small, no errors and at least 1 answer. */
1604   if (r >= sizeof (HEADER) && r <= 65536
1605       && (((HEADER *)(void *) answer)->rcode) == NOERROR
1606       && (count = ntohs (((HEADER *)(void *) answer)->ancount)))
1607     {
1608       int rc;
1609       unsigned char *pt, *emsg;
1610
1611       emsg = &answer[r];
1612
1613       pt = &answer[sizeof (HEADER)];
1614
1615       /* Skip over the query */
1616
1617       rc = dn_skipname (pt, emsg);
1618       if (rc == -1)
1619         {
1620           err = gpg_error (GPG_ERR_INV_OBJ);
1621           goto leave;
1622         }
1623       pt += rc + QFIXEDSZ;
1624
1625       /* There are several possible response types for a CERT request.
1626          We're interested in the PGP (a key) and IPGP (a URI) types.
1627          Skip all others.  TODO: A key is better than a URI since
1628          we've gone through all this bother to fetch it, so favor that
1629          if we have both PGP and IPGP? */
1630
1631       while (count-- > 0 && pt < emsg)
1632         {
1633           u16 type, class, dlen, ctype;
1634
1635           rc = dn_skipname (pt, emsg);  /* the name we just queried for */
1636           if (rc == -1)
1637             {
1638               err = gpg_error (GPG_ERR_INV_OBJ);
1639               goto leave;
1640             }
1641
1642           pt += rc;
1643
1644           /* Truncated message? 15 bytes takes us to the point where
1645              we start looking at the ctype. */
1646           if ((emsg - pt) < 15)
1647             break;
1648
1649           type = buf16_to_u16 (pt);
1650           pt += 2;
1651
1652           class = buf16_to_u16 (pt);
1653           pt += 2;
1654
1655           if (class != C_IN)
1656             break;
1657
1658           /* ttl */
1659           pt += 4;
1660
1661           /* data length */
1662           dlen = buf16_to_u16 (pt);
1663           pt += 2;
1664
1665           /* Check the type and parse.  */
1666           if (want_certtype >= DNS_CERTTYPE_RRBASE
1667               && type == (want_certtype - DNS_CERTTYPE_RRBASE)
1668               && r_key)
1669             {
1670               *r_key = xtrymalloc (dlen);
1671               if (!*r_key)
1672                 err = gpg_error_from_syserror ();
1673               else
1674                 {
1675                   memcpy (*r_key, pt, dlen);
1676                   *r_keylen = dlen;
1677                   err = 0;
1678                 }
1679               goto leave;
1680             }
1681           else if (want_certtype >= DNS_CERTTYPE_RRBASE)
1682             {
1683               /* We did not found the requested RR.  */
1684               pt += dlen;
1685             }
1686           else if (type == T_CERT)
1687             {
1688               /* We got a CERT type.   */
1689               ctype = buf16_to_u16 (pt);
1690               pt += 2;
1691
1692               /* Skip the CERT key tag and algo which we don't need. */
1693               pt += 3;
1694
1695               dlen -= 5;
1696
1697               /* 15 bytes takes us to here */
1698               if (want_certtype && want_certtype != ctype)
1699                 ; /* Not of the requested certtype.  */
1700               else if (ctype == DNS_CERTTYPE_PGP && dlen && r_key && r_keylen)
1701                 {
1702                   /* PGP type */
1703                   *r_key = xtrymalloc (dlen);
1704                   if (!*r_key)
1705                     err = gpg_error_from_syserror ();
1706                   else
1707                     {
1708                       memcpy (*r_key, pt, dlen);
1709                       *r_keylen = dlen;
1710                       err = 0;
1711                     }
1712                   goto leave;
1713                 }
1714               else if (ctype == DNS_CERTTYPE_IPGP
1715                        && dlen && dlen < 1023 && dlen >= pt[0] + 1)
1716                 {
1717                   /* IPGP type */
1718                   *r_fprlen = pt[0];
1719                   if (*r_fprlen)
1720                     {
1721                       *r_fpr = xtrymalloc (*r_fprlen);
1722                       if (!*r_fpr)
1723                         {
1724                           err = gpg_error_from_syserror ();
1725                           goto leave;
1726                         }
1727                       memcpy (*r_fpr, &pt[1], *r_fprlen);
1728                     }
1729                   else
1730                     *r_fpr = NULL;
1731
1732                   if (dlen > *r_fprlen + 1)
1733                     {
1734                       *r_url = xtrymalloc (dlen - (*r_fprlen + 1) + 1);
1735                       if (!*r_url)
1736                         {
1737                           err = gpg_error_from_syserror ();
1738                           xfree (*r_fpr);
1739                           *r_fpr = NULL;
1740                           goto leave;
1741                         }
1742                       memcpy (*r_url, &pt[*r_fprlen + 1],
1743                               dlen - (*r_fprlen + 1));
1744                       (*r_url)[dlen - (*r_fprlen + 1)] = '\0';
1745                     }
1746                   else
1747                     *r_url = NULL;
1748
1749                   err = 0;
1750                   goto leave;
1751                 }
1752
1753               /* No subtype matches, so continue with the next answer. */
1754               pt += dlen;
1755             }
1756           else
1757             {
1758               /* Not a requested type - might be a CNAME. Try next item.  */
1759               pt += dlen;
1760             }
1761         }
1762     }
1763
1764  leave:
1765   xfree (answer);
1766   return err;
1767
1768 #else /*!HAVE_SYSTEM_RESOLVER*/
1769
1770   (void)name;
1771   (void)want_certtype;
1772   (void)r_key;
1773   (void)r_keylen;
1774   (void)r_fpr;
1775   (void)r_fprlen;
1776   (void)r_url;
1777   return gpg_error (GPG_ERR_NOT_SUPPORTED);
1778
1779 #endif /*!HAVE_SYSTEM_RESOLVER*/
1780 }
1781
1782
1783 /* Returns 0 on success or an error code.  If a PGP CERT record was
1784    found, the malloced data is returned at (R_KEY, R_KEYLEN) and
1785    the other return parameters are set to NULL/0.  If an IPGP CERT
1786    record was found the fingerprint is stored as an allocated block at
1787    R_FPR and its length at R_FPRLEN; an URL is allocated as a
1788    string and returned at R_URL.  If WANT_CERTTYPE is 0 this function
1789    returns the first CERT found with a supported type; it is expected
1790    that only one CERT record is used.  If WANT_CERTTYPE is one of the
1791    supported certtypes only records with this certtype are considered
1792    and the first found is returned.  (R_KEY,R_KEYLEN) are optional. */
1793 gpg_error_t
1794 get_dns_cert (ctrl_t ctrl, const char *name, int want_certtype,
1795               void **r_key, size_t *r_keylen,
1796               unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
1797 {
1798   gpg_error_t err;
1799
1800   if (r_key)
1801     *r_key = NULL;
1802   if (r_keylen)
1803     *r_keylen = 0;
1804   *r_fpr = NULL;
1805   *r_fprlen = 0;
1806   *r_url = NULL;
1807
1808 #ifdef USE_LIBDNS
1809   if (!standard_resolver)
1810     {
1811       err = get_dns_cert_libdns (ctrl, name, want_certtype, r_key, r_keylen,
1812                                  r_fpr, r_fprlen, r_url);
1813       if (err && libdns_switch_port_p (err))
1814         err = get_dns_cert_libdns (ctrl, name, want_certtype, r_key, r_keylen,
1815                                    r_fpr, r_fprlen, r_url);
1816     }
1817   else
1818 #endif /*USE_LIBDNS*/
1819     err = get_dns_cert_standard (name, want_certtype, r_key, r_keylen,
1820                                  r_fpr, r_fprlen, r_url);
1821
1822   if (opt_debug)
1823     log_debug ("dns: get_dns_cert(%s): %s\n", name, gpg_strerror (err));
1824   return err;
1825 }
1826
1827
1828 static int
1829 priosort(const void *a,const void *b)
1830 {
1831   const struct srventry *sa=a,*sb=b;
1832   if(sa->priority>sb->priority)
1833     return 1;
1834   else if(sa->priority<sb->priority)
1835     return -1;
1836   else
1837     return 0;
1838 }
1839
1840
1841 /* Libdns based helper for getsrv.  Note that it is expected that NULL
1842  * is stored at the address of LIST and 0 is stored at the address of
1843  * R_COUNT.  */
1844 #ifdef USE_LIBDNS
1845 static gpg_error_t
1846 getsrv_libdns (ctrl_t ctrl,
1847                const char *name, struct srventry **list, unsigned int *r_count)
1848 {
1849   gpg_error_t err;
1850   struct dns_resolver *res = NULL;
1851   struct dns_packet *ans = NULL;
1852   struct dns_rr rr;
1853   struct dns_rr_i rri;
1854   char host[DNS_D_MAXNAME + 1];
1855   int derr;
1856   unsigned int srvcount = 0;
1857
1858   err = libdns_res_open (ctrl, &res);
1859   if (err)
1860     goto leave;
1861
1862   if (dns_d_anchor (host, sizeof host, name, strlen (name)) >= sizeof host)
1863     {
1864       err = gpg_error (GPG_ERR_ENAMETOOLONG);
1865       goto leave;
1866     }
1867
1868   err = libdns_res_submit (res, name, DNS_T_SRV, DNS_C_IN);
1869   if (err)
1870     goto leave;
1871
1872   err = libdns_res_wait (res);
1873   if (err)
1874     goto leave;
1875
1876   ans = dns_res_fetch (res, &derr);
1877   if (!ans)
1878     {
1879       err = libdns_error_to_gpg_error (derr);
1880       goto leave;
1881     }
1882
1883   /* Check the rcode.  */
1884   switch (dns_p_rcode (ans))
1885     {
1886     case DNS_RC_NOERROR: break;
1887     case DNS_RC_NXDOMAIN: err = gpg_error (GPG_ERR_NO_NAME); break;
1888     default: err = GPG_ERR_SERVER_FAILED; break;
1889     }
1890   if (err)
1891     goto leave;
1892
1893   memset (&rri, 0, sizeof rri);
1894   dns_rr_i_init (&rri);
1895   rri.section = DNS_S_ALL & ~DNS_S_QD;
1896   rri.name        = host;
1897   rri.type        = DNS_T_SRV;
1898
1899   while (dns_rr_grep (&rr, 1, &rri, ans, &derr))
1900     {
1901       struct dns_srv dsrv;
1902       struct srventry *srv;
1903       struct srventry *newlist;
1904
1905       err = libdns_error_to_gpg_error (dns_srv_parse(&dsrv, &rr, ans));
1906       if (err)
1907         goto leave;
1908
1909       newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
1910       if (!newlist)
1911         {
1912           err = gpg_error_from_syserror ();
1913           goto leave;
1914         }
1915       *list = newlist;
1916       memset (&(*list)[srvcount], 0, sizeof(struct srventry));
1917       srv = &(*list)[srvcount];
1918       srvcount++;
1919       srv->priority = dsrv.priority;
1920       srv->weight   = dsrv.weight;
1921       srv->port     = dsrv.port;
1922       mem2str (srv->target, dsrv.target, sizeof srv->target);
1923       /* Libdns appends the root zone part which is problematic for
1924        * most other functions - strip it.  */
1925       if (*srv->target && (srv->target)[strlen (srv->target)-1] == '.')
1926         (srv->target)[strlen (srv->target)-1] = 0;
1927     }
1928
1929   *r_count = srvcount;
1930
1931  leave:
1932   if (err)
1933     {
1934       xfree (*list);
1935       *list = NULL;
1936     }
1937   dns_free (ans);
1938   dns_res_close (res);
1939   return err;
1940 }
1941 #endif /*USE_LIBDNS*/
1942
1943
1944 /* Standard resolver based helper for getsrv.  Note that it is
1945  * expected that NULL is stored at the address of LIST and 0 is stored
1946  * at the address of R_COUNT.  */
1947 static gpg_error_t
1948 getsrv_standard (const char *name,
1949                  struct srventry **list, unsigned int *r_count)
1950 {
1951 #ifdef HAVE_SYSTEM_RESOLVER
1952   union {
1953     unsigned char ans[2048];
1954     HEADER header[1];
1955   } res;
1956   unsigned char *answer = res.ans;
1957   HEADER *header = res.header;
1958   unsigned char *pt, *emsg;
1959   int r, rc;
1960   u16 dlen;
1961   unsigned int srvcount = 0;
1962   u16 count;
1963
1964   /* Do not allow a query using the standard resolver in Tor mode.  */
1965   if (tor_mode)
1966     return gpg_error (GPG_ERR_NOT_ENABLED);
1967
1968   my_unprotect ();
1969   r = res_query (name, C_IN, T_SRV, answer, sizeof res.ans);
1970   my_protect ();
1971   if (r < 0)
1972     return get_h_errno_as_gpg_error ();
1973   if (r < sizeof (HEADER))
1974     return gpg_error (GPG_ERR_SERVER_FAILED);
1975   if (r > sizeof res.ans)
1976     return gpg_error (GPG_ERR_SYSTEM_BUG);
1977   if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
1978     return gpg_error (GPG_ERR_NO_NAME); /* Error or no record found.  */
1979
1980   emsg = &answer[r];
1981   pt = &answer[sizeof(HEADER)];
1982
1983   /* Skip over the query */
1984   rc = dn_skipname (pt, emsg);
1985   if (rc == -1)
1986     goto fail;
1987
1988   pt += rc + QFIXEDSZ;
1989
1990   while (count-- > 0 && pt < emsg)
1991     {
1992       struct srventry *srv;
1993       u16 type, class;
1994       struct srventry *newlist;
1995
1996       newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
1997       if (!newlist)
1998         goto fail;
1999       *list = newlist;
2000       memset (&(*list)[srvcount], 0, sizeof(struct srventry));
2001       srv = &(*list)[srvcount];
2002       srvcount++;
2003
2004       rc = dn_skipname (pt, emsg); /* The name we just queried for.  */
2005       if (rc == -1)
2006         goto fail;
2007       pt += rc;
2008
2009       /* Truncated message? */
2010       if ((emsg-pt) < 16)
2011         goto fail;
2012
2013       type = buf16_to_u16 (pt);
2014       pt += 2;
2015       /* We asked for SRV and got something else !? */
2016       if (type != T_SRV)
2017         goto fail;
2018
2019       class = buf16_to_u16 (pt);
2020       pt += 2;
2021       /* We asked for IN and got something else !? */
2022       if (class != C_IN)
2023         goto fail;
2024
2025       pt += 4; /* ttl */
2026       dlen = buf16_to_u16 (pt);
2027       pt += 2;
2028
2029       srv->priority = buf16_to_ushort (pt);
2030       pt += 2;
2031       srv->weight = buf16_to_ushort (pt);
2032       pt += 2;
2033       srv->port = buf16_to_ushort (pt);
2034       pt += 2;
2035
2036       /* Get the name.  2782 doesn't allow name compression, but
2037        * dn_expand still works to pull the name out of the packet. */
2038       rc = dn_expand (answer, emsg, pt, srv->target, sizeof srv->target);
2039       if (rc == 1 && srv->target[0] == 0) /* "." */
2040         {
2041           xfree(*list);
2042           *list = NULL;
2043           return 0;
2044         }
2045       if (rc == -1)
2046         goto fail;
2047       pt += rc;
2048       /* Corrupt packet? */
2049       if (dlen != rc+6)
2050         goto fail;
2051     }
2052
2053   *r_count = srvcount;
2054   return 0;
2055
2056  fail:
2057   xfree (*list);
2058   *list = NULL;
2059   return gpg_error (GPG_ERR_GENERAL);
2060
2061 #else /*!HAVE_SYSTEM_RESOLVER*/
2062
2063   (void)name;
2064   (void)list;
2065   (void)r_count;
2066   return gpg_error (GPG_ERR_NOT_SUPPORTED);
2067
2068 #endif /*!HAVE_SYSTEM_RESOLVER*/
2069 }
2070
2071
2072 /* Query a SRV record for SERVICE and PROTO for NAME.  If SERVICE is
2073  * NULL, NAME is expected to contain the full query name.  Note that
2074  * we do not return NONAME but simply store 0 at R_COUNT.  On error an
2075  * error code is returned and 0 stored at R_COUNT.  */
2076 gpg_error_t
2077 get_dns_srv (ctrl_t ctrl,
2078              const char *name, const char *service, const char *proto,
2079              struct srventry **list, unsigned int *r_count)
2080 {
2081   gpg_error_t err;
2082   char *namebuffer = NULL;
2083   unsigned int srvcount;
2084   int i;
2085
2086   *list = NULL;
2087   *r_count = 0;
2088   srvcount = 0;
2089
2090   /* If SERVICE is given construct the query from it and PROTO.  */
2091   if (service)
2092     {
2093       namebuffer = xtryasprintf ("_%s._%s.%s",
2094                                  service, proto? proto:"tcp", name);
2095       if (!namebuffer)
2096         {
2097           err = gpg_error_from_syserror ();
2098           goto leave;
2099         }
2100       name = namebuffer;
2101     }
2102
2103
2104 #ifdef USE_LIBDNS
2105   if (!standard_resolver)
2106     {
2107       err = getsrv_libdns (ctrl, name, list, &srvcount);
2108       if (err && libdns_switch_port_p (err))
2109         err = getsrv_libdns (ctrl, name, list, &srvcount);
2110     }
2111   else
2112 #endif /*USE_LIBDNS*/
2113     err = getsrv_standard (name, list, &srvcount);
2114
2115   if (err)
2116     {
2117       if (gpg_err_code (err) == GPG_ERR_NO_NAME)
2118         err = 0;
2119       goto leave;
2120     }
2121
2122   /* Now we have an array of all the srv records. */
2123
2124   /* Order by priority */
2125   qsort(*list,srvcount,sizeof(struct srventry),priosort);
2126
2127   /* For each priority, move the zero-weighted items first. */
2128   for (i=0; i < srvcount; i++)
2129     {
2130       int j;
2131
2132       for (j=i;j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
2133         {
2134           if((*list)[j].weight==0)
2135             {
2136               /* Swap j with i */
2137               if(j!=i)
2138                 {
2139                   struct srventry temp;
2140
2141                   memcpy (&temp,&(*list)[j],sizeof(struct srventry));
2142                   memcpy (&(*list)[j],&(*list)[i],sizeof(struct srventry));
2143                   memcpy (&(*list)[i],&temp,sizeof(struct srventry));
2144                 }
2145
2146               break;
2147             }
2148         }
2149     }
2150
2151   /* Run the RFC-2782 weighting algorithm.  We don't need very high
2152      quality randomness for this, so regular libc srand/rand is
2153      sufficient.  */
2154
2155   {
2156     static int done;
2157     if (!done)
2158       {
2159         done = 1;
2160         srand (time (NULL)*getpid());
2161       }
2162   }
2163
2164   for (i=0; i < srvcount; i++)
2165     {
2166       int j;
2167       float prio_count=0,chose;
2168
2169       for (j=i; j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
2170         {
2171           prio_count+=(*list)[j].weight;
2172           (*list)[j].run_count=prio_count;
2173         }
2174
2175       chose=prio_count*rand()/RAND_MAX;
2176
2177       for (j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
2178         {
2179           if (chose<=(*list)[j].run_count)
2180             {
2181               /* Swap j with i */
2182               if(j!=i)
2183                 {
2184                   struct srventry temp;
2185
2186                   memcpy(&temp,&(*list)[j],sizeof(struct srventry));
2187                   memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
2188                   memcpy(&(*list)[i],&temp,sizeof(struct srventry));
2189                 }
2190               break;
2191             }
2192         }
2193     }
2194
2195  leave:
2196   if (opt_debug)
2197     {
2198       if (err)
2199         log_debug ("dns: getsrv(%s): %s\n", name, gpg_strerror (err));
2200       else
2201         log_debug ("dns: getsrv(%s) -> %u records\n", name, srvcount);
2202     }
2203   if (!err)
2204     *r_count = srvcount;
2205   xfree (namebuffer);
2206   return err;
2207 }
2208
2209
2210 \f
2211 #ifdef USE_LIBDNS
2212 /* libdns version of get_dns_cname.  */
2213 gpg_error_t
2214 get_dns_cname_libdns (ctrl_t ctrl, const char *name, char **r_cname)
2215 {
2216   gpg_error_t err;
2217   struct dns_resolver *res;
2218   struct dns_packet *ans = NULL;
2219   struct dns_cname cname;
2220   int derr;
2221
2222   err = libdns_res_open (ctrl, &res);
2223   if (err)
2224     goto leave;
2225
2226   err = libdns_res_submit (res, name, DNS_T_CNAME, DNS_C_IN);
2227   if (err)
2228     goto leave;
2229
2230   err = libdns_res_wait (res);
2231   if (err)
2232     goto leave;
2233
2234   ans = dns_res_fetch (res, &derr);
2235   if (!ans)
2236     {
2237       err = libdns_error_to_gpg_error (derr);
2238       goto leave;
2239     }
2240
2241   /* Check the rcode.  */
2242   switch (dns_p_rcode (ans))
2243     {
2244     case DNS_RC_NOERROR: break;
2245     case DNS_RC_NXDOMAIN: err = gpg_error (GPG_ERR_NO_NAME); break;
2246     default: err = GPG_ERR_SERVER_FAILED; break;
2247     }
2248   if (err)
2249     goto leave;
2250
2251   /* Parse the result into CNAME.  */
2252   err = libdns_error_to_gpg_error (dns_p_study (ans));
2253   if (err)
2254     goto leave;
2255
2256   if (!dns_d_cname (&cname, sizeof cname, name, strlen (name), ans, &derr))
2257     {
2258       err = libdns_error_to_gpg_error (derr);
2259       goto leave;
2260     }
2261
2262   /* Copy result.  */
2263   *r_cname = xtrystrdup (cname.host);
2264   if (!*r_cname)
2265     err = gpg_error_from_syserror ();
2266   else
2267     {
2268       /* Libdns appends the root zone part which is problematic
2269        * for most other functions - strip it.  */
2270       if (**r_cname && (*r_cname)[strlen (*r_cname)-1] == '.')
2271         (*r_cname)[strlen (*r_cname)-1] = 0;
2272     }
2273
2274  leave:
2275   dns_free (ans);
2276   dns_res_close (res);
2277   return err;
2278 }
2279 #endif /*USE_LIBDNS*/
2280
2281
2282 /* Standard resolver version of get_dns_cname.  */
2283 gpg_error_t
2284 get_dns_cname_standard (const char *name, char **r_cname)
2285 {
2286 #ifdef HAVE_SYSTEM_RESOLVER
2287   gpg_error_t err;
2288   int rc;
2289   union {
2290     unsigned char ans[2048];
2291     HEADER header[1];
2292   } res;
2293   unsigned char *answer = res.ans;
2294   HEADER *header = res.header;
2295   unsigned char *pt, *emsg;
2296   int r;
2297   char *cname;
2298   int cnamesize = 1025;
2299   u16 count;
2300
2301   /* Do not allow a query using the standard resolver in Tor mode.  */
2302   if (tor_mode)
2303     return -1;
2304
2305   my_unprotect ();
2306   r = res_query (name, C_IN, T_CERT, answer, sizeof res.ans);
2307   my_protect ();
2308   if (r < 0)
2309     return get_h_errno_as_gpg_error ();
2310   if (r < sizeof (HEADER))
2311     return gpg_error (GPG_ERR_SERVER_FAILED);
2312   if (r > sizeof res.ans)
2313     return gpg_error (GPG_ERR_SYSTEM_BUG);
2314   if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
2315     return gpg_error (GPG_ERR_NO_NAME); /* Error or no record found.  */
2316   if (count != 1)
2317     return gpg_error (GPG_ERR_SERVER_FAILED);
2318
2319   emsg = &answer[r];
2320   pt = &answer[sizeof(HEADER)];
2321   rc = dn_skipname (pt, emsg);
2322   if (rc == -1)
2323     return gpg_error (GPG_ERR_SERVER_FAILED);
2324
2325   pt += rc + QFIXEDSZ;
2326   if (pt >= emsg)
2327     return gpg_error (GPG_ERR_SERVER_FAILED);
2328
2329   rc = dn_skipname (pt, emsg);
2330   if (rc == -1)
2331     return gpg_error (GPG_ERR_SERVER_FAILED);
2332   pt += rc + 2 + 2 + 4;
2333   if (pt+2 >= emsg)
2334     return gpg_error (GPG_ERR_SERVER_FAILED);
2335   pt += 2;  /* Skip rdlen */
2336
2337   cname = xtrymalloc (cnamesize);
2338   if (!cname)
2339     return gpg_error_from_syserror ();
2340
2341   rc = dn_expand (answer, emsg, pt, cname, cnamesize -1);
2342   if (rc == -1)
2343     {
2344       xfree (cname);
2345       return gpg_error (GPG_ERR_SERVER_FAILED);
2346     }
2347   *r_cname = xtryrealloc (cname, strlen (cname)+1);
2348   if (!*r_cname)
2349     {
2350       err = gpg_error_from_syserror ();
2351       xfree (cname);
2352       return err;
2353     }
2354   return 0;
2355
2356 #else /*!HAVE_SYSTEM_RESOLVER*/
2357
2358   (void)name;
2359   (void)r_cname;
2360   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2361
2362 #endif /*!HAVE_SYSTEM_RESOLVER*/
2363 }
2364
2365
2366 gpg_error_t
2367 get_dns_cname (ctrl_t ctrl, const char *name, char **r_cname)
2368 {
2369   gpg_error_t err;
2370
2371   *r_cname = NULL;
2372
2373 #ifdef USE_LIBDNS
2374   if (!standard_resolver)
2375     {
2376       err = get_dns_cname_libdns (ctrl, name, r_cname);
2377       if (err && libdns_switch_port_p (err))
2378         err = get_dns_cname_libdns (ctrl, name, r_cname);
2379       return err;
2380     }
2381 #endif /*USE_LIBDNS*/
2382
2383   err = get_dns_cname_standard (name, r_cname);
2384   if (opt_debug)
2385     log_debug ("get_dns_cname(%s)%s%s\n", name,
2386                err ? ": " : " -> ",
2387                err ? gpg_strerror (err) : *r_cname);
2388   return err;
2389 }