sm: Fix certificate creation with key on card.
[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
705   *r_res = NULL;
706
707   /* Force a reload if resolv.conf has changed.  */
708   if (resolv_conf_changed_p ())
709     {
710       if (opt_debug)
711         log_debug ("dns: resolv.conf changed - forcing reload\n");
712       libdns_reinit_pending = 1;
713     }
714
715   if (libdns_reinit_pending)
716     {
717       libdns_reinit_pending = 0;
718       libdns_deinit ();
719     }
720
721   err = libdns_init (ctrl);
722   if (err)
723     return err;
724
725   if (!opt_timeout)
726     set_dns_timeout (0);
727
728   res = dns_res_open (libdns.resolv_conf, libdns.hosts, libdns.hints, NULL,
729                       dns_opts (.socks_host     = &libdns.socks_host,
730                                 .socks_user     = tor_socks_user,
731                                 .socks_password = tor_socks_password ),
732                       &derr);
733   if (!res)
734     return libdns_error_to_gpg_error (derr);
735
736   *r_res = res;
737   return 0;
738 }
739 #endif /*USE_LIBDNS*/
740
741
742 #ifdef USE_LIBDNS
743 /* Helper to test whether we need to try again after having switched
744  * the Tor port.  */
745 static int
746 libdns_switch_port_p (gpg_error_t err)
747 {
748   if (tor_mode && gpg_err_code (err) == GPG_ERR_ECONNREFUSED
749       && libdns_tor_port == TOR_PORT)
750     {
751       /* Switch port and try again.  */
752       if (opt_debug)
753         log_debug ("dns: switching from SOCKS port %d to %d\n",
754                    TOR_PORT, TOR_PORT2);
755       libdns_tor_port = TOR_PORT2;
756       libdns_reinit_pending = 1;
757       return 1;
758     }
759   return 0;
760 }
761 #endif /*USE_LIBDNS*/
762
763
764 #ifdef USE_LIBDNS
765 /* Wrapper around dns_res_submit.  */
766 static gpg_error_t
767 libdns_res_submit (struct dns_resolver *res, const char *qname,
768                    enum dns_type qtype, enum dns_class qclass)
769 {
770   return libdns_error_to_gpg_error (dns_res_submit (res, qname, qtype, qclass));
771 }
772 #endif /*USE_LIBDNS*/
773
774
775 #ifdef USE_LIBDNS
776 /* Standard event handling loop.  */
777 gpg_error_t
778 libdns_res_wait (struct dns_resolver *res)
779 {
780   gpg_error_t err;
781
782   while ((err = libdns_error_to_gpg_error (dns_res_check (res)))
783          && gpg_err_code (err) == GPG_ERR_EAGAIN)
784     {
785       if (dns_res_elapsed (res) > opt_timeout)
786         {
787           err = gpg_error (GPG_ERR_DNS_TIMEOUT);
788           break;
789         }
790
791       my_unprotect ();
792       dns_res_poll (res, 1);
793       my_protect ();
794     }
795
796   return err;
797 }
798 #endif /*USE_LIBDNS*/
799
800
801 #ifdef USE_LIBDNS
802 static gpg_error_t
803 resolve_name_libdns (ctrl_t ctrl, const char *name, unsigned short port,
804                      int want_family, int want_socktype,
805                      dns_addrinfo_t *r_dai, char **r_canonname)
806 {
807   gpg_error_t err;
808   dns_addrinfo_t daihead = NULL;
809   dns_addrinfo_t dai;
810   struct dns_resolver *res = NULL;
811   struct dns_addrinfo *ai = NULL;
812   struct addrinfo hints;
813   struct addrinfo *ent;
814   char portstr_[21];
815   char *portstr = NULL;
816   char *namebuf = NULL;
817   int derr;
818
819   *r_dai = NULL;
820   if (r_canonname)
821     *r_canonname = NULL;
822
823   memset (&hints, 0, sizeof hints);
824   hints.ai_family = want_family;
825   hints.ai_socktype = want_socktype;
826   hints.ai_flags = AI_ADDRCONFIG;
827   if (r_canonname)
828     hints.ai_flags |= AI_CANONNAME;
829
830   if (port)
831     {
832       snprintf (portstr_, sizeof portstr_, "%hu", port);
833       portstr = portstr_;
834     }
835
836   err = libdns_res_open (ctrl, &res);
837   if (err)
838     goto leave;
839
840
841   if (is_ip_address (name))
842     {
843       hints.ai_flags |= AI_NUMERICHOST;
844       /* libdns does not grok brackets - remove them.  */
845       if (*name == '[' && name[strlen(name)-1] == ']')
846         {
847           namebuf = xtrymalloc (strlen (name));
848           if (!namebuf)
849             {
850               err = gpg_error_from_syserror ();
851               goto leave;
852             }
853           strcpy (namebuf, name+1);
854           namebuf[strlen (namebuf)-1] = 0;
855           name = namebuf;
856         }
857     }
858
859   ai = dns_ai_open (name, portstr, 0, &hints, res, &derr);
860   if (!ai)
861     {
862       err = libdns_error_to_gpg_error (derr);
863       goto leave;
864     }
865
866   /* Loop over all records.  */
867   for (;;)
868     {
869       err = libdns_error_to_gpg_error (dns_ai_nextent (&ent, ai));
870       if (gpg_err_code (err) == GPG_ERR_ENOENT)
871         {
872           if (daihead)
873             err = 0; /* We got some results, we're good.  */
874           break; /* Ready.  */
875         }
876       if (gpg_err_code (err) == GPG_ERR_EAGAIN)
877         {
878           if (dns_ai_elapsed (ai) > opt_timeout)
879             {
880               err = gpg_error (GPG_ERR_DNS_TIMEOUT);
881               goto leave;
882             }
883
884           my_unprotect ();
885           dns_ai_poll (ai, 1);
886           my_protect ();
887           continue;
888         }
889       if (err)
890         goto leave;
891
892       if (r_canonname && ! *r_canonname && ent && ent->ai_canonname)
893         {
894           *r_canonname = xtrystrdup (ent->ai_canonname);
895           if (!*r_canonname)
896             {
897               err = gpg_error_from_syserror ();
898               goto leave;
899             }
900           /* Libdns appends the root zone part which is problematic
901            * for most other functions - strip it.  */
902           if (**r_canonname && (*r_canonname)[strlen (*r_canonname)-1] == '.')
903             (*r_canonname)[strlen (*r_canonname)-1] = 0;
904         }
905
906       dai = xtrymalloc (sizeof *dai);
907       if (dai == NULL)
908         {
909           err = gpg_error_from_syserror ();
910           goto leave;
911         }
912
913       dai->family = ent->ai_family;
914       dai->socktype = ent->ai_socktype;
915       dai->protocol = ent->ai_protocol;
916       dai->addrlen = ent->ai_addrlen;
917       memcpy (dai->addr, ent->ai_addr, ent->ai_addrlen);
918       dai->next = daihead;
919       daihead = dai;
920
921       xfree (ent);
922   }
923
924  leave:
925   dns_ai_close (ai);
926   dns_res_close (res);
927
928   if (err)
929     {
930       if (r_canonname)
931         {
932           xfree (*r_canonname);
933           *r_canonname = NULL;
934         }
935       free_dns_addrinfo (daihead);
936     }
937   else
938     *r_dai = daihead;
939
940   xfree (namebuf);
941   return err;
942 }
943 #endif /*USE_LIBDNS*/
944
945
946 /* Resolve a name using the standard system function.  */
947 static gpg_error_t
948 resolve_name_standard (ctrl_t ctrl, const char *name, unsigned short port,
949                        int want_family, int want_socktype,
950                        dns_addrinfo_t *r_dai, char **r_canonname)
951 {
952   gpg_error_t err = 0;
953   dns_addrinfo_t daihead = NULL;
954   dns_addrinfo_t dai;
955   struct addrinfo *aibuf = NULL;
956   struct addrinfo hints, *ai;
957   char portstr[21];
958   int ret;
959
960   *r_dai = NULL;
961   if (r_canonname)
962     *r_canonname = NULL;
963
964   memset (&hints, 0, sizeof hints);
965   hints.ai_family = want_family;
966   hints.ai_socktype = want_socktype;
967   hints.ai_flags = AI_ADDRCONFIG;
968   if (r_canonname)
969     hints.ai_flags |= AI_CANONNAME;
970   if (is_ip_address (name))
971     hints.ai_flags |= AI_NUMERICHOST;
972
973   if (port)
974     snprintf (portstr, sizeof portstr, "%hu", port);
975   else
976     *portstr = 0;
977
978   /* We can't use the AI_IDN flag because that does the conversion
979      using the current locale.  However, GnuPG always used UTF-8.  To
980      support IDN we would need to make use of the libidn API.  */
981   ret = getaddrinfo (name, *portstr? portstr : NULL, &hints, &aibuf);
982   if (ret)
983     {
984       aibuf = NULL;
985       err = map_eai_to_gpg_error (ret);
986       if (gpg_err_code (err) == GPG_ERR_NO_NAME)
987         {
988           /* There seems to be a bug in the glibc getaddrinfo function
989              if the CNAME points to a long list of A and AAAA records
990              in which case the function return NO_NAME.  Let's do the
991              CNAME redirection again.  */
992           char *cname;
993
994           if (get_dns_cname (ctrl, name, &cname))
995             goto leave; /* Still no success.  */
996
997           ret = getaddrinfo (cname, *portstr? portstr : NULL, &hints, &aibuf);
998           xfree (cname);
999           if (ret)
1000             {
1001               aibuf = NULL;
1002               err = map_eai_to_gpg_error (ret);
1003               goto leave;
1004             }
1005           err = 0; /* Yep, now it worked.  */
1006         }
1007       else
1008         goto leave;
1009     }
1010
1011   if (r_canonname && aibuf && aibuf->ai_canonname)
1012     {
1013       *r_canonname = xtrystrdup (aibuf->ai_canonname);
1014       if (!*r_canonname)
1015         {
1016           err = gpg_error_from_syserror ();
1017           goto leave;
1018         }
1019     }
1020
1021   for (ai = aibuf; ai; ai = ai->ai_next)
1022     {
1023       if (ai->ai_family != AF_INET6 && ai->ai_family != AF_INET)
1024         continue;
1025       if (opt_disable_ipv4 && ai->ai_family == AF_INET)
1026         continue;
1027       if (opt_disable_ipv6 && ai->ai_family == AF_INET6)
1028         continue;
1029
1030       dai = xtrymalloc (sizeof *dai);
1031       dai->family = ai->ai_family;
1032       dai->socktype = ai->ai_socktype;
1033       dai->protocol = ai->ai_protocol;
1034       dai->addrlen = ai->ai_addrlen;
1035       memcpy (dai->addr, ai->ai_addr, ai->ai_addrlen);
1036       dai->next = daihead;
1037       daihead = dai;
1038     }
1039
1040  leave:
1041   if (aibuf)
1042     freeaddrinfo (aibuf);
1043   if (err)
1044     {
1045       if (r_canonname)
1046         {
1047           xfree (*r_canonname);
1048           *r_canonname = NULL;
1049         }
1050       free_dns_addrinfo (daihead);
1051     }
1052   else
1053     *r_dai = daihead;
1054   return err;
1055 }
1056
1057
1058 /* This a wrapper around getaddrinfo with slightly different semantics.
1059  * NAME is the name to resolve.
1060  * PORT is the requested port or 0.
1061  * WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4.
1062  * WANT_SOCKETTYPE is either 0 for any socket type
1063  *                 or SOCK_STREAM or SOCK_DGRAM.
1064  *
1065  * On success the result is stored in a linked list with the head
1066  * stored at the address R_AI; the caller must call free_dns_addrinfo
1067  * on this.  If R_CANONNAME is not NULL the official name of the host
1068  * is stored there as a malloced string; if that name is not available
1069  * NULL is stored.  */
1070 gpg_error_t
1071 resolve_dns_name (ctrl_t ctrl, const char *name, unsigned short port,
1072                   int want_family, int want_socktype,
1073                   dns_addrinfo_t *r_ai, char **r_canonname)
1074 {
1075   gpg_error_t err;
1076
1077 #ifdef USE_LIBDNS
1078   if (!standard_resolver)
1079     {
1080       err = resolve_name_libdns (ctrl, name, port, want_family, want_socktype,
1081                                   r_ai, r_canonname);
1082       if (err && libdns_switch_port_p (err))
1083         err = resolve_name_libdns (ctrl, name, port, want_family, want_socktype,
1084                                    r_ai, r_canonname);
1085     }
1086   else
1087 #endif /*USE_LIBDNS*/
1088     err = resolve_name_standard (ctrl, name, port, want_family, want_socktype,
1089                                  r_ai, r_canonname);
1090   if (opt_debug)
1091     log_debug ("dns: resolve_dns_name(%s): %s\n", name, gpg_strerror (err));
1092   return err;
1093 }
1094
1095
1096 #ifdef USE_LIBDNS
1097 /* Resolve an address using libdns.  */
1098 static gpg_error_t
1099 resolve_addr_libdns (ctrl_t ctrl,
1100                      const struct sockaddr_storage *addr, int addrlen,
1101                      unsigned int flags, char **r_name)
1102 {
1103   gpg_error_t err;
1104   char host[DNS_D_MAXNAME + 1];
1105   struct dns_resolver *res = NULL;
1106   struct dns_packet *ans = NULL;
1107   struct dns_ptr ptr;
1108   int derr;
1109
1110   *r_name = NULL;
1111
1112   /* First we turn ADDR into a DNS name (with ".arpa" suffix).  */
1113   err = 0;
1114   if (addr->ss_family == AF_INET6)
1115     {
1116       const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)addr;
1117       if (!dns_aaaa_arpa (host, sizeof host, (void*)&a6->sin6_addr))
1118         err = gpg_error (GPG_ERR_INV_OBJ);
1119     }
1120   else if (addr->ss_family == AF_INET)
1121     {
1122       const struct sockaddr_in *a4 = (const struct sockaddr_in *)addr;
1123       if (!dns_a_arpa (host, sizeof host, (void*)&a4->sin_addr))
1124         err = gpg_error (GPG_ERR_INV_OBJ);
1125     }
1126   else
1127     err = gpg_error (GPG_ERR_EAFNOSUPPORT);
1128   if (err)
1129     goto leave;
1130
1131
1132   err = libdns_res_open (ctrl, &res);
1133   if (err)
1134     goto leave;
1135
1136   err = libdns_res_submit (res, host, DNS_T_PTR, DNS_C_IN);
1137   if (err)
1138     goto leave;
1139
1140   err = libdns_res_wait (res);
1141   if (err)
1142     goto leave;
1143
1144   ans = dns_res_fetch (res, &derr);
1145   if (!ans)
1146     {
1147       err = libdns_error_to_gpg_error (derr);
1148       goto leave;
1149     }
1150
1151   /* Check the rcode.  */
1152   switch (dns_p_rcode (ans))
1153     {
1154     case DNS_RC_NOERROR:
1155       break;
1156     case DNS_RC_NXDOMAIN:
1157       err = gpg_error (GPG_ERR_NO_NAME);
1158       break;
1159     default:
1160       err = GPG_ERR_SERVER_FAILED;
1161       goto leave;
1162     }
1163
1164   /* Parse the result.  */
1165   if (!err)
1166     {
1167       struct dns_rr rr;
1168       struct dns_rr_i rri;
1169
1170       memset (&rri, 0, sizeof rri);
1171       dns_rr_i_init (&rri, ans);
1172       rri.section = DNS_S_ALL & ~DNS_S_QD;
1173       rri.name    = host;
1174       rri.type    = DNS_T_PTR;
1175
1176       if (!dns_rr_grep (&rr, 1, &rri, ans, &derr))
1177         {
1178           err = gpg_error (GPG_ERR_NOT_FOUND);
1179           goto leave;
1180         }
1181
1182       err = libdns_error_to_gpg_error (dns_ptr_parse (&ptr, &rr, ans));
1183       if (err)
1184         goto leave;
1185
1186       /* Copy result.  */
1187       *r_name = xtrystrdup (ptr.host);
1188       if (!*r_name)
1189         {
1190           err = gpg_error_from_syserror ();
1191           goto leave;
1192         }
1193       /* Libdns appends the root zone part which is problematic
1194        * for most other functions - strip it.  */
1195       if (**r_name && (*r_name)[strlen (*r_name)-1] == '.')
1196         (*r_name)[strlen (*r_name)-1] = 0;
1197     }
1198   else /* GPG_ERR_NO_NAME */
1199     {
1200       char *buffer, *p;
1201       int buflen;
1202       int ec;
1203
1204       buffer = ptr.host;
1205       buflen = sizeof ptr.host;
1206
1207       p = buffer;
1208       if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
1209         {
1210           *p++ = '[';
1211           buflen -= 2;
1212         }
1213       ec = getnameinfo ((const struct sockaddr *)addr,
1214                         addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
1215       if (ec)
1216         {
1217           err = map_eai_to_gpg_error (ec);
1218           goto leave;
1219         }
1220       if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
1221         strcat (buffer, "]");
1222     }
1223
1224  leave:
1225   dns_free (ans);
1226   dns_res_close (res);
1227   return err;
1228 }
1229 #endif /*USE_LIBDNS*/
1230
1231
1232 /* Resolve an address using the standard system function.  */
1233 static gpg_error_t
1234 resolve_addr_standard (const struct sockaddr_storage *addr, int addrlen,
1235                        unsigned int flags, char **r_name)
1236 {
1237   gpg_error_t err;
1238   int ec;
1239   char *buffer, *p;
1240   int buflen;
1241
1242   *r_name = NULL;
1243
1244   buflen = NI_MAXHOST;
1245   buffer = xtrymalloc (buflen + 2 + 1);
1246   if (!buffer)
1247     return gpg_error_from_syserror ();
1248
1249   if ((flags & DNS_NUMERICHOST) || tor_mode)
1250     ec = EAI_NONAME;
1251   else
1252     ec = getnameinfo ((const struct sockaddr *)addr,
1253                       addrlen, buffer, buflen, NULL, 0, NI_NAMEREQD);
1254
1255   if (!ec && *buffer == '[')
1256     ec = EAI_FAIL;  /* A name may never start with a bracket.  */
1257   else if (ec == EAI_NONAME)
1258     {
1259       p = buffer;
1260       if (addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
1261         {
1262           *p++ = '[';
1263           buflen -= 2;
1264         }
1265       ec = getnameinfo ((const struct sockaddr *)addr,
1266                         addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
1267       if (!ec && addr->ss_family == AF_INET6 && (flags & DNS_WITHBRACKET))
1268         strcat (buffer, "]");
1269     }
1270
1271   if (ec)
1272     err = map_eai_to_gpg_error (ec);
1273   else
1274     {
1275       p = xtryrealloc (buffer, strlen (buffer)+1);
1276       if (!p)
1277         err = gpg_error_from_syserror ();
1278       else
1279         {
1280           buffer = p;
1281           err = 0;
1282         }
1283     }
1284
1285   if (err)
1286     xfree (buffer);
1287   else
1288     *r_name = buffer;
1289
1290   return err;
1291 }
1292
1293
1294 /* A wrapper around getnameinfo.  */
1295 gpg_error_t
1296 resolve_dns_addr (ctrl_t ctrl,
1297                   const struct sockaddr_storage *addr, int addrlen,
1298                   unsigned int flags, char **r_name)
1299 {
1300   gpg_error_t err;
1301
1302 #ifdef USE_LIBDNS
1303   /* Note that we divert to the standard resolver for NUMERICHOST.  */
1304   if (!standard_resolver && !(flags & DNS_NUMERICHOST))
1305     {
1306       err = resolve_addr_libdns (ctrl, addr, addrlen, flags, r_name);
1307       if (err && libdns_switch_port_p (err))
1308         err = resolve_addr_libdns (ctrl, addr, addrlen, flags, r_name);
1309     }
1310   else
1311 #endif /*USE_LIBDNS*/
1312     err = resolve_addr_standard (addr, addrlen, flags, r_name);
1313
1314   if (opt_debug)
1315     log_debug ("dns: resolve_dns_addr(): %s\n", gpg_strerror (err));
1316   return err;
1317 }
1318
1319
1320 /* Check whether NAME is an IP address.  Returns a true if it is
1321  * either an IPv6 or a IPv4 numerical address.  The actual return
1322  * values can also be used to identify whether it is v4 or v6: The
1323  * true value will surprisingly be 4 for IPv4 and 6 for IPv6.  */
1324 int
1325 is_ip_address (const char *name)
1326 {
1327   const char *s;
1328   int ndots, dblcol, n;
1329
1330   if (*name == '[')
1331     return 6; /* yes: A legal DNS name may not contain this character;
1332                  this must be bracketed v6 address.  */
1333   if (*name == '.')
1334     return 0; /* No.  A leading dot is not a valid IP address.  */
1335
1336   /* Check whether this is a v6 address.  */
1337   ndots = n = dblcol = 0;
1338   for (s=name; *s; s++)
1339     {
1340       if (*s == ':')
1341         {
1342           ndots++;
1343           if (s[1] == ':')
1344             {
1345               ndots++;
1346               if (dblcol)
1347                 return 0; /* No: Only one "::" allowed.  */
1348               dblcol++;
1349               if (s[1])
1350                 s++;
1351             }
1352           n = 0;
1353         }
1354       else if (*s == '.')
1355         goto legacy;
1356       else if (!strchr ("0123456789abcdefABCDEF", *s))
1357         return 0; /* No: Not a hex digit.  */
1358       else if (++n > 4)
1359         return 0; /* To many digits in a group.  */
1360     }
1361   if (ndots > 7)
1362     return 0; /* No: Too many colons.  */
1363   else if (ndots > 1)
1364     return 6; /* Yes: At least 2 colons indicate an v6 address.  */
1365
1366  legacy:
1367   /* Check whether it is legacy IP address.  */
1368   ndots = n = 0;
1369   for (s=name; *s; s++)
1370     {
1371       if (*s == '.')
1372         {
1373           if (s[1] == '.')
1374             return 0; /* No:  Double dot. */
1375           if (atoi (s+1) > 255)
1376             return 0; /* No:  Ipv4 byte value too large.  */
1377           ndots++;
1378           n = 0;
1379         }
1380       else if (!strchr ("0123456789", *s))
1381         return 0; /* No: Not a digit.  */
1382       else if (++n > 3)
1383         return 0; /* No: More than 3 digits.  */
1384     }
1385   return (ndots == 3)? 4 : 0;
1386 }
1387
1388
1389 /* Return true if NAME is an onion address.  */
1390 int
1391 is_onion_address (const char *name)
1392 {
1393   size_t len;
1394
1395   len = name? strlen (name) : 0;
1396   if (len < 8 || strcmp (name + len - 6, ".onion"))
1397     return 0;
1398   /* Note that we require at least 2 characters before the suffix.  */
1399   return 1;  /* Yes.  */
1400 }
1401
1402
1403 /* libdns version of get_dns_cert.  */
1404 #ifdef USE_LIBDNS
1405 static gpg_error_t
1406 get_dns_cert_libdns (ctrl_t ctrl, const char *name, int want_certtype,
1407                      void **r_key, size_t *r_keylen,
1408                      unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
1409 {
1410   gpg_error_t err;
1411   struct dns_resolver *res = NULL;
1412   struct dns_packet *ans = NULL;
1413   struct dns_rr rr;
1414   struct dns_rr_i rri;
1415   char host[DNS_D_MAXNAME + 1];
1416   int derr;
1417   int qtype;
1418
1419   /* Get the query type from WANT_CERTTYPE (which in general indicates
1420    * the subtype we want). */
1421   qtype = (want_certtype < DNS_CERTTYPE_RRBASE
1422            ? T_CERT
1423            : (want_certtype - DNS_CERTTYPE_RRBASE));
1424
1425
1426   err = libdns_res_open (ctrl, &res);
1427   if (err)
1428     goto leave;
1429
1430   if (dns_d_anchor (host, sizeof host, name, strlen (name)) >= sizeof host)
1431     {
1432       err = gpg_error (GPG_ERR_ENAMETOOLONG);
1433       goto leave;
1434     }
1435
1436   err = libdns_res_submit (res, name, qtype, DNS_C_IN);
1437   if (err)
1438     goto leave;
1439
1440   err = libdns_res_wait (res);
1441   if (err)
1442     goto leave;
1443
1444   ans = dns_res_fetch (res, &derr);
1445   if (!ans)
1446     {
1447       err = libdns_error_to_gpg_error (derr);
1448       goto leave;
1449     }
1450
1451   /* Check the rcode.  */
1452   switch (dns_p_rcode (ans))
1453     {
1454     case DNS_RC_NOERROR: break;
1455     case DNS_RC_NXDOMAIN: err = gpg_error (GPG_ERR_NO_NAME); break;
1456     default: err = GPG_ERR_SERVER_FAILED; break;
1457     }
1458   if (err)
1459     goto leave;
1460
1461   memset (&rri, 0, sizeof rri);
1462   dns_rr_i_init (&rri, ans);
1463   rri.section = DNS_S_ALL & ~DNS_S_QD;
1464   rri.name    = host;
1465   rri.type    = qtype;
1466
1467   err = gpg_error (GPG_ERR_NOT_FOUND);
1468   while (dns_rr_grep (&rr, 1, &rri, ans, &derr))
1469     {
1470       unsigned char *rp  = ans->data + rr.rd.p;
1471       unsigned short len = rr.rd.len;
1472       u16 subtype;
1473
1474        if (!len)
1475         {
1476           /* Definitely too short - skip.  */
1477         }
1478       else if (want_certtype >= DNS_CERTTYPE_RRBASE
1479           && rr.type == (want_certtype - DNS_CERTTYPE_RRBASE)
1480           && r_key)
1481         {
1482           *r_key = xtrymalloc (len);
1483           if (!*r_key)
1484             err = gpg_error_from_syserror ();
1485           else
1486             {
1487               memcpy (*r_key, rp, len);
1488               *r_keylen = len;
1489               err = 0;
1490             }
1491           goto leave;
1492         }
1493       else if (want_certtype >= DNS_CERTTYPE_RRBASE)
1494         {
1495           /* We did not found the requested RR - skip. */
1496         }
1497       else if (rr.type == T_CERT && len > 5)
1498         {
1499           /* We got a CERT type.   */
1500           subtype = buf16_to_u16 (rp);
1501           rp += 2; len -= 2;
1502
1503           /* Skip the CERT key tag and algo which we don't need.  */
1504           rp += 3; len -= 3;
1505
1506           if (want_certtype && want_certtype != subtype)
1507             ; /* Not the requested subtype - skip.  */
1508           else if (subtype == DNS_CERTTYPE_PGP && len && r_key && r_keylen)
1509             {
1510               /* PGP subtype */
1511               *r_key = xtrymalloc (len);
1512               if (!*r_key)
1513                 err = gpg_error_from_syserror ();
1514               else
1515                 {
1516                   memcpy (*r_key, rp, len);
1517                   *r_keylen = len;
1518                   err = 0;
1519                 }
1520               goto leave;
1521             }
1522           else if (subtype == DNS_CERTTYPE_IPGP
1523                    && len && len < 1023 && len >= rp[0] + 1)
1524             {
1525               /* IPGP type */
1526               *r_fprlen = rp[0];
1527               if (*r_fprlen)
1528                 {
1529                   *r_fpr = xtrymalloc (*r_fprlen);
1530                   if (!*r_fpr)
1531                     {
1532                       err = gpg_error_from_syserror ();
1533                       goto leave;
1534                     }
1535                   memcpy (*r_fpr, rp+1, *r_fprlen);
1536                 }
1537               else
1538                 *r_fpr = NULL;
1539
1540               if (len > *r_fprlen + 1)
1541                 {
1542                   *r_url = xtrymalloc (len - (*r_fprlen + 1) + 1);
1543                   if (!*r_url)
1544                     {
1545                       err = gpg_error_from_syserror ();
1546                       xfree (*r_fpr);
1547                       *r_fpr = NULL;
1548                       goto leave;
1549                     }
1550                   memcpy (*r_url, rp + *r_fprlen + 1, len - (*r_fprlen + 1));
1551                   (*r_url)[len - (*r_fprlen + 1)] = 0;
1552                 }
1553               else
1554                 *r_url = NULL;
1555
1556               err = 0;
1557               goto leave;
1558             }
1559           else
1560             {
1561               /* Unknown subtype or record too short - skip.  */
1562             }
1563         }
1564       else
1565         {
1566           /* Not a requested type - skip.  */
1567         }
1568     }
1569
1570  leave:
1571   dns_free (ans);
1572   dns_res_close (res);
1573   return err;
1574 }
1575 #endif /*USE_LIBDNS*/
1576
1577
1578 /* Standard resolver version of get_dns_cert.  */
1579 static gpg_error_t
1580 get_dns_cert_standard (const char *name, int want_certtype,
1581                        void **r_key, size_t *r_keylen,
1582                        unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
1583 {
1584 #ifdef HAVE_SYSTEM_RESOLVER
1585   gpg_error_t err;
1586   unsigned char *answer;
1587   int r;
1588   u16 count;
1589
1590   /* Allocate a 64k buffer which is the limit for an DNS response.  */
1591   answer = xtrymalloc (65536);
1592   if (!answer)
1593     return gpg_error_from_syserror ();
1594
1595   err = gpg_error (GPG_ERR_NOT_FOUND);
1596   r = res_query (name, C_IN,
1597                  (want_certtype < DNS_CERTTYPE_RRBASE
1598                   ? T_CERT
1599                   : (want_certtype - DNS_CERTTYPE_RRBASE)),
1600                  answer, 65536);
1601   /* Not too big, not too small, no errors and at least 1 answer. */
1602   if (r >= sizeof (HEADER) && r <= 65536
1603       && (((HEADER *)(void *) answer)->rcode) == NOERROR
1604       && (count = ntohs (((HEADER *)(void *) answer)->ancount)))
1605     {
1606       int rc;
1607       unsigned char *pt, *emsg;
1608
1609       emsg = &answer[r];
1610
1611       pt = &answer[sizeof (HEADER)];
1612
1613       /* Skip over the query */
1614
1615       rc = dn_skipname (pt, emsg);
1616       if (rc == -1)
1617         {
1618           err = gpg_error (GPG_ERR_INV_OBJ);
1619           goto leave;
1620         }
1621       pt += rc + QFIXEDSZ;
1622
1623       /* There are several possible response types for a CERT request.
1624          We're interested in the PGP (a key) and IPGP (a URI) types.
1625          Skip all others.  TODO: A key is better than a URI since
1626          we've gone through all this bother to fetch it, so favor that
1627          if we have both PGP and IPGP? */
1628
1629       while (count-- > 0 && pt < emsg)
1630         {
1631           u16 type, class, dlen, ctype;
1632
1633           rc = dn_skipname (pt, emsg);  /* the name we just queried for */
1634           if (rc == -1)
1635             {
1636               err = gpg_error (GPG_ERR_INV_OBJ);
1637               goto leave;
1638             }
1639
1640           pt += rc;
1641
1642           /* Truncated message? 15 bytes takes us to the point where
1643              we start looking at the ctype. */
1644           if ((emsg - pt) < 15)
1645             break;
1646
1647           type = buf16_to_u16 (pt);
1648           pt += 2;
1649
1650           class = buf16_to_u16 (pt);
1651           pt += 2;
1652
1653           if (class != C_IN)
1654             break;
1655
1656           /* ttl */
1657           pt += 4;
1658
1659           /* data length */
1660           dlen = buf16_to_u16 (pt);
1661           pt += 2;
1662
1663           /* Check the type and parse.  */
1664           if (want_certtype >= DNS_CERTTYPE_RRBASE
1665               && type == (want_certtype - DNS_CERTTYPE_RRBASE)
1666               && r_key)
1667             {
1668               *r_key = xtrymalloc (dlen);
1669               if (!*r_key)
1670                 err = gpg_error_from_syserror ();
1671               else
1672                 {
1673                   memcpy (*r_key, pt, dlen);
1674                   *r_keylen = dlen;
1675                   err = 0;
1676                 }
1677               goto leave;
1678             }
1679           else if (want_certtype >= DNS_CERTTYPE_RRBASE)
1680             {
1681               /* We did not found the requested RR.  */
1682               pt += dlen;
1683             }
1684           else if (type == T_CERT)
1685             {
1686               /* We got a CERT type.   */
1687               ctype = buf16_to_u16 (pt);
1688               pt += 2;
1689
1690               /* Skip the CERT key tag and algo which we don't need. */
1691               pt += 3;
1692
1693               dlen -= 5;
1694
1695               /* 15 bytes takes us to here */
1696               if (want_certtype && want_certtype != ctype)
1697                 ; /* Not of the requested certtype.  */
1698               else if (ctype == DNS_CERTTYPE_PGP && dlen && r_key && r_keylen)
1699                 {
1700                   /* PGP type */
1701                   *r_key = xtrymalloc (dlen);
1702                   if (!*r_key)
1703                     err = gpg_error_from_syserror ();
1704                   else
1705                     {
1706                       memcpy (*r_key, pt, dlen);
1707                       *r_keylen = dlen;
1708                       err = 0;
1709                     }
1710                   goto leave;
1711                 }
1712               else if (ctype == DNS_CERTTYPE_IPGP
1713                        && dlen && dlen < 1023 && dlen >= pt[0] + 1)
1714                 {
1715                   /* IPGP type */
1716                   *r_fprlen = pt[0];
1717                   if (*r_fprlen)
1718                     {
1719                       *r_fpr = xtrymalloc (*r_fprlen);
1720                       if (!*r_fpr)
1721                         {
1722                           err = gpg_error_from_syserror ();
1723                           goto leave;
1724                         }
1725                       memcpy (*r_fpr, &pt[1], *r_fprlen);
1726                     }
1727                   else
1728                     *r_fpr = NULL;
1729
1730                   if (dlen > *r_fprlen + 1)
1731                     {
1732                       *r_url = xtrymalloc (dlen - (*r_fprlen + 1) + 1);
1733                       if (!*r_url)
1734                         {
1735                           err = gpg_error_from_syserror ();
1736                           xfree (*r_fpr);
1737                           *r_fpr = NULL;
1738                           goto leave;
1739                         }
1740                       memcpy (*r_url, &pt[*r_fprlen + 1],
1741                               dlen - (*r_fprlen + 1));
1742                       (*r_url)[dlen - (*r_fprlen + 1)] = '\0';
1743                     }
1744                   else
1745                     *r_url = NULL;
1746
1747                   err = 0;
1748                   goto leave;
1749                 }
1750
1751               /* No subtype matches, so continue with the next answer. */
1752               pt += dlen;
1753             }
1754           else
1755             {
1756               /* Not a requested type - might be a CNAME. Try next item.  */
1757               pt += dlen;
1758             }
1759         }
1760     }
1761
1762  leave:
1763   xfree (answer);
1764   return err;
1765
1766 #else /*!HAVE_SYSTEM_RESOLVER*/
1767
1768   (void)name;
1769   (void)want_certtype;
1770   (void)r_key;
1771   (void)r_keylen;
1772   (void)r_fpr;
1773   (void)r_fprlen;
1774   (void)r_url;
1775   return gpg_error (GPG_ERR_NOT_SUPPORTED);
1776
1777 #endif /*!HAVE_SYSTEM_RESOLVER*/
1778 }
1779
1780
1781 /* Returns 0 on success or an error code.  If a PGP CERT record was
1782    found, the malloced data is returned at (R_KEY, R_KEYLEN) and
1783    the other return parameters are set to NULL/0.  If an IPGP CERT
1784    record was found the fingerprint is stored as an allocated block at
1785    R_FPR and its length at R_FPRLEN; an URL is allocated as a
1786    string and returned at R_URL.  If WANT_CERTTYPE is 0 this function
1787    returns the first CERT found with a supported type; it is expected
1788    that only one CERT record is used.  If WANT_CERTTYPE is one of the
1789    supported certtypes only records with this certtype are considered
1790    and the first found is returned.  (R_KEY,R_KEYLEN) are optional. */
1791 gpg_error_t
1792 get_dns_cert (ctrl_t ctrl, const char *name, int want_certtype,
1793               void **r_key, size_t *r_keylen,
1794               unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
1795 {
1796   gpg_error_t err;
1797
1798   if (r_key)
1799     *r_key = NULL;
1800   if (r_keylen)
1801     *r_keylen = 0;
1802   *r_fpr = NULL;
1803   *r_fprlen = 0;
1804   *r_url = NULL;
1805
1806 #ifdef USE_LIBDNS
1807   if (!standard_resolver)
1808     {
1809       err = get_dns_cert_libdns (ctrl, name, want_certtype, r_key, r_keylen,
1810                                  r_fpr, r_fprlen, r_url);
1811       if (err && libdns_switch_port_p (err))
1812         err = get_dns_cert_libdns (ctrl, name, want_certtype, r_key, r_keylen,
1813                                    r_fpr, r_fprlen, r_url);
1814     }
1815   else
1816 #endif /*USE_LIBDNS*/
1817     err = get_dns_cert_standard (name, want_certtype, r_key, r_keylen,
1818                                  r_fpr, r_fprlen, r_url);
1819
1820   if (opt_debug)
1821     log_debug ("dns: get_dns_cert(%s): %s\n", name, gpg_strerror (err));
1822   return err;
1823 }
1824
1825
1826 static int
1827 priosort(const void *a,const void *b)
1828 {
1829   const struct srventry *sa=a,*sb=b;
1830   if(sa->priority>sb->priority)
1831     return 1;
1832   else if(sa->priority<sb->priority)
1833     return -1;
1834   else
1835     return 0;
1836 }
1837
1838
1839 /* Libdns based helper for getsrv.  Note that it is expected that NULL
1840  * is stored at the address of LIST and 0 is stored at the address of
1841  * R_COUNT.  */
1842 #ifdef USE_LIBDNS
1843 static gpg_error_t
1844 getsrv_libdns (ctrl_t ctrl,
1845                const char *name, struct srventry **list, unsigned int *r_count)
1846 {
1847   gpg_error_t err;
1848   struct dns_resolver *res = NULL;
1849   struct dns_packet *ans = NULL;
1850   struct dns_rr rr;
1851   struct dns_rr_i rri;
1852   char host[DNS_D_MAXNAME + 1];
1853   int derr;
1854   unsigned int srvcount = 0;
1855
1856   err = libdns_res_open (ctrl, &res);
1857   if (err)
1858     goto leave;
1859
1860   if (dns_d_anchor (host, sizeof host, name, strlen (name)) >= sizeof host)
1861     {
1862       err = gpg_error (GPG_ERR_ENAMETOOLONG);
1863       goto leave;
1864     }
1865
1866   err = libdns_res_submit (res, name, DNS_T_SRV, DNS_C_IN);
1867   if (err)
1868     goto leave;
1869
1870   err = libdns_res_wait (res);
1871   if (err)
1872     goto leave;
1873
1874   ans = dns_res_fetch (res, &derr);
1875   if (!ans)
1876     {
1877       err = libdns_error_to_gpg_error (derr);
1878       goto leave;
1879     }
1880
1881   /* Check the rcode.  */
1882   switch (dns_p_rcode (ans))
1883     {
1884     case DNS_RC_NOERROR: break;
1885     case DNS_RC_NXDOMAIN: err = gpg_error (GPG_ERR_NO_NAME); break;
1886     default: err = GPG_ERR_SERVER_FAILED; break;
1887     }
1888   if (err)
1889     goto leave;
1890
1891   memset (&rri, 0, sizeof rri);
1892   dns_rr_i_init (&rri, ans);
1893   rri.section = DNS_S_ALL & ~DNS_S_QD;
1894   rri.name        = host;
1895   rri.type        = DNS_T_SRV;
1896
1897   while (dns_rr_grep (&rr, 1, &rri, ans, &derr))
1898     {
1899       struct dns_srv dsrv;
1900       struct srventry *srv;
1901       struct srventry *newlist;
1902
1903       err = libdns_error_to_gpg_error (dns_srv_parse(&dsrv, &rr, ans));
1904       if (err)
1905         goto leave;
1906
1907       newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
1908       if (!newlist)
1909         {
1910           err = gpg_error_from_syserror ();
1911           goto leave;
1912         }
1913       *list = newlist;
1914       memset (&(*list)[srvcount], 0, sizeof(struct srventry));
1915       srv = &(*list)[srvcount];
1916       srvcount++;
1917       srv->priority = dsrv.priority;
1918       srv->weight   = dsrv.weight;
1919       srv->port     = dsrv.port;
1920       mem2str (srv->target, dsrv.target, sizeof srv->target);
1921       /* Libdns appends the root zone part which is problematic for
1922        * most other functions - strip it.  */
1923       if (*srv->target && (srv->target)[strlen (srv->target)-1] == '.')
1924         (srv->target)[strlen (srv->target)-1] = 0;
1925     }
1926
1927   *r_count = srvcount;
1928
1929  leave:
1930   if (err)
1931     {
1932       xfree (*list);
1933       *list = NULL;
1934     }
1935   dns_free (ans);
1936   dns_res_close (res);
1937   return err;
1938 }
1939 #endif /*USE_LIBDNS*/
1940
1941
1942 /* Standard resolver based helper for getsrv.  Note that it is
1943  * expected that NULL is stored at the address of LIST and 0 is stored
1944  * at the address of R_COUNT.  */
1945 static gpg_error_t
1946 getsrv_standard (const char *name,
1947                  struct srventry **list, unsigned int *r_count)
1948 {
1949 #ifdef HAVE_SYSTEM_RESOLVER
1950   union {
1951     unsigned char ans[2048];
1952     HEADER header[1];
1953   } res;
1954   unsigned char *answer = res.ans;
1955   HEADER *header = res.header;
1956   unsigned char *pt, *emsg;
1957   int r, rc;
1958   u16 dlen;
1959   unsigned int srvcount = 0;
1960   u16 count;
1961
1962   /* Do not allow a query using the standard resolver in Tor mode.  */
1963   if (tor_mode)
1964     return gpg_error (GPG_ERR_NOT_ENABLED);
1965
1966   my_unprotect ();
1967   r = res_query (name, C_IN, T_SRV, answer, sizeof res.ans);
1968   my_protect ();
1969   if (r < 0)
1970     return get_h_errno_as_gpg_error ();
1971   if (r < sizeof (HEADER))
1972     return gpg_error (GPG_ERR_SERVER_FAILED);
1973   if (r > sizeof res.ans)
1974     return gpg_error (GPG_ERR_SYSTEM_BUG);
1975   if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
1976     return gpg_error (GPG_ERR_NO_NAME); /* Error or no record found.  */
1977
1978   emsg = &answer[r];
1979   pt = &answer[sizeof(HEADER)];
1980
1981   /* Skip over the query */
1982   rc = dn_skipname (pt, emsg);
1983   if (rc == -1)
1984     goto fail;
1985
1986   pt += rc + QFIXEDSZ;
1987
1988   while (count-- > 0 && pt < emsg)
1989     {
1990       struct srventry *srv;
1991       u16 type, class;
1992       struct srventry *newlist;
1993
1994       newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
1995       if (!newlist)
1996         goto fail;
1997       *list = newlist;
1998       memset (&(*list)[srvcount], 0, sizeof(struct srventry));
1999       srv = &(*list)[srvcount];
2000       srvcount++;
2001
2002       rc = dn_skipname (pt, emsg); /* The name we just queried for.  */
2003       if (rc == -1)
2004         goto fail;
2005       pt += rc;
2006
2007       /* Truncated message? */
2008       if ((emsg-pt) < 16)
2009         goto fail;
2010
2011       type = buf16_to_u16 (pt);
2012       pt += 2;
2013       /* We asked for SRV and got something else !? */
2014       if (type != T_SRV)
2015         goto fail;
2016
2017       class = buf16_to_u16 (pt);
2018       pt += 2;
2019       /* We asked for IN and got something else !? */
2020       if (class != C_IN)
2021         goto fail;
2022
2023       pt += 4; /* ttl */
2024       dlen = buf16_to_u16 (pt);
2025       pt += 2;
2026
2027       srv->priority = buf16_to_ushort (pt);
2028       pt += 2;
2029       srv->weight = buf16_to_ushort (pt);
2030       pt += 2;
2031       srv->port = buf16_to_ushort (pt);
2032       pt += 2;
2033
2034       /* Get the name.  2782 doesn't allow name compression, but
2035        * dn_expand still works to pull the name out of the packet. */
2036       rc = dn_expand (answer, emsg, pt, srv->target, sizeof srv->target);
2037       if (rc == 1 && srv->target[0] == 0) /* "." */
2038         {
2039           xfree(*list);
2040           *list = NULL;
2041           return 0;
2042         }
2043       if (rc == -1)
2044         goto fail;
2045       pt += rc;
2046       /* Corrupt packet? */
2047       if (dlen != rc+6)
2048         goto fail;
2049     }
2050
2051   *r_count = srvcount;
2052   return 0;
2053
2054  fail:
2055   xfree (*list);
2056   *list = NULL;
2057   return gpg_error (GPG_ERR_GENERAL);
2058
2059 #else /*!HAVE_SYSTEM_RESOLVER*/
2060
2061   (void)name;
2062   (void)list;
2063   (void)r_count;
2064   return gpg_error (GPG_ERR_NOT_SUPPORTED);
2065
2066 #endif /*!HAVE_SYSTEM_RESOLVER*/
2067 }
2068
2069
2070 /* Query a SRV record for SERVICE and PROTO for NAME.  If SERVICE is
2071  * NULL, NAME is expected to contain the full query name.  Note that
2072  * we do not return NONAME but simply store 0 at R_COUNT.  On error an
2073  * error code is returned and 0 stored at R_COUNT.  */
2074 gpg_error_t
2075 get_dns_srv (ctrl_t ctrl,
2076              const char *name, const char *service, const char *proto,
2077              struct srventry **list, unsigned int *r_count)
2078 {
2079   gpg_error_t err;
2080   char *namebuffer = NULL;
2081   unsigned int srvcount;
2082   int i;
2083
2084   *list = NULL;
2085   *r_count = 0;
2086   srvcount = 0;
2087
2088   /* If SERVICE is given construct the query from it and PROTO.  */
2089   if (service)
2090     {
2091       namebuffer = xtryasprintf ("_%s._%s.%s",
2092                                  service, proto? proto:"tcp", name);
2093       if (!namebuffer)
2094         {
2095           err = gpg_error_from_syserror ();
2096           goto leave;
2097         }
2098       name = namebuffer;
2099     }
2100
2101
2102 #ifdef USE_LIBDNS
2103   if (!standard_resolver)
2104     {
2105       err = getsrv_libdns (ctrl, name, list, &srvcount);
2106       if (err && libdns_switch_port_p (err))
2107         err = getsrv_libdns (ctrl, name, list, &srvcount);
2108     }
2109   else
2110 #endif /*USE_LIBDNS*/
2111     err = getsrv_standard (name, list, &srvcount);
2112
2113   if (err)
2114     {
2115       if (gpg_err_code (err) == GPG_ERR_NO_NAME)
2116         err = 0;
2117       goto leave;
2118     }
2119
2120   /* Now we have an array of all the srv records. */
2121
2122   /* Order by priority */
2123   qsort(*list,srvcount,sizeof(struct srventry),priosort);
2124
2125   /* For each priority, move the zero-weighted items first. */
2126   for (i=0; i < srvcount; i++)
2127     {
2128       int j;
2129
2130       for (j=i;j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
2131         {
2132           if((*list)[j].weight==0)
2133             {
2134               /* Swap j with i */
2135               if(j!=i)
2136                 {
2137                   struct srventry temp;
2138
2139                   memcpy (&temp,&(*list)[j],sizeof(struct srventry));
2140                   memcpy (&(*list)[j],&(*list)[i],sizeof(struct srventry));
2141                   memcpy (&(*list)[i],&temp,sizeof(struct srventry));
2142                 }
2143
2144               break;
2145             }
2146         }
2147     }
2148
2149   /* Run the RFC-2782 weighting algorithm.  We don't need very high
2150      quality randomness for this, so regular libc srand/rand is
2151      sufficient.  */
2152
2153   {
2154     static int done;
2155     if (!done)
2156       {
2157         done = 1;
2158         srand (time (NULL)*getpid());
2159       }
2160   }
2161
2162   for (i=0; i < srvcount; i++)
2163     {
2164       int j;
2165       float prio_count=0,chose;
2166
2167       for (j=i; j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
2168         {
2169           prio_count+=(*list)[j].weight;
2170           (*list)[j].run_count=prio_count;
2171         }
2172
2173       chose=prio_count*rand()/RAND_MAX;
2174
2175       for (j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
2176         {
2177           if (chose<=(*list)[j].run_count)
2178             {
2179               /* Swap j with i */
2180               if(j!=i)
2181                 {
2182                   struct srventry temp;
2183
2184                   memcpy(&temp,&(*list)[j],sizeof(struct srventry));
2185                   memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
2186                   memcpy(&(*list)[i],&temp,sizeof(struct srventry));
2187                 }
2188               break;
2189             }
2190         }
2191     }
2192
2193  leave:
2194   if (opt_debug)
2195     {
2196       if (err)
2197         log_debug ("dns: getsrv(%s): %s\n", name, gpg_strerror (err));
2198       else
2199         log_debug ("dns: getsrv(%s) -> %u records\n", name, srvcount);
2200     }
2201   if (!err)
2202     *r_count = srvcount;
2203   xfree (namebuffer);
2204   return err;
2205 }
2206
2207
2208 \f
2209 #ifdef USE_LIBDNS
2210 /* libdns version of get_dns_cname.  */
2211 gpg_error_t
2212 get_dns_cname_libdns (ctrl_t ctrl, const char *name, char **r_cname)
2213 {
2214   gpg_error_t err;
2215   struct dns_resolver *res;
2216   struct dns_packet *ans = NULL;
2217   struct dns_cname cname;
2218   int derr;
2219
2220   err = libdns_res_open (ctrl, &res);
2221   if (err)
2222     goto leave;
2223
2224   err = libdns_res_submit (res, name, DNS_T_CNAME, DNS_C_IN);
2225   if (err)
2226     goto leave;
2227
2228   err = libdns_res_wait (res);
2229   if (err)
2230     goto leave;
2231
2232   ans = dns_res_fetch (res, &derr);
2233   if (!ans)
2234     {
2235       err = libdns_error_to_gpg_error (derr);
2236       goto leave;
2237     }
2238
2239   /* Check the rcode.  */
2240   switch (dns_p_rcode (ans))
2241     {
2242     case DNS_RC_NOERROR: break;
2243     case DNS_RC_NXDOMAIN: err = gpg_error (GPG_ERR_NO_NAME); break;
2244     default: err = GPG_ERR_SERVER_FAILED; break;
2245     }
2246   if (err)
2247     goto leave;
2248
2249   /* Parse the result into CNAME.  */
2250   err = libdns_error_to_gpg_error (dns_p_study (ans));
2251   if (err)
2252     goto leave;
2253
2254   if (!dns_d_cname (&cname, sizeof cname, name, strlen (name), ans, &derr))
2255     {
2256       err = libdns_error_to_gpg_error (derr);
2257       goto leave;
2258     }
2259
2260   /* Copy result.  */
2261   *r_cname = xtrystrdup (cname.host);
2262   if (!*r_cname)
2263     err = gpg_error_from_syserror ();
2264   else
2265     {
2266       /* Libdns appends the root zone part which is problematic
2267        * for most other functions - strip it.  */
2268       if (**r_cname && (*r_cname)[strlen (*r_cname)-1] == '.')
2269         (*r_cname)[strlen (*r_cname)-1] = 0;
2270     }
2271
2272  leave:
2273   dns_free (ans);
2274   dns_res_close (res);
2275   return err;
2276 }
2277 #endif /*USE_LIBDNS*/
2278
2279
2280 /* Standard resolver version of get_dns_cname.  */
2281 gpg_error_t
2282 get_dns_cname_standard (const char *name, char **r_cname)
2283 {
2284 #ifdef HAVE_SYSTEM_RESOLVER
2285   gpg_error_t err;
2286   int rc;
2287   union {
2288     unsigned char ans[2048];
2289     HEADER header[1];
2290   } res;
2291   unsigned char *answer = res.ans;
2292   HEADER *header = res.header;
2293   unsigned char *pt, *emsg;
2294   int r;
2295   char *cname;
2296   int cnamesize = 1025;
2297   u16 count;
2298
2299   /* Do not allow a query using the standard resolver in Tor mode.  */
2300   if (tor_mode)
2301     return -1;
2302
2303   my_unprotect ();
2304   r = res_query (name, C_IN, T_CERT, answer, sizeof res.ans);
2305   my_protect ();
2306   if (r < 0)
2307     return get_h_errno_as_gpg_error ();
2308   if (r < sizeof (HEADER))
2309     return gpg_error (GPG_ERR_SERVER_FAILED);
2310   if (r > sizeof res.ans)
2311     return gpg_error (GPG_ERR_SYSTEM_BUG);
2312   if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
2313     return gpg_error (GPG_ERR_NO_NAME); /* Error or no record found.  */
2314   if (count != 1)
2315     return gpg_error (GPG_ERR_SERVER_FAILED);
2316
2317   emsg = &answer[r];
2318   pt = &answer[sizeof(HEADER)];
2319   rc = dn_skipname (pt, emsg);
2320   if (rc == -1)
2321     return gpg_error (GPG_ERR_SERVER_FAILED);
2322
2323   pt += rc + QFIXEDSZ;
2324   if (pt >= emsg)
2325     return gpg_error (GPG_ERR_SERVER_FAILED);
2326
2327   rc = dn_skipname (pt, emsg);
2328   if (rc == -1)
2329     return gpg_error (GPG_ERR_SERVER_FAILED);
2330   pt += rc + 2 + 2 + 4;
2331   if (pt+2 >= emsg)
2332     return gpg_error (GPG_ERR_SERVER_FAILED);
2333   pt += 2;  /* Skip rdlen */
2334
2335   cname = xtrymalloc (cnamesize);
2336   if (!cname)
2337     return gpg_error_from_syserror ();
2338
2339   rc = dn_expand (answer, emsg, pt, cname, cnamesize -1);
2340   if (rc == -1)
2341     {
2342       xfree (cname);
2343       return gpg_error (GPG_ERR_SERVER_FAILED);
2344     }
2345   *r_cname = xtryrealloc (cname, strlen (cname)+1);
2346   if (!*r_cname)
2347     {
2348       err = gpg_error_from_syserror ();
2349       xfree (cname);
2350       return err;
2351     }
2352   return 0;
2353
2354 #else /*!HAVE_SYSTEM_RESOLVER*/
2355
2356   (void)name;
2357   (void)r_cname;
2358   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2359
2360 #endif /*!HAVE_SYSTEM_RESOLVER*/
2361 }
2362
2363
2364 gpg_error_t
2365 get_dns_cname (ctrl_t ctrl, const char *name, char **r_cname)
2366 {
2367   gpg_error_t err;
2368
2369   *r_cname = NULL;
2370
2371 #ifdef USE_LIBDNS
2372   if (!standard_resolver)
2373     {
2374       err = get_dns_cname_libdns (ctrl, name, r_cname);
2375       if (err && libdns_switch_port_p (err))
2376         err = get_dns_cname_libdns (ctrl, name, r_cname);
2377       return err;
2378     }
2379 #endif /*USE_LIBDNS*/
2380
2381   err = get_dns_cname_standard (name, r_cname);
2382   if (opt_debug)
2383     log_debug ("get_dns_cname(%s)%s%s\n", name,
2384                err ? ": " : " -> ",
2385                err ? gpg_strerror (err) : *r_cname);
2386   return err;
2387 }