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