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