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