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