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