Silence compiler warnings related to not using assuan_fd_t.
[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 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 <http://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 # include <netinet/in.h>
40 # include <arpa/nameser.h>
41 # include <resolv.h>
42 # include <netdb.h>
43 #endif
44 #include <string.h>
45 #include <unistd.h>
46 #ifdef USE_ADNS
47 # include <adns.h>
48 #endif
49
50 #if !defined(HAVE_GETADDRINFO) && !defined(USE_ADNS)
51 # error Either getaddrinfo or the ADNS library is required.
52 #endif
53
54 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
55 # undef USE_NPTH
56 #endif
57 #ifdef USE_NPTH
58 # include <npth.h>
59 #endif
60
61 #include "util.h"
62 #include "host2net.h"
63 #include "dns-stuff.h"
64
65 #ifdef USE_NPTH
66 # define my_unprotect()        npth_unprotect ()
67 # define my_protect()          npth_protect ()
68 #else
69 # define my_unprotect()        do { } while(0)
70 # define my_protect()          do { } while(0)
71 #endif
72
73 /* We allow the use of 0 instead of AF_UNSPEC - check this assumption.  */
74 #if AF_UNSPEC != 0
75 # error AF_UNSPEC does not have the value 0
76 #endif
77
78 /* Windows does not support the AI_ADDRCONFIG flag - use zero instead.  */
79 #ifndef AI_ADDRCONFIG
80 # define AI_ADDRCONFIG 0
81 #endif
82
83 /* Provide a replacement function for older ADNS versions.  */
84 #ifndef HAVE_ADNS_FREE
85 # define adns_free(a) free ((a))
86 #endif
87
88 /* Not every installation has gotten around to supporting SRVs or
89    CERTs yet... */
90 #ifndef T_SRV
91 #define T_SRV 33
92 #endif
93 #ifndef T_CERT
94 # define T_CERT 37
95 #endif
96
97 /* ADNS has no support for CERT yet. */
98 #define my_adns_r_cert 37
99
100
101 /* The default nameserver used with ADNS in Tor mode.  */
102 #define DEFAULT_NAMESERVER "8.8.8.8"
103
104
105 /* If set Tor mode shall be used.  */
106 static int tor_mode;
107
108 /* A string with the nameserver IP address used with Tor.
109   (40 should be sufficient for v6 but we add some extra for a scope.) */
110 static char tor_nameserver[40+20];
111
112 /* A string to hold the credentials presented to Tor.  */
113 #ifdef USE_ADNS
114 static char tor_credentials[50];
115 #endif
116
117 /* Sets the module in Tor mode.  Returns 0 is this is possible or an
118    error code.  */
119 gpg_error_t
120 enable_dns_tormode (int new_circuit)
121 {
122 #if defined(USE_DNS_CERT) && defined(USE_ADNS)
123 # if HAVE_ADNS_IF_TORMODE
124    if (!*tor_credentials || new_circuit)
125      {
126        static unsigned int counter;
127
128        gpgrt_snprintf (tor_credentials, sizeof tor_credentials,
129                        "dirmngr-%lu:p%u",
130                        (unsigned long)getpid (), counter);
131        counter++;
132      }
133    tor_mode = 1;
134    return 0;
135 # endif
136 #endif
137
138   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
139 }
140
141
142 /* Change the default IP address of the nameserver to IPADDR.  The
143    address needs to be a numerical IP address and will be used for the
144    next DNS query.  Note that this is only used in Tor mode.  */
145 void
146 set_dns_nameserver (const char *ipaddr)
147 {
148   strncpy (tor_nameserver, ipaddr? ipaddr : DEFAULT_NAMESERVER,
149            sizeof tor_nameserver -1);
150   tor_nameserver[sizeof tor_nameserver -1] = 0;
151 }
152
153
154 /* Free an addressinfo linked list as returned by resolve_dns_name.  */
155 void
156 free_dns_addrinfo (dns_addrinfo_t ai)
157 {
158   while (ai)
159     {
160       dns_addrinfo_t next = ai->next;
161       xfree (ai);
162       ai = next;
163     }
164 }
165
166
167 static gpg_error_t
168 map_eai_to_gpg_error (int ec)
169 {
170   gpg_error_t err;
171
172   switch (ec)
173     {
174     case EAI_AGAIN:     err = gpg_error (GPG_ERR_EAGAIN); break;
175     case EAI_BADFLAGS:  err = gpg_error (GPG_ERR_INV_FLAG); break;
176     case EAI_FAIL:      err = gpg_error (GPG_ERR_SERVER_FAILED); break;
177     case EAI_MEMORY:    err = gpg_error (GPG_ERR_ENOMEM); break;
178     case EAI_NODATA:    err = gpg_error (GPG_ERR_NO_DATA); break;
179     case EAI_NONAME:    err = gpg_error (GPG_ERR_NO_NAME); break;
180     case EAI_SERVICE:   err = gpg_error (GPG_ERR_NOT_SUPPORTED); break;
181     case EAI_FAMILY:    err = gpg_error (GPG_ERR_EAFNOSUPPORT); break;
182     case EAI_SOCKTYPE:  err = gpg_error (GPG_ERR_ESOCKTNOSUPPORT); break;
183 #ifndef HAVE_W32_SYSTEM
184     case EAI_ADDRFAMILY:err = gpg_error (GPG_ERR_EADDRNOTAVAIL); break;
185     case EAI_SYSTEM:    err = gpg_error_from_syserror (); break;
186 #endif
187     default:            err = gpg_error (GPG_ERR_UNKNOWN_ERRNO); break;
188     }
189   return err;
190 }
191
192
193 #ifdef USE_ADNS
194 /* Init ADNS and store the new state at R_STATE.  Returns 0 on
195    success; prints an error message and returns an error code on
196    failure.  */
197 static gpg_error_t
198 my_adns_init (adns_state *r_state)
199 {
200   gpg_error_t err = 0;
201   int ret;
202
203   if (tor_mode)
204     {
205       char *cfgstr;
206
207       if (!*tor_nameserver)
208         set_dns_nameserver (NULL);
209
210       cfgstr = xtryasprintf ("nameserver %s\n"
211                              "options adns_tormode adns_sockscred:%s",
212                              tor_nameserver, tor_credentials);
213       if (!cfgstr)
214         err = gpg_error_from_syserror ();
215       else
216         {
217           ret = adns_init_strcfg (r_state, adns_if_debug /*adns_if_noerrprint*/, NULL, cfgstr);
218           if (ret)
219             err = gpg_error_from_errno (ret);
220           xfree (cfgstr);
221         }
222     }
223   else
224     {
225       ret = adns_init (r_state, adns_if_noerrprint, NULL);
226       if (ret)
227         err = gpg_error_from_errno (ret);
228     }
229
230   if (err)
231     {
232       log_error ("error initializing adns: %s\n", gpg_strerror (err));
233       return err;
234     }
235   return 0;
236 }
237 #endif /*USE_ADNS*/
238
239
240 #ifdef USE_ADNS
241 /* Resolve a name using the ADNS library.  See resolve_dns_name for
242    the description.  */
243 static gpg_error_t
244 resolve_name_adns (const char *name, unsigned short port,
245                    int want_family, int want_socktype,
246                    dns_addrinfo_t *r_dai, char **r_canonname)
247 {
248   gpg_error_t err = 0;
249   int ret;
250   dns_addrinfo_t daihead = NULL;
251   dns_addrinfo_t dai;
252   adns_state state;
253   adns_answer *answer = NULL;
254   int count;
255
256   (void)want_family;
257
258   *r_dai = NULL;
259   if (r_canonname)
260     *r_canonname = NULL;
261
262   if (want_socktype != SOCK_STREAM && want_socktype != SOCK_DGRAM)
263     return gpg_error (GPG_ERR_ESOCKTNOSUPPORT);
264
265   err = my_adns_init (&state);
266   if (err)
267     return err;
268
269   my_unprotect ();
270   ret = adns_synchronous (state, name, adns_r_addr,
271                           adns_qf_quoteok_query, &answer);
272   my_protect ();
273   if (ret)
274     {
275       err = gpg_error_from_syserror ();
276       log_error ("DNS query failed: %s\n", gpg_strerror (err));
277       goto leave;
278     }
279
280   err = gpg_error (GPG_ERR_NOT_FOUND);
281   if (answer->status != adns_s_ok || answer->type != adns_r_addr)
282     {
283       log_error ("DNS query returned an error: %s (%s)\n",
284                  adns_strerror (answer->status),
285                  adns_errabbrev (answer->status));
286       goto leave;
287     }
288
289   if (r_canonname && answer->cname)
290     {
291       *r_canonname = xtrystrdup (answer->cname);
292       if (!*r_canonname)
293         {
294           err = gpg_error_from_syserror ();
295           goto leave;
296         }
297     }
298
299   for (count = 0; count < answer->nrrs; count++)
300     {
301       int len;
302       adns_rr_addr *addr;
303
304       len  = answer->rrs.addr[count].len;
305       addr = &answer->rrs.addr[count];
306       if (addr->addr.sa.sa_family != AF_INET6
307           && addr->addr.sa.sa_family != AF_INET)
308         continue;
309
310       dai = xtrymalloc (sizeof *dai + len - 1);
311       if (!dai)
312         {
313           err = gpg_error_from_syserror ();
314           goto leave;
315         }
316       dai->family = addr->addr.sa.sa_family;
317       dai->socktype = want_socktype == SOCK_STREAM? SOCK_STREAM : SOCK_DGRAM;
318       dai->protocol = want_socktype == SOCK_STREAM? IPPROTO_TCP : IPPROTO_UDP;
319       dai->addrlen = len;
320       memcpy (dai->addr, &addr->addr.sa, len);
321       ((struct sockaddr_in *) dai->addr)->sin_port = htons (port);
322       dai->next = daihead;
323       daihead = dai;
324       err = 0;
325     }
326
327  leave:
328   adns_free (answer);
329   adns_finish (state);
330   if (err)
331     {
332       if (r_canonname)
333         {
334           xfree (*r_canonname);
335           *r_canonname = NULL;
336         }
337       free_dns_addrinfo (daihead);
338     }
339   else
340     *r_dai = daihead;
341   return err;
342 }
343 #endif /*USE_ADNS*/
344
345
346 #ifndef USE_ADNS
347 /* Resolve a name using the standard system function.  */
348 static gpg_error_t
349 resolve_name_standard (const char *name, unsigned short port,
350                        int want_family, int want_socktype,
351                        dns_addrinfo_t *r_dai, char **r_canonname)
352 {
353   gpg_error_t err = 0;
354   dns_addrinfo_t daihead = NULL;
355   dns_addrinfo_t dai;
356   struct addrinfo *aibuf = NULL;
357   struct addrinfo hints, *ai;
358   char portstr[21];
359   int ret;
360
361   *r_dai = NULL;
362   if (r_canonname)
363     *r_canonname = NULL;
364
365   memset (&hints, 0, sizeof hints);
366   hints.ai_family = want_family;
367   hints.ai_socktype = want_socktype;
368   hints.ai_flags = AI_ADDRCONFIG;
369   if (r_canonname)
370     hints.ai_flags |= AI_CANONNAME;
371
372   if (port)
373     snprintf (portstr, sizeof portstr, "%hu", port);
374   else
375     *portstr = 0;
376
377   /* We can't use the the AI_IDN flag because that does the conversion
378      using the current locale.  However, GnuPG always used UTF-8.  To
379      support IDN we would need to make use of the libidn API.  */
380   ret = getaddrinfo (name, *portstr? portstr : NULL, &hints, &aibuf);
381   if (ret)
382     {
383       aibuf = NULL;
384       err = map_eai_to_gpg_error (ret);
385       if (gpg_err_code (err) == GPG_ERR_NO_NAME)
386         {
387           /* There seems to be a bug in the glibc getaddrinfo function
388              if the CNAME points to a long list of A and AAAA records
389              in which case the function return NO_NAME.  Let's do the
390              CNAME redirection again.  */
391           char *cname;
392
393           if (get_dns_cname (name, &cname))
394             goto leave; /* Still no success.  */
395
396           ret = getaddrinfo (cname, *portstr? portstr : NULL, &hints, &aibuf);
397           xfree (cname);
398           if (ret)
399             {
400               aibuf = NULL;
401               err = map_eai_to_gpg_error (ret);
402               goto leave;
403             }
404           err = 0; /* Yep, now it worked.  */
405         }
406       else
407         goto leave;
408     }
409
410   if (r_canonname && aibuf && aibuf->ai_canonname)
411     {
412       *r_canonname = xtrystrdup (aibuf->ai_canonname);
413       if (!*r_canonname)
414         {
415           err = gpg_error_from_syserror ();
416           goto leave;
417         }
418     }
419
420   for (ai = aibuf; ai; ai = ai->ai_next)
421     {
422       if (ai->ai_family != AF_INET6 && ai->ai_family != AF_INET)
423         continue;
424
425       dai = xtrymalloc (sizeof *dai + ai->ai_addrlen - 1);
426       dai->family = ai->ai_family;
427       dai->socktype = ai->ai_socktype;
428       dai->protocol = ai->ai_protocol;
429       dai->addrlen = ai->ai_addrlen;
430       memcpy (dai->addr, ai->ai_addr, ai->ai_addrlen);
431       dai->next = daihead;
432       daihead = dai;
433     }
434
435  leave:
436   if (aibuf)
437     freeaddrinfo (aibuf);
438   if (err)
439     {
440       if (r_canonname)
441         {
442           xfree (*r_canonname);
443           *r_canonname = NULL;
444         }
445       free_dns_addrinfo (daihead);
446     }
447   else
448     *r_dai = daihead;
449   return err;
450 }
451 #endif /*!USE_ADNS*/
452
453
454 /* Resolve an address using the standard system function.  */
455 static gpg_error_t
456 resolve_addr_standard (const struct sockaddr *addr, int addrlen,
457                        unsigned int flags, char **r_name)
458 {
459   gpg_error_t err;
460   int ec;
461   char *buffer, *p;
462   int buflen;
463
464   *r_name = NULL;
465
466   buflen = NI_MAXHOST;
467   buffer = xtrymalloc (buflen + 2 + 1);
468   if (!buffer)
469     return gpg_error_from_syserror ();
470
471   if ((flags & DNS_NUMERICHOST) || tor_mode)
472     ec = EAI_NONAME;
473   else
474     ec = getnameinfo (addr, addrlen, buffer, buflen, NULL, 0, NI_NAMEREQD);
475
476   if (!ec && *buffer == '[')
477     ec = EAI_FAIL;  /* A name may never start with a bracket.  */
478   else if (ec == EAI_NONAME)
479     {
480       p = buffer;
481       if (addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
482         {
483           *p++ = '[';
484           buflen -= 2;
485         }
486       ec = getnameinfo (addr, addrlen, p, buflen, NULL, 0, NI_NUMERICHOST);
487       if (!ec && addr->sa_family == AF_INET6 && (flags & DNS_WITHBRACKET))
488         strcat (buffer, "]");
489     }
490
491   if (ec)
492     err = map_eai_to_gpg_error (ec);
493   else
494     {
495       p = xtryrealloc (buffer, strlen (buffer)+1);
496       if (!p)
497         err = gpg_error_from_syserror ();
498       else
499         {
500           buffer = p;
501           err = 0;
502         }
503     }
504
505   if (err)
506     xfree (buffer);
507   else
508     *r_name = buffer;
509
510   return err;
511 }
512
513
514 /* This a wrapper around getaddrinfo with slightly different semantics.
515    NAME is the name to resolve.
516    PORT is the requested port or 0.
517    WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4.
518    WANT_SOCKETTYPE is either SOCK_STREAM or SOCK_DGRAM.
519
520    On success the result is stored in a linked list with the head
521    stored at the address R_AI; the caller must call gpg_addrinfo_free
522    on this.  If R_CANONNAME is not NULL the official name of the host
523    is stored there as a malloced string; if that name is not available
524    NULL is stored.  */
525 gpg_error_t
526 resolve_dns_name (const char *name, unsigned short port,
527                   int want_family, int want_socktype,
528                   dns_addrinfo_t *r_ai, char **r_canonname)
529 {
530 #ifdef USE_ADNS
531   return resolve_name_adns (name, port, want_family, want_socktype,
532                             r_ai, r_canonname);
533 #else
534   return resolve_name_standard (name, port, want_family, want_socktype,
535                                 r_ai, r_canonname);
536 #endif
537 }
538
539
540 gpg_error_t
541 resolve_dns_addr (const struct sockaddr *addr, int addrlen,
542                   unsigned int flags, char **r_name)
543 {
544 #ifdef USE_ADNS_disabled_for_now
545   return resolve_addr_adns (addr, addrlen, flags, r_name);
546 #else
547   return resolve_addr_standard (addr, addrlen, flags, r_name);
548 #endif
549 }
550
551
552 /* Check whether NAME is an IP address.  Returns true if it is either
553    an IPv6 or IPv4 numerical address.  */
554 int
555 is_ip_address (const char *name)
556 {
557   const char *s;
558   int ndots, dblcol, n;
559
560   if (*name == '[')
561     return 1; /* yes: A legal DNS name may not contain this character;
562                  this mut be bracketed v6 address.  */
563   if (*name == '.')
564     return 0; /* No.  A leading dot is not a valid IP address.  */
565
566   /* Check whether this is a v6 address.  */
567   ndots = n = dblcol = 0;
568   for (s=name; *s; s++)
569     {
570       if (*s == ':')
571         {
572           ndots++;
573           if (s[1] == ':')
574             {
575               ndots++;
576               if (dblcol)
577                 return 0; /* No: Only one "::" allowed.  */
578               dblcol++;
579               if (s[1])
580                 s++;
581             }
582           n = 0;
583         }
584       else if (*s == '.')
585         goto legacy;
586       else if (!strchr ("0123456789abcdefABCDEF", *s))
587         return 0; /* No: Not a hex digit.  */
588       else if (++n > 4)
589         return 0; /* To many digits in a group.  */
590     }
591   if (ndots > 7)
592     return 0; /* No: Too many colons.  */
593   else if (ndots > 1)
594     return 1; /* Yes: At least 2 colons indicate an v6 address.  */
595
596  legacy:
597   /* Check whether it is legacy IP address.  */
598   ndots = n = 0;
599   for (s=name; *s; s++)
600     {
601       if (*s == '.')
602         {
603           if (s[1] == '.')
604             return 0; /* No:  Douple dot. */
605           if (atoi (s+1) > 255)
606             return 0; /* No:  Ipv4 byte value too large.  */
607           ndots++;
608           n = 0;
609         }
610       else if (!strchr ("0123456789", *s))
611         return 0; /* No: Not a digit.  */
612       else if (++n > 3)
613         return 0; /* No: More than 3 digits.  */
614     }
615   return !!(ndots == 3);
616 }
617
618
619 /* Return true if NAME is an onion address.  */
620 int
621 is_onion_address (const char *name)
622 {
623   size_t len;
624
625   len = name? strlen (name) : 0;
626   if (len < 8 || strcmp (name + len - 6, ".onion"))
627     return 0;
628   /* Note that we require at least 2 characters before the suffix.  */
629   return 1;  /* Yes.  */
630 }
631
632
633 /* Returns 0 on success or an error code.  If a PGP CERT record was
634    found, the malloced data is returned at (R_KEY, R_KEYLEN) and
635    the other return parameters are set to NULL/0.  If an IPGP CERT
636    record was found the fingerprint is stored as an allocated block at
637    R_FPR and its length at R_FPRLEN; an URL is is allocated as a
638    string and returned at R_URL.  If WANT_CERTTYPE is 0 this function
639    returns the first CERT found with a supported type; it is expected
640    that only one CERT record is used.  If WANT_CERTTYPE is one of the
641    supported certtypes only records with this certtype are considered
642    and the first found is returned.  (R_KEY,R_KEYLEN) are optional. */
643 gpg_error_t
644 get_dns_cert (const char *name, int want_certtype,
645               void **r_key, size_t *r_keylen,
646               unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
647 {
648 #ifdef USE_DNS_CERT
649 #ifdef USE_ADNS
650   gpg_error_t err;
651   int ret;
652   adns_state state;
653   adns_answer *answer = NULL;
654   unsigned int ctype;
655   int count;
656
657   if (r_key)
658     *r_key = NULL;
659   if (r_keylen)
660     *r_keylen = 0;
661   *r_fpr = NULL;
662   *r_fprlen = 0;
663   *r_url = NULL;
664
665   err = my_adns_init (&state);
666   if (err)
667     return err;
668
669   my_unprotect ();
670   ret = adns_synchronous (state, name,
671                           (adns_r_unknown
672                            | (want_certtype < DNS_CERTTYPE_RRBASE
673                               ? my_adns_r_cert
674                               : (want_certtype - DNS_CERTTYPE_RRBASE))),
675                           adns_qf_quoteok_query, &answer);
676   my_protect ();
677   if (ret)
678     {
679       err = gpg_error_from_syserror ();
680       /* log_error ("DNS query failed: %s\n", strerror (errno)); */
681       adns_finish (state);
682       return err;
683     }
684   if (answer->status != adns_s_ok)
685     {
686       /* log_error ("DNS query returned an error: %s (%s)\n", */
687       /*            adns_strerror (answer->status), */
688       /*            adns_errabbrev (answer->status)); */
689       err = gpg_error (GPG_ERR_NOT_FOUND);
690       goto leave;
691     }
692
693   err = gpg_error (GPG_ERR_NOT_FOUND);
694   for (count = 0; count < answer->nrrs; count++)
695     {
696       int datalen = answer->rrs.byteblock[count].len;
697       const unsigned char *data = answer->rrs.byteblock[count].data;
698
699       /* First check for our generic RR hack.  */
700       if (datalen
701           && want_certtype >= DNS_CERTTYPE_RRBASE
702           && ((want_certtype - DNS_CERTTYPE_RRBASE)
703               == (answer->type & ~adns_r_unknown)))
704         {
705           /* Found the requested record - return it.  */
706           *r_key = xtrymalloc (datalen);
707           if (!*r_key)
708             err = gpg_error_from_syserror ();
709           else
710             {
711               memcpy (*r_key, data, datalen);
712               *r_keylen = datalen;
713               err = 0;
714             }
715           goto leave;
716         }
717
718       if (datalen < 5)
719         continue;  /* Truncated CERT record - skip.  */
720
721       ctype = buf16_to_uint (data);
722       /* (key tag and algorithm fields are not required.) */
723       data += 5;
724       datalen -= 5;
725
726       if (want_certtype && want_certtype != ctype)
727         ; /* Not of the requested certtype.  */
728       else if (ctype == DNS_CERTTYPE_PGP && datalen >= 11 && r_key && r_keylen)
729         {
730           /* CERT type is PGP.  Gpg checks for a minimum length of 11,
731              thus we do the same.  */
732           *r_key = xtrymalloc (datalen);
733           if (!*r_key)
734             err = gpg_error_from_syserror ();
735           else
736             {
737               memcpy (*r_key, data, datalen);
738               *r_keylen = datalen;
739               err = 0;
740             }
741           goto leave;
742         }
743       else if (ctype == DNS_CERTTYPE_IPGP && datalen && datalen < 1023
744                && datalen >= data[0] + 1 && r_fpr && r_fprlen && r_url)
745         {
746           /* CERT type is IPGP.  We made sure that the data is
747              plausible and that the caller requested this
748              information.  */
749           *r_fprlen = data[0];
750           if (*r_fprlen)
751             {
752               *r_fpr = xtrymalloc (*r_fprlen);
753               if (!*r_fpr)
754                 {
755                   err = gpg_error_from_syserror ();
756                   goto leave;
757                 }
758               memcpy (*r_fpr, data + 1, *r_fprlen);
759             }
760           else
761             *r_fpr = NULL;
762
763           if (datalen > *r_fprlen + 1)
764             {
765               *r_url = xtrymalloc (datalen - (*r_fprlen + 1) + 1);
766               if (!*r_url)
767                 {
768                   err = gpg_error_from_syserror ();
769                   xfree (*r_fpr);
770                   *r_fpr = NULL;
771                   goto leave;
772                 }
773               memcpy (*r_url,
774                       data + (*r_fprlen + 1), datalen - (*r_fprlen + 1));
775               (*r_url)[datalen - (*r_fprlen + 1)] = '\0';
776             }
777           else
778             *r_url = NULL;
779
780           err = 0;
781           goto leave;
782         }
783     }
784
785  leave:
786   adns_free (answer);
787   adns_finish (state);
788   return err;
789
790 #else /*!USE_ADNS*/
791
792   gpg_error_t err;
793   unsigned char *answer;
794   int r;
795   u16 count;
796
797   if (r_key)
798     *r_key = NULL;
799   if (r_keylen)
800     *r_keylen = 0;
801   *r_fpr = NULL;
802   *r_fprlen = 0;
803   *r_url = NULL;
804
805   /* Allocate a 64k buffer which is the limit for an DNS response.  */
806   answer = xtrymalloc (65536);
807   if (!answer)
808     return gpg_error_from_syserror ();
809
810   err = gpg_error (GPG_ERR_NOT_FOUND);
811   r = res_query (name, C_IN,
812                  (want_certtype < DNS_CERTTYPE_RRBASE
813                   ? T_CERT
814                   : (want_certtype - DNS_CERTTYPE_RRBASE)),
815                  answer, 65536);
816   /* Not too big, not too small, no errors and at least 1 answer. */
817   if (r >= sizeof (HEADER) && r <= 65536
818       && (((HEADER *) answer)->rcode) == NOERROR
819       && (count = ntohs (((HEADER *) answer)->ancount)))
820     {
821       int rc;
822       unsigned char *pt, *emsg;
823
824       emsg = &answer[r];
825
826       pt = &answer[sizeof (HEADER)];
827
828       /* Skip over the query */
829
830       rc = dn_skipname (pt, emsg);
831       if (rc == -1)
832         {
833           err = gpg_error (GPG_ERR_INV_OBJ);
834           goto leave;
835         }
836       pt += rc + QFIXEDSZ;
837
838       /* There are several possible response types for a CERT request.
839          We're interested in the PGP (a key) and IPGP (a URI) types.
840          Skip all others.  TODO: A key is better than a URI since
841          we've gone through all this bother to fetch it, so favor that
842          if we have both PGP and IPGP? */
843
844       while (count-- > 0 && pt < emsg)
845         {
846           u16 type, class, dlen, ctype;
847
848           rc = dn_skipname (pt, emsg);  /* the name we just queried for */
849           if (rc == -1)
850             {
851               err = gpg_error (GPG_ERR_INV_OBJ);
852               goto leave;
853             }
854
855           pt += rc;
856
857           /* Truncated message? 15 bytes takes us to the point where
858              we start looking at the ctype. */
859           if ((emsg - pt) < 15)
860             break;
861
862           type = buf16_to_u16 (pt);
863           pt += 2;
864
865           class = buf16_to_u16 (pt);
866           pt += 2;
867
868           if (class != C_IN)
869             break;
870
871           /* ttl */
872           pt += 4;
873
874           /* data length */
875           dlen = buf16_to_u16 (pt);
876           pt += 2;
877
878           /* Check the type and parse.  */
879           if (want_certtype >= DNS_CERTTYPE_RRBASE
880               && type == (want_certtype - DNS_CERTTYPE_RRBASE)
881               && r_key)
882             {
883               *r_key = xtrymalloc (dlen);
884               if (!*r_key)
885                 err = gpg_error_from_syserror ();
886               else
887                 {
888                   memcpy (*r_key, pt, dlen);
889                   *r_keylen = dlen;
890                   err = 0;
891                 }
892               goto leave;
893             }
894           else if (want_certtype >= DNS_CERTTYPE_RRBASE)
895             {
896               /* We did not found the requested RR.  */
897               pt += dlen;
898             }
899           else if (type == T_CERT)
900             {
901               /* We got a CERT type.   */
902               ctype = buf16_to_u16 (pt);
903               pt += 2;
904
905               /* Skip the CERT key tag and algo which we don't need. */
906               pt += 3;
907
908               dlen -= 5;
909
910               /* 15 bytes takes us to here */
911               if (want_certtype && want_certtype != ctype)
912                 ; /* Not of the requested certtype.  */
913               else if (ctype == DNS_CERTTYPE_PGP && dlen && r_key && r_keylen)
914                 {
915                   /* PGP type */
916                   *r_key = xtrymalloc (dlen);
917                   if (!*r_key)
918                     err = gpg_error_from_syserror ();
919                   else
920                     {
921                       memcpy (*r_key, pt, dlen);
922                       *r_keylen = dlen;
923                       err = 0;
924                     }
925                   goto leave;
926                 }
927               else if (ctype == DNS_CERTTYPE_IPGP
928                        && dlen && dlen < 1023 && dlen >= pt[0] + 1)
929                 {
930                   /* IPGP type */
931                   *r_fprlen = pt[0];
932                   if (*r_fprlen)
933                     {
934                       *r_fpr = xtrymalloc (*r_fprlen);
935                       if (!*r_fpr)
936                         {
937                           err = gpg_error_from_syserror ();
938                           goto leave;
939                         }
940                       memcpy (*r_fpr, &pt[1], *r_fprlen);
941                     }
942                   else
943                     *r_fpr = NULL;
944
945                   if (dlen > *r_fprlen + 1)
946                     {
947                       *r_url = xtrymalloc (dlen - (*r_fprlen + 1) + 1);
948                       if (!*r_fpr)
949                         {
950                           err = gpg_error_from_syserror ();
951                           xfree (*r_fpr);
952                           *r_fpr = NULL;
953                           goto leave;
954                         }
955                       memcpy (*r_url, &pt[*r_fprlen + 1],
956                               dlen - (*r_fprlen + 1));
957                       (*r_url)[dlen - (*r_fprlen + 1)] = '\0';
958                     }
959                   else
960                     *r_url = NULL;
961
962                   err = 0;
963                   goto leave;
964                 }
965
966               /* No subtype matches, so continue with the next answer. */
967               pt += dlen;
968             }
969           else
970             {
971               /* Not a requested type - might be a CNAME. Try next item.  */
972               pt += dlen;
973             }
974         }
975     }
976
977  leave:
978   xfree (answer);
979   return err;
980
981 #endif /*!USE_ADNS */
982 #else /* !USE_DNS_CERT */
983   (void)name;
984   if (r_key)
985     *r_key = NULL;
986   if (r_keylen)
987     *r_keylen = NULL;
988   *r_fpr = NULL;
989   *r_fprlen = 0;
990   *r_url = NULL;
991
992   return gpg_error (GPG_ERR_NOT_SUPPORTED);
993 #endif
994 }
995
996 #ifdef USE_DNS_SRV
997 static int
998 priosort(const void *a,const void *b)
999 {
1000   const struct srventry *sa=a,*sb=b;
1001   if(sa->priority>sb->priority)
1002     return 1;
1003   else if(sa->priority<sb->priority)
1004     return -1;
1005   else
1006     return 0;
1007 }
1008
1009
1010 int
1011 getsrv (const char *name,struct srventry **list)
1012 {
1013   int srvcount=0;
1014   u16 count;
1015   int i, rc;
1016
1017   *list = NULL;
1018
1019 #ifdef USE_ADNS
1020   {
1021     adns_state state;
1022     adns_answer *answer = NULL;
1023
1024     if (my_adns_init (&state))
1025       return -1;
1026
1027     my_unprotect ();
1028     rc = adns_synchronous (state, name, adns_r_srv, adns_qf_quoteok_query,
1029                            &answer);
1030     my_protect ();
1031     if (rc)
1032       {
1033         log_error ("DNS query failed: %s\n", strerror (errno));
1034         adns_finish (state);
1035         return -1;
1036       }
1037     if (answer->status != adns_s_ok
1038         || answer->type != adns_r_srv || !answer->nrrs)
1039       {
1040         log_error ("DNS query returned an error or no records: %s (%s)\n",
1041                    adns_strerror (answer->status),
1042                    adns_errabbrev (answer->status));
1043         adns_free (answer);
1044         adns_finish (state);
1045         return 0;
1046       }
1047
1048     for (count = 0; count < answer->nrrs; count++)
1049       {
1050         struct srventry *srv = NULL;
1051         struct srventry *newlist;
1052
1053         if (strlen (answer->rrs.srvha[count].ha.host) >= sizeof srv->target)
1054           {
1055             log_info ("hostname in SRV record too long - skipped\n");
1056             continue;
1057           }
1058
1059         newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
1060         if (!newlist)
1061           goto fail;
1062         *list = newlist;
1063         memset (&(*list)[srvcount], 0, sizeof(struct srventry));
1064         srv = &(*list)[srvcount];
1065         srvcount++;
1066
1067         srv->priority = answer->rrs.srvha[count].priority;
1068         srv->weight   = answer->rrs.srvha[count].weight;
1069         srv->port     = answer->rrs.srvha[count].port;
1070         strcpy (srv->target, answer->rrs.srvha[count].ha.host);
1071       }
1072
1073     adns_free (answer);
1074     adns_finish (state);
1075   }
1076 #else /*!USE_ADNS*/
1077   {
1078     unsigned char answer[2048];
1079     HEADER *header = (HEADER *)answer;
1080     unsigned char *pt, *emsg;
1081     int r;
1082     u16 dlen;
1083
1084     /* Do not allow a query using the standard resolver in Tor mode.  */
1085     if (tor_mode)
1086       return -1;
1087
1088     r = res_query (name, C_IN, T_SRV, answer, sizeof answer);
1089     if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
1090       return 0; /* Error or no record found.  */
1091     if (r < sizeof (HEADER) || r > sizeof answer)
1092       return -1;
1093
1094     emsg = &answer[r];
1095     pt = &answer[sizeof(HEADER)];
1096
1097     /* Skip over the query */
1098     rc = dn_skipname (pt, emsg);
1099     if (rc == -1)
1100       goto fail;
1101
1102     pt += rc + QFIXEDSZ;
1103
1104     while (count-- > 0 && pt < emsg)
1105       {
1106         struct srventry *srv=NULL;
1107         u16 type,class;
1108         struct srventry *newlist;
1109
1110         newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
1111         if (!newlist)
1112           goto fail;
1113         *list = newlist;
1114         memset(&(*list)[srvcount],0,sizeof(struct srventry));
1115         srv=&(*list)[srvcount];
1116         srvcount++;
1117
1118         rc = dn_skipname(pt,emsg); /* the name we just queried for */
1119         if (rc == -1)
1120           goto fail;
1121         pt+=rc;
1122
1123         /* Truncated message? */
1124         if((emsg-pt)<16)
1125           goto fail;
1126
1127         type = buf16_to_u16 (pt);
1128         pt += 2;
1129         /* We asked for SRV and got something else !? */
1130         if(type!=T_SRV)
1131           goto fail;
1132
1133         class = buf16_to_u16 (pt);
1134         pt += 2;
1135         /* We asked for IN and got something else !? */
1136         if(class!=C_IN)
1137           goto fail;
1138
1139         pt += 4; /* ttl */
1140         dlen = buf16_to_u16 (pt);
1141         pt += 2;
1142
1143         srv->priority = buf16_to_ushort (pt);
1144         pt += 2;
1145         srv->weight = buf16_to_ushort (pt);
1146         pt += 2;
1147         srv->port = buf16_to_ushort (pt);
1148         pt += 2;
1149
1150         /* Get the name.  2782 doesn't allow name compression, but
1151            dn_expand still works to pull the name out of the
1152            packet. */
1153         rc = dn_expand(answer,emsg,pt,srv->target, sizeof srv->target);
1154         if (rc == 1 && srv->target[0] == 0) /* "." */
1155           {
1156             xfree(*list);
1157             *list = NULL;
1158             return 0;
1159           }
1160         if (rc == -1)
1161           goto fail;
1162         pt += rc;
1163         /* Corrupt packet? */
1164         if (dlen != rc+6)
1165           goto fail;
1166       }
1167   }
1168 #endif /*!USE_ADNS*/
1169
1170   /* Now we have an array of all the srv records. */
1171
1172   /* Order by priority */
1173   qsort(*list,srvcount,sizeof(struct srventry),priosort);
1174
1175   /* For each priority, move the zero-weighted items first. */
1176   for (i=0; i < srvcount; i++)
1177     {
1178       int j;
1179
1180       for (j=i;j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
1181         {
1182           if((*list)[j].weight==0)
1183             {
1184               /* Swap j with i */
1185               if(j!=i)
1186                 {
1187                   struct srventry temp;
1188
1189                   memcpy (&temp,&(*list)[j],sizeof(struct srventry));
1190                   memcpy (&(*list)[j],&(*list)[i],sizeof(struct srventry));
1191                   memcpy (&(*list)[i],&temp,sizeof(struct srventry));
1192                 }
1193
1194               break;
1195             }
1196         }
1197     }
1198
1199   /* Run the RFC-2782 weighting algorithm.  We don't need very high
1200      quality randomness for this, so regular libc srand/rand is
1201      sufficient.  */
1202
1203   {
1204     static int done;
1205     if (!done)
1206       {
1207         done = 1;
1208         srand (time (NULL)*getpid());
1209       }
1210   }
1211
1212   for (i=0; i < srvcount; i++)
1213     {
1214       int j;
1215       float prio_count=0,chose;
1216
1217       for (j=i; j < srvcount && (*list)[i].priority == (*list)[j].priority; j++)
1218         {
1219           prio_count+=(*list)[j].weight;
1220           (*list)[j].run_count=prio_count;
1221         }
1222
1223       chose=prio_count*rand()/RAND_MAX;
1224
1225       for (j=i;j<srvcount && (*list)[i].priority==(*list)[j].priority;j++)
1226         {
1227           if (chose<=(*list)[j].run_count)
1228             {
1229               /* Swap j with i */
1230               if(j!=i)
1231                 {
1232                   struct srventry temp;
1233
1234                   memcpy(&temp,&(*list)[j],sizeof(struct srventry));
1235                   memcpy(&(*list)[j],&(*list)[i],sizeof(struct srventry));
1236                   memcpy(&(*list)[i],&temp,sizeof(struct srventry));
1237                 }
1238               break;
1239             }
1240         }
1241     }
1242
1243   return srvcount;
1244
1245  fail:
1246   xfree(*list);
1247   *list=NULL;
1248   return -1;
1249 }
1250 #endif /*USE_DNS_SRV*/
1251
1252
1253 gpg_error_t
1254 get_dns_cname (const char *name, char **r_cname)
1255 {
1256   gpg_error_t err;
1257   int rc;
1258
1259   *r_cname = NULL;
1260
1261 #ifdef USE_ADNS
1262   {
1263     adns_state state;
1264     adns_answer *answer = NULL;
1265
1266     if (my_adns_init (&state))
1267       return gpg_error (GPG_ERR_GENERAL);
1268
1269     my_unprotect ();
1270     rc = adns_synchronous (state, name, adns_r_cname, adns_qf_quoteok_query,
1271                            &answer);
1272     my_protect ();
1273     if (rc)
1274       {
1275         err = gpg_error_from_syserror ();
1276         log_error ("DNS query failed: %s\n", gpg_strerror (err));
1277         adns_finish (state);
1278         return err;
1279       }
1280     if (answer->status != adns_s_ok
1281         || answer->type != adns_r_cname || answer->nrrs != 1)
1282       {
1283         err = gpg_error (GPG_ERR_GENERAL);
1284         log_error ("DNS query returned an error or no records: %s (%s)\n",
1285                    adns_strerror (answer->status),
1286                    adns_errabbrev (answer->status));
1287         adns_free (answer);
1288         adns_finish (state);
1289         return err;
1290       }
1291     *r_cname = xtrystrdup (answer->rrs.str[0]);
1292     if (!*r_cname)
1293       err = gpg_error_from_syserror ();
1294     else
1295       err = 0;
1296
1297     adns_free (answer);
1298     adns_finish (state);
1299     return err;
1300   }
1301 #else /*!USE_ADNS*/
1302   {
1303     unsigned char answer[2048];
1304     HEADER *header = (HEADER *)answer;
1305     unsigned char *pt, *emsg;
1306     int r;
1307     char *cname;
1308     int cnamesize = 1025;
1309     u16 count;
1310
1311     /* Do not allow a query using the standard resolver in Tor mode.  */
1312     if (tor_mode)
1313       return -1;
1314
1315     r = res_query (name, C_IN, T_CERT, answer, sizeof answer);
1316     if (r < sizeof (HEADER) || r > sizeof answer)
1317       return gpg_error (GPG_ERR_SERVER_FAILED);
1318     if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
1319       return gpg_error (GPG_ERR_NO_NAME); /* Error or no record found.  */
1320     if (count != 1)
1321       return gpg_error (GPG_ERR_SERVER_FAILED);
1322
1323     emsg = &answer[r];
1324     pt = &answer[sizeof(HEADER)];
1325     rc = dn_skipname (pt, emsg);
1326     if (rc == -1)
1327       return gpg_error (GPG_ERR_SERVER_FAILED);
1328
1329     pt += rc + QFIXEDSZ;
1330     if (pt >= emsg)
1331       return gpg_error (GPG_ERR_SERVER_FAILED);
1332
1333     rc = dn_skipname (pt, emsg);
1334     if (rc == -1)
1335       return gpg_error (GPG_ERR_SERVER_FAILED);
1336     pt += rc + 2 + 2 + 4;
1337     if (pt+2 >= emsg)
1338       return gpg_error (GPG_ERR_SERVER_FAILED);
1339     pt += 2;  /* Skip rdlen */
1340
1341     cname = xtrymalloc (cnamesize);
1342     if (!cname)
1343       return gpg_error_from_syserror ();
1344
1345     rc = dn_expand (answer, emsg, pt, cname, cnamesize -1);
1346     if (rc == -1)
1347       {
1348         xfree (cname);
1349         return gpg_error (GPG_ERR_SERVER_FAILED);
1350       }
1351     *r_cname = xtryrealloc (cname, strlen (cname)+1);
1352     if (!*r_cname)
1353       {
1354         err = gpg_error_from_syserror ();
1355         xfree (cname);
1356         return err;
1357       }
1358     return 0;
1359   }
1360 #endif /*!USE_ADNS*/
1361 }