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