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