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