1 /* $OpenBSD: frontend.c,v 1.12 2019/02/10 14:10:22 florian Exp $ */ 2 3 /* 4 * Copyright (c) 2018 Florian Obser <florian@openbsd.org> 5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 6 * Copyright (c) 2004 Esben Norby <norby@openbsd.org> 7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 #include <sys/types.h> 23 #include <sys/queue.h> 24 #include <sys/socket.h> 25 #include <sys/syslog.h> 26 #include <sys/uio.h> 27 28 #include <netinet/in.h> 29 #include <net/if.h> 30 #include <net/route.h> 31 32 #include <errno.h> 33 #include <event.h> 34 #include <imsg.h> 35 #include <netdb.h> 36 #include <pwd.h> 37 #include <signal.h> 38 #include <stdint.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <time.h> 43 #include <unistd.h> 44 45 #include "libunbound/config.h" 46 #include "libunbound/sldns/pkthdr.h" 47 #include "libunbound/sldns/sbuffer.h" 48 #include "libunbound/sldns/str2wire.h" 49 #include "libunbound/sldns/wire2str.h" 50 51 #include "uw_log.h" 52 #include "unwind.h" 53 #include "frontend.h" 54 #include "control.h" 55 56 #define ROUTE_SOCKET_BUF_SIZE 16384 57 58 struct udp_ev { 59 struct event ev; 60 uint8_t query[65536]; 61 struct msghdr rcvmhdr; 62 struct iovec rcviov[1]; 63 struct sockaddr_storage from; 64 } udp4ev, udp6ev; 65 66 struct pending_query { 67 TAILQ_ENTRY(pending_query) entry; 68 struct sockaddr_storage from; 69 uint8_t *query; 70 ssize_t len; 71 uint64_t imsg_id; 72 int fd; 73 int bogus; 74 }; 75 76 TAILQ_HEAD(, pending_query) pending_queries; 77 78 __dead void frontend_shutdown(void); 79 void frontend_sig_handler(int, short, void *); 80 void frontend_startup(void); 81 void udp_receive(int, short, void *); 82 void send_answer(struct pending_query *, uint8_t *, 83 ssize_t); 84 void route_receive(int, short, void *); 85 void handle_route_message(struct rt_msghdr *, 86 struct sockaddr **); 87 void get_rtaddrs(int, struct sockaddr *, 88 struct sockaddr **); 89 void rtmget_default(void); 90 struct pending_query *find_pending_query(uint64_t); 91 void parse_dhcp_lease(int); 92 void parse_trust_anchor(struct trust_anchor_head *, int); 93 void send_trust_anchors(struct trust_anchor_head *); 94 void write_trust_anchors(struct trust_anchor_head *, int); 95 96 struct unwind_conf *frontend_conf; 97 struct imsgev *iev_main; 98 struct imsgev *iev_resolver; 99 struct imsgev *iev_captiveportal; 100 struct event ev_route; 101 int udp4sock = -1, udp6sock = -1, routesock = -1; 102 int ta_fd = -1; 103 104 static struct trust_anchor_head built_in_trust_anchors; 105 static struct trust_anchor_head trust_anchors, new_trust_anchors; 106 107 void 108 frontend_sig_handler(int sig, short event, void *bula) 109 { 110 /* 111 * Normal signal handler rules don't apply because libevent 112 * decouples for us. 113 */ 114 115 switch (sig) { 116 case SIGINT: 117 case SIGTERM: 118 frontend_shutdown(); 119 default: 120 fatalx("unexpected signal"); 121 } 122 } 123 124 void 125 frontend(int debug, int verbose) 126 { 127 struct event ev_sigint, ev_sigterm; 128 struct passwd *pw; 129 size_t rcvcmsglen, sndcmsgbuflen; 130 uint8_t *rcvcmsgbuf; 131 uint8_t *sndcmsgbuf = NULL; 132 133 frontend_conf = config_new_empty(); 134 control_state.fd = -1; 135 136 log_init(debug, LOG_DAEMON); 137 log_setverbose(verbose); 138 139 if ((pw = getpwnam(UNWIND_USER)) == NULL) 140 fatal("getpwnam"); 141 142 if (chroot(pw->pw_dir) == -1) 143 fatal("chroot"); 144 if (chdir("/") == -1) 145 fatal("chdir(\"/\")"); 146 147 unwind_process = PROC_FRONTEND; 148 setproctitle("%s", log_procnames[unwind_process]); 149 log_procinit(log_procnames[unwind_process]); 150 151 if (setgroups(1, &pw->pw_gid) || 152 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 153 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 154 fatal("can't drop privileges"); 155 156 if (pledge("stdio unix recvfd", NULL) == -1) 157 fatal("pledge"); 158 159 event_init(); 160 161 /* Setup signal handler. */ 162 signal_set(&ev_sigint, SIGINT, frontend_sig_handler, NULL); 163 signal_set(&ev_sigterm, SIGTERM, frontend_sig_handler, NULL); 164 signal_add(&ev_sigint, NULL); 165 signal_add(&ev_sigterm, NULL); 166 signal(SIGPIPE, SIG_IGN); 167 signal(SIGHUP, SIG_IGN); 168 169 /* Setup pipe and event handler to the parent process. */ 170 if ((iev_main = malloc(sizeof(struct imsgev))) == NULL) 171 fatal(NULL); 172 imsg_init(&iev_main->ibuf, 3); 173 iev_main->handler = frontend_dispatch_main; 174 iev_main->events = EV_READ; 175 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events, 176 iev_main->handler, iev_main); 177 event_add(&iev_main->ev, NULL); 178 179 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 180 CMSG_SPACE(sizeof(int)); 181 if((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) 182 fatal("malloc"); 183 184 udp4ev.rcviov[0].iov_base = (caddr_t)udp4ev.query; 185 udp4ev.rcviov[0].iov_len = sizeof(udp4ev.query); 186 udp4ev.rcvmhdr.msg_name = (caddr_t)&udp4ev.from; 187 udp4ev.rcvmhdr.msg_namelen = sizeof(udp4ev.from); 188 udp4ev.rcvmhdr.msg_iov = udp4ev.rcviov; 189 udp4ev.rcvmhdr.msg_iovlen = 1; 190 191 udp6ev.rcviov[0].iov_base = (caddr_t)udp6ev.query; 192 udp6ev.rcviov[0].iov_len = sizeof(udp6ev.query); 193 udp6ev.rcvmhdr.msg_name = (caddr_t)&udp6ev.from; 194 udp6ev.rcvmhdr.msg_namelen = sizeof(udp6ev.from); 195 udp6ev.rcvmhdr.msg_iov = udp6ev.rcviov; 196 udp6ev.rcvmhdr.msg_iovlen = 1; 197 198 sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 199 CMSG_SPACE(sizeof(int)); 200 if ((sndcmsgbuf = malloc(sndcmsgbuflen)) == NULL) 201 fatal("%s", __func__); 202 203 TAILQ_INIT(&pending_queries); 204 205 TAILQ_INIT(&built_in_trust_anchors); 206 TAILQ_INIT(&trust_anchors); 207 TAILQ_INIT(&new_trust_anchors); 208 209 add_new_ta(&built_in_trust_anchors, KSK2017); 210 211 event_dispatch(); 212 213 frontend_shutdown(); 214 } 215 216 __dead void 217 frontend_shutdown(void) 218 { 219 /* Close pipes. */ 220 msgbuf_write(&iev_resolver->ibuf.w); 221 msgbuf_clear(&iev_resolver->ibuf.w); 222 close(iev_resolver->ibuf.fd); 223 msgbuf_write(&iev_captiveportal->ibuf.w); 224 msgbuf_clear(&iev_captiveportal->ibuf.w); 225 close(iev_captiveportal->ibuf.fd); 226 msgbuf_write(&iev_main->ibuf.w); 227 msgbuf_clear(&iev_main->ibuf.w); 228 close(iev_main->ibuf.fd); 229 230 config_clear(frontend_conf); 231 232 free(iev_resolver); 233 free(iev_captiveportal); 234 free(iev_main); 235 236 log_info("frontend exiting"); 237 exit(0); 238 } 239 240 int 241 frontend_imsg_compose_main(int type, pid_t pid, void *data, uint16_t datalen) 242 { 243 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, 244 datalen)); 245 } 246 247 int 248 frontend_imsg_compose_resolver(int type, pid_t pid, void *data, uint16_t datalen) 249 { 250 return (imsg_compose_event(iev_resolver, type, 0, pid, -1, data, 251 datalen)); 252 } 253 254 int 255 frontend_imsg_compose_captiveportal(int type, pid_t pid, void *data, uint16_t datalen) 256 { 257 return (imsg_compose_event(iev_captiveportal, type, 0, pid, -1, data, 258 datalen)); 259 } 260 261 void 262 frontend_dispatch_main(int fd, short event, void *bula) 263 { 264 static struct unwind_conf *nconf; 265 struct unwind_forwarder *unwind_forwarder; 266 struct imsg imsg; 267 struct imsgev *iev = bula; 268 struct imsgbuf *ibuf = &iev->ibuf; 269 int n, shut = 0; 270 271 if (event & EV_READ) { 272 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 273 fatal("imsg_read error"); 274 if (n == 0) /* Connection closed. */ 275 shut = 1; 276 } 277 if (event & EV_WRITE) { 278 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 279 fatal("msgbuf_write"); 280 if (n == 0) /* Connection closed. */ 281 shut = 1; 282 } 283 284 for (;;) { 285 if ((n = imsg_get(ibuf, &imsg)) == -1) 286 fatal("%s: imsg_get error", __func__); 287 if (n == 0) /* No more messages. */ 288 break; 289 290 switch (imsg.hdr.type) { 291 case IMSG_SOCKET_IPC_RESOLVER: 292 /* 293 * Setup pipe and event handler to the resolver 294 * process. 295 */ 296 if (iev_resolver) { 297 fatalx("%s: received unexpected imsg fd " 298 "to frontend", __func__); 299 break; 300 } 301 if ((fd = imsg.fd) == -1) { 302 fatalx("%s: expected to receive imsg fd to " 303 "frontend but didn't receive any", 304 __func__); 305 break; 306 } 307 308 iev_resolver = malloc(sizeof(struct imsgev)); 309 if (iev_resolver == NULL) 310 fatal(NULL); 311 312 imsg_init(&iev_resolver->ibuf, fd); 313 iev_resolver->handler = frontend_dispatch_resolver; 314 iev_resolver->events = EV_READ; 315 316 event_set(&iev_resolver->ev, iev_resolver->ibuf.fd, 317 iev_resolver->events, iev_resolver->handler, iev_resolver); 318 event_add(&iev_resolver->ev, NULL); 319 break; 320 case IMSG_SOCKET_IPC_CAPTIVEPORTAL: 321 /* 322 * Setup pipe and event handler to the captiveportal 323 * process. 324 */ 325 if (iev_captiveportal) { 326 fatalx("%s: received unexpected imsg fd " 327 "to frontend", __func__); 328 break; 329 } 330 if ((fd = imsg.fd) == -1) { 331 fatalx("%s: expected to receive imsg fd to " 332 "frontend but didn't receive any", 333 __func__); 334 break; 335 } 336 337 iev_captiveportal = malloc(sizeof(struct imsgev)); 338 if (iev_captiveportal == NULL) 339 fatal(NULL); 340 341 imsg_init(&iev_captiveportal->ibuf, fd); 342 iev_captiveportal->handler = frontend_dispatch_captiveportal; 343 iev_captiveportal->events = EV_READ; 344 345 event_set(&iev_captiveportal->ev, iev_captiveportal->ibuf.fd, 346 iev_captiveportal->events, iev_captiveportal->handler, iev_captiveportal); 347 event_add(&iev_captiveportal->ev, NULL); 348 break; 349 case IMSG_RECONF_CONF: 350 if (imsg.hdr.len != IMSG_HEADER_SIZE + 351 sizeof(struct unwind_conf)) 352 fatalx("%s: IMSG_RECONF_CONF wrong length: %d", 353 __func__, imsg.hdr.len); 354 if ((nconf = malloc(sizeof(struct unwind_conf))) == 355 NULL) 356 fatal(NULL); 357 memcpy(nconf, imsg.data, sizeof(struct unwind_conf)); 358 nconf->captive_portal_host = NULL; 359 nconf->captive_portal_path = NULL; 360 nconf->captive_portal_expected_response = NULL; 361 SIMPLEQ_INIT(&nconf->unwind_forwarder_list); 362 SIMPLEQ_INIT(&nconf->unwind_dot_forwarder_list); 363 break; 364 case IMSG_RECONF_CAPTIVE_PORTAL_HOST: 365 /* make sure this is a string */ 366 ((char *)imsg.data)[imsg.hdr.len - IMSG_HEADER_SIZE - 1] 367 = '\0'; 368 if ((nconf->captive_portal_host = strdup(imsg.data)) == 369 NULL) 370 fatal("%s: strdup", __func__); 371 break; 372 case IMSG_RECONF_CAPTIVE_PORTAL_PATH: 373 /* make sure this is a string */ 374 ((char *)imsg.data)[imsg.hdr.len - IMSG_HEADER_SIZE - 1] 375 = '\0'; 376 if ((nconf->captive_portal_path = strdup(imsg.data)) == 377 NULL) 378 fatal("%s: strdup", __func__); 379 break; 380 case IMSG_RECONF_CAPTIVE_PORTAL_EXPECTED_RESPONSE: 381 /* make sure this is a string */ 382 ((char *)imsg.data)[imsg.hdr.len - IMSG_HEADER_SIZE - 1] 383 = '\0'; 384 if ((nconf->captive_portal_expected_response = 385 strdup(imsg.data)) == NULL) 386 fatal("%s: strdup", __func__); 387 break; 388 case IMSG_RECONF_FORWARDER: 389 if (imsg.hdr.len != IMSG_HEADER_SIZE + 390 sizeof(struct unwind_forwarder)) 391 fatalx("%s: IMSG_RECONF_FORWARDER wrong length:" 392 " %d", __func__, imsg.hdr.len); 393 if ((unwind_forwarder = malloc(sizeof(struct 394 unwind_forwarder))) == NULL) 395 fatal(NULL); 396 memcpy(unwind_forwarder, imsg.data, sizeof(struct 397 unwind_forwarder)); 398 SIMPLEQ_INSERT_TAIL(&nconf->unwind_forwarder_list, 399 unwind_forwarder, entry); 400 break; 401 case IMSG_RECONF_DOT_FORWARDER: 402 if (imsg.hdr.len != IMSG_HEADER_SIZE + 403 sizeof(struct unwind_forwarder)) 404 fatalx("%s: IMSG_RECONF_DOT_FORWARDER wrong " 405 "length: %d", __func__, imsg.hdr.len); 406 if ((unwind_forwarder = malloc(sizeof(struct 407 unwind_forwarder))) == NULL) 408 fatal(NULL); 409 memcpy(unwind_forwarder, imsg.data, sizeof(struct 410 unwind_forwarder)); 411 SIMPLEQ_INSERT_TAIL(&nconf->unwind_dot_forwarder_list, 412 unwind_forwarder, entry); 413 break; 414 case IMSG_RECONF_END: 415 merge_config(frontend_conf, nconf); 416 nconf = NULL; 417 break; 418 case IMSG_UDP6SOCK: 419 if (udp6sock != -1) 420 fatalx("%s: received unexpected udp6sock", 421 __func__); 422 if ((udp6sock = imsg.fd) == -1) 423 fatalx("%s: expected to receive imsg " 424 "UDP6 fd but didn't receive any", 425 __func__); 426 event_set(&udp6ev.ev, udp6sock, EV_READ | EV_PERSIST, 427 udp_receive, &udp6ev); 428 event_add(&udp6ev.ev, NULL); 429 break; 430 case IMSG_UDP4SOCK: 431 if (udp4sock != -1) 432 fatalx("%s: received unexpected udp4sock", 433 __func__); 434 if ((udp4sock = imsg.fd) == -1) 435 fatalx("%s: expected to receive imsg " 436 "UDP4 fd but didn't receive any", 437 __func__); 438 event_set(&udp4ev.ev, udp4sock, EV_READ | EV_PERSIST, 439 udp_receive, &udp4ev); 440 event_add(&udp4ev.ev, NULL); 441 break; 442 case IMSG_ROUTESOCK: 443 if (routesock != -1) 444 fatalx("%s: received unexpected routesock", 445 __func__); 446 if ((fd = imsg.fd) == -1) 447 fatalx("%s: expected to receive imsg " 448 "routesocket fd but didn't receive any", 449 __func__); 450 routesock = fd; 451 event_set(&ev_route, fd, EV_READ | EV_PERSIST, 452 route_receive, NULL); 453 break; 454 case IMSG_STARTUP: 455 frontend_startup(); 456 break; 457 case IMSG_CONTROLFD: 458 if (control_state.fd != -1) 459 fatalx("%s: received unexpected controlsock", 460 __func__); 461 if ((fd = imsg.fd) == -1) 462 fatalx("%s: expected to receive imsg " 463 "control fd but didn't receive any", 464 __func__); 465 control_state.fd = fd; 466 /* Listen on control socket. */ 467 TAILQ_INIT(&ctl_conns); 468 control_listen(); 469 break; 470 case IMSG_LEASEFD: 471 if ((fd = imsg.fd) == -1) 472 fatalx("%s: expected to receive imsg " 473 "dhcp lease fd but didn't receive any", 474 __func__); 475 parse_dhcp_lease(fd); 476 break; 477 case IMSG_TAFD: 478 if ((ta_fd = imsg.fd) != -1) 479 parse_trust_anchor(&trust_anchors, ta_fd); 480 if (!TAILQ_EMPTY(&trust_anchors)) 481 send_trust_anchors(&trust_anchors); 482 else 483 send_trust_anchors(&built_in_trust_anchors); 484 break; 485 default: 486 log_debug("%s: error handling imsg %d", __func__, 487 imsg.hdr.type); 488 break; 489 } 490 imsg_free(&imsg); 491 } 492 if (!shut) 493 imsg_event_add(iev); 494 else { 495 /* This pipe is dead. Remove its event handler. */ 496 event_del(&iev->ev); 497 event_loopexit(NULL); 498 } 499 } 500 501 void 502 frontend_dispatch_resolver(int fd, short event, void *bula) 503 { 504 static struct pending_query *pq; 505 struct imsgev *iev = bula; 506 struct imsgbuf *ibuf = &iev->ibuf; 507 struct imsg imsg; 508 struct query_imsg *query_imsg; 509 int n, shut = 0, chg; 510 char *ta; 511 512 if (event & EV_READ) { 513 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 514 fatal("imsg_read error"); 515 if (n == 0) /* Connection closed. */ 516 shut = 1; 517 } 518 if (event & EV_WRITE) { 519 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 520 fatal("msgbuf_write"); 521 if (n == 0) /* Connection closed. */ 522 shut = 1; 523 } 524 525 for (;;) { 526 if ((n = imsg_get(ibuf, &imsg)) == -1) 527 fatal("%s: imsg_get error", __func__); 528 if (n == 0) /* No more messages. */ 529 break; 530 531 switch (imsg.hdr.type) { 532 case IMSG_ANSWER_HEADER: 533 if (imsg.hdr.len != IMSG_HEADER_SIZE + 534 sizeof(*query_imsg)) 535 fatalx("%s: IMSG_ANSWER_HEADER wrong length: " 536 "%d", __func__, imsg.hdr.len); 537 query_imsg = (struct query_imsg *)imsg.data; 538 if ((pq = find_pending_query(query_imsg->id)) == 539 NULL) { 540 log_warnx("cannot find pending query %llu", 541 query_imsg->id); 542 break; 543 } 544 if (query_imsg->err) { 545 send_answer(pq, NULL, 0); 546 pq = NULL; 547 break; 548 } 549 pq->bogus = query_imsg->bogus; 550 break; 551 case IMSG_ANSWER: 552 if (pq == NULL) 553 fatalx("IMSG_ANSWER without HEADER"); 554 send_answer(pq, imsg.data, imsg.hdr.len - 555 IMSG_HEADER_SIZE); 556 break; 557 case IMSG_RESOLVER_DOWN: 558 log_debug("%s: IMSG_RESOLVER_DOWN", __func__); 559 if (udp4sock != -1) { 560 event_del(&udp4ev.ev); 561 close(udp4sock); 562 udp4sock = -1; 563 } 564 if (udp6sock != -1) { 565 event_del(&udp6ev.ev); 566 close(udp6sock); 567 udp6sock = -1; 568 } 569 break; 570 case IMSG_RESOLVER_UP: 571 log_debug("%s: IMSG_RESOLVER_UP", __func__); 572 frontend_imsg_compose_main(IMSG_OPEN_PORTS, 0, NULL, 0); 573 break; 574 case IMSG_CTL_RESOLVER_INFO: 575 case IMSG_CTL_CAPTIVEPORTAL_INFO: 576 case IMSG_CTL_RESOLVER_WHY_BOGUS: 577 case IMSG_CTL_RESOLVER_HISTOGRAM: 578 case IMSG_CTL_END: 579 control_imsg_relay(&imsg); 580 break; 581 case IMSG_NEW_TA: 582 /* make sure this is a string */ 583 ((char *)imsg.data)[imsg.hdr.len - IMSG_HEADER_SIZE - 1] 584 = '\0'; 585 ta = imsg.data; 586 add_new_ta(&new_trust_anchors, ta); 587 break; 588 case IMSG_NEW_TAS_ABORT: 589 log_debug("%s: IMSG_NEW_TAS_ABORT", __func__); 590 free_tas(&new_trust_anchors); 591 break; 592 case IMSG_NEW_TAS_DONE: 593 chg = merge_tas(&new_trust_anchors, &trust_anchors); 594 log_debug("%s: IMSG_NEW_TAS_DONE: change: %d", 595 __func__, chg); 596 if (chg) { 597 send_trust_anchors(&trust_anchors); 598 } 599 /* 600 * always write trust anchors, the modify date on 601 * the file is an indication when we made progress 602 */ 603 if (ta_fd != -1) 604 write_trust_anchors(&trust_anchors, ta_fd); 605 break; 606 default: 607 log_debug("%s: error handling imsg %d", __func__, 608 imsg.hdr.type); 609 break; 610 } 611 imsg_free(&imsg); 612 } 613 if (!shut) 614 imsg_event_add(iev); 615 else { 616 /* This pipe is dead. Remove its event handler. */ 617 event_del(&iev->ev); 618 event_loopexit(NULL); 619 } 620 } 621 622 void 623 frontend_dispatch_captiveportal(int fd, short event, void *bula) 624 { 625 struct imsgev *iev = bula; 626 struct imsgbuf *ibuf = &iev->ibuf; 627 struct imsg imsg; 628 int n, shut = 0; 629 630 if (event & EV_READ) { 631 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 632 fatal("imsg_read error"); 633 if (n == 0) /* Connection closed. */ 634 shut = 1; 635 } 636 if (event & EV_WRITE) { 637 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 638 fatal("msgbuf_write"); 639 if (n == 0) /* Connection closed. */ 640 shut = 1; 641 } 642 643 for (;;) { 644 if ((n = imsg_get(ibuf, &imsg)) == -1) 645 fatal("%s: imsg_get error", __func__); 646 if (n == 0) /* No more messages. */ 647 break; 648 649 switch (imsg.hdr.type) { 650 default: 651 log_debug("%s: error handling imsg %d", __func__, 652 imsg.hdr.type); 653 break; 654 } 655 imsg_free(&imsg); 656 } 657 if (!shut) 658 imsg_event_add(iev); 659 else { 660 /* This pipe is dead. Remove its event handler. */ 661 event_del(&iev->ev); 662 event_loopexit(NULL); 663 } 664 } 665 666 void 667 frontend_startup(void) 668 { 669 if (!event_initialized(&ev_route)) 670 fatalx("%s: did not receive a route socket from the main " 671 "process", __func__); 672 673 event_add(&ev_route, NULL); 674 675 frontend_imsg_compose_main(IMSG_STARTUP_DONE, 0, NULL, 0); 676 rtmget_default(); 677 } 678 679 void 680 udp_receive(int fd, short events, void *arg) 681 { 682 struct udp_ev *udpev = (struct udp_ev *)arg; 683 struct pending_query *pq; 684 struct query_imsg *query_imsg; 685 ssize_t len, rem_len, buf_len; 686 uint16_t qdcount, ancount, nscount, arcount, t, c; 687 uint8_t *queryp; 688 char *str_from, *str, buf[1024], *bufp; 689 690 if ((len = recvmsg(fd, &udpev->rcvmhdr, 0)) < 0) { 691 log_warn("recvmsg"); 692 return; 693 } 694 695 bufp = buf; 696 buf_len = sizeof(buf); 697 698 str_from = ip_port((struct sockaddr *)&udpev->from); 699 700 if (len < LDNS_HEADER_SIZE) { 701 log_warnx("bad query: too short, from: %s", str_from); 702 return; 703 } 704 705 qdcount = LDNS_QDCOUNT(udpev->query); 706 ancount = LDNS_ANCOUNT(udpev->query); 707 nscount = LDNS_NSCOUNT(udpev->query); 708 arcount = LDNS_ARCOUNT(udpev->query); 709 710 if (qdcount != 1 && ancount != 0 && nscount != 0 && arcount != 0) { 711 log_warnx("invalid query from %s, qdcount: %d, ancount: %d " 712 "nscount: %d, arcount: %d", str_from, qdcount, ancount, 713 nscount, arcount); 714 return; 715 } 716 717 log_debug("query from %s", str_from); 718 if ((str = sldns_wire2str_pkt(udpev->query, len)) != NULL) { 719 log_debug("%s", str); 720 free(str); 721 } 722 723 queryp = udpev->query; 724 rem_len = len; 725 726 queryp += LDNS_HEADER_SIZE; 727 rem_len -= LDNS_HEADER_SIZE; 728 729 sldns_wire2str_dname_scan(&queryp, &rem_len, &bufp, &buf_len, 730 udpev->query, len); 731 732 if (rem_len < 4) { 733 log_warnx("malformed query"); 734 return; 735 } 736 737 t = sldns_read_uint16(queryp); 738 c = sldns_read_uint16(queryp+2); 739 queryp += 4; 740 rem_len -= 4; 741 742 if ((pq = malloc(sizeof(*pq))) == NULL) { 743 log_warn(NULL); 744 return; 745 } 746 747 if ((pq->query = malloc(len)) == NULL) { 748 log_warn(NULL); 749 free(pq); 750 return; 751 } 752 753 do { 754 arc4random_buf(&pq->imsg_id, sizeof(pq->imsg_id)); 755 } while(find_pending_query(pq->imsg_id) != NULL); 756 757 memcpy(pq->query, udpev->query, len); 758 pq->len = len; 759 pq->from = udpev->from; 760 pq->fd = fd; 761 762 if ((query_imsg = calloc(1, sizeof(*query_imsg))) == NULL) { 763 log_warn(NULL); 764 return; 765 } 766 767 if (strlcpy(query_imsg->qname, buf, sizeof(query_imsg->qname)) >= 768 sizeof(buf)) { 769 log_warnx("qname too long"); 770 free(query_imsg); 771 /* XXX SERVFAIL */ 772 free(pq->query); 773 free(pq); 774 return; 775 } 776 query_imsg->id = pq->imsg_id; 777 query_imsg->t = t; 778 query_imsg->c = c; 779 780 if (frontend_imsg_compose_resolver(IMSG_QUERY, 0, query_imsg, 781 sizeof(*query_imsg)) != -1) { 782 TAILQ_INSERT_TAIL(&pending_queries, pq, entry); 783 } else { 784 free(query_imsg); 785 /* XXX SERVFAIL */ 786 free(pq->query); 787 free(pq); 788 } 789 790 } 791 792 void 793 send_answer(struct pending_query *pq, uint8_t *answer, ssize_t len) 794 { 795 log_debug("result for %s", 796 ip_port((struct sockaddr*)&pq->from)); 797 798 if (answer == NULL) { 799 answer = pq->query; 800 len = pq->len; 801 802 LDNS_QR_SET(answer); 803 LDNS_RA_SET(answer); 804 LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL); 805 } else { 806 if (pq->bogus) { 807 if(LDNS_CD_WIRE(pq->query)) { 808 LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query)); 809 LDNS_CD_SET(answer); 810 } else { 811 answer = pq->query; 812 len = pq->len; 813 814 LDNS_QR_SET(answer); 815 LDNS_RA_SET(answer); 816 LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL); 817 } 818 } else { 819 LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query)); 820 } 821 } 822 823 if(sendto(pq->fd, answer, len, 0, (struct sockaddr *) 824 &pq->from, pq->from.ss_len) == -1) 825 log_warn("sendto"); 826 827 TAILQ_REMOVE(&pending_queries, pq, entry); 828 free(pq->query); 829 free(pq); 830 } 831 832 char* 833 ip_port(struct sockaddr *sa) 834 { 835 static char hbuf[NI_MAXHOST], buf[NI_MAXHOST]; 836 837 if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0, 838 NI_NUMERICHOST) != 0) { 839 snprintf(buf, sizeof(buf), "%s", "(unknown)"); 840 return buf; 841 } 842 843 if (sa->sa_family == AF_INET6) 844 snprintf(buf, sizeof(buf), "[%s]:%d", hbuf, ntohs( 845 ((struct sockaddr_in6 *)sa)->sin6_port)); 846 if (sa->sa_family == AF_INET) 847 snprintf(buf, sizeof(buf), "[%s]:%d", hbuf, ntohs( 848 ((struct sockaddr_in *)sa)->sin_port)); 849 850 return buf; 851 } 852 853 struct pending_query* 854 find_pending_query(uint64_t id) 855 { 856 struct pending_query *pq; 857 858 TAILQ_FOREACH(pq, &pending_queries, entry) 859 if (pq->imsg_id == id) 860 return pq; 861 return NULL; 862 } 863 864 void 865 route_receive(int fd, short events, void *arg) 866 { 867 static uint8_t *buf; 868 869 struct rt_msghdr *rtm; 870 struct sockaddr *sa, *rti_info[RTAX_MAX]; 871 ssize_t n; 872 873 if (buf == NULL) { 874 buf = malloc(ROUTE_SOCKET_BUF_SIZE); 875 if (buf == NULL) 876 fatal("malloc"); 877 } 878 rtm = (struct rt_msghdr *)buf; 879 if ((n = read(fd, buf, ROUTE_SOCKET_BUF_SIZE)) == -1) { 880 if (errno == EAGAIN || errno == EINTR) 881 return; 882 log_warn("dispatch_rtmsg: read error"); 883 return; 884 } 885 886 if (n == 0) 887 fatal("routing socket closed"); 888 889 if (n < (ssize_t)sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen) { 890 log_warnx("partial rtm of %zd in buffer", n); 891 return; 892 } 893 894 if (rtm->rtm_version != RTM_VERSION) 895 return; 896 897 sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen); 898 get_rtaddrs(rtm->rtm_addrs, sa, rti_info); 899 900 handle_route_message(rtm, rti_info); 901 } 902 903 #define ROUNDUP(a) \ 904 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 905 906 void 907 get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) 908 { 909 int i; 910 911 for (i = 0; i < RTAX_MAX; i++) { 912 if (addrs & (1 << i)) { 913 rti_info[i] = sa; 914 sa = (struct sockaddr *)((char *)(sa) + 915 ROUNDUP(sa->sa_len)); 916 } else 917 rti_info[i] = NULL; 918 } 919 } 920 921 void 922 handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info) 923 { 924 char buf[IF_NAMESIZE], *bufp; 925 926 switch (rtm->rtm_type) { 927 case RTM_GET: 928 if (rtm->rtm_errno != 0) 929 break; 930 if (!(rtm->rtm_flags & RTF_UP)) 931 break; 932 if (!(rtm->rtm_addrs & RTA_DST)) 933 break; 934 if (rti_info[RTAX_DST]->sa_family != AF_INET) 935 break; 936 if (((struct sockaddr_in *)rti_info[RTAX_DST])->sin_addr. 937 s_addr != INADDR_ANY) 938 break; 939 if (!(rtm->rtm_addrs & RTA_NETMASK)) 940 break; 941 if (rti_info[RTAX_NETMASK]->sa_family != AF_INET) 942 break; 943 if (((struct sockaddr_in *)rti_info[RTAX_NETMASK])->sin_addr. 944 s_addr != INADDR_ANY) 945 break; 946 947 frontend_imsg_compose_main(IMSG_OPEN_DHCP_LEASE, 0, 948 &rtm->rtm_index, sizeof(rtm->rtm_index)); 949 950 bufp = if_indextoname(rtm->rtm_index, buf); 951 if (bufp) 952 log_debug("default route is on %s", buf); 953 954 break; 955 default: 956 break; 957 } 958 959 } 960 961 void 962 rtmget_default(void) 963 { 964 static int rtm_seq; 965 struct rt_msghdr rtm; 966 struct sockaddr_in sin; 967 struct iovec iov[5]; 968 long pad = 0; 969 int iovcnt = 0, padlen; 970 971 memset(&sin, 0, sizeof(sin)); 972 sin.sin_family = AF_INET; 973 sin.sin_len = sizeof(sin); 974 975 memset(&rtm, 0, sizeof(rtm)); 976 977 rtm.rtm_version = RTM_VERSION; 978 rtm.rtm_type = RTM_GET; 979 rtm.rtm_msglen = sizeof(rtm); 980 rtm.rtm_tableid = 0; /* XXX imsg->rdomain; */ 981 rtm.rtm_seq = ++rtm_seq; 982 rtm.rtm_addrs = RTA_DST | RTA_NETMASK; 983 984 iov[iovcnt].iov_base = &rtm; 985 iov[iovcnt++].iov_len = sizeof(rtm); 986 987 /* dst */ 988 iov[iovcnt].iov_base = &sin; 989 iov[iovcnt++].iov_len = sizeof(sin); 990 rtm.rtm_msglen += sizeof(sin); 991 padlen = ROUNDUP(sizeof(sin)) - sizeof(sin); 992 if (padlen > 0) { 993 iov[iovcnt].iov_base = &pad; 994 iov[iovcnt++].iov_len = padlen; 995 rtm.rtm_msglen += padlen; 996 } 997 998 /* mask */ 999 iov[iovcnt].iov_base = &sin; 1000 iov[iovcnt++].iov_len = sizeof(sin); 1001 rtm.rtm_msglen += sizeof(sin); 1002 padlen = ROUNDUP(sizeof(sin)) - sizeof(sin); 1003 if (padlen > 0) { 1004 iov[iovcnt].iov_base = &pad; 1005 iov[iovcnt++].iov_len = padlen; 1006 rtm.rtm_msglen += padlen; 1007 } 1008 1009 if (writev(routesock, iov, iovcnt) == -1) 1010 log_warn("failed to send route message"); 1011 } 1012 1013 void 1014 parse_dhcp_lease(int fd) 1015 { 1016 FILE *f; 1017 char *line = NULL, *cur_ns = NULL, *ns = NULL; 1018 size_t linesize = 0; 1019 ssize_t linelen; 1020 time_t epoch = 0, lease_time = 0, now; 1021 char **tok, *toks[4], *p; 1022 1023 if((f = fdopen(fd, "r")) == NULL) { 1024 log_warn("cannot read dhcp lease"); 1025 close(fd); 1026 return; 1027 } 1028 1029 now = time(NULL); 1030 1031 while ((linelen = getline(&line, &linesize, f)) != -1) { 1032 for (tok = toks; tok < &toks[3] && (*tok = strsep(&line, " \t")) 1033 != NULL;) { 1034 if (**tok != '\0') 1035 tok++; 1036 } 1037 *tok = NULL; 1038 if (strcmp(toks[0], "option") == 0) { 1039 if (strcmp(toks[1], "domain-name-servers") == 0) { 1040 if((p = strchr(toks[2], ';')) != NULL) { 1041 *p='\0'; 1042 cur_ns = strdup(toks[2]); 1043 } 1044 } 1045 if (strcmp(toks[1], "dhcp-lease-time") == 0) { 1046 if((p = strchr(toks[2], ';')) != NULL) { 1047 *p='\0'; 1048 lease_time = strtonum(toks[2], 0, 1049 INT64_MAX, NULL); 1050 } 1051 } 1052 } else if (strcmp(toks[0], "epoch") == 0) { 1053 if((p = strchr(toks[1], ';')) != NULL) { 1054 *p='\0'; 1055 epoch = strtonum(toks[1], 0, 1056 INT64_MAX, NULL); 1057 } 1058 } 1059 else if (*toks[0] == '}') { 1060 if (epoch + lease_time > now ) { 1061 free(ns); 1062 ns = cur_ns; 1063 } else /* expired lease */ 1064 free(cur_ns); 1065 } 1066 } 1067 free(line); 1068 1069 if (ferror(f)) 1070 log_warn("getline"); 1071 fclose(f); 1072 1073 if (ns != NULL) { 1074 log_debug("%s: ns: %s", __func__, ns); 1075 frontend_imsg_compose_resolver(IMSG_FORWARDER, 0, ns, 1076 strlen(ns) + 1); 1077 } 1078 } 1079 1080 1081 void 1082 add_new_ta(struct trust_anchor_head *tah, char *val) 1083 { 1084 1085 struct trust_anchor *ta, *i; 1086 int cmp; 1087 1088 if ((ta = malloc(sizeof(*ta))) == NULL) 1089 fatal("%s", __func__); 1090 if ((ta->ta = strdup(val)) == NULL) 1091 fatal("%s", __func__); 1092 1093 /* keep the list sorted to prevent churn if the order changes in DNS */ 1094 TAILQ_FOREACH(i, tah, entry) { 1095 cmp = strcmp(i->ta, ta->ta); 1096 if ( cmp == 0) { 1097 /* duplicate */ 1098 free(ta->ta); 1099 free(ta); 1100 return; 1101 } else if (cmp > 0) { 1102 TAILQ_INSERT_BEFORE(i, ta, entry); 1103 return; 1104 } 1105 } 1106 TAILQ_INSERT_TAIL(tah, ta, entry); 1107 } 1108 1109 void 1110 free_tas(struct trust_anchor_head *tah) 1111 { 1112 struct trust_anchor *ta; 1113 1114 while ((ta = TAILQ_FIRST(tah))) { 1115 TAILQ_REMOVE(tah, ta, entry); 1116 free(ta->ta); 1117 free(ta); 1118 } 1119 } 1120 1121 int 1122 merge_tas(struct trust_anchor_head *newh, struct trust_anchor_head *oldh) 1123 { 1124 struct trust_anchor *i, *j; 1125 int chg = 0; 1126 1127 j = TAILQ_FIRST(oldh); 1128 1129 TAILQ_FOREACH(i, newh, entry) { 1130 if (j == NULL || strcmp(i->ta, j->ta) != 0) { 1131 chg = 1; 1132 break; 1133 } 1134 j = TAILQ_NEXT(j, entry); 1135 } 1136 if (j!= NULL) 1137 chg = 1; 1138 1139 if (chg) { 1140 free_tas(oldh); 1141 while((i = TAILQ_FIRST(newh)) != NULL) { 1142 TAILQ_REMOVE(newh, i, entry); 1143 TAILQ_INSERT_TAIL(oldh, i, entry); 1144 } 1145 } else { 1146 free_tas(newh); 1147 } 1148 return (chg); 1149 } 1150 1151 void 1152 parse_trust_anchor(struct trust_anchor_head *tah, int fd) 1153 { 1154 size_t len, dname_len; 1155 ssize_t n, sz; 1156 uint8_t rr[LDNS_RR_BUF_SIZE]; 1157 char *str, *p, buf[512], *line; 1158 1159 sz = 0; 1160 str = NULL; 1161 1162 while ((n = read(fd, buf, sizeof(buf))) > 0) { 1163 p = recallocarray(str, sz, sz + n, 1); 1164 if (p == NULL) { 1165 log_warn("%s", __func__); 1166 goto out; 1167 } 1168 str = p; 1169 memcpy(str + sz, buf, n); 1170 sz += n; 1171 } 1172 1173 if (n == -1) { 1174 log_warn("%s", __func__); 1175 goto out; 1176 } 1177 1178 /* make it a string */ 1179 p = recallocarray(str, sz, sz + 1, 1); 1180 if (p == NULL) { 1181 log_warn("%s", __func__); 1182 goto out; 1183 } 1184 str = p; 1185 sz++; 1186 1187 len = sizeof(rr); 1188 1189 while ((line = strsep(&str, "\n")) != NULL) { 1190 if (sldns_str2wire_rr_buf(line, rr, &len, &dname_len, 1191 172800, NULL, 0, NULL, 0) != 0) 1192 continue; 1193 if (sldns_wirerr_get_type(rr, len, dname_len) == 1194 LDNS_RR_TYPE_DNSKEY) 1195 add_new_ta(tah, line); 1196 } 1197 1198 out: 1199 free(str); 1200 return; 1201 } 1202 1203 void 1204 send_trust_anchors(struct trust_anchor_head *tah) 1205 { 1206 struct trust_anchor *ta; 1207 1208 TAILQ_FOREACH(ta, tah, entry) 1209 frontend_imsg_compose_resolver(IMSG_NEW_TA, 0, ta->ta, 1210 strlen(ta->ta) + 1); 1211 frontend_imsg_compose_resolver(IMSG_NEW_TAS_DONE, 0, NULL, 0); 1212 } 1213 1214 void 1215 write_trust_anchors(struct trust_anchor_head *tah, int fd) 1216 { 1217 struct trust_anchor *ta; 1218 size_t len = 0; 1219 ssize_t n; 1220 char *str; 1221 1222 log_debug("%s", __func__); 1223 1224 if (lseek(fd, 0, SEEK_SET) == -1) { 1225 log_warn("%s", __func__); 1226 goto out; 1227 } 1228 1229 TAILQ_FOREACH(ta, tah, entry) { 1230 if ((n = asprintf(&str, "%s\n", ta->ta)) == -1) { 1231 log_warn("%s", __func__); 1232 len = 0; 1233 goto out; 1234 } 1235 len += n; 1236 if (write(fd, str, n) != n) { 1237 log_warn("%s", __func__); 1238 free(str); 1239 len = 0; 1240 goto out; 1241 } 1242 free(str); 1243 } 1244 out: 1245 ftruncate(fd, len); 1246 fsync(fd); 1247 } 1248