1 /* $OpenBSD: config.c,v 1.41 2019/09/15 19:23:29 rob Exp $ */ 2 3 /* 4 * Copyright (c) 2011 - 2014 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/queue.h> 21 #include <sys/time.h> 22 #include <sys/uio.h> 23 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <unistd.h> 27 #include <limits.h> 28 #include <string.h> 29 #include <imsg.h> 30 31 #include "relayd.h" 32 33 int 34 config_init(struct relayd *env) 35 { 36 struct privsep *ps = env->sc_ps; 37 u_int what; 38 39 /* Global configuration */ 40 if (privsep_process == PROC_PARENT) { 41 env->sc_conf.timeout.tv_sec = CHECK_TIMEOUT / 1000; 42 env->sc_conf.timeout.tv_usec = (CHECK_TIMEOUT % 1000) * 1000; 43 env->sc_conf.interval.tv_sec = CHECK_INTERVAL; 44 env->sc_conf.interval.tv_usec = 0; 45 env->sc_conf.prefork_relay = RELAY_NUMPROC; 46 env->sc_conf.statinterval.tv_sec = RELAY_STATINTERVAL; 47 env->sc_ps->ps_csock.cs_name = RELAYD_SOCKET; 48 } 49 50 ps->ps_what[PROC_PARENT] = CONFIG_ALL; 51 ps->ps_what[PROC_PFE] = CONFIG_ALL & ~(CONFIG_PROTOS|CONFIG_CERTS); 52 ps->ps_what[PROC_HCE] = CONFIG_TABLES; 53 ps->ps_what[PROC_CA] = CONFIG_RELAYS|CONFIG_CERTS; 54 ps->ps_what[PROC_RELAY] = CONFIG_RELAYS|CONFIG_CERTS| 55 CONFIG_TABLES|CONFIG_PROTOS|CONFIG_CA_ENGINE; 56 57 /* Other configuration */ 58 what = ps->ps_what[privsep_process]; 59 if (what & CONFIG_TABLES) { 60 if ((env->sc_tables = 61 calloc(1, sizeof(*env->sc_tables))) == NULL) 62 return (-1); 63 TAILQ_INIT(env->sc_tables); 64 65 memset(&env->sc_empty_table, 0, sizeof(env->sc_empty_table)); 66 env->sc_empty_table.conf.id = EMPTY_TABLE; 67 env->sc_empty_table.conf.flags |= F_DISABLE; 68 (void)strlcpy(env->sc_empty_table.conf.name, "empty", 69 sizeof(env->sc_empty_table.conf.name)); 70 71 } 72 if (what & CONFIG_RDRS) { 73 if ((env->sc_rdrs = 74 calloc(1, sizeof(*env->sc_rdrs))) == NULL) 75 return (-1); 76 TAILQ_INIT(env->sc_rdrs); 77 78 } 79 if (what & CONFIG_RELAYS) { 80 if ((env->sc_relays = 81 calloc(1, sizeof(*env->sc_relays))) == NULL) 82 return (-1); 83 TAILQ_INIT(env->sc_relays); 84 85 if ((env->sc_certs = 86 calloc(1, sizeof(*env->sc_certs))) == NULL) 87 return (-1); 88 TAILQ_INIT(env->sc_certs); 89 90 if ((env->sc_pkeys = 91 calloc(1, sizeof(*env->sc_pkeys))) == NULL) 92 return (-1); 93 TAILQ_INIT(env->sc_pkeys); 94 } 95 if (what & CONFIG_PROTOS) { 96 if ((env->sc_protos = 97 calloc(1, sizeof(*env->sc_protos))) == NULL) 98 return (-1); 99 TAILQ_INIT(env->sc_protos); 100 101 bzero(&env->sc_proto_default, sizeof(env->sc_proto_default)); 102 env->sc_proto_default.id = EMPTY_ID; 103 env->sc_proto_default.flags = F_USED; 104 env->sc_proto_default.tcpflags = TCPFLAG_DEFAULT; 105 env->sc_proto_default.tcpbacklog = RELAY_BACKLOG; 106 env->sc_proto_default.tlsflags = TLSFLAG_DEFAULT; 107 TAILQ_INIT(&env->sc_proto_default.tlscerts); 108 (void)strlcpy(env->sc_proto_default.tlsciphers, 109 TLSCIPHERS_DEFAULT, 110 sizeof(env->sc_proto_default.tlsciphers)); 111 (void)strlcpy(env->sc_proto_default.tlsecdhecurves, 112 TLSECDHECURVES_DEFAULT, 113 sizeof(env->sc_proto_default.tlsecdhecurves)); 114 (void)strlcpy(env->sc_proto_default.tlsdhparams, 115 TLSDHPARAM_DEFAULT, 116 sizeof(env->sc_proto_default.tlsdhparams)); 117 env->sc_proto_default.type = RELAY_PROTO_TCP; 118 (void)strlcpy(env->sc_proto_default.name, "default", 119 sizeof(env->sc_proto_default.name)); 120 } 121 if (what & CONFIG_RTS) { 122 if ((env->sc_rts = 123 calloc(1, sizeof(*env->sc_rts))) == NULL) 124 return (-1); 125 TAILQ_INIT(env->sc_rts); 126 } 127 if (what & CONFIG_ROUTES) { 128 if ((env->sc_routes = 129 calloc(1, sizeof(*env->sc_routes))) == NULL) 130 return (-1); 131 TAILQ_INIT(env->sc_routes); 132 } 133 134 return (0); 135 } 136 137 void 138 config_purge(struct relayd *env, u_int reset) 139 { 140 struct privsep *ps = env->sc_ps; 141 struct table *table; 142 struct rdr *rdr; 143 struct address *virt; 144 struct protocol *proto; 145 struct relay_rule *rule; 146 struct relay *rlay; 147 struct netroute *nr; 148 struct router *rt; 149 struct ca_pkey *pkey; 150 struct keyname *keyname; 151 u_int what; 152 153 what = ps->ps_what[privsep_process] & reset; 154 155 if (what & CONFIG_TABLES && env->sc_tables != NULL) { 156 while ((table = TAILQ_FIRST(env->sc_tables)) != NULL) 157 purge_table(env, env->sc_tables, table); 158 env->sc_tablecount = 0; 159 } 160 if (what & CONFIG_RDRS && env->sc_rdrs != NULL) { 161 while ((rdr = TAILQ_FIRST(env->sc_rdrs)) != NULL) { 162 TAILQ_REMOVE(env->sc_rdrs, rdr, entry); 163 while ((virt = TAILQ_FIRST(&rdr->virts)) != NULL) { 164 TAILQ_REMOVE(&rdr->virts, virt, entry); 165 free(virt); 166 } 167 free(rdr); 168 } 169 env->sc_rdrcount = 0; 170 } 171 if (what & CONFIG_RELAYS && env->sc_pkeys != NULL) { 172 while ((pkey = TAILQ_FIRST(env->sc_pkeys)) != NULL) { 173 TAILQ_REMOVE(env->sc_pkeys, pkey, pkey_entry); 174 free(pkey); 175 } 176 } 177 if (what & CONFIG_RELAYS && env->sc_relays != NULL) { 178 while ((rlay = TAILQ_FIRST(env->sc_relays)) != NULL) 179 purge_relay(env, rlay); 180 env->sc_relaycount = 0; 181 } 182 if (what & CONFIG_PROTOS && env->sc_protos != NULL) { 183 while ((proto = TAILQ_FIRST(env->sc_protos)) != NULL) { 184 TAILQ_REMOVE(env->sc_protos, proto, entry); 185 while ((rule = TAILQ_FIRST(&proto->rules)) != NULL) 186 rule_delete(&proto->rules, rule); 187 proto->rulecount = 0; 188 } 189 } 190 if (what & CONFIG_PROTOS && env->sc_protos != NULL) { 191 while ((proto = TAILQ_FIRST(env->sc_protos)) != NULL) { 192 TAILQ_REMOVE(env->sc_protos, proto, entry); 193 free(proto->style); 194 free(proto->tlscapass); 195 free(proto); 196 while ((keyname = 197 TAILQ_FIRST(&proto->tlscerts)) != NULL) { 198 TAILQ_REMOVE(&proto->tlscerts, keyname, entry); 199 free(keyname->name); 200 free(keyname); 201 } 202 } 203 env->sc_protocount = 0; 204 } 205 if (what & CONFIG_RTS && env->sc_rts != NULL) { 206 while ((rt = TAILQ_FIRST(env->sc_rts)) != NULL) { 207 TAILQ_REMOVE(env->sc_rts, rt, rt_entry); 208 while ((nr = TAILQ_FIRST(&rt->rt_netroutes)) != NULL) { 209 TAILQ_REMOVE(&rt->rt_netroutes, nr, nr_entry); 210 TAILQ_REMOVE(env->sc_routes, nr, nr_route); 211 free(nr); 212 env->sc_routecount--; 213 } 214 free(rt); 215 } 216 env->sc_routercount = 0; 217 } 218 if (what & CONFIG_ROUTES && env->sc_routes != NULL) { 219 while ((nr = TAILQ_FIRST(env->sc_routes)) != NULL) { 220 if ((rt = nr->nr_router) != NULL) 221 TAILQ_REMOVE(&rt->rt_netroutes, nr, nr_entry); 222 TAILQ_REMOVE(env->sc_routes, nr, nr_route); 223 free(nr); 224 } 225 env->sc_routecount = 0; 226 } 227 } 228 229 int 230 config_setreset(struct relayd *env, u_int reset) 231 { 232 struct privsep *ps = env->sc_ps; 233 int id; 234 235 for (id = 0; id < PROC_MAX; id++) { 236 if ((reset & ps->ps_what[id]) == 0 || 237 id == privsep_process) 238 continue; 239 proc_compose(ps, id, IMSG_CTL_RESET, &reset, sizeof(reset)); 240 241 /* 242 * XXX Make sure that the reset message is sent 243 * immediately by flushing the imsg output buffer, before 244 * sending any other imsg that potentially include an fd. 245 * This should better be fixed in the imsg API itself. 246 */ 247 proc_flush_imsg(ps, id, -1); 248 } 249 250 return (0); 251 } 252 253 int 254 config_getreset(struct relayd *env, struct imsg *imsg) 255 { 256 u_int mode; 257 258 IMSG_SIZE_CHECK(imsg, &mode); 259 memcpy(&mode, imsg->data, sizeof(mode)); 260 261 config_purge(env, mode); 262 263 return (0); 264 } 265 266 int 267 config_getcfg(struct relayd *env, struct imsg *imsg) 268 { 269 struct privsep *ps = env->sc_ps; 270 struct table *tb; 271 struct host *h, *ph; 272 u_int what; 273 274 if (IMSG_DATA_SIZE(imsg) != sizeof(struct relayd_config)) 275 return (0); /* ignore */ 276 277 /* Update runtime flags */ 278 memcpy(&env->sc_conf, imsg->data, sizeof(env->sc_conf)); 279 280 what = ps->ps_what[privsep_process]; 281 282 if (what & CONFIG_TABLES) { 283 /* Update the tables */ 284 TAILQ_FOREACH(tb, env->sc_tables, entry) { 285 TAILQ_FOREACH(h, &tb->hosts, entry) { 286 if (h->conf.parentid && (ph = host_find(env, 287 h->conf.parentid)) != NULL) { 288 SLIST_INSERT_HEAD(&ph->children, 289 h, child); 290 } 291 } 292 } 293 } 294 295 if (env->sc_conf.flags & (F_TLS|F_TLSCLIENT)) { 296 ssl_init(env); 297 if (what & CONFIG_CA_ENGINE) 298 ca_engine_init(env); 299 if (tls_init() == -1) 300 fatalx("unable to initialize TLS"); 301 } 302 303 if (privsep_process != PROC_PARENT) 304 proc_compose(env->sc_ps, PROC_PARENT, IMSG_CFG_DONE, NULL, 0); 305 306 return (0); 307 } 308 309 int 310 config_settable(struct relayd *env, struct table *tb) 311 { 312 struct privsep *ps = env->sc_ps; 313 struct host *host; 314 int id, c; 315 struct iovec iov[2]; 316 317 for (id = 0; id < PROC_MAX; id++) { 318 if ((ps->ps_what[id] & CONFIG_TABLES) == 0 || 319 id == privsep_process) 320 continue; 321 322 /* XXX need to send table to pfe for control socket */ 323 if (id == PROC_HCE && tb->conf.check == CHECK_NOCHECK) 324 continue; 325 326 DPRINTF("%s: sending table %s %d to %s", __func__, 327 tb->conf.name, tb->conf.id, env->sc_ps->ps_title[id]); 328 329 c = 0; 330 iov[c].iov_base = &tb->conf; 331 iov[c++].iov_len = sizeof(tb->conf); 332 if (tb->sendbuf != NULL) { 333 iov[c].iov_base = tb->sendbuf; 334 iov[c++].iov_len = strlen(tb->sendbuf); 335 } 336 337 proc_composev(ps, id, IMSG_CFG_TABLE, iov, c); 338 339 TAILQ_FOREACH(host, &tb->hosts, entry) { 340 proc_compose(ps, id, IMSG_CFG_HOST, 341 &host->conf, sizeof(host->conf)); 342 } 343 } 344 345 return (0); 346 } 347 348 int 349 config_gettable(struct relayd *env, struct imsg *imsg) 350 { 351 struct table *tb; 352 size_t sb; 353 u_int8_t *p = imsg->data; 354 size_t s; 355 356 if ((tb = calloc(1, sizeof(*tb))) == NULL) 357 return (-1); 358 359 IMSG_SIZE_CHECK(imsg, &tb->conf); 360 memcpy(&tb->conf, p, sizeof(tb->conf)); 361 s = sizeof(tb->conf); 362 363 sb = IMSG_DATA_SIZE(imsg) - s; 364 if (sb > 0) { 365 if ((tb->sendbuf = get_string(p + s, sb)) == NULL) { 366 free(tb); 367 return (-1); 368 } 369 } 370 if (tb->conf.check == CHECK_BINSEND_EXPECT) { 371 tb->sendbinbuf = string2binary(tb->sendbuf); 372 if (tb->sendbinbuf == NULL) { 373 free(tb); 374 return (-1); 375 } 376 } 377 378 TAILQ_INIT(&tb->hosts); 379 TAILQ_INSERT_TAIL(env->sc_tables, tb, entry); 380 381 env->sc_tablecount++; 382 383 DPRINTF("%s: %s %d received table %d (%s)", __func__, 384 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 385 tb->conf.id, tb->conf.name); 386 387 return (0); 388 } 389 390 int 391 config_gethost(struct relayd *env, struct imsg *imsg) 392 { 393 struct table *tb; 394 struct host *host; 395 396 if ((host = calloc(1, sizeof(*host))) == NULL) 397 return (-1); 398 399 IMSG_SIZE_CHECK(imsg, &host->conf); 400 memcpy(&host->conf, imsg->data, sizeof(host->conf)); 401 402 if (host_find(env, host->conf.id) != NULL) { 403 log_debug("%s: host %d already exists", 404 __func__, host->conf.id); 405 free(host); 406 return (-1); 407 } 408 409 if ((tb = table_find(env, host->conf.tableid)) == NULL) { 410 log_debug("%s: " 411 "received host for unknown table %d", __func__, 412 host->conf.tableid); 413 free(host); 414 return (-1); 415 } 416 417 host->tablename = tb->conf.name; 418 host->cte.s = -1; 419 420 SLIST_INIT(&host->children); 421 TAILQ_INSERT_TAIL(&tb->hosts, host, entry); 422 TAILQ_INSERT_TAIL(&env->sc_hosts, host, globalentry); 423 424 DPRINTF("%s: %s %d received host %s for table %s", __func__, 425 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 426 host->conf.name, tb->conf.name); 427 428 return (0); 429 } 430 431 int 432 config_setrdr(struct relayd *env, struct rdr *rdr) 433 { 434 struct privsep *ps = env->sc_ps; 435 struct address *virt; 436 int id; 437 438 for (id = 0; id < PROC_MAX; id++) { 439 if ((ps->ps_what[id] & CONFIG_RDRS) == 0 || 440 id == privsep_process) 441 continue; 442 443 DPRINTF("%s: sending rdr %s to %s", __func__, 444 rdr->conf.name, ps->ps_title[id]); 445 446 proc_compose(ps, id, IMSG_CFG_RDR, 447 &rdr->conf, sizeof(rdr->conf)); 448 449 TAILQ_FOREACH(virt, &rdr->virts, entry) { 450 virt->rdrid = rdr->conf.id; 451 proc_compose(ps, id, IMSG_CFG_VIRT, 452 virt, sizeof(*virt)); 453 } 454 } 455 456 return (0); 457 } 458 459 int 460 config_getrdr(struct relayd *env, struct imsg *imsg) 461 { 462 struct rdr *rdr; 463 464 if ((rdr = calloc(1, sizeof(*rdr))) == NULL) 465 return (-1); 466 467 IMSG_SIZE_CHECK(imsg, &rdr->conf); 468 memcpy(&rdr->conf, imsg->data, sizeof(rdr->conf)); 469 470 if ((rdr->table = table_find(env, rdr->conf.table_id)) == NULL) { 471 log_debug("%s: table not found", __func__); 472 free(rdr); 473 return (-1); 474 } 475 if ((rdr->backup = table_find(env, rdr->conf.backup_id)) == NULL) { 476 rdr->conf.backup_id = EMPTY_TABLE; 477 rdr->backup = &env->sc_empty_table; 478 } 479 480 TAILQ_INIT(&rdr->virts); 481 TAILQ_INSERT_TAIL(env->sc_rdrs, rdr, entry); 482 483 env->sc_rdrcount++; 484 485 DPRINTF("%s: %s %d received rdr %s", __func__, 486 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 487 rdr->conf.name); 488 489 return (0); 490 } 491 492 int 493 config_getvirt(struct relayd *env, struct imsg *imsg) 494 { 495 struct rdr *rdr; 496 struct address *virt; 497 498 IMSG_SIZE_CHECK(imsg, virt); 499 500 if ((virt = calloc(1, sizeof(*virt))) == NULL) 501 return (-1); 502 memcpy(virt, imsg->data, sizeof(*virt)); 503 504 if ((rdr = rdr_find(env, virt->rdrid)) == NULL) { 505 log_debug("%s: rdr not found", __func__); 506 free(virt); 507 return (-1); 508 } 509 510 TAILQ_INSERT_TAIL(&rdr->virts, virt, entry); 511 512 DPRINTF("%s: %s %d received address for rdr %s", __func__, 513 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 514 rdr->conf.name); 515 516 return (0); 517 } 518 519 int 520 config_setrt(struct relayd *env, struct router *rt) 521 { 522 struct privsep *ps = env->sc_ps; 523 struct netroute *nr; 524 int id; 525 526 for (id = 0; id < PROC_MAX; id++) { 527 if ((ps->ps_what[id] & CONFIG_RTS) == 0 || 528 id == privsep_process) 529 continue; 530 531 DPRINTF("%s: sending router %s to %s tbl %d", __func__, 532 rt->rt_conf.name, ps->ps_title[id], rt->rt_conf.gwtable); 533 534 proc_compose(ps, id, IMSG_CFG_ROUTER, 535 &rt->rt_conf, sizeof(rt->rt_conf)); 536 537 TAILQ_FOREACH(nr, &rt->rt_netroutes, nr_entry) { 538 proc_compose(ps, id, IMSG_CFG_ROUTE, 539 &nr->nr_conf, sizeof(nr->nr_conf)); 540 } 541 } 542 543 return (0); 544 } 545 546 int 547 config_getrt(struct relayd *env, struct imsg *imsg) 548 { 549 struct router *rt; 550 551 if ((rt = calloc(1, sizeof(*rt))) == NULL) 552 return (-1); 553 554 IMSG_SIZE_CHECK(imsg, &rt->rt_conf); 555 memcpy(&rt->rt_conf, imsg->data, sizeof(rt->rt_conf)); 556 557 if ((rt->rt_gwtable = table_find(env, rt->rt_conf.gwtable)) == NULL) { 558 log_debug("%s: table not found", __func__); 559 free(rt); 560 return (-1); 561 } 562 563 TAILQ_INIT(&rt->rt_netroutes); 564 TAILQ_INSERT_TAIL(env->sc_rts, rt, rt_entry); 565 566 env->sc_routercount++; 567 568 DPRINTF("%s: %s %d received router %s", __func__, 569 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 570 rt->rt_conf.name); 571 572 return (0); 573 } 574 575 int 576 config_getroute(struct relayd *env, struct imsg *imsg) 577 { 578 struct router *rt; 579 struct netroute *nr; 580 581 if ((nr = calloc(1, sizeof(*nr))) == NULL) 582 return (-1); 583 584 IMSG_SIZE_CHECK(imsg, &nr->nr_conf); 585 memcpy(&nr->nr_conf, imsg->data, sizeof(nr->nr_conf)); 586 587 if (route_find(env, nr->nr_conf.id) != NULL) { 588 log_debug("%s: route %d already exists", 589 __func__, nr->nr_conf.id); 590 free(nr); 591 return (-1); 592 } 593 594 if ((rt = router_find(env, nr->nr_conf.routerid)) == NULL) { 595 log_debug("%s: received route for unknown router", __func__); 596 free(nr); 597 return (-1); 598 } 599 600 nr->nr_router = rt; 601 602 TAILQ_INSERT_TAIL(env->sc_routes, nr, nr_route); 603 TAILQ_INSERT_TAIL(&rt->rt_netroutes, nr, nr_entry); 604 605 env->sc_routecount++; 606 607 DPRINTF("%s: %s %d received route %d for router %s", __func__, 608 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 609 nr->nr_conf.id, rt->rt_conf.name); 610 611 return (0); 612 } 613 614 int 615 config_setproto(struct relayd *env, struct protocol *proto) 616 { 617 struct privsep *ps = env->sc_ps; 618 int id; 619 struct iovec iov[IOV_MAX]; 620 size_t c; 621 622 for (id = 0; id < PROC_MAX; id++) { 623 if ((ps->ps_what[id] & CONFIG_PROTOS) == 0 || 624 id == privsep_process) 625 continue; 626 627 DPRINTF("%s: sending protocol %s to %s", __func__, 628 proto->name, ps->ps_title[id]); 629 630 c = 0; 631 iov[c].iov_base = proto; 632 iov[c++].iov_len = sizeof(*proto); 633 634 if (proto->style != NULL) { 635 iov[c].iov_base = proto->style; 636 iov[c++].iov_len = strlen(proto->style) + 1; 637 } 638 639 proc_composev(ps, id, IMSG_CFG_PROTO, iov, c); 640 } 641 642 return (0); 643 } 644 645 int 646 config_setrule(struct relayd *env, struct protocol *proto) 647 { 648 struct privsep *ps = env->sc_ps; 649 struct relay_rule *rule; 650 struct iovec iov[IOV_MAX]; 651 int id; 652 size_t c, i; 653 654 for (id = 0; id < PROC_MAX; id++) { 655 if ((ps->ps_what[id] & CONFIG_PROTOS) == 0 || 656 id == privsep_process) 657 continue; 658 659 DPRINTF("%s: sending rules %s to %s", __func__, 660 proto->name, ps->ps_title[id]); 661 662 /* Now send all the rules */ 663 TAILQ_FOREACH(rule, &proto->rules, rule_entry) { 664 rule->rule_protoid = proto->id; 665 bzero(&rule->rule_ctl, sizeof(rule->rule_ctl)); 666 c = 0; 667 iov[c].iov_base = rule; 668 iov[c++].iov_len = sizeof(*rule); 669 for (i = 1; i < KEY_TYPE_MAX; i++) { 670 if (rule->rule_kv[i].kv_key != NULL) { 671 rule->rule_ctl.kvlen[i].key = 672 strlen(rule->rule_kv[i].kv_key); 673 iov[c].iov_base = 674 rule->rule_kv[i].kv_key; 675 iov[c++].iov_len = 676 rule->rule_ctl.kvlen[i].key; 677 } else 678 rule->rule_ctl.kvlen[i].key = -1; 679 if (rule->rule_kv[i].kv_value != NULL) { 680 rule->rule_ctl.kvlen[i].value = 681 strlen(rule->rule_kv[i].kv_value); 682 iov[c].iov_base = 683 rule->rule_kv[i].kv_value; 684 iov[c++].iov_len = 685 rule->rule_ctl.kvlen[i].value; 686 } else 687 rule->rule_ctl.kvlen[i].value = -1; 688 } 689 690 proc_composev(ps, id, IMSG_CFG_RULE, iov, c); 691 } 692 } 693 694 return (0); 695 } 696 697 int 698 config_getproto(struct relayd *env, struct imsg *imsg) 699 { 700 struct protocol *proto; 701 size_t styl; 702 size_t s; 703 u_int8_t *p = imsg->data; 704 705 if ((proto = calloc(1, sizeof(*proto))) == NULL) 706 return (-1); 707 708 IMSG_SIZE_CHECK(imsg, proto); 709 memcpy(proto, p, sizeof(*proto)); 710 s = sizeof(*proto); 711 712 styl = IMSG_DATA_SIZE(imsg) - s; 713 proto->style = NULL; 714 if (styl > 0) { 715 if ((proto->style = get_string(p + s, styl - 1)) == NULL) { 716 free(proto); 717 return (-1); 718 } 719 } 720 721 TAILQ_INIT(&proto->rules); 722 TAILQ_INIT(&proto->tlscerts); 723 proto->tlscapass = NULL; 724 725 TAILQ_INSERT_TAIL(env->sc_protos, proto, entry); 726 727 env->sc_protocount++; 728 729 DPRINTF("%s: %s %d received protocol %s", __func__, 730 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 731 proto->name); 732 733 return (0); 734 } 735 736 int 737 config_getrule(struct relayd *env, struct imsg *imsg) 738 { 739 struct protocol *proto; 740 struct relay_rule *rule; 741 size_t s, i; 742 u_int8_t *p = imsg->data; 743 ssize_t len; 744 745 if ((rule = calloc(1, sizeof(*rule))) == NULL) 746 return (-1); 747 748 IMSG_SIZE_CHECK(imsg, rule); 749 memcpy(rule, p, sizeof(*rule)); 750 s = sizeof(*rule); 751 len = IMSG_DATA_SIZE(imsg) - s; 752 753 if ((proto = proto_find(env, rule->rule_protoid)) == NULL) { 754 free(rule); 755 return (-1); 756 } 757 758 #define GETKV(_n, _f) { \ 759 if (rule->rule_ctl.kvlen[_n]._f >= 0) { \ 760 /* Also accept "empty" 0-length strings */ \ 761 if ((len < rule->rule_ctl.kvlen[_n]._f) || \ 762 (rule->rule_kv[_n].kv_##_f = \ 763 get_string(p + s, \ 764 rule->rule_ctl.kvlen[_n]._f)) == NULL) { \ 765 free(rule); \ 766 return (-1); \ 767 } \ 768 s += rule->rule_ctl.kvlen[_n]._f; \ 769 len -= rule->rule_ctl.kvlen[_n]._f; \ 770 \ 771 DPRINTF("%s: %s %s (len %ld, option %d): %s", __func__, \ 772 #_n, #_f, rule->rule_ctl.kvlen[_n]._f, \ 773 rule->rule_kv[_n].kv_option, \ 774 rule->rule_kv[_n].kv_##_f); \ 775 } \ 776 } 777 778 memset(&rule->rule_kv[0], 0, sizeof(struct kv)); 779 for (i = 1; i < KEY_TYPE_MAX; i++) { 780 TAILQ_INIT(&rule->rule_kv[i].kv_children); 781 GETKV(i, key); 782 GETKV(i, value); 783 } 784 785 if (rule->rule_labelname[0]) 786 rule->rule_label = label_name2id(rule->rule_labelname); 787 788 if (rule->rule_tagname[0]) 789 rule->rule_tag = tag_name2id(rule->rule_tagname); 790 791 if (rule->rule_taggedname[0]) 792 rule->rule_tagged = tag_name2id(rule->rule_taggedname); 793 794 rule->rule_id = proto->rulecount++; 795 796 TAILQ_INSERT_TAIL(&proto->rules, rule, rule_entry); 797 798 DPRINTF("%s: %s %d received rule %u for protocol %s", __func__, 799 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 800 rule->rule_id, proto->name); 801 802 return (0); 803 } 804 805 static int 806 config_setrelayfd(struct privsep *ps, int id, int n, 807 objid_t obj_id, objid_t rlay_id, enum fd_type type, int ofd) 808 { 809 struct ctl_relayfd rfd; 810 int fd; 811 812 rfd.id = obj_id; 813 rfd.relayid = rlay_id; 814 rfd.type = type; 815 816 if ((fd = dup(ofd)) == -1) 817 return (-1); 818 if (proc_compose_imsg(ps, id, n, IMSG_CFG_RELAY_FD, -1, fd, 819 &rfd, sizeof(rfd)) != 0) 820 return (-1); 821 822 return (0); 823 } 824 825 int 826 config_setrelay(struct relayd *env, struct relay *rlay) 827 { 828 struct privsep *ps = env->sc_ps; 829 struct ctl_relaytable crt; 830 struct relay_table *rlt; 831 struct relay_config rl; 832 struct relay_cert *cert; 833 int id; 834 int fd, n, m; 835 struct iovec iov[6]; 836 size_t c; 837 u_int what; 838 839 /* opens listening sockets etc. */ 840 if (relay_privinit(rlay) == -1) 841 return (-1); 842 843 for (id = 0; id < PROC_MAX; id++) { 844 what = ps->ps_what[id]; 845 846 if ((what & CONFIG_RELAYS) == 0 || id == privsep_process) 847 continue; 848 849 DPRINTF("%s: sending relay %s to %s fd %d", __func__, 850 rlay->rl_conf.name, ps->ps_title[id], rlay->rl_s); 851 852 memcpy(&rl, &rlay->rl_conf, sizeof(rl)); 853 854 c = 0; 855 iov[c].iov_base = &rl; 856 iov[c++].iov_len = sizeof(rl); 857 858 if ((what & CONFIG_CA_ENGINE) == 0 && 859 rl.tls_cakey_len) { 860 iov[c].iov_base = rlay->rl_tls_cakey; 861 iov[c++].iov_len = rl.tls_cakey_len; 862 } else 863 rl.tls_cakey_len = 0; 864 865 if (id == PROC_RELAY) { 866 /* XXX imsg code will close the fd after 1st call */ 867 n = -1; 868 proc_range(ps, id, &n, &m); 869 for (n = 0; n < m; n++) { 870 if ((fd = dup(rlay->rl_s)) == -1) 871 return (-1); 872 if (proc_composev_imsg(ps, id, n, 873 IMSG_CFG_RELAY, -1, fd, iov, c) != 0) { 874 log_warn("%s: failed to compose " 875 "IMSG_CFG_RELAY imsg for `%s'", 876 __func__, rlay->rl_conf.name); 877 return (-1); 878 } 879 /* Prevent fd exhaustion in the parent. */ 880 if (proc_flush_imsg(ps, id, n) == -1) { 881 log_warn("%s: failed to flush " 882 "IMSG_CFG_RELAY imsg for `%s'", 883 __func__, rlay->rl_conf.name); 884 return (-1); 885 } 886 } 887 } else { 888 if (proc_composev(ps, id, 889 IMSG_CFG_RELAY, iov, c) != 0) { 890 log_warn("%s: failed to compose " 891 "IMSG_CFG_RELAY imsg for `%s'", 892 __func__, rlay->rl_conf.name); 893 return (-1); 894 } 895 } 896 897 /* cert keypairs */ 898 TAILQ_FOREACH(cert, env->sc_certs, cert_entry) { 899 if (cert->cert_relayid != rlay->rl_conf.id) 900 continue; 901 n = -1; 902 proc_range(ps, id, &n, &m); 903 for (n = 0; (what & CONFIG_CERTS) && n < m; n++) { 904 if (cert->cert_fd != -1 && 905 config_setrelayfd(ps, id, n, 906 cert->cert_id, cert->cert_relayid, 907 RELAY_FD_CERT, cert->cert_fd) == -1) { 908 log_warn("%s: fd passing failed for " 909 "`%s'", __func__, 910 rlay->rl_conf.name); 911 return (-1); 912 } 913 if (id == PROC_RELAY && 914 cert->cert_ocsp_fd != -1 && 915 config_setrelayfd(ps, id, n, 916 cert->cert_id, cert->cert_relayid, 917 RELAY_FD_OCSP, cert->cert_ocsp_fd) == -1) { 918 log_warn("%s: fd passing failed for " 919 "`%s'", __func__, 920 rlay->rl_conf.name); 921 return (-1); 922 } 923 if (id == PROC_CA && 924 cert->cert_key_fd != -1 && 925 config_setrelayfd(ps, id, n, 926 cert->cert_id, cert->cert_relayid, 927 RELAY_FD_KEY, cert->cert_key_fd) == -1) { 928 log_warn("%s: fd passing failed for " 929 "`%s'", __func__, 930 rlay->rl_conf.name); 931 return (-1); 932 } 933 } 934 } 935 936 /* CA certs */ 937 if (what & CONFIG_CERTS) { 938 n = -1; 939 proc_range(ps, id, &n, &m); 940 for (n = 0; n < m; n++) { 941 if (rlay->rl_tls_ca_fd != -1 && 942 config_setrelayfd(ps, id, n, 0, 943 rlay->rl_conf.id, RELAY_FD_CACERT, 944 rlay->rl_tls_ca_fd) == -1) { 945 log_warn("%s: fd passing failed for " 946 "`%s'", __func__, 947 rlay->rl_conf.name); 948 return (-1); 949 } 950 if (rlay->rl_tls_cacert_fd != -1 && 951 config_setrelayfd(ps, id, n, 0, 952 rlay->rl_conf.id, RELAY_FD_CAFILE, 953 rlay->rl_tls_cacert_fd) == -1) { 954 log_warn("%s: fd passing failed for " 955 "`%s'", __func__, 956 rlay->rl_conf.name); 957 return (-1); 958 } 959 /* Prevent fd exhaustion in the parent. */ 960 if (proc_flush_imsg(ps, id, n) == -1) { 961 log_warn("%s: failed to flush " 962 "IMSG_CFG_RELAY imsg for `%s'", 963 __func__, rlay->rl_conf.name); 964 return (-1); 965 } 966 } 967 } 968 969 if ((what & CONFIG_TABLES) == 0) 970 continue; 971 972 /* Now send the tables associated to this relay */ 973 TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) { 974 crt.id = rlt->rlt_table->conf.id; 975 crt.relayid = rlay->rl_conf.id; 976 crt.mode = rlt->rlt_mode; 977 crt.flags = rlt->rlt_flags; 978 979 c = 0; 980 iov[c].iov_base = &crt; 981 iov[c++].iov_len = sizeof(crt); 982 983 proc_composev(ps, id, IMSG_CFG_RELAY_TABLE, iov, c); 984 } 985 } 986 987 /* Close server socket early to prevent fd exhaustion in the parent. */ 988 if (rlay->rl_s != -1) { 989 close(rlay->rl_s); 990 rlay->rl_s = -1; 991 } 992 if (rlay->rl_tls_cacert_fd != -1) { 993 close(rlay->rl_tls_cacert_fd); 994 rlay->rl_tls_cacert_fd = -1; 995 } 996 if (rlay->rl_tls_ca_fd != -1) { 997 close(rlay->rl_tls_ca_fd); 998 rlay->rl_tls_ca_fd = -1; 999 } 1000 TAILQ_FOREACH(cert, env->sc_certs, cert_entry) { 1001 if (cert->cert_relayid != rlay->rl_conf.id) 1002 continue; 1003 1004 if (cert->cert_fd != -1) { 1005 close(cert->cert_fd); 1006 cert->cert_fd = -1; 1007 } 1008 if (cert->cert_key_fd != -1) { 1009 close(cert->cert_key_fd); 1010 cert->cert_key_fd = -1; 1011 } 1012 if (cert->cert_ocsp_fd != -1) { 1013 close(cert->cert_ocsp_fd); 1014 cert->cert_ocsp_fd = -1; 1015 } 1016 } 1017 1018 return (0); 1019 } 1020 1021 int 1022 config_getrelay(struct relayd *env, struct imsg *imsg) 1023 { 1024 struct privsep *ps = env->sc_ps; 1025 struct relay *rlay; 1026 u_int8_t *p = imsg->data; 1027 size_t s; 1028 1029 if ((rlay = calloc(1, sizeof(*rlay))) == NULL) 1030 return (-1); 1031 1032 IMSG_SIZE_CHECK(imsg, &rlay->rl_conf); 1033 memcpy(&rlay->rl_conf, p, sizeof(rlay->rl_conf)); 1034 s = sizeof(rlay->rl_conf); 1035 1036 rlay->rl_s = imsg->fd; 1037 rlay->rl_tls_ca_fd = -1; 1038 rlay->rl_tls_cacert_fd = -1; 1039 1040 if (ps->ps_what[privsep_process] & CONFIG_PROTOS) { 1041 if (rlay->rl_conf.proto == EMPTY_ID) 1042 rlay->rl_proto = &env->sc_proto_default; 1043 else if ((rlay->rl_proto = 1044 proto_find(env, rlay->rl_conf.proto)) == NULL) { 1045 log_debug("%s: unknown protocol", __func__); 1046 goto fail; 1047 } 1048 } 1049 1050 if ((off_t)(IMSG_DATA_SIZE(imsg) - s) < 1051 (rlay->rl_conf.tls_cakey_len)) { 1052 log_debug("%s: invalid message length", __func__); 1053 goto fail; 1054 } 1055 1056 if (rlay->rl_conf.tls_cakey_len) { 1057 if ((rlay->rl_tls_cakey = get_data(p + s, 1058 rlay->rl_conf.tls_cakey_len)) == NULL) 1059 goto fail; 1060 s += rlay->rl_conf.tls_cakey_len; 1061 } 1062 1063 TAILQ_INIT(&rlay->rl_tables); 1064 TAILQ_INSERT_TAIL(env->sc_relays, rlay, rl_entry); 1065 1066 env->sc_relaycount++; 1067 1068 DPRINTF("%s: %s %d received relay %s", __func__, 1069 ps->ps_title[privsep_process], ps->ps_instance, 1070 rlay->rl_conf.name); 1071 1072 return (0); 1073 1074 fail: 1075 free(rlay->rl_tls_cakey); 1076 close(rlay->rl_s); 1077 free(rlay); 1078 return (-1); 1079 } 1080 1081 int 1082 config_getrelaytable(struct relayd *env, struct imsg *imsg) 1083 { 1084 struct relay_table *rlt = NULL; 1085 struct ctl_relaytable crt; 1086 struct relay *rlay; 1087 struct table *table; 1088 u_int8_t *p = imsg->data; 1089 1090 IMSG_SIZE_CHECK(imsg, &crt); 1091 memcpy(&crt, p, sizeof(crt)); 1092 1093 if ((rlay = relay_find(env, crt.relayid)) == NULL) { 1094 log_debug("%s: unknown relay", __func__); 1095 goto fail; 1096 } 1097 1098 if ((table = table_find(env, crt.id)) == NULL) { 1099 log_debug("%s: unknown table", __func__); 1100 goto fail; 1101 } 1102 1103 if ((rlt = calloc(1, sizeof(*rlt))) == NULL) 1104 goto fail; 1105 1106 rlt->rlt_table = table; 1107 rlt->rlt_mode = crt.mode; 1108 rlt->rlt_flags = crt.flags; 1109 1110 TAILQ_INSERT_TAIL(&rlay->rl_tables, rlt, rlt_entry); 1111 1112 DPRINTF("%s: %s %d received relay table %s for relay %s", __func__, 1113 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 1114 table->conf.name, rlay->rl_conf.name); 1115 1116 return (0); 1117 1118 fail: 1119 free(rlt); 1120 return (-1); 1121 } 1122 1123 int 1124 config_getrelayfd(struct relayd *env, struct imsg *imsg) 1125 { 1126 struct ctl_relayfd crfd; 1127 struct relay *rlay = NULL; 1128 struct relay_cert *cert; 1129 u_int8_t *p = imsg->data; 1130 1131 IMSG_SIZE_CHECK(imsg, &crfd); 1132 memcpy(&crfd, p, sizeof(crfd)); 1133 1134 switch (crfd.type) { 1135 case RELAY_FD_CERT: 1136 case RELAY_FD_KEY: 1137 case RELAY_FD_OCSP: 1138 if ((cert = cert_find(env, crfd.id)) == NULL) { 1139 if ((cert = cert_add(env, crfd.id)) == NULL) 1140 return (-1); 1141 cert->cert_relayid = crfd.relayid; 1142 } 1143 /* FALLTHROUGH */ 1144 default: 1145 if ((rlay = relay_find(env, crfd.relayid)) == NULL) { 1146 log_debug("%s: unknown relay", __func__); 1147 return (-1); 1148 } 1149 break; 1150 } 1151 1152 switch (crfd.type) { 1153 case RELAY_FD_CERT: 1154 cert->cert_fd = imsg->fd; 1155 break; 1156 case RELAY_FD_KEY: 1157 cert->cert_key_fd = imsg->fd; 1158 break; 1159 case RELAY_FD_OCSP: 1160 cert->cert_ocsp_fd = imsg->fd; 1161 break; 1162 case RELAY_FD_CACERT: 1163 rlay->rl_tls_ca_fd = imsg->fd; 1164 break; 1165 case RELAY_FD_CAFILE: 1166 rlay->rl_tls_cacert_fd = imsg->fd; 1167 break; 1168 } 1169 1170 DPRINTF("%s: %s %d received relay fd %d type %d for relay %s", __func__, 1171 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 1172 imsg->fd, crfd.type, rlay->rl_conf.name); 1173 1174 return (0); 1175 } 1176