Moved generic RADIUS protocol support to a dedicated libradius
[strongswan.git] / src / pluto / dnskey.c
1 /* Find public key in DNS
2 * Copyright (C) 2000-2002 D. Hugh Redelmeier.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 */
14
15 #include <stdlib.h>
16 #include <stddef.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <arpa/nameser.h>
26 #include <resolv.h>
27 #include <netdb.h> /* ??? for h_errno */
28 #include <sys/queue.h>
29
30 #include <freeswan.h>
31
32 #include <utils/identification.h>
33 #include <credentials/keys/public_key.h>
34
35 #include "constants.h"
36 #include "adns.h" /* needs <resolv.h> */
37 #include "defs.h"
38 #include "log.h"
39 #include "myid.h"
40 #include "connections.h"
41 #include "keys.h" /* needs connections.h */
42 #include "dnskey.h"
43 #include "packet.h"
44 #include "timer.h"
45
46 /* somebody has to decide */
47 #define MAX_TXT_RDATA ((MAX_KEY_BYTES * 8 / 6) + 40) /* somewhat arbitrary overkill */
48
49 /* ADNS stuff */
50
51 int adns_qfd = NULL_FD, /* file descriptor for sending queries to adns (O_NONBLOCK) */
52 adns_afd = NULL_FD; /* file descriptor for receiving answers from adns */
53 static pid_t adns_pid = 0;
54 const char *pluto_adns_option = NULL; /* path from --pluto_adns */
55
56 int adns_restart_count;
57 #define ADNS_RESTART_MAX 20
58
59 void
60 init_adns(void)
61 {
62 const char *adns_path = pluto_adns_option;
63 static const char adns_name[] = "_pluto_adns";
64 const char *helper_bin_dir = getenv("IPSEC_LIBDIR");
65 char adns_path_space[4096]; /* plenty long? */
66 int qfds[2];
67 int afds[2];
68
69 /* find a pathname to the ADNS program */
70 if (adns_path == NULL)
71 {
72 /* pathname was not specified as an option: build it.
73 * First, figure out the directory to be used.
74 */
75 ssize_t n;
76
77 if (helper_bin_dir != NULL)
78 {
79 n = strlen(helper_bin_dir);
80 if ((size_t)n <= sizeof(adns_path_space) - sizeof(adns_name))
81 {
82 strcpy(adns_path_space, helper_bin_dir);
83 if (n > 0 && adns_path_space[n -1] != '/')
84 {
85 adns_path_space[n++] = '/';
86 }
87 }
88 }
89 else
90 {
91 /* The program will be in the same directory as Pluto,
92 * so we use the sympolic link /proc/self/exe to
93 * tell us of the path prefix.
94 */
95 n = readlink("/proc/self/exe", adns_path_space, sizeof(adns_path_space));
96
97 if (n < 0)
98 {
99 exit_log_errno((e
100 , "readlink(\"/proc/self/exe\") failed in init_adns()"));
101 }
102 }
103
104 if ((size_t)n > sizeof(adns_path_space) - sizeof(adns_name))
105 {
106 exit_log("path to %s is too long", adns_name);
107 }
108
109 while (n > 0 && adns_path_space[n - 1] != '/')
110 {
111 n--;
112 }
113 strcpy(adns_path_space + n, adns_name);
114 adns_path = adns_path_space;
115 }
116 if (access(adns_path, X_OK) < 0)
117 {
118 exit_log_errno((e, "%s missing or not executable", adns_path));
119 }
120
121 if (pipe(qfds) != 0 || pipe(afds) != 0)
122 {
123 exit_log_errno((e, "pipe(2) failed in init_adns()"));
124 }
125
126 adns_pid = fork();
127 switch (adns_pid)
128 {
129 case -1:
130 exit_log_errno((e, "fork() failed in init_adns()"));
131
132 case 0:
133 /* child */
134 {
135 /* Make stdin and stdout our pipes.
136 * Take care to handle case where pipes already use these fds.
137 */
138 if (afds[1] == 0)
139 {
140 afds[1] = dup(afds[1]); /* avoid being overwritten */
141 }
142 if (qfds[0] != 0)
143 {
144 dup2(qfds[0], 0);
145 close(qfds[0]);
146 }
147 if (afds[1] != 1)
148 {
149 dup2(afds[1], 1);
150 close(qfds[1]);
151 }
152 if (afds[0] > 1)
153 {
154 close(afds[0]);
155 }
156 if (afds[1] > 1)
157 {
158 close(afds[1]);
159 }
160 DBG(DBG_DNS, execlp(adns_path, adns_name, "-d", NULL));
161
162 execlp(adns_path, adns_name, NULL);
163 exit_log_errno((e, "execlp of %s failed", adns_path));
164 }
165 default:
166 /* parent */
167 close(qfds[0]);
168 adns_qfd = qfds[1];
169 adns_afd = afds[0];
170 close(afds[1]);
171 fcntl(adns_qfd, F_SETFD, FD_CLOEXEC);
172 fcntl(adns_afd, F_SETFD, FD_CLOEXEC);
173 fcntl(adns_qfd, F_SETFL, O_NONBLOCK);
174 break;
175 }
176 }
177
178 void
179 stop_adns(void)
180 {
181 close_any(adns_qfd);
182 adns_qfd = NULL_FD;
183 close_any(adns_afd);
184 adns_afd = NULL_FD;
185
186 if (adns_pid != 0)
187 {
188 int status;
189 pid_t p = waitpid(adns_pid, &status, 0);
190
191 if (p == -1)
192 {
193 log_errno((e, "waitpid for ADNS process failed"));
194 }
195 else if (WIFEXITED(status))
196 {
197 if (WEXITSTATUS(status) != 0)
198 {
199 plog("ADNS process exited with status %d"
200 , (int) WEXITSTATUS(status));
201 }
202 }
203 else if (WIFSIGNALED(status))
204 {
205 plog("ADNS process terminated by signal %d", (int)WTERMSIG(status));
206 }
207 else
208 {
209 plog("wait for end of ADNS process returned odd status 0x%x\n"
210 , status);
211 }
212 }
213 }
214
215
216
217 /* tricky macro to pass any hot potato */
218 #define TRY(x) { err_t ugh = x; if (ugh != NULL) return ugh; }
219
220
221 /* Process TXT X-IPsec-Server record, accumulating relevant ones
222 * in cr->gateways_from_dns, a list sorted by "preference".
223 *
224 * Format of TXT record body: X-IPsec-Server ( nnn ) = iii kkk
225 * nnn is a 16-bit unsigned integer preference
226 * iii is @FQDN or dotted-decimal IPv4 address or colon-hex IPv6 address
227 * kkk is an optional RSA public signing key in base 64.
228 *
229 * NOTE: we've got to be very wary of anything we find -- bad guys
230 * might have prepared it.
231 */
232
233 #define our_TXT_attr_string "X-IPsec-Server"
234 static const char our_TXT_attr[] = our_TXT_attr_string;
235
236 identification_t* decode_iii(u_char **pp)
237 {
238 identification_t *gw_id;
239 u_char *p = *pp + strspn(*pp, " \t");
240 u_char *e = p + strcspn(p, " \t");
241 u_char under = *e;
242
243 if (p == e)
244 {
245 return NULL;
246 }
247 *e = '\0';
248 gw_id = identification_create_from_string(p);
249 *e = under;
250 *pp = e + strspn(e, " \t");
251
252 return gw_id;
253 }
254
255 static err_t process_txt_rr_body(u_char *str, bool doit,
256 enum dns_auth_level dns_auth_level,
257 struct adns_continuation *const cr)
258 {
259 identification_t *client_id = cr->id; /* subject of query */
260 u_char *p = str;
261 unsigned long pref = 0;
262 struct gw_info gi;
263
264 p += strspn(p, " \t"); /* ignore leading whitespace */
265
266 /* is this for us? */
267 if (strncasecmp(p, our_TXT_attr, sizeof(our_TXT_attr)-1) != 0)
268 {
269 return NULL; /* neither interesting nor bad */
270 }
271
272 p += sizeof(our_TXT_attr) - 1; /* ignore our attribute name */
273 p += strspn(p, " \t"); /* ignore leading whitespace */
274
275 /* decode '(' nnn ')' */
276 if (*p != '(')
277 {
278 return "X-IPsec-Server missing '('";
279 }
280
281 {
282 char *e;
283
284 p++;
285 pref = strtoul(p, &e, 0);
286 if ((u_char *)e == p)
287 {
288 return "malformed X-IPsec-Server priority";
289 }
290 p = e + strspn(e, " \t");
291
292 if (*p != ')')
293 {
294 return "X-IPsec-Server priority missing ')'";
295 }
296 p++;
297 p += strspn(p, " \t");
298
299 if (pref > 0xFFFF)
300 {
301 return "X-IPsec-Server priority larger than 0xFFFF";
302 }
303 }
304
305 /* time for '=' */
306
307 if (*p != '=')
308 {
309 return "X-IPsec-Server priority missing '='";
310 }
311 p++;
312 p += strspn(p, " \t");
313
314 /* Decode iii (Security Gateway ID). */
315 zero(&gi); /* before first use */
316
317 gi.gw_id = decode_iii(&p);
318 if (gi.gw_id == NULL)
319 {
320 return "TXT " our_TXT_attr_string " badly formed (no gateway specified)";
321 }
322
323 if (!cr->sgw_specified)
324 {
325 /* we don't know the peer's ID (because we are initiating
326 * and we don't know who to initiate with.
327 * So we're looking for gateway specs with an IP address
328 */
329 if (gi.gw_id->get_type(gi.gw_id) != ID_IPV4_ADDR &&
330 gi.gw_id->get_type(gi.gw_id) != ID_IPV6_ADDR)
331 {
332 DBG(DBG_DNS,
333 DBG_log("TXT %s record for '%Y': security gateway '%Y';"
334 " ignored because gateway's IP is unspecified",
335 our_TXT_attr, client_id, gi.gw_id);
336 )
337 return NULL; /* we cannot use this record, but it isn't wrong */
338 }
339 }
340 else
341 {
342 /* We do know the peer's ID (because we are responding)
343 * So we're looking for gateway specs specifying this known ID.
344 */
345 identification_t *peer_id = cr->sgw_id;
346
347 if (!peer_id->equals(peer_id, gi.gw_id))
348 {
349 DBG(DBG_DNS,
350 DBG_log("TXT %s record for '%Y': security gateway '%Y';"
351 " ignored -- looking to confirm '%Y' as gateway",
352 our_TXT_attr, client_id, gi.gw_id, peer_id);
353 )
354 return NULL; /* we cannot use this record, but it isn't wrong */
355 }
356 }
357
358 if (doit)
359 {
360 /* really accept gateway */
361 struct gw_info **gwip; /* gateway insertion point */
362
363 gi.client_id = client_id; /* will need to unshare_id_content */
364
365 /* decode optional kkk: base 64 encoding of key */
366
367 gi.gw_key_present = *p != '\0';
368 if (gi.gw_key_present)
369 {
370 /* Decode base 64 encoding of key.
371 * Similar code is in process_lwdnsq_key.
372 */
373 u_char buf[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
374 size_t sz;
375 err_t ugh;
376 chunk_t rfc3110_chunk;
377 public_key_t *key;
378
379 ugh = ttodatav(p, 0, 64, buf, sizeof(buf), &sz,
380 diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
381 if (ugh)
382 {
383 return builddiag("malformed key data: %s", ugh);
384 }
385 if (sz > sizeof(buf))
386 {
387 return builddiag("key data larger than %lu bytes",
388 (unsigned long) sizeof(buf));
389 }
390 rfc3110_chunk = chunk_create(buf, sz);
391 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
392 BUILD_BLOB_DNSKEY, rfc3110_chunk,
393 BUILD_END);
394 if (key == NULL)
395 {
396 return builddiag("invalid key data");
397 }
398
399 /* now find a key entry to put it in */
400 gi.key = public_key_from_rsa(key);
401
402 unreference_key(&cr->last_info);
403 cr->last_info = reference_key(gi.key);
404 }
405
406 /* we're home free! Allocate everything and add to gateways list. */
407 gi.refcnt = 1;
408 gi.pref = pref;
409 gi.key->dns_auth_level = dns_auth_level;
410 gi.key->last_tried_time = gi.key->last_worked_time = NO_TIME;
411
412 /* find insertion point */
413 for (gwip = &cr->gateways_from_dns; *gwip != NULL && (*gwip)->pref < pref; gwip = &(*gwip)->next)
414 ;
415
416 DBG(DBG_DNS,
417 {
418 chunk_t keyid;
419 public_key_t *key = gi.key->public_key;
420
421 if (gi.gw_key_present &&
422 key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &keyid))
423 {
424 DBG_log("gateway for %s is %s with key %#B",
425 client_id, gi.gw_id, &keyid);
426 }
427 else
428 {
429 DBG_log("gateway for '%Y' is '%Y'; no key specified",
430 client_id, gi.gw_id);
431 }
432 });
433
434 gi.next = *gwip;
435 *gwip = clone_thing(gi);
436 (*gwip)->gw_id = (*gwip)->gw_id->clone((*gwip)->gw_id);
437 (*gwip)->client_id = (*gwip)->client_id->clone((*gwip)->client_id);
438 }
439
440 return NULL;
441 }
442
443 static const char *
444 rr_typename(int type)
445 {
446 switch (type)
447 {
448 case T_TXT:
449 return "TXT";
450 case T_KEY:
451 return "KEY";
452 default:
453 return "???";
454 }
455 }
456
457
458 /* structure of Query Reply (RFC 1035 4.1.1):
459 *
460 * +---------------------+
461 * | Header |
462 * +---------------------+
463 * | Question | the question for the name server
464 * +---------------------+
465 * | Answer | RRs answering the question
466 * +---------------------+
467 * | Authority | RRs pointing toward an authority
468 * +---------------------+
469 * | Additional | RRs holding additional information
470 * +---------------------+
471 */
472
473 /* Header section format (as modified by RFC 2535 6.1):
474 * 1 1 1 1 1 1
475 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
476 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
477 * | ID |
478 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
479 * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE |
480 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
481 * | QDCOUNT |
482 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
483 * | ANCOUNT |
484 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
485 * | NSCOUNT |
486 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
487 * | ARCOUNT |
488 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
489 */
490 struct qr_header {
491 u_int16_t id; /* 16-bit identifier to match query */
492
493 u_int16_t stuff; /* packed crud: */
494
495 #define QRS_QR 0x8000 /* QR: on if this is a response */
496
497 #define QRS_OPCODE_SHIFT 11 /* OPCODE field */
498 #define QRS_OPCODE_MASK 0xF
499 #define QRSO_QUERY 0 /* standard query */
500 #define QRSO_IQUERY 1 /* inverse query */
501 #define QRSO_STATUS 2 /* server status request query */
502
503 #define QRS_AA 0x0400 /* AA: on if Authoritative Answer */
504 #define QRS_TC 0x0200 /* TC: on if truncation happened */
505 #define QRS_RD 0x0100 /* RD: on if recursion desired */
506 #define QRS_RA 0x0080 /* RA: on if recursion available */
507 #define QRS_Z 0x0040 /* Z: reserved; must be zero */
508 #define QRS_AD 0x0020 /* AD: on if authentic data (RFC 2535) */
509 #define QRS_CD 0x0010 /* AD: on if checking disabled (RFC 2535) */
510
511 #define QRS_RCODE_SHIFT 0 /* RCODE field: response code */
512 #define QRS_RCODE_MASK 0xF
513 #define QRSR_OK 0
514
515
516 u_int16_t qdcount; /* number of entries in question section */
517 u_int16_t ancount; /* number of resource records in answer section */
518 u_int16_t nscount; /* number of name server resource records in authority section */
519 u_int16_t arcount; /* number of resource records in additional records section */
520 };
521
522 static field_desc qr_header_fields[] = {
523 { ft_nat, 16/BITS_PER_BYTE, "ID", NULL },
524 { ft_nat, 16/BITS_PER_BYTE, "stuff", NULL },
525 { ft_nat, 16/BITS_PER_BYTE, "QD Count", NULL },
526 { ft_nat, 16/BITS_PER_BYTE, "Answer Count", NULL },
527 { ft_nat, 16/BITS_PER_BYTE, "Authority Count", NULL },
528 { ft_nat, 16/BITS_PER_BYTE, "Additional Count", NULL },
529 { ft_end, 0, NULL, NULL }
530 };
531
532 static struct_desc qr_header_desc = {
533 "Query Response Header",
534 qr_header_fields,
535 sizeof(struct qr_header)
536 };
537
538 /* Messages for codes in RCODE (see RFC 1035 4.1.1) */
539 static const err_t rcode_text[QRS_RCODE_MASK + 1] = {
540 NULL, /* not an error */
541 "Format error - The name server was unable to interpret the query",
542 "Server failure - The name server was unable to process this query"
543 " due to a problem with the name server",
544 "Name Error - Meaningful only for responses from an authoritative name"
545 " server, this code signifies that the domain name referenced in"
546 " the query does not exist",
547 "Not Implemented - The name server does not support the requested"
548 " kind of query",
549 "Refused - The name server refuses to perform the specified operation"
550 " for policy reasons",
551 /* the rest are reserved for future use */
552 };
553
554 /* throw away a possibly compressed domain name */
555
556 static err_t
557 eat_name(pb_stream *pbs)
558 {
559 u_char name_buf[NS_MAXDNAME + 2];
560 u_char *ip = pbs->cur;
561 unsigned oi = 0;
562 unsigned jump_count = 0;
563
564 for (;;)
565 {
566 u_int8_t b;
567
568 if (ip >= pbs->roof)
569 return "ran out of message while skipping domain name";
570
571 b = *ip++;
572 if (jump_count == 0)
573 pbs->cur = ip;
574
575 if (b == 0)
576 break;
577
578 switch (b & 0xC0)
579 {
580 case 0x00:
581 /* we grab the next b characters */
582 if (oi + b > NS_MAXDNAME)
583 return "domain name too long";
584
585 if (pbs->roof - ip <= b)
586 return "domain name falls off end of message";
587
588 if (oi != 0)
589 name_buf[oi++] = '.';
590
591 memcpy(name_buf + oi, ip, b);
592 oi += b;
593 ip += b;
594 if (jump_count == 0)
595 pbs->cur = ip;
596 break;
597
598 case 0xC0:
599 {
600 unsigned ix;
601
602 if (ip >= pbs->roof)
603 return "ran out of message in middle of compressed domain name";
604
605 ix = ((b & ~0xC0u) << 8) | *ip++;
606 if (jump_count == 0)
607 pbs->cur = ip;
608
609 if (ix >= pbs_room(pbs))
610 return "impossible compressed domain name";
611
612 /* Avoid infinite loop.
613 * There can be no more jumps than there are bytes
614 * in the packet. Not a tight limit, but good enough.
615 */
616 jump_count++;
617 if (jump_count > pbs_room(pbs))
618 return "loop in compressed domain name";
619
620 ip = pbs->start + ix;
621 }
622 break;
623
624 default:
625 return "invalid code in label";
626 }
627 }
628
629 name_buf[oi++] = '\0';
630
631 DBG(DBG_DNS, DBG_log("skipping name %s", name_buf));
632
633 return NULL;
634 }
635
636 static err_t
637 eat_name_helpfully(pb_stream *pbs, const char *context)
638 {
639 err_t ugh = eat_name(pbs);
640
641 return ugh == NULL? ugh
642 : builddiag("malformed name within DNS record of %s: %s", context, ugh);
643 }
644
645 /* non-variable part of 4.1.2 Question Section entry:
646 * 1 1 1 1 1 1
647 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
648 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
649 * | |
650 * / QNAME /
651 * / /
652 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
653 * | QTYPE |
654 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
655 * | QCLASS |
656 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
657 */
658
659 struct qs_fixed {
660 u_int16_t qtype;
661 u_int16_t qclass;
662 };
663
664 static field_desc qs_fixed_fields[] = {
665 { ft_loose_enum, 16/BITS_PER_BYTE, "QTYPE", &rr_qtype_names },
666 { ft_loose_enum, 16/BITS_PER_BYTE, "QCLASS", &rr_class_names },
667 { ft_end, 0, NULL, NULL }
668 };
669
670 static struct_desc qs_fixed_desc = {
671 "Question Section entry fixed part",
672 qs_fixed_fields,
673 sizeof(struct qs_fixed)
674 };
675
676 /* 4.1.3. Resource record format:
677 * 1 1 1 1 1 1
678 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
679 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
680 * | |
681 * / /
682 * / NAME /
683 * | |
684 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
685 * | TYPE |
686 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
687 * | CLASS |
688 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
689 * | TTL |
690 * | |
691 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
692 * | RDLENGTH |
693 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
694 * / RDATA /
695 * / /
696 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
697 */
698
699 struct rr_fixed {
700 u_int16_t type;
701 u_int16_t class;
702 u_int32_t ttl; /* actually signed */
703 u_int16_t rdlength;
704 };
705
706
707 static field_desc rr_fixed_fields[] = {
708 { ft_loose_enum, 16/BITS_PER_BYTE, "type", &rr_type_names },
709 { ft_loose_enum, 16/BITS_PER_BYTE, "class", &rr_class_names },
710 { ft_nat, 32/BITS_PER_BYTE, "TTL", NULL },
711 { ft_nat, 16/BITS_PER_BYTE, "RD length", NULL },
712 { ft_end, 0, NULL, NULL }
713 };
714
715 static struct_desc rr_fixed_desc = {
716 "Resource Record fixed part",
717 rr_fixed_fields,
718 /* note: following is tricky: avoids padding problems */
719 offsetof(struct rr_fixed, rdlength) + sizeof(u_int16_t)
720 };
721
722 /* RFC 1035 3.3.14: TXT RRs have text in the RDATA field.
723 * It is in the form of a sequence of <character-string>s as described in 3.3.
724 * unpack_txt_rdata() deals with this peculiar representation.
725 */
726
727 /* RFC 2535 3.1 KEY RDATA format:
728 *
729 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
730 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
731 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
732 * | flags | protocol | algorithm |
733 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
734 * | /
735 * / public key /
736 * / /
737 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
738 */
739
740 struct key_rdata {
741 u_int16_t flags;
742 u_int8_t protocol;
743 u_int8_t algorithm;
744 };
745
746 static field_desc key_rdata_fields[] = {
747 { ft_nat, 16/BITS_PER_BYTE, "flags", NULL },
748 { ft_nat, 8/BITS_PER_BYTE, "protocol", NULL },
749 { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL },
750 { ft_end, 0, NULL, NULL }
751 };
752
753 static struct_desc key_rdata_desc = {
754 "KEY RR RData fixed part",
755 key_rdata_fields,
756 sizeof(struct key_rdata)
757 };
758
759 /* RFC 2535 4.1 SIG RDATA format:
760 *
761 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
762 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
763 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
764 * | type covered | algorithm | labels |
765 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
766 * | original TTL |
767 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
768 * | signature expiration |
769 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
770 * | signature inception |
771 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
772 * | key tag | |
773 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ signer's name +
774 * | /
775 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-/
776 * / /
777 * / signature /
778 * / /
779 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
780 */
781
782 struct sig_rdata {
783 u_int16_t type_covered;
784 u_int8_t algorithm;
785 u_int8_t labels;
786 u_int32_t original_ttl;
787 u_int32_t sig_expiration;
788 u_int32_t sig_inception;
789 u_int16_t key_tag;
790 };
791
792 static field_desc sig_rdata_fields[] = {
793 { ft_nat, 16/BITS_PER_BYTE, "type_covered", NULL},
794 { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL},
795 { ft_nat, 8/BITS_PER_BYTE, "labels", NULL},
796 { ft_nat, 32/BITS_PER_BYTE, "original ttl", NULL},
797 { ft_nat, 32/BITS_PER_BYTE, "sig expiration", NULL},
798 { ft_nat, 32/BITS_PER_BYTE, "sig inception", NULL},
799 { ft_nat, 16/BITS_PER_BYTE, "key tag", NULL},
800 { ft_end, 0, NULL, NULL }
801 };
802
803 static struct_desc sig_rdata_desc = {
804 "SIG RR RData fixed part",
805 sig_rdata_fields,
806 sizeof(struct sig_rdata)
807 };
808
809 /* handle a KEY Resource Record. */
810
811 #ifdef USE_KEYRR
812 static err_t
813 process_key_rr(u_char *ptr, size_t len
814 , bool doit /* should we capture information? */
815 , enum dns_auth_level dns_auth_level
816 , struct adns_continuation *const cr)
817 {
818 pb_stream pbs;
819 struct key_rdata kr;
820
821 if (len < sizeof(struct key_rdata))
822 return "KEY Resource Record's RD Length is too small";
823
824 init_pbs(&pbs, ptr, len, "KEY RR");
825
826 if (!in_struct(&kr, &key_rdata_desc, &pbs, NULL))
827 return "failed to get fixed part of KEY Resource Record RDATA";
828
829 if (kr.protocol == 4 /* IPSEC (RFC 2535 3.1.3) */
830 && kr.algorithm == 1 /* RSA/MD5 (RFC 2535 3.2) */
831 && (kr.flags & 0x8000) == 0 /* use for authentication (3.1.2) */
832 && (kr.flags & 0x2CF0) == 0) /* must be zero */
833 {
834 /* we have what seems to be a tasty key */
835
836 if (doit)
837 {
838 chunk_t k = { pbs.cur, pbs_left(&pbs) };
839
840 TRY(add_public_key(&cr->id, dns_auth_level, PUBKEY_ALG_RSA, &k
841 , &cr->keys_from_dns));
842 }
843 }
844 return NULL;
845 }
846 #endif /* USE_KEYRR */
847
848
849 /* unpack TXT rr RDATA into C string.
850 * A sequence of <character-string>s as described in RFC 1035 3.3.
851 * We concatenate them.
852 */
853 static err_t
854 unpack_txt_rdata(u_char *d, size_t dlen, const u_char *s, size_t slen)
855 {
856 size_t i = 0
857 , o = 0;
858
859 while (i < slen)
860 {
861 size_t cl = s[i++];
862
863 if (i + cl > slen)
864 return "TXT rr RDATA representation malformed";
865
866 if (o + cl >= dlen)
867 return "TXT rr RDATA too large";
868
869 memcpy(d + o, s + i, cl);
870 i += cl;
871 o += cl;
872 }
873 d[o] = '\0';
874 if (strlen(d) != o)
875 return "TXT rr RDATA contains a NUL";
876
877 return NULL;
878 }
879
880 static err_t
881 process_txt_rr(u_char *rdata, size_t rdlen
882 , bool doit /* should we capture information? */
883 , enum dns_auth_level dns_auth_level
884 , struct adns_continuation *const cr)
885 {
886 u_char str[RSA_MAX_ENCODING_BYTES * 8 / 6 + 20]; /* space for unpacked RDATA */
887
888 TRY(unpack_txt_rdata(str, sizeof(str), rdata, rdlen));
889 return process_txt_rr_body(str, doit, dns_auth_level, cr);
890 }
891
892 static err_t
893 process_answer_section(pb_stream *pbs
894 , bool doit /* should we capture information? */
895 , enum dns_auth_level *dns_auth_level
896 , u_int16_t ancount /* number of RRs in the answer section */
897 , struct adns_continuation *const cr)
898 {
899 const int type = cr->query.type; /* type of RR of interest */
900 unsigned c;
901
902 DBG(DBG_DNS, DBG_log("*Answer Section:"));
903
904 for (c = 0; c != ancount; c++)
905 {
906 struct rr_fixed rrf;
907 size_t tail;
908
909 /* ??? do we need to match the name? */
910
911 TRY(eat_name_helpfully(pbs, "Answer Section"));
912
913 if (!in_struct(&rrf, &rr_fixed_desc, pbs, NULL))
914 return "failed to get fixed part of Answer Section Resource Record";
915
916 if (rrf.rdlength > pbs_left(pbs))
917 return "RD Length extends beyond end of message";
918
919 /* ??? should we care about ttl? */
920
921 tail = rrf.rdlength;
922
923 if (rrf.type == type && rrf.class == C_IN)
924 {
925 err_t ugh = NULL;
926
927 switch (type)
928 {
929 #ifdef USE_KEYRR
930 case T_KEY:
931 ugh = process_key_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
932 break;
933 #endif /* USE_KEYRR */
934 case T_TXT:
935 ugh = process_txt_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
936 break;
937 case T_SIG:
938 /* Check if SIG RR authenticates what we are learning.
939 * The RRset covered by a SIG must have the same owner,
940 * class, and type.
941 * For us, the class is always C_IN, so that matches.
942 * We decode the SIG RR's fixed part to check
943 * that the type_covered field matches our query type
944 * (this may be redundant).
945 * We don't check the owner (apparently this is the
946 * name on the record) -- we assume that it matches
947 * or we would not have been given this SIG in the
948 * Answer Section.
949 *
950 * We only look on first pass, and only if we've something
951 * to learn. This cuts down on useless decoding.
952 */
953 if (!doit && *dns_auth_level == DAL_UNSIGNED)
954 {
955 struct sig_rdata sr;
956
957 if (!in_struct(&sr, &sig_rdata_desc, pbs, NULL))
958 ugh = "failed to get fixed part of SIG Resource Record RDATA";
959 else if (sr.type_covered == type)
960 *dns_auth_level = DAL_SIGNED;
961 }
962 break;
963 default:
964 ugh = builddiag("unexpected RR type %d", type);
965 break;
966 }
967 if (ugh != NULL)
968 return ugh;
969 }
970 in_raw(NULL, tail, pbs, "RR RDATA");
971 }
972
973 return doit
974 && cr->gateways_from_dns == NULL
975 #ifdef USE_KEYRR
976 && cr->keys_from_dns == NULL
977 #endif /* USE_KEYRR */
978 ? builddiag("no suitable %s record found in DNS", rr_typename(type))
979 : NULL;
980 }
981
982 /* process DNS answer -- TXT or KEY query */
983
984 static err_t
985 process_dns_answer(struct adns_continuation *const cr
986 , u_char ans[], int anslen)
987 {
988 const int type = cr->query.type; /* type of record being sought */
989 int r; /* all-purpose return value holder */
990 u_int16_t c; /* number of current RR in current answer section */
991 pb_stream pbs;
992 u_int8_t *ans_start; /* saved position of answer section */
993 struct qr_header qr_header;
994 enum dns_auth_level dns_auth_level;
995
996 init_pbs(&pbs, ans, anslen, "Query Response Message");
997
998 /* decode and check header */
999
1000 if (!in_struct(&qr_header, &qr_header_desc, &pbs, NULL))
1001 return "malformed header";
1002
1003 /* ID: nothing to do with us */
1004
1005 /* stuff -- lots of things */
1006 if ((qr_header.stuff & QRS_QR) == 0)
1007 return "not a response?!?";
1008
1009 if (((qr_header.stuff >> QRS_OPCODE_SHIFT) & QRS_OPCODE_MASK) != QRSO_QUERY)
1010 return "unexpected opcode";
1011
1012 /* I don't think we care about AA */
1013
1014 if (qr_header.stuff & QRS_TC)
1015 return "response truncated";
1016
1017 /* I don't think we care about RD, RA, or CD */
1018
1019 /* AD means "authentic data" */
1020 dns_auth_level = qr_header.stuff & QRS_AD? DAL_UNSIGNED : DAL_NOTSEC;
1021
1022 if (qr_header.stuff & QRS_Z)
1023 return "Z bit is not zero";
1024
1025 r = (qr_header.stuff >> QRS_RCODE_SHIFT) & QRS_RCODE_MASK;
1026 if (r != 0)
1027 return r < (int)countof(rcode_text)? rcode_text[r] : "unknown rcode";
1028
1029 if (qr_header.ancount == 0)
1030 return builddiag("no %s RR found by DNS", rr_typename(type));
1031
1032 /* end of header checking */
1033
1034 /* Question Section processing */
1035
1036 /* 4.1.2. Question section format:
1037 * 1 1 1 1 1 1
1038 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
1039 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1040 * | |
1041 * / QNAME /
1042 * / /
1043 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1044 * | QTYPE |
1045 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1046 * | QCLASS |
1047 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1048 */
1049
1050 DBG(DBG_DNS, DBG_log("*Question Section:"));
1051
1052 for (c = 0; c != qr_header.qdcount; c++)
1053 {
1054 struct qs_fixed qsf;
1055
1056 TRY(eat_name_helpfully(&pbs, "Question Section"));
1057
1058 if (!in_struct(&qsf, &qs_fixed_desc, &pbs, NULL))
1059 return "failed to get fixed part of Question Section";
1060
1061 if (qsf.qtype != type)
1062 return "unexpected QTYPE in Question Section";
1063
1064 if (qsf.qclass != C_IN)
1065 return "unexpected QCLASS in Question Section";
1066 }
1067
1068 /* rest of sections are made up of Resource Records */
1069
1070 /* Answer Section processing -- error checking, noting T_SIG */
1071
1072 ans_start = pbs.cur; /* remember start of answer section */
1073
1074 TRY(process_answer_section(&pbs, FALSE, &dns_auth_level
1075 , qr_header.ancount, cr));
1076
1077 /* Authority Section processing (just sanity checking) */
1078
1079 DBG(DBG_DNS, DBG_log("*Authority Section:"));
1080
1081 for (c = 0; c != qr_header.nscount; c++)
1082 {
1083 struct rr_fixed rrf;
1084 size_t tail;
1085
1086 TRY(eat_name_helpfully(&pbs, "Authority Section"));
1087
1088 if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
1089 return "failed to get fixed part of Authority Section Resource Record";
1090
1091 if (rrf.rdlength > pbs_left(&pbs))
1092 return "RD Length extends beyond end of message";
1093
1094 /* ??? should we care about ttl? */
1095
1096 tail = rrf.rdlength;
1097
1098 in_raw(NULL, tail, &pbs, "RR RDATA");
1099 }
1100
1101 /* Additional Section processing (just sanity checking) */
1102
1103 DBG(DBG_DNS, DBG_log("*Additional Section:"));
1104
1105 for (c = 0; c != qr_header.arcount; c++)
1106 {
1107 struct rr_fixed rrf;
1108 size_t tail;
1109
1110 TRY(eat_name_helpfully(&pbs, "Additional Section"));
1111
1112 if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
1113 return "failed to get fixed part of Additional Section Resource Record";
1114
1115 if (rrf.rdlength > pbs_left(&pbs))
1116 return "RD Length extends beyond end of message";
1117
1118 /* ??? should we care about ttl? */
1119
1120 tail = rrf.rdlength;
1121
1122 in_raw(NULL, tail, &pbs, "RR RDATA");
1123 }
1124
1125 /* done all sections */
1126
1127 /* ??? is padding legal, or can we complain if more left in record? */
1128
1129 /* process Answer Section again -- accept contents */
1130
1131 pbs.cur = ans_start; /* go back to start of answer section */
1132
1133 return process_answer_section(&pbs, TRUE, &dns_auth_level
1134 , qr_header.ancount, cr);
1135 }
1136
1137 /****************************************************************/
1138
1139 static err_t build_dns_name(u_char name_buf[NS_MAXDNAME + 2],
1140 unsigned long serial USED_BY_DEBUG,
1141 identification_t *id,
1142 const char *typename USED_BY_DEBUG,
1143 identification_t *gw USED_BY_DEBUG)
1144 {
1145 /* note: all end in "." to suppress relative searches */
1146 id = resolve_myid(id);
1147
1148 switch (id->get_type(id))
1149 {
1150 case ID_IPV4_ADDR:
1151 {
1152 chunk_t b = id->get_encoding(id);
1153
1154 snprintf(name_buf, NS_MAXDNAME + 2, "%d.%d.%d.%d.in-addr.arpa.",
1155 b.ptr[3], b.ptr[2], b.ptr[1], b.ptr[0]);
1156 break;
1157 }
1158 case ID_IPV6_ADDR:
1159 {
1160 chunk_t b = id->get_encoding(id);
1161 size_t bl;
1162 u_char *op = name_buf;
1163 static const char suffix[] = "IP6.INT.";
1164
1165 for (bl = b.len; bl-- != 0; )
1166 {
1167 if (op + 4 + sizeof(suffix) >= name_buf + NS_MAXDNAME + 1)
1168 {
1169 return "IPv6 reverse name too long";
1170 }
1171 op += sprintf(op, "%x.%x.", b.ptr[bl] & 0xF, b.ptr[bl] >> 4);
1172 }
1173 strcpy(op, suffix);
1174 break;
1175 }
1176 case ID_FQDN:
1177 {
1178 if (snprintf(name_buf, NS_MAXDNAME + 2, "%Y.", id) > NS_MAXDNAME + 1)
1179 {
1180 return "FQDN too long for domain name";
1181 }
1182 break;
1183 }
1184 default:
1185 return "can only query DNS for key for ID that is a FQDN, IPV4_ADDR, or IPV6_ADDR";
1186 }
1187
1188 DBG(DBG_CONTROL | DBG_DNS,
1189 DBG_log("DNS query %lu for %s for %s (gw: %Y)", serial, typename, name_buf, gw)
1190 )
1191 return NULL;
1192 }
1193
1194 void gw_addref(struct gw_info *gw)
1195 {
1196 if (gw != NULL)
1197 {
1198 DBG(DBG_DNS, DBG_log("gw_addref: %p refcnt: %d++", gw, gw->refcnt))
1199 gw->refcnt++;
1200 }
1201 }
1202
1203 void gw_delref(struct gw_info **gwp)
1204 {
1205 struct gw_info *gw = *gwp;
1206
1207 if (gw != NULL)
1208 {
1209 DBG(DBG_DNS, DBG_log("gw_delref: %p refcnt: %d--", gw, gw->refcnt));
1210
1211 passert(gw->refcnt != 0);
1212 gw->refcnt--;
1213 if (gw->refcnt == 0)
1214 {
1215 DESTROY_IF(gw->client_id);
1216 DESTROY_IF(gw->gw_id);
1217 if (gw->gw_key_present)
1218 {
1219 unreference_key(&gw->key);
1220 }
1221 gw_delref(&gw->next);
1222 free(gw); /* trickery could make this a tail-call */
1223 }
1224 *gwp = NULL;
1225 }
1226 }
1227
1228 static int adns_in_flight = 0; /* queries outstanding */
1229
1230 /* Start an asynchronous DNS query.
1231 *
1232 * For KEY record, the result will be a list in cr->keys_from_dns.
1233 * For TXT records, the result will be a list in cr->gateways_from_dns.
1234 *
1235 * If sgw_id is null, only consider TXT records that specify an
1236 * IP address for the gatway: we need this in the initiation case.
1237 *
1238 * If sgw_id is non-null, only consider TXT records that specify
1239 * this id as the security gatway; this is useful to the Responder
1240 * for confirming claims of gateways.
1241 *
1242 * Continuation cr gives information for continuing when the result shows up.
1243 *
1244 * Two kinds of errors must be handled: synchronous (immediate)
1245 * and asynchronous. Synchronous errors are indicated by the returned
1246 * value of start_adns_query; in this case, the continuation will
1247 * have been freed and the continuation routine will not be called.
1248 * Asynchronous errors are indicated by the ugh parameter passed to the
1249 * continuation routine.
1250 *
1251 * After the continuation routine has completed, handle_adns_answer
1252 * will free the continuation. The continuation routine should have
1253 * freed any axiliary resources.
1254 *
1255 * Note: in the synchronous error case, start_adns_query will have
1256 * freed the continuation; this means that the caller will have to
1257 * be very careful to release any auxiliary resources that were in
1258 * the continuation record without using the continuation record.
1259 *
1260 * Either there will be an error result passed to the continuation routine,
1261 * or the results will be in cr->keys_from_dns or cr->gateways_from_dns.
1262 * The result variables must by left NULL by the continutation routine.
1263 * The continuation routine is responsible for establishing and
1264 * disestablishing any logging context (whack_log_fd, cur_*).
1265 */
1266
1267 static struct adns_continuation *continuations = NULL; /* newest of queue */
1268 static struct adns_continuation *next_query = NULL; /* oldest not sent */
1269
1270 static struct adns_continuation *continuation_for_qtid(unsigned long qtid)
1271 {
1272 struct adns_continuation *cr = NULL;
1273
1274 if (qtid != 0)
1275 {
1276 for (cr = continuations; cr != NULL && cr->qtid != qtid; cr = cr->previous)
1277 ;
1278 }
1279 return cr;
1280 }
1281
1282 static void release_adns_continuation(struct adns_continuation *cr)
1283 {
1284 passert(cr != next_query);
1285 gw_delref(&cr->gateways_from_dns);
1286 #ifdef USE_KEYRR
1287 free_public_keys(&cr->keys_from_dns);
1288 #endif /* USE_KEYRR */
1289 cr->id = cr->id->clone(cr->id);
1290 cr->sgw_id = cr->sgw_id->clone(cr->sgw_id);
1291
1292 /* unlink from doubly-linked list */
1293 if (cr->next == NULL)
1294 {
1295 continuations = cr->previous;
1296 }
1297 else
1298 {
1299 cr->next->previous = cr->previous;
1300 }
1301
1302 if (cr->previous != NULL)
1303 {
1304 cr->previous->next = cr->next;
1305 }
1306
1307 free(cr);
1308 }
1309
1310 err_t start_adns_query(identification_t *id, /* domain to query */
1311 identification_t *sgw_id, /* if non-null, any accepted gw_info must match */
1312 int type, /* T_TXT or T_KEY, selecting rr type of interest */
1313 cont_fn_t cont_fn,
1314 struct adns_continuation *cr)
1315 {
1316 static unsigned long qtid = 1; /* query transaction id; NOTE: static */
1317 const char *typename = rr_typename(type);
1318
1319 if(adns_pid == 0 && adns_restart_count < ADNS_RESTART_MAX)
1320 {
1321 plog("ADNS helper was not running. Restarting attempt %d",adns_restart_count);
1322 init_adns();
1323 }
1324
1325 /* Splice this in at head of doubly-linked list of continuations.
1326 * Note: this must be done before any release_adns_continuation().
1327 */
1328 cr->next = NULL;
1329 cr->previous = continuations;
1330 if (continuations != NULL)
1331 {
1332 continuations->next = cr;
1333 }
1334 continuations = cr;
1335
1336 cr->qtid = qtid++;
1337 cr->type = type;
1338 cr->cont_fn = cont_fn;
1339 cr->id = id->clone(id);
1340 cr->sgw_specified = (sgw_id != NULL);
1341 cr->sgw_id = cr->sgw_specified ?
1342 sgw_id->clone(sgw_id) :
1343 identification_create_from_string("%any");
1344 cr->gateways_from_dns = NULL;
1345 #ifdef USE_KEYRR
1346 cr->keys_from_dns = NULL;
1347 #endif /* USE_KEYRR */
1348
1349 #ifdef DEBUG
1350 cr->debugging = cur_debugging;
1351 #else
1352 cr->debugging = LEMPTY;
1353 #endif
1354
1355 zero(&cr->query);
1356 {
1357 err_t ugh = build_dns_name(cr->query.name_buf, cr->qtid, id,
1358 typename, cr->sgw_id);
1359
1360 if (ugh)
1361 {
1362 release_adns_continuation(cr);
1363 return ugh;
1364 }
1365 }
1366
1367 if (next_query == NULL)
1368 next_query = cr;
1369
1370 unsent_ADNS_queries = TRUE;
1371
1372 return NULL;
1373 }
1374
1375 /* send remaining ADNS queries (until pipe full or none left)
1376 *
1377 * This is a co-routine, so it uses static variables to
1378 * preserve state across calls.
1379 */
1380 bool unsent_ADNS_queries = FALSE;
1381
1382 void
1383 send_unsent_ADNS_queries(void)
1384 {
1385 static const unsigned char *buf_end = NULL; /* NOTE STATIC */
1386 static const unsigned char *buf_cur = NULL; /* NOTE STATIC */
1387
1388 if (adns_qfd == NULL_FD)
1389 return; /* nothing useful to do */
1390
1391 for (;;)
1392 {
1393 if (buf_cur != buf_end)
1394 {
1395 static int try = 0; /* NOTE STATIC */
1396 size_t n = buf_end - buf_cur;
1397 ssize_t r = write(adns_qfd, buf_cur, n);
1398
1399 if (r == -1)
1400 {
1401 switch (errno)
1402 {
1403 case EINTR:
1404 continue; /* try again now */
1405 case EAGAIN:
1406 DBG(DBG_DNS, DBG_log("EAGAIN writing to ADNS"));
1407 break; /* try again later */
1408 default:
1409 try++;
1410 log_errno((e, "error %d writing DNS query", try));
1411 break; /* try again later */
1412 }
1413 unsent_ADNS_queries = TRUE;
1414 break; /* done! */
1415 }
1416 else
1417 {
1418 passert(r >= 0);
1419 try = 0;
1420 buf_cur += r;
1421 }
1422 }
1423 else
1424 {
1425 if (next_query == NULL)
1426 {
1427 unsent_ADNS_queries = FALSE;
1428 break; /* done! */
1429 }
1430
1431 next_query->query.debugging = next_query->debugging;
1432 next_query->query.serial = next_query->qtid;
1433 next_query->query.len = sizeof(next_query->query);
1434 next_query->query.qmagic = ADNS_Q_MAGIC;
1435 next_query->query.type = next_query->type;
1436 buf_cur = (const void *)&next_query->query;
1437 buf_end = buf_cur + sizeof(next_query->query);
1438
1439 next_query = next_query->next;
1440 adns_in_flight++;
1441 }
1442 }
1443 }
1444
1445 static void recover_adns_die(void)
1446 {
1447 struct adns_continuation *cr = NULL;
1448
1449 adns_pid = 0;
1450 if(adns_restart_count < ADNS_RESTART_MAX) {
1451 adns_restart_count++;
1452
1453 /* next DNS query will restart it */
1454
1455 /* we have to walk the list of the outstanding requests,
1456 * and redo them!
1457 */
1458
1459 cr = continuations;
1460
1461 /* find the head of the list */
1462 if(continuations != NULL) {
1463 for (; cr->previous != NULL; cr = cr->previous);
1464 }
1465
1466 next_query = cr;
1467
1468 if(next_query != NULL) {
1469 unsent_ADNS_queries = TRUE;
1470 }
1471 }
1472 }
1473
1474 void reset_adns_restart_count(void)
1475 {
1476 adns_restart_count=0;
1477 }
1478
1479 void handle_adns_answer(void)
1480 {
1481 /* These are retained across calls to handle_adns_answer. */
1482 static size_t buflen = 0; /* bytes in answer buffer */
1483 static struct adns_answer buf;
1484
1485 ssize_t n;
1486
1487 passert(buflen < sizeof(buf));
1488 n = read(adns_afd, (unsigned char *)&buf + buflen, sizeof(buf) - buflen);
1489
1490 if (n < 0)
1491 {
1492 if (errno != EINTR)
1493 {
1494 log_errno((e, "error reading answer from adns"));
1495 /* ??? how can we recover? */
1496 }
1497 n = 0; /* now n reflects amount read */
1498 }
1499 else if (n == 0)
1500 {
1501 /* EOF */
1502 if (adns_in_flight != 0)
1503 {
1504 plog("EOF from ADNS with %d queries outstanding (restarts %d)"
1505 , adns_in_flight, adns_restart_count);
1506 recover_adns_die();
1507 }
1508 if (buflen != 0)
1509 {
1510 plog("EOF from ADNS with %lu bytes of a partial answer outstanding"
1511 "(restarts %d)"
1512 , (unsigned long)buflen
1513 , adns_restart_count);
1514 recover_adns_die();
1515 }
1516 stop_adns();
1517 return;
1518 }
1519 else
1520 {
1521 passert(adns_in_flight > 0);
1522 }
1523
1524 buflen += n;
1525 while (buflen >= offsetof(struct adns_answer, ans) && buflen >= buf.len)
1526 {
1527 /* we've got a tasty answer -- process it */
1528 err_t ugh;
1529 struct adns_continuation *cr = continuation_for_qtid(buf.serial); /* assume it works */
1530 const char *typename = rr_typename(cr->query.type);
1531 const char *name_buf = cr->query.name_buf;
1532
1533 #ifdef USE_KEYRR
1534 passert(cr->keys_from_dns == NULL);
1535 #endif /* USE_KEYRR */
1536 passert(cr->gateways_from_dns == NULL);
1537 adns_in_flight--;
1538 if (buf.result == -1)
1539 {
1540 /* newer resolvers support statp->res_h_errno as well as h_errno.
1541 * That might be better, but older resolvers don't.
1542 * See resolver(3), if you have it.
1543 * The undocumented(!) h_errno values are defined in
1544 * /usr/include/netdb.h.
1545 */
1546 switch (buf.h_errno_val)
1547 {
1548 case NO_DATA:
1549 ugh = builddiag("no %s record for %s", typename, name_buf);
1550 break;
1551 case HOST_NOT_FOUND:
1552 ugh = builddiag("no host %s for %s record", name_buf, typename);
1553 break;
1554 default:
1555 ugh = builddiag("failure querying DNS for %s of %s: %s"
1556 , typename, name_buf, hstrerror(buf.h_errno_val));
1557 break;
1558 }
1559 }
1560 else if (buf.result > (int) sizeof(buf.ans))
1561 {
1562 ugh = builddiag("(INTERNAL ERROR) answer too long (%ld) for buffer"
1563 , (long)buf.result);
1564 }
1565 else
1566 {
1567 ugh = process_dns_answer(cr, buf.ans, buf.result);
1568 if (ugh != NULL)
1569 ugh = builddiag("failure processing %s record of DNS answer for %s: %s"
1570 , typename, name_buf, ugh);
1571 }
1572 DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS,
1573 DBG_log(BLANK_FORMAT);
1574 if (ugh == NULL)
1575 DBG_log("asynch DNS answer %lu for %s of %s"
1576 , cr->query.serial, typename, name_buf);
1577 else
1578 DBG_log("asynch DNS answer %lu %s", cr->query.serial, ugh);
1579 );
1580
1581 passert(GLOBALS_ARE_RESET());
1582 cr->cont_fn(cr, ugh);
1583 reset_globals();
1584 release_adns_continuation(cr);
1585
1586 /* shift out answer that we've consumed */
1587 buflen -= buf.len;
1588 memmove((unsigned char *)&buf, (unsigned char *)&buf + buf.len, buflen);
1589 }
1590 }