1 /* $OpenBSD: relayd.c,v 1.108 2012/05/08 15:10:15 benno Exp $ */ 2 3 /* 4 * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org> 5 * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/types.h> 21 #include <sys/queue.h> 22 #include <sys/socket.h> 23 #include <sys/wait.h> 24 #include <sys/resource.h> 25 #include <sys/hash.h> 26 27 #include <net/if.h> 28 #include <netinet/in.h> 29 #include <arpa/inet.h> 30 31 #include <string.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <fcntl.h> 35 #include <getopt.h> 36 #include <err.h> 37 #include <errno.h> 38 #include <event.h> 39 #include <unistd.h> 40 #include <ctype.h> 41 #include <pwd.h> 42 #include <sha1.h> 43 #include <md5.h> 44 45 #include <openssl/ssl.h> 46 47 #include "relayd.h" 48 49 __dead void usage(void); 50 51 int parent_configure(struct relayd *); 52 void parent_configure_done(struct relayd *); 53 void parent_reload(struct relayd *, u_int, const char *); 54 void parent_sig_handler(int, short, void *); 55 void parent_shutdown(struct relayd *); 56 int parent_dispatch_pfe(int, struct privsep_proc *, struct imsg *); 57 int parent_dispatch_hce(int, struct privsep_proc *, struct imsg *); 58 int parent_dispatch_relay(int, struct privsep_proc *, 59 struct imsg *); 60 int bindany(struct ctl_bindany *); 61 62 struct relayd *relayd_env; 63 64 static struct privsep_proc procs[] = { 65 { "pfe", PROC_PFE, parent_dispatch_pfe, pfe }, 66 { "hce", PROC_HCE, parent_dispatch_hce, hce }, 67 { "relay", PROC_RELAY, parent_dispatch_relay, relay } 68 }; 69 70 void 71 parent_sig_handler(int sig, short event, void *arg) 72 { 73 struct privsep *ps = arg; 74 int die = 0, status, fail, id; 75 pid_t pid; 76 char *cause; 77 78 switch (sig) { 79 case SIGTERM: 80 case SIGINT: 81 die = 1; 82 /* FALLTHROUGH */ 83 case SIGCHLD: 84 do { 85 pid = waitpid(WAIT_ANY, &status, WNOHANG); 86 if (pid <= 0) 87 continue; 88 89 fail = 0; 90 if (WIFSIGNALED(status)) { 91 fail = 1; 92 asprintf(&cause, "terminated; signal %d", 93 WTERMSIG(status)); 94 } else if (WIFEXITED(status)) { 95 if (WEXITSTATUS(status) != 0) { 96 fail = 1; 97 asprintf(&cause, "exited abnormally"); 98 } else 99 asprintf(&cause, "exited okay"); 100 } else 101 fatalx("unexpected cause of SIGCHLD"); 102 103 die = 1; 104 105 for (id = 0; id < PROC_MAX; id++) 106 if (pid == ps->ps_pid[id]) { 107 log_warnx("lost child: %s %s", 108 ps->ps_title[id], cause); 109 break; 110 } 111 112 free(cause); 113 } while (pid > 0 || (pid == -1 && errno == EINTR)); 114 115 if (die) 116 parent_shutdown(ps->ps_env); 117 break; 118 case SIGHUP: 119 log_info("%s: reload requested with SIGHUP", __func__); 120 121 /* 122 * This is safe because libevent uses async signal handlers 123 * that run in the event loop and not in signal context. 124 */ 125 parent_reload(ps->ps_env, CONFIG_RELOAD, NULL); 126 break; 127 case SIGPIPE: 128 /* ignore */ 129 break; 130 default: 131 fatalx("unexpected signal"); 132 } 133 } 134 135 /* __dead is for lint */ 136 __dead void 137 usage(void) 138 { 139 extern char *__progname; 140 141 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n", 142 __progname); 143 exit(1); 144 } 145 146 int 147 main(int argc, char *argv[]) 148 { 149 int c; 150 int debug = 0, verbose = 0; 151 u_int32_t opts = 0; 152 struct relayd *env; 153 struct privsep *ps; 154 const char *conffile = CONF_FILE; 155 156 while ((c = getopt(argc, argv, "dD:nf:v")) != -1) { 157 switch (c) { 158 case 'd': 159 debug = 2; 160 break; 161 case 'D': 162 if (cmdline_symset(optarg) < 0) 163 log_warnx("could not parse macro definition %s", 164 optarg); 165 break; 166 case 'n': 167 debug = 2; 168 opts |= RELAYD_OPT_NOACTION; 169 break; 170 case 'f': 171 conffile = optarg; 172 break; 173 case 'v': 174 verbose++; 175 opts |= RELAYD_OPT_VERBOSE; 176 break; 177 default: 178 usage(); 179 } 180 } 181 182 log_init(debug ? debug : 1); /* log to stderr until daemonized */ 183 184 argc -= optind; 185 argv += optind; 186 if (argc > 0) 187 usage(); 188 189 if ((env = calloc(1, sizeof(*env))) == NULL || 190 (ps = calloc(1, sizeof(*ps))) == NULL) 191 exit(1); 192 193 relayd_env = env; 194 env->sc_ps = ps; 195 ps->ps_env = env; 196 env->sc_conffile = conffile; 197 env->sc_opts = opts; 198 199 if (parse_config(env->sc_conffile, env) == -1) 200 exit(1); 201 202 if (debug) 203 env->sc_opts |= RELAYD_OPT_LOGUPDATE; 204 205 if (geteuid()) 206 errx(1, "need root privileges"); 207 208 if ((ps->ps_pw = getpwnam(RELAYD_USER)) == NULL) 209 errx(1, "unknown user %s", RELAYD_USER); 210 211 /* Configure the control socket */ 212 ps->ps_csock.cs_name = RELAYD_SOCKET; 213 214 log_init(debug); 215 log_verbose(verbose); 216 217 if (!debug && daemon(1, 0) == -1) 218 err(1, "failed to daemonize"); 219 220 if (env->sc_opts & RELAYD_OPT_NOACTION) 221 ps->ps_noaction = 1; 222 else 223 log_info("startup"); 224 225 ps->ps_instances[PROC_RELAY] = env->sc_prefork_relay; 226 proc_init(ps, procs, nitems(procs)); 227 228 setproctitle("parent"); 229 230 event_init(); 231 232 signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps); 233 signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps); 234 signal_set(&ps->ps_evsigchld, SIGCHLD, parent_sig_handler, ps); 235 signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps); 236 signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps); 237 238 signal_add(&ps->ps_evsigint, NULL); 239 signal_add(&ps->ps_evsigterm, NULL); 240 signal_add(&ps->ps_evsigchld, NULL); 241 signal_add(&ps->ps_evsighup, NULL); 242 signal_add(&ps->ps_evsigpipe, NULL); 243 244 proc_config(ps, procs, nitems(procs)); 245 246 if (load_config(env->sc_conffile, env) == -1) { 247 proc_kill(env->sc_ps); 248 exit(1); 249 } 250 251 if (env->sc_opts & RELAYD_OPT_NOACTION) { 252 fprintf(stderr, "configuration OK\n"); 253 proc_kill(env->sc_ps); 254 exit(0); 255 } 256 257 if (env->sc_flags & (F_SSL|F_SSLCLIENT)) 258 ssl_init(env); 259 260 if (parent_configure(env) == -1) 261 fatalx("configuration failed"); 262 263 init_routes(env); 264 265 event_dispatch(); 266 267 parent_shutdown(env); 268 /* NOTREACHED */ 269 270 return (0); 271 } 272 273 int 274 parent_configure(struct relayd *env) 275 { 276 struct table *tb; 277 struct rdr *rdr; 278 struct router *rt; 279 struct protocol *proto; 280 struct relay *rlay; 281 int id; 282 struct ctl_flags cf; 283 int s, ret = -1; 284 285 TAILQ_FOREACH(tb, env->sc_tables, entry) 286 config_settable(env, tb); 287 TAILQ_FOREACH(rdr, env->sc_rdrs, entry) 288 config_setrdr(env, rdr); 289 TAILQ_FOREACH(rt, env->sc_rts, rt_entry) 290 config_setrt(env, rt); 291 TAILQ_FOREACH(proto, env->sc_protos, entry) 292 config_setproto(env, proto); 293 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) 294 config_setrelay(env, rlay); 295 296 /* HCE, PFE and the preforked relays need to reload their config. */ 297 env->sc_reload = 2 + env->sc_prefork_relay; 298 299 for (id = 0; id < PROC_MAX; id++) { 300 if (id == privsep_process) 301 continue; 302 cf.cf_opts = env->sc_opts; 303 cf.cf_flags = env->sc_flags; 304 305 if ((env->sc_flags & F_NEEDPF) && id == PROC_PFE) { 306 /* Send pf socket to the pf engine */ 307 if ((s = open(PF_SOCKET, O_RDWR)) == -1) { 308 log_debug("%s: cannot open pf socket", 309 __func__); 310 goto done; 311 } 312 } else 313 s = -1; 314 315 proc_compose_imsg(env->sc_ps, id, -1, IMSG_CFG_DONE, s, 316 &cf, sizeof(cf)); 317 } 318 319 ret = 0; 320 321 done: 322 config_purge(env, CONFIG_ALL); 323 return (ret); 324 } 325 326 void 327 parent_reload(struct relayd *env, u_int reset, const char *filename) 328 { 329 if (env->sc_reload) { 330 log_debug("%s: already in progress: %d pending", 331 __func__, env->sc_reload); 332 return; 333 } 334 335 /* Switch back to the default config file */ 336 if (filename == NULL || *filename == '\0') 337 filename = env->sc_conffile; 338 339 log_debug("%s: level %d config file %s", __func__, reset, filename); 340 341 config_purge(env, CONFIG_ALL); 342 343 if (reset == CONFIG_RELOAD) { 344 if (load_config(filename, env) == -1) { 345 log_debug("%s: failed to load config file %s", 346 __func__, filename); 347 } 348 349 config_setreset(env, CONFIG_ALL); 350 351 if (parent_configure(env) == -1) { 352 log_debug("%s: failed to commit config from %s", 353 __func__, filename); 354 } 355 } else 356 config_setreset(env, reset); 357 } 358 359 void 360 parent_configure_done(struct relayd *env) 361 { 362 int id; 363 364 if (env->sc_reload == 0) { 365 log_warnx("%s: configuration already finished", __func__); 366 return; 367 } 368 369 env->sc_reload--; 370 if (env->sc_reload == 0) { 371 for (id = 0; id < PROC_MAX; id++) { 372 if (id == privsep_process) 373 continue; 374 375 proc_compose_imsg(env->sc_ps, id, -1, IMSG_CTL_START, 376 -1, NULL, 0); 377 } 378 } 379 } 380 381 void 382 parent_shutdown(struct relayd *env) 383 { 384 config_purge(env, CONFIG_ALL); 385 386 proc_kill(env->sc_ps); 387 control_cleanup(&env->sc_ps->ps_csock); 388 carp_demote_shutdown(); 389 390 free(env->sc_ps); 391 free(env); 392 393 log_info("parent terminating, pid %d", getpid()); 394 395 exit(0); 396 } 397 398 int 399 parent_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg) 400 { 401 struct relayd *env = p->p_env; 402 struct ctl_demote demote; 403 struct ctl_netroute crt; 404 u_int v; 405 char *str = NULL; 406 407 switch (imsg->hdr.type) { 408 case IMSG_DEMOTE: 409 IMSG_SIZE_CHECK(imsg, &demote); 410 memcpy(&demote, imsg->data, sizeof(demote)); 411 carp_demote_set(demote.group, demote.level); 412 break; 413 case IMSG_RTMSG: 414 IMSG_SIZE_CHECK(imsg, &crt); 415 memcpy(&crt, imsg->data, sizeof(crt)); 416 pfe_route(env, &crt); 417 break; 418 case IMSG_CTL_RESET: 419 IMSG_SIZE_CHECK(imsg, &v); 420 memcpy(&v, imsg->data, sizeof(v)); 421 parent_reload(env, v, NULL); 422 break; 423 case IMSG_CTL_RELOAD: 424 if (IMSG_DATA_SIZE(imsg) > 0) 425 str = get_string(imsg->data, IMSG_DATA_SIZE(imsg)); 426 parent_reload(env, CONFIG_RELOAD, str); 427 if (str != NULL) 428 free(str); 429 break; 430 case IMSG_CTL_SHUTDOWN: 431 parent_shutdown(env); 432 break; 433 case IMSG_CFG_DONE: 434 parent_configure_done(env); 435 break; 436 default: 437 return (-1); 438 } 439 440 return (0); 441 } 442 443 int 444 parent_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg) 445 { 446 struct relayd *env = p->p_env; 447 struct privsep *ps = env->sc_ps; 448 struct ctl_script scr; 449 450 switch (imsg->hdr.type) { 451 case IMSG_SCRIPT: 452 IMSG_SIZE_CHECK(imsg, &scr); 453 bcopy(imsg->data, &scr, sizeof(scr)); 454 scr.retval = script_exec(env, &scr); 455 proc_compose_imsg(ps, PROC_HCE, -1, IMSG_SCRIPT, 456 -1, &scr, sizeof(scr)); 457 break; 458 case IMSG_SNMPSOCK: 459 (void)snmp_setsock(env, p->p_id); 460 break; 461 case IMSG_CFG_DONE: 462 parent_configure_done(env); 463 break; 464 default: 465 return (-1); 466 } 467 468 return (0); 469 } 470 471 int 472 parent_dispatch_relay(int fd, struct privsep_proc *p, struct imsg *imsg) 473 { 474 struct relayd *env = p->p_env; 475 struct privsep *ps = env->sc_ps; 476 struct ctl_bindany bnd; 477 int s; 478 479 switch (imsg->hdr.type) { 480 case IMSG_BINDANY: 481 IMSG_SIZE_CHECK(imsg, &bnd); 482 bcopy(imsg->data, &bnd, sizeof(bnd)); 483 if (bnd.bnd_proc > env->sc_prefork_relay) 484 fatalx("pfe_dispatch_relay: " 485 "invalid relay proc"); 486 switch (bnd.bnd_proto) { 487 case IPPROTO_TCP: 488 case IPPROTO_UDP: 489 break; 490 default: 491 fatalx("pfe_dispatch_relay: requested socket " 492 "for invalid protocol"); 493 /* NOTREACHED */ 494 } 495 s = bindany(&bnd); 496 proc_compose_imsg(ps, PROC_RELAY, bnd.bnd_proc, 497 IMSG_BINDANY, s, &bnd.bnd_id, sizeof(bnd.bnd_id)); 498 break; 499 case IMSG_CFG_DONE: 500 parent_configure_done(env); 501 break; 502 default: 503 return (-1); 504 } 505 506 return (0); 507 } 508 509 void 510 purge_tree(struct proto_tree *tree) 511 { 512 struct protonode *proot, *pn; 513 514 while ((proot = RB_ROOT(tree)) != NULL) { 515 RB_REMOVE(proto_tree, tree, proot); 516 if (proot->key != NULL) 517 free(proot->key); 518 if (proot->value != NULL) 519 free(proot->value); 520 while ((pn = SIMPLEQ_FIRST(&proot->head)) != NULL) { 521 SIMPLEQ_REMOVE_HEAD(&proot->head, entry); 522 if (pn->key != NULL) 523 free(pn->key); 524 if (pn->value != NULL) 525 free(pn->value); 526 if (pn->labelname != NULL) 527 free(pn->labelname); 528 if (pn->label != 0) 529 pn_unref(pn->label); 530 free(pn); 531 } 532 free(proot); 533 } 534 } 535 536 void 537 purge_table(struct tablelist *head, struct table *table) 538 { 539 struct host *host; 540 541 while ((host = TAILQ_FIRST(&table->hosts)) != NULL) { 542 TAILQ_REMOVE(&table->hosts, host, entry); 543 if (event_initialized(&host->cte.ev)) { 544 event_del(&host->cte.ev); 545 close(host->cte.s); 546 } 547 if (host->cte.buf != NULL) 548 ibuf_free(host->cte.buf); 549 if (host->cte.ssl != NULL) 550 SSL_free(host->cte.ssl); 551 free(host); 552 } 553 if (table->sendbuf != NULL) 554 free(table->sendbuf); 555 if (table->conf.flags & F_SSL) 556 SSL_CTX_free(table->ssl_ctx); 557 558 if (head != NULL) 559 TAILQ_REMOVE(head, table, entry); 560 free(table); 561 } 562 563 void 564 purge_relay(struct relayd *env, struct relay *rlay) 565 { 566 struct rsession *con; 567 568 /* shutdown and remove relay */ 569 if (event_initialized(&rlay->rl_ev)) 570 event_del(&rlay->rl_ev); 571 close(rlay->rl_s); 572 TAILQ_REMOVE(env->sc_relays, rlay, rl_entry); 573 574 /* cleanup sessions */ 575 while ((con = 576 SPLAY_ROOT(&rlay->rl_sessions)) != NULL) 577 relay_close(con, NULL); 578 579 /* cleanup relay */ 580 if (rlay->rl_bev != NULL) 581 bufferevent_free(rlay->rl_bev); 582 if (rlay->rl_dstbev != NULL) 583 bufferevent_free(rlay->rl_dstbev); 584 585 if (rlay->rl_ssl_ctx != NULL) 586 SSL_CTX_free(rlay->rl_ssl_ctx); 587 if (rlay->rl_ssl_cert != NULL) 588 free(rlay->rl_ssl_cert); 589 if (rlay->rl_ssl_key != NULL) 590 free(rlay->rl_ssl_key); 591 if (rlay->rl_ssl_ca != NULL) 592 free(rlay->rl_ssl_ca); 593 594 free(rlay); 595 } 596 597 /* 598 * Utility functions 599 */ 600 601 struct host * 602 host_find(struct relayd *env, objid_t id) 603 { 604 struct table *table; 605 struct host *host; 606 607 TAILQ_FOREACH(table, env->sc_tables, entry) 608 TAILQ_FOREACH(host, &table->hosts, entry) 609 if (host->conf.id == id) 610 return (host); 611 return (NULL); 612 } 613 614 struct table * 615 table_find(struct relayd *env, objid_t id) 616 { 617 struct table *table; 618 619 TAILQ_FOREACH(table, env->sc_tables, entry) 620 if (table->conf.id == id) 621 return (table); 622 return (NULL); 623 } 624 625 struct rdr * 626 rdr_find(struct relayd *env, objid_t id) 627 { 628 struct rdr *rdr; 629 630 TAILQ_FOREACH(rdr, env->sc_rdrs, entry) 631 if (rdr->conf.id == id) 632 return (rdr); 633 return (NULL); 634 } 635 636 struct relay * 637 relay_find(struct relayd *env, objid_t id) 638 { 639 struct relay *rlay; 640 641 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) 642 if (rlay->rl_conf.id == id) 643 return (rlay); 644 return (NULL); 645 } 646 647 struct protocol * 648 proto_find(struct relayd *env, objid_t id) 649 { 650 struct protocol *p; 651 652 TAILQ_FOREACH(p, env->sc_protos, entry) 653 if (p->id == id) 654 return (p); 655 return (NULL); 656 } 657 658 struct rsession * 659 session_find(struct relayd *env, objid_t id) 660 { 661 struct relay *rlay; 662 struct rsession *con; 663 664 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) 665 SPLAY_FOREACH(con, session_tree, &rlay->rl_sessions) 666 if (con->se_id == id) 667 return (con); 668 return (NULL); 669 } 670 671 struct netroute * 672 route_find(struct relayd *env, objid_t id) 673 { 674 struct netroute *nr; 675 676 TAILQ_FOREACH(nr, env->sc_routes, nr_route) 677 if (nr->nr_conf.id == id) 678 return (nr); 679 return (NULL); 680 } 681 682 struct router * 683 router_find(struct relayd *env, objid_t id) 684 { 685 struct router *rt; 686 687 TAILQ_FOREACH(rt, env->sc_rts, rt_entry) 688 if (rt->rt_conf.id == id) 689 return (rt); 690 return (NULL); 691 } 692 693 struct host * 694 host_findbyname(struct relayd *env, const char *name) 695 { 696 struct table *table; 697 struct host *host; 698 699 TAILQ_FOREACH(table, env->sc_tables, entry) 700 TAILQ_FOREACH(host, &table->hosts, entry) 701 if (strcmp(host->conf.name, name) == 0) 702 return (host); 703 return (NULL); 704 } 705 706 struct table * 707 table_findbyname(struct relayd *env, const char *name) 708 { 709 struct table *table; 710 711 TAILQ_FOREACH(table, env->sc_tables, entry) 712 if (strcmp(table->conf.name, name) == 0) 713 return (table); 714 return (NULL); 715 } 716 717 struct table * 718 table_findbyconf(struct relayd *env, struct table *tb) 719 { 720 struct table *table; 721 struct table_config a, b; 722 723 bcopy(&tb->conf, &a, sizeof(a)); 724 a.id = a.rdrid = 0; 725 a.flags &= ~(F_USED|F_BACKUP); 726 727 TAILQ_FOREACH(table, env->sc_tables, entry) { 728 bcopy(&table->conf, &b, sizeof(b)); 729 b.id = b.rdrid = 0; 730 b.flags &= ~(F_USED|F_BACKUP); 731 732 /* 733 * Compare two tables and return the existing table if 734 * the configuration seems to be the same. 735 */ 736 if (bcmp(&a, &b, sizeof(b)) == 0 && 737 ((tb->sendbuf == NULL && table->sendbuf == NULL) || 738 (tb->sendbuf != NULL && table->sendbuf != NULL && 739 strcmp(tb->sendbuf, table->sendbuf) == 0))) 740 return (table); 741 } 742 return (NULL); 743 } 744 745 struct rdr * 746 rdr_findbyname(struct relayd *env, const char *name) 747 { 748 struct rdr *rdr; 749 750 TAILQ_FOREACH(rdr, env->sc_rdrs, entry) 751 if (strcmp(rdr->conf.name, name) == 0) 752 return (rdr); 753 return (NULL); 754 } 755 756 struct relay * 757 relay_findbyname(struct relayd *env, const char *name) 758 { 759 struct relay *rlay; 760 761 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) 762 if (strcmp(rlay->rl_conf.name, name) == 0) 763 return (rlay); 764 return (NULL); 765 } 766 767 struct relay * 768 relay_findbyaddr(struct relayd *env, struct relay_config *rc) 769 { 770 struct relay *rlay; 771 772 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) 773 if (bcmp(&rlay->rl_conf.ss, &rc->ss, sizeof(rc->ss)) == 0 && 774 rlay->rl_conf.port == rc->port) 775 return (rlay); 776 return (NULL); 777 } 778 779 void 780 event_again(struct event *ev, int fd, short event, 781 void (*fn)(int, short, void *), 782 struct timeval *start, struct timeval *end, void *arg) 783 { 784 struct timeval tv_next, tv_now, tv; 785 786 if (gettimeofday(&tv_now, NULL) == -1) 787 fatal("event_again: gettimeofday"); 788 789 bcopy(end, &tv_next, sizeof(tv_next)); 790 timersub(&tv_now, start, &tv_now); 791 timersub(&tv_next, &tv_now, &tv_next); 792 793 bzero(&tv, sizeof(tv)); 794 if (timercmp(&tv_next, &tv, >)) 795 bcopy(&tv_next, &tv, sizeof(tv)); 796 797 event_del(ev); 798 event_set(ev, fd, event, fn, arg); 799 event_add(ev, &tv); 800 } 801 802 int 803 expand_string(char *label, size_t len, const char *srch, const char *repl) 804 { 805 char *tmp; 806 char *p, *q; 807 808 if ((tmp = calloc(1, len)) == NULL) { 809 log_debug("%s: calloc", __func__); 810 return (-1); 811 } 812 p = q = label; 813 while ((q = strstr(p, srch)) != NULL) { 814 *q = '\0'; 815 if ((strlcat(tmp, p, len) >= len) || 816 (strlcat(tmp, repl, len) >= len)) { 817 log_debug("%s: string too long", __func__); 818 free(tmp); 819 return (-1); 820 } 821 q += strlen(srch); 822 p = q; 823 } 824 if (strlcat(tmp, p, len) >= len) { 825 log_debug("%s: string too long", __func__); 826 free(tmp); 827 return (-1); 828 } 829 (void)strlcpy(label, tmp, len); /* always fits */ 830 free(tmp); 831 832 return (0); 833 } 834 835 void 836 translate_string(char *str) 837 { 838 char *reader; 839 char *writer; 840 841 reader = writer = str; 842 843 while (*reader) { 844 if (*reader == '\\') { 845 reader++; 846 switch (*reader) { 847 case 'n': 848 *writer++ = '\n'; 849 break; 850 case 'r': 851 *writer++ = '\r'; 852 break; 853 default: 854 *writer++ = *reader; 855 } 856 } else 857 *writer++ = *reader; 858 reader++; 859 } 860 *writer = '\0'; 861 } 862 863 char * 864 digeststr(enum digest_type type, const u_int8_t *data, size_t len, char *buf) 865 { 866 switch (type) { 867 case DIGEST_SHA1: 868 return (SHA1Data(data, len, buf)); 869 break; 870 case DIGEST_MD5: 871 return (MD5Data(data, len, buf)); 872 break; 873 default: 874 break; 875 } 876 return (NULL); 877 } 878 879 const char * 880 canonicalize_host(const char *host, char *name, size_t len) 881 { 882 struct sockaddr_in sin4; 883 struct sockaddr_in6 sin6; 884 u_int i, j; 885 size_t plen; 886 char c; 887 888 if (len < 2) 889 goto fail; 890 891 /* 892 * Canonicalize an IPv4/6 address 893 */ 894 if (inet_pton(AF_INET, host, &sin4) == 1) 895 return (inet_ntop(AF_INET, &sin4, name, len)); 896 if (inet_pton(AF_INET6, host, &sin6) == 1) 897 return (inet_ntop(AF_INET6, &sin6, name, len)); 898 899 /* 900 * Canonicalize a hostname 901 */ 902 903 /* 1. remove repeated dots and convert upper case to lower case */ 904 plen = strlen(host); 905 bzero(name, len); 906 for (i = j = 0; i < plen; i++) { 907 if (j >= (len - 1)) 908 goto fail; 909 c = tolower(host[i]); 910 if ((c == '.') && (j == 0 || name[j - 1] == '.')) 911 continue; 912 name[j++] = c; 913 } 914 915 /* 2. remove trailing dots */ 916 for (i = j; i > 0; i--) { 917 if (name[i - 1] != '.') 918 break; 919 name[i - 1] = '\0'; 920 j--; 921 } 922 if (j <= 0) 923 goto fail; 924 925 return (name); 926 927 fail: 928 errno = EINVAL; 929 return (NULL); 930 } 931 932 struct protonode * 933 protonode_header(enum direction dir, struct protocol *proto, 934 struct protonode *pk) 935 { 936 struct protonode *pn; 937 struct proto_tree *tree; 938 939 if (dir == RELAY_DIR_RESPONSE) 940 tree = &proto->response_tree; 941 else 942 tree = &proto->request_tree; 943 944 pn = RB_FIND(proto_tree, tree, pk); 945 if (pn != NULL) 946 return (pn); 947 if ((pn = (struct protonode *)calloc(1, sizeof(*pn))) == NULL) { 948 log_warn("%s: calloc", __func__); 949 return (NULL); 950 } 951 pn->key = strdup(pk->key); 952 if (pn->key == NULL) { 953 free(pn); 954 log_warn("%s: strdup", __func__); 955 return (NULL); 956 } 957 pn->value = NULL; 958 pn->action = NODE_ACTION_NONE; 959 pn->type = pk->type; 960 SIMPLEQ_INIT(&pn->head); 961 if (dir == RELAY_DIR_RESPONSE) 962 pn->id = 963 proto->response_nodes++; 964 else 965 pn->id = proto->request_nodes++; 966 if (pn->id == INT_MAX) { 967 log_warnx("%s: too many protocol " 968 "nodes defined", __func__); 969 return (NULL); 970 } 971 RB_INSERT(proto_tree, tree, pn); 972 return (pn); 973 } 974 975 int 976 protonode_add(enum direction dir, struct protocol *proto, 977 struct protonode *node) 978 { 979 struct protonode *pn, *proot, pk; 980 struct proto_tree *tree; 981 982 if (dir == RELAY_DIR_RESPONSE) 983 tree = &proto->response_tree; 984 else 985 tree = &proto->request_tree; 986 987 if ((pn = calloc(1, sizeof (*pn))) == NULL) { 988 log_warn("%s: calloc", __func__); 989 return (-1); 990 } 991 bcopy(node, pn, sizeof(*pn)); 992 pn->key = node->key; 993 pn->value = node->value; 994 pn->labelname = NULL; 995 if (node->labelname != NULL) 996 pn->label = pn_name2id(node->labelname); 997 SIMPLEQ_INIT(&pn->head); 998 if (dir == RELAY_DIR_RESPONSE) 999 pn->id = proto->response_nodes++; 1000 else 1001 pn->id = proto->request_nodes++; 1002 if (pn->id == INT_MAX) { 1003 log_warnx("%s: too many protocol nodes defined", __func__); 1004 free(pn); 1005 return (-1); 1006 } 1007 if ((proot = 1008 RB_INSERT(proto_tree, tree, pn)) != NULL) { 1009 /* 1010 * A protocol node with the same key already 1011 * exists, append it to a queue behind the 1012 * existing node-> 1013 */ 1014 if (SIMPLEQ_EMPTY(&proot->head)) 1015 SIMPLEQ_NEXT(proot, entry) = pn; 1016 SIMPLEQ_INSERT_TAIL(&proot->head, pn, entry); 1017 } 1018 if (node->type == NODE_TYPE_COOKIE) 1019 pk.key = "Cookie"; 1020 else if (node->type == NODE_TYPE_URL) 1021 pk.key = "Host"; 1022 else 1023 pk.key = "GET"; 1024 if (node->type != NODE_TYPE_HEADER) { 1025 pk.type = NODE_TYPE_HEADER; 1026 pn = protonode_header(dir, proto, &pk); 1027 if (pn == NULL) 1028 return (-1); 1029 switch (node->type) { 1030 case NODE_TYPE_QUERY: 1031 pn->flags |= PNFLAG_LOOKUP_QUERY; 1032 break; 1033 case NODE_TYPE_COOKIE: 1034 pn->flags |= PNFLAG_LOOKUP_COOKIE; 1035 break; 1036 case NODE_TYPE_URL: 1037 if (node->flags & 1038 PNFLAG_LOOKUP_URL_DIGEST) 1039 pn->flags |= node->flags & 1040 PNFLAG_LOOKUP_URL_DIGEST; 1041 else 1042 pn->flags |= 1043 PNFLAG_LOOKUP_DIGEST(0); 1044 break; 1045 default: 1046 break; 1047 } 1048 } 1049 1050 return (0); 1051 } 1052 1053 int 1054 protonode_load(enum direction dir, struct protocol *proto, 1055 struct protonode *node, const char *name) 1056 { 1057 FILE *fp; 1058 char buf[BUFSIZ]; 1059 int ret = -1; 1060 struct protonode pn; 1061 1062 bcopy(node, &pn, sizeof(pn)); 1063 pn.key = pn.value = NULL; 1064 1065 if ((fp = fopen(name, "r")) == NULL) 1066 return (-1); 1067 1068 while (fgets(buf, sizeof(buf), fp) != NULL) { 1069 /* strip whitespace and newline characters */ 1070 buf[strcspn(buf, "\r\n\t ")] = '\0'; 1071 if (!strlen(buf) || buf[0] == '#') 1072 continue; 1073 pn.key = strdup(buf); 1074 if (node->value != NULL) 1075 pn.value = strdup(node->value); 1076 if (pn.key == NULL || 1077 (node->value != NULL && pn.value == NULL)) 1078 goto fail; 1079 if (protonode_add(dir, proto, &pn) == -1) 1080 goto fail; 1081 pn.key = pn.value = NULL; 1082 } 1083 1084 ret = 0; 1085 fail: 1086 if (pn.key != NULL) 1087 free(pn.key); 1088 if (pn.value != NULL) 1089 free(pn.value); 1090 fclose(fp); 1091 return (ret); 1092 } 1093 1094 int 1095 bindany(struct ctl_bindany *bnd) 1096 { 1097 int s, v; 1098 1099 s = -1; 1100 v = 1; 1101 1102 if (relay_socket_af(&bnd->bnd_ss, bnd->bnd_port) == -1) 1103 goto fail; 1104 if ((s = socket(bnd->bnd_ss.ss_family, 1105 bnd->bnd_proto == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM, 1106 bnd->bnd_proto)) == -1) 1107 goto fail; 1108 if (setsockopt(s, SOL_SOCKET, SO_BINDANY, 1109 &v, sizeof(v)) == -1) 1110 goto fail; 1111 if (bind(s, (struct sockaddr *)&bnd->bnd_ss, 1112 bnd->bnd_ss.ss_len) == -1) 1113 goto fail; 1114 1115 return (s); 1116 1117 fail: 1118 if (s != -1) 1119 close(s); 1120 return (-1); 1121 } 1122 1123 int 1124 map6to4(struct sockaddr_storage *in6) 1125 { 1126 struct sockaddr_storage out4; 1127 struct sockaddr_in *sin4 = (struct sockaddr_in *)&out4; 1128 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)in6; 1129 1130 bzero(sin4, sizeof(*sin4)); 1131 sin4->sin_len = sizeof(*sin4); 1132 sin4->sin_family = AF_INET; 1133 sin4->sin_port = sin6->sin6_port; 1134 1135 bcopy(&sin6->sin6_addr.s6_addr[12], &sin4->sin_addr.s_addr, 1136 sizeof(sin4->sin_addr)); 1137 1138 if (sin4->sin_addr.s_addr == INADDR_ANY || 1139 sin4->sin_addr.s_addr == INADDR_BROADCAST || 1140 IN_MULTICAST(ntohl(sin4->sin_addr.s_addr))) 1141 return (-1); 1142 1143 bcopy(&out4, in6, sizeof(*in6)); 1144 1145 return (0); 1146 } 1147 1148 int 1149 map4to6(struct sockaddr_storage *in4, struct sockaddr_storage *map) 1150 { 1151 struct sockaddr_storage out6; 1152 struct sockaddr_in *sin4 = (struct sockaddr_in *)in4; 1153 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&out6; 1154 struct sockaddr_in6 *map6 = (struct sockaddr_in6 *)map; 1155 1156 if (sin4->sin_addr.s_addr == INADDR_ANY || 1157 sin4->sin_addr.s_addr == INADDR_BROADCAST || 1158 IN_MULTICAST(ntohl(sin4->sin_addr.s_addr))) 1159 return (-1); 1160 1161 bcopy(map6, sin6, sizeof(*sin6)); 1162 sin6->sin6_len = sizeof(*sin6); 1163 sin6->sin6_family = AF_INET6; 1164 sin6->sin6_port = sin4->sin_port; 1165 1166 bcopy(&sin4->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12], 1167 sizeof(sin4->sin_addr)); 1168 1169 bcopy(&out6, in4, sizeof(*in4)); 1170 1171 return (0); 1172 } 1173 1174 void 1175 socket_rlimit(int maxfd) 1176 { 1177 struct rlimit rl; 1178 1179 if (getrlimit(RLIMIT_NOFILE, &rl) == -1) 1180 fatal("socket_rlimit: failed to get resource limit"); 1181 log_debug("%s: max open files %d", __func__, rl.rlim_max); 1182 1183 /* 1184 * Allow the maximum number of open file descriptors for this 1185 * login class (which should be the class "daemon" by default). 1186 */ 1187 if (maxfd == -1) 1188 rl.rlim_cur = rl.rlim_max; 1189 else 1190 rl.rlim_cur = MAX(rl.rlim_max, (rlim_t)maxfd); 1191 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) 1192 fatal("socket_rlimit: failed to set resource limit"); 1193 } 1194 1195 char * 1196 get_string(u_int8_t *ptr, size_t len) 1197 { 1198 size_t i; 1199 char *str; 1200 1201 for (i = 0; i < len; i++) 1202 if (!(isprint((char)ptr[i]) || isspace((char)ptr[i]))) 1203 break; 1204 1205 if ((str = calloc(1, i + 1)) == NULL) 1206 return (NULL); 1207 memcpy(str, ptr, i); 1208 1209 return (str); 1210 } 1211 1212 void * 1213 get_data(u_int8_t *ptr, size_t len) 1214 { 1215 u_int8_t *data; 1216 1217 if ((data = calloc(1, len)) == NULL) 1218 return (NULL); 1219 memcpy(data, ptr, len); 1220 1221 return (data); 1222 } 1223