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