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