dirmngr: Check that getaddrinfo is available.
[gnupg.git] / dirmngr / dns-stuff.c
1 /* dns-stuff.c - DNS related code including CERT RR (rfc-4398)
2  * Copyright (C) 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 /* Not every installation has gotten around to supporting CERTs
58    yet... */
59 #ifndef T_CERT
60 # define T_CERT 37
61 #endif
62
63 /* ADNS has no support for CERT yet. */
64 #define my_adns_r_cert 37
65
66 /* If set Tor mode shall be used.  */
67 static int tor_mode;
68
69 /* Sets the module in Tor mode.  Returns 0 is this is possible or an
70    error code.  */
71 gpg_error_t
72 enable_dns_tormode (void)
73 {
74 #if defined(USE_DNS_CERT) && defined(USE_ADNS)
75 # if HAVE_ADNS_IF_TORMODE
76    tor_mode = 1;
77    return 0;
78 # endif
79 #endif
80   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
81 }
82
83 /* Free an addressinfo linked list as returned by resolve_dns_name.  */
84 void
85 free_dns_addrinfo (dns_addrinfo_t ai)
86 {
87   while (ai)
88     {
89       dns_addrinfo_t next = ai->next;
90       xfree (ai);
91       ai = next;
92     }
93 }
94
95
96 /* Resolve a name using the standard system function.  */
97 static gpg_error_t
98 resolve_name_standard (const char *name, unsigned short port,
99                        int want_family, int want_socktype,
100                        dns_addrinfo_t *r_dai, char **r_canonname)
101 {
102   gpg_error_t err = 0;
103   dns_addrinfo_t daihead = NULL;
104   dns_addrinfo_t dai;
105   struct addrinfo *aibuf = NULL;
106   struct addrinfo hints, *ai;
107   char portstr[21];
108   int ret;
109
110   *r_dai = NULL;
111   if (r_canonname)
112     *r_canonname = NULL;
113
114   memset (&hints, 0, sizeof hints);
115   hints.ai_family = want_family;
116   hints.ai_socktype = want_socktype;
117   if (r_canonname)
118     hints.ai_flags = AI_CANONNAME;
119
120   if (port)
121     snprintf (portstr, sizeof portstr, "%hu", port);
122   else
123     *portstr = 0;
124
125   /* We can't use the the AI_IDN flag because that does the conversion
126      using the current locale.  However, GnuPG always used UTF-8.  To
127      support IDN we would need to make use of the libidn API.  */
128   ret = getaddrinfo (name, *portstr? portstr : NULL, &hints, &aibuf);
129   if (ret)
130     {
131       aibuf = NULL;
132       switch (ret)
133         {
134         case EAI_AGAIN:     err = gpg_error (GPG_ERR_EAGAIN); break;
135         case EAI_BADFLAGS:  err = gpg_error (GPG_ERR_INV_FLAG); break;
136         case EAI_FAIL:      err = gpg_error (GPG_ERR_SERVER_FAILED); break;
137         case EAI_MEMORY:    err = gpg_error (GPG_ERR_ENOMEM); break;
138         case EAI_NODATA:    err = gpg_error (GPG_ERR_NO_DATA); break;
139         case EAI_NONAME:    err = gpg_error (GPG_ERR_NO_NAME); break;
140         case EAI_SERVICE:   err = gpg_error (GPG_ERR_NOT_SUPPORTED); break;
141         case EAI_ADDRFAMILY:err = gpg_error (GPG_ERR_EADDRNOTAVAIL); break;
142         case EAI_FAMILY:    err = gpg_error (GPG_ERR_EAFNOSUPPORT); break;
143         case EAI_SOCKTYPE:  err = gpg_error (GPG_ERR_ESOCKTNOSUPPORT); break;
144         case EAI_SYSTEM:    err = gpg_error_from_syserror (); break;
145         default:            err = gpg_error (GPG_ERR_UNKNOWN_ERRNO); break;
146         }
147       goto leave;
148     }
149
150   if (r_canonname && aibuf && aibuf->ai_canonname)
151     {
152       *r_canonname = xtrystrdup (aibuf->ai_canonname);
153       if (!*r_canonname)
154         {
155           err = gpg_error_from_syserror ();
156           goto leave;
157         }
158     }
159
160   for (ai = aibuf; ai; ai = ai->ai_next)
161     {
162       if (ai->ai_family != AF_INET6 && ai->ai_family != AF_INET)
163         continue;
164
165       dai = xtrymalloc (sizeof *dai + ai->ai_addrlen - 1);
166       dai->family = ai->ai_family;
167       dai->socktype = ai->ai_socktype;
168       dai->protocol = ai->ai_protocol;
169       dai->addrlen = ai->ai_addrlen;
170       memcpy (dai->addr, ai->ai_addr, ai->ai_addrlen);
171       dai->next = daihead;
172       daihead = dai;
173     }
174
175  leave:
176   if (aibuf)
177     freeaddrinfo (aibuf);
178   if (err)
179     {
180       if (r_canonname)
181         {
182           xfree (*r_canonname);
183           *r_canonname = NULL;
184         }
185       free_dns_addrinfo (daihead);
186     }
187   else
188     *r_dai = daihead;
189   return err;
190 }
191
192
193 /* This a wrapper around getaddrinfo with slighly different semantics.
194    NAME is the name to resolve.
195    PORT is the requested port or 0.
196    WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4.
197    WANT_SOCKETTYPE is either SOCK_STREAM or SOCK_DGRAM.
198
199    On success the result is stored in a linked list with the head
200    stored at the address R_AI; the caller must call gpg_addrinfo_free
201    on this.  If R_CANONNAME is not NULL the official name of the host
202    is stored there as a malloced string; if that name is not available
203    NULL is stored.  */
204 gpg_error_t
205 resolve_dns_name (const char *name, unsigned short port,
206                   int want_family, int want_socktype,
207                   dns_addrinfo_t *r_ai, char **r_canonname)
208 {
209 #ifdef USE_ADNS_disabled_for_now
210   return resolve_name_adns (name, port, want_family, want_socktype,
211                             r_ai, r_canonname);
212 #else
213   return resolve_name_standard (name, port, want_family, want_socktype,
214                                 r_ai, r_canonname);
215 #endif
216 }
217
218
219 /* Returns 0 on success or an error code.  If a PGP CERT record was
220    found, the malloced data is returned at (R_KEY, R_KEYLEN) and
221    the other return parameters are set to NULL/0.  If an IPGP CERT
222    record was found the fingerprint is stored as an allocated block at
223    R_FPR and its length at R_FPRLEN; an URL is is allocated as a
224    string and returned at R_URL.  If WANT_CERTTYPE is 0 this function
225    returns the first CERT found with a supported type; it is expected
226    that only one CERT record is used.  If WANT_CERTTYPE is one of the
227    supported certtypes only records with this certtype are considered
228    and the first found is returned.  (R_KEY,R_KEYLEN) are optional. */
229 gpg_error_t
230 get_dns_cert (const char *name, int want_certtype,
231               void **r_key, size_t *r_keylen,
232               unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
233 {
234 #ifdef USE_DNS_CERT
235 #ifdef USE_ADNS
236   gpg_error_t err;
237   adns_state state;
238   adns_answer *answer = NULL;
239   unsigned int ctype;
240   int count;
241
242   if (r_key)
243     *r_key = NULL;
244   if (r_keylen)
245     *r_keylen = 0;
246   *r_fpr = NULL;
247   *r_fprlen = 0;
248   *r_url = NULL;
249
250   if (tor_mode? adns_init_strcfg (&state, adns_if_noerrprint|adns_if_tormode,
251                                   NULL, "nameserver 8.8.8.8")
252       /*    */: adns_init (&state, adns_if_noerrprint, NULL))
253     {
254       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
255       log_error ("error initializing adns: %s\n", strerror (errno));
256       return err;
257     }
258
259   if (adns_synchronous (state, name,
260                         (adns_r_unknown
261                          | (want_certtype < DNS_CERTTYPE_RRBASE
262                             ? my_adns_r_cert
263                             : (want_certtype - DNS_CERTTYPE_RRBASE))),
264                         adns_qf_quoteok_query, &answer))
265     {
266       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
267       /* log_error ("DNS query failed: %s\n", strerror (errno)); */
268       adns_finish (state);
269       return err;
270     }
271   if (answer->status != adns_s_ok)
272     {
273       /* log_error ("DNS query returned an error: %s (%s)\n", */
274       /*            adns_strerror (answer->status), */
275       /*            adns_errabbrev (answer->status)); */
276       err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
277       goto leave;
278     }
279
280   err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
281   for (count = 0; count < answer->nrrs; count++)
282     {
283       int datalen = answer->rrs.byteblock[count].len;
284       const unsigned char *data = answer->rrs.byteblock[count].data;
285
286       /* First check for our generic RR hack.  */
287       if (datalen
288           && want_certtype >= DNS_CERTTYPE_RRBASE
289           && ((want_certtype - DNS_CERTTYPE_RRBASE)
290               == (answer->type & ~adns_r_unknown)))
291         {
292           /* Found the requested record - return it.  */
293           *r_key = xtrymalloc (datalen);
294           if (!*r_key)
295             err = gpg_err_make (default_errsource,
296                                 gpg_err_code_from_syserror ());
297           else
298             {
299               memcpy (*r_key, data, datalen);
300               *r_keylen = datalen;
301               err = 0;
302             }
303           goto leave;
304         }
305
306       if (datalen < 5)
307         continue;  /* Truncated CERT record - skip.  */
308
309       ctype = buf16_to_uint (data);
310       /* (key tag and algorithm fields are not required.) */
311       data += 5;
312       datalen -= 5;
313
314       if (want_certtype && want_certtype != ctype)
315         ; /* Not of the requested certtype.  */
316       else if (ctype == DNS_CERTTYPE_PGP && datalen >= 11 && r_key && r_keylen)
317         {
318           /* CERT type is PGP.  Gpg checks for a minimum length of 11,
319              thus we do the same.  */
320           *r_key = xtrymalloc (datalen);
321           if (!*r_key)
322             err = gpg_err_make (default_errsource,
323                                 gpg_err_code_from_syserror ());
324           else
325             {
326               memcpy (*r_key, data, datalen);
327               *r_keylen = datalen;
328               err = 0;
329             }
330           goto leave;
331         }
332       else if (ctype == DNS_CERTTYPE_IPGP && datalen && datalen < 1023
333                && datalen >= data[0] + 1 && r_fpr && r_fprlen && r_url)
334         {
335           /* CERT type is IPGP.  We made sure that the data is
336              plausible and that the caller requested this
337              information.  */
338           *r_fprlen = data[0];
339           if (*r_fprlen)
340             {
341               *r_fpr = xtrymalloc (*r_fprlen);
342               if (!*r_fpr)
343                 {
344                   err = gpg_err_make (default_errsource,
345                                       gpg_err_code_from_syserror ());
346                   goto leave;
347                 }
348               memcpy (*r_fpr, data + 1, *r_fprlen);
349             }
350           else
351             *r_fpr = NULL;
352
353           if (datalen > *r_fprlen + 1)
354             {
355               *r_url = xtrymalloc (datalen - (*r_fprlen + 1) + 1);
356               if (!*r_url)
357                 {
358                   err = gpg_err_make (default_errsource,
359                                       gpg_err_code_from_syserror ());
360                   xfree (*r_fpr);
361                   *r_fpr = NULL;
362                   goto leave;
363                 }
364               memcpy (*r_url,
365                       data + (*r_fprlen + 1), datalen - (*r_fprlen + 1));
366               (*r_url)[datalen - (*r_fprlen + 1)] = '\0';
367             }
368           else
369             *r_url = NULL;
370
371           err = 0;
372           goto leave;
373         }
374     }
375
376  leave:
377   adns_free (answer);
378   adns_finish (state);
379   return err;
380
381 #else /*!USE_ADNS*/
382
383   gpg_error_t err;
384   unsigned char *answer;
385   int r;
386   u16 count;
387
388   if (r_key)
389     *r_key = NULL;
390   if (r_keylen)
391     *r_keylen = 0;
392   *r_fpr = NULL;
393   *r_fprlen = 0;
394   *r_url = NULL;
395
396   /* Allocate a 64k buffer which is the limit for an DNS response.  */
397   answer = xtrymalloc (65536);
398   if (!answer)
399     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
400
401   err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
402
403   r = res_query (name, C_IN,
404                  (want_certtype < DNS_CERTTYPE_RRBASE
405                   ? T_CERT
406                   : (want_certtype - DNS_CERTTYPE_RRBASE)),
407                  answer, 65536);
408   /* Not too big, not too small, no errors and at least 1 answer. */
409   if (r >= sizeof (HEADER) && r <= 65536
410       && (((HEADER *) answer)->rcode) == NOERROR
411       && (count = ntohs (((HEADER *) answer)->ancount)))
412     {
413       int rc;
414       unsigned char *pt, *emsg;
415
416       emsg = &answer[r];
417
418       pt = &answer[sizeof (HEADER)];
419
420       /* Skip over the query */
421
422       rc = dn_skipname (pt, emsg);
423       if (rc == -1)
424         {
425           err = gpg_err_make (default_errsource, GPG_ERR_INV_OBJ);
426           goto leave;
427         }
428       pt += rc + QFIXEDSZ;
429
430       /* There are several possible response types for a CERT request.
431          We're interested in the PGP (a key) and IPGP (a URI) types.
432          Skip all others.  TODO: A key is better than a URI since
433          we've gone through all this bother to fetch it, so favor that
434          if we have both PGP and IPGP? */
435
436       while (count-- > 0 && pt < emsg)
437         {
438           u16 type, class, dlen, ctype;
439
440           rc = dn_skipname (pt, emsg);  /* the name we just queried for */
441           if (rc == -1)
442             {
443               err = gpg_err_make (default_errsource, GPG_ERR_INV_OBJ);
444               goto leave;
445             }
446
447           pt += rc;
448
449           /* Truncated message? 15 bytes takes us to the point where
450              we start looking at the ctype. */
451           if ((emsg - pt) < 15)
452             break;
453
454           type = buf16_to_u16 (pt);
455           pt += 2;
456
457           class = buf16_to_u16 (pt);
458           pt += 2;
459
460           if (class != C_IN)
461             break;
462
463           /* ttl */
464           pt += 4;
465
466           /* data length */
467           dlen = buf16_to_u16 (pt);
468           pt += 2;
469
470           /* Check the type and parse.  */
471           if (want_certtype >= DNS_CERTTYPE_RRBASE
472               && type == (want_certtype - DNS_CERTTYPE_RRBASE)
473               && r_key)
474             {
475               *r_key = xtrymalloc (dlen);
476               if (!*r_key)
477                 err = gpg_err_make (default_errsource,
478                                     gpg_err_code_from_syserror ());
479               else
480                 {
481                   memcpy (*r_key, pt, dlen);
482                   *r_keylen = dlen;
483                   err = 0;
484                 }
485               goto leave;
486             }
487           else if (want_certtype >= DNS_CERTTYPE_RRBASE)
488             {
489               /* We did not found the requested RR.  */
490               pt += dlen;
491             }
492           else if (type == T_CERT)
493             {
494               /* We got a CERT type.   */
495               ctype = buf16_to_u16 (pt);
496               pt += 2;
497
498               /* Skip the CERT key tag and algo which we don't need. */
499               pt += 3;
500
501               dlen -= 5;
502
503               /* 15 bytes takes us to here */
504               if (want_certtype && want_certtype != ctype)
505                 ; /* Not of the requested certtype.  */
506               else if (ctype == DNS_CERTTYPE_PGP && dlen && r_key && r_keylen)
507                 {
508                   /* PGP type */
509                   *r_key = xtrymalloc (dlen);
510                   if (!*r_key)
511                     err = gpg_err_make (default_errsource,
512                                         gpg_err_code_from_syserror ());
513                   else
514                     {
515                       memcpy (*r_key, pt, dlen);
516                       *r_keylen = dlen;
517                       err = 0;
518                     }
519                   goto leave;
520                 }
521               else if (ctype == DNS_CERTTYPE_IPGP
522                        && dlen && dlen < 1023 && dlen >= pt[0] + 1)
523                 {
524                   /* IPGP type */
525                   *r_fprlen = pt[0];
526                   if (*r_fprlen)
527                     {
528                       *r_fpr = xtrymalloc (*r_fprlen);
529                       if (!*r_fpr)
530                         {
531                           err = gpg_err_make (default_errsource,
532                                               gpg_err_code_from_syserror ());
533                           goto leave;
534                         }
535                       memcpy (*r_fpr, &pt[1], *r_fprlen);
536                     }
537                   else
538                     *r_fpr = NULL;
539
540                   if (dlen > *r_fprlen + 1)
541                     {
542                       *r_url = xtrymalloc (dlen - (*r_fprlen + 1) + 1);
543                       if (!*r_fpr)
544                         {
545                           err = gpg_err_make (default_errsource,
546                                               gpg_err_code_from_syserror ());
547                           xfree (*r_fpr);
548                           *r_fpr = NULL;
549                           goto leave;
550                         }
551                       memcpy (*r_url, &pt[*r_fprlen + 1],
552                               dlen - (*r_fprlen + 1));
553                       (*r_url)[dlen - (*r_fprlen + 1)] = '\0';
554                     }
555                   else
556                     *r_url = NULL;
557
558                   err = 0;
559                   goto leave;
560                 }
561
562               /* No subtype matches, so continue with the next answer. */
563               pt += dlen;
564             }
565           else
566             {
567               /* Not a requested type - might be a CNAME. Try next item.  */
568               pt += dlen;
569             }
570         }
571     }
572
573  leave:
574   xfree (answer);
575   return err;
576
577 #endif /*!USE_ADNS */
578 #else /* !USE_DNS_CERT */
579   (void)name;
580   if (r_key)
581     *r_key = NULL;
582   if (r_keylen)
583     *r_keylen = NULL;
584   *r_fpr = NULL;
585   *r_fprlen = 0;
586   *r_url = NULL;
587
588   return gpg_err_make (default_errsource, GPG_ERR_NOT_SUPPORTED);
589 #endif
590 }