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