1 /* $OpenBSD: config.c,v 1.30 2016/09/02 14:45:51 reyk 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 } 48 49 ps->ps_what[PROC_PARENT] = CONFIG_ALL; 50 ps->ps_what[PROC_PFE] = CONFIG_ALL & ~CONFIG_PROTOS; 51 ps->ps_what[PROC_HCE] = CONFIG_TABLES; 52 ps->ps_what[PROC_CA] = CONFIG_RELAYS; 53 ps->ps_what[PROC_RELAY] = CONFIG_RELAYS| 54 CONFIG_TABLES|CONFIG_PROTOS|CONFIG_CA_ENGINE; 55 56 /* Other configuration */ 57 what = ps->ps_what[privsep_process]; 58 if (what & CONFIG_TABLES) { 59 if ((env->sc_tables = 60 calloc(1, sizeof(*env->sc_tables))) == NULL) 61 return (-1); 62 TAILQ_INIT(env->sc_tables); 63 64 memset(&env->sc_empty_table, 0, sizeof(env->sc_empty_table)); 65 env->sc_empty_table.conf.id = EMPTY_TABLE; 66 env->sc_empty_table.conf.flags |= F_DISABLE; 67 (void)strlcpy(env->sc_empty_table.conf.name, "empty", 68 sizeof(env->sc_empty_table.conf.name)); 69 70 } 71 if (what & CONFIG_RDRS) { 72 if ((env->sc_rdrs = 73 calloc(1, sizeof(*env->sc_rdrs))) == NULL) 74 return (-1); 75 TAILQ_INIT(env->sc_rdrs); 76 77 } 78 if (what & CONFIG_RELAYS) { 79 if ((env->sc_relays = 80 calloc(1, sizeof(*env->sc_relays))) == NULL) 81 return (-1); 82 TAILQ_INIT(env->sc_relays); 83 if ((env->sc_pkeys = 84 calloc(1, sizeof(*env->sc_pkeys))) == NULL) 85 return (-1); 86 TAILQ_INIT(env->sc_pkeys); 87 } 88 if (what & CONFIG_PROTOS) { 89 if ((env->sc_protos = 90 calloc(1, sizeof(*env->sc_protos))) == NULL) 91 return (-1); 92 TAILQ_INIT(env->sc_protos); 93 94 bzero(&env->sc_proto_default, sizeof(env->sc_proto_default)); 95 env->sc_proto_default.id = EMPTY_ID; 96 env->sc_proto_default.flags = F_USED; 97 env->sc_proto_default.tcpflags = TCPFLAG_DEFAULT; 98 env->sc_proto_default.tcpbacklog = RELAY_BACKLOG; 99 env->sc_proto_default.tlsflags = TLSFLAG_DEFAULT; 100 (void)strlcpy(env->sc_proto_default.tlsciphers, 101 TLSCIPHERS_DEFAULT, 102 sizeof(env->sc_proto_default.tlsciphers)); 103 env->sc_proto_default.tlsecdhcurve = TLSECDHCURVE_DEFAULT; 104 env->sc_proto_default.tlsdhparams = TLSDHPARAMS_DEFAULT; 105 env->sc_proto_default.type = RELAY_PROTO_TCP; 106 (void)strlcpy(env->sc_proto_default.name, "default", 107 sizeof(env->sc_proto_default.name)); 108 } 109 if (what & CONFIG_RTS) { 110 if ((env->sc_rts = 111 calloc(1, sizeof(*env->sc_rts))) == NULL) 112 return (-1); 113 TAILQ_INIT(env->sc_rts); 114 } 115 if (what & CONFIG_ROUTES) { 116 if ((env->sc_routes = 117 calloc(1, sizeof(*env->sc_routes))) == NULL) 118 return (-1); 119 TAILQ_INIT(env->sc_routes); 120 } 121 122 return (0); 123 } 124 125 void 126 config_purge(struct relayd *env, u_int reset) 127 { 128 struct privsep *ps = env->sc_ps; 129 struct table *table; 130 struct rdr *rdr; 131 struct address *virt; 132 struct protocol *proto; 133 struct relay_rule *rule; 134 struct relay *rlay; 135 struct netroute *nr; 136 struct router *rt; 137 struct ca_pkey *pkey; 138 u_int what; 139 140 what = ps->ps_what[privsep_process] & reset; 141 142 if (what & CONFIG_TABLES && env->sc_tables != NULL) { 143 while ((table = TAILQ_FIRST(env->sc_tables)) != NULL) 144 purge_table(env, env->sc_tables, table); 145 env->sc_tablecount = 0; 146 } 147 if (what & CONFIG_RDRS && env->sc_rdrs != NULL) { 148 while ((rdr = TAILQ_FIRST(env->sc_rdrs)) != NULL) { 149 TAILQ_REMOVE(env->sc_rdrs, rdr, entry); 150 while ((virt = TAILQ_FIRST(&rdr->virts)) != NULL) { 151 TAILQ_REMOVE(&rdr->virts, virt, entry); 152 free(virt); 153 } 154 free(rdr); 155 } 156 env->sc_rdrcount = 0; 157 } 158 if (what & CONFIG_RELAYS && env->sc_pkeys != NULL) { 159 while ((pkey = TAILQ_FIRST(env->sc_pkeys)) != NULL) { 160 TAILQ_REMOVE(env->sc_pkeys, pkey, pkey_entry); 161 free(pkey); 162 } 163 } 164 if (what & CONFIG_RELAYS && env->sc_relays != NULL) { 165 while ((rlay = TAILQ_FIRST(env->sc_relays)) != NULL) 166 purge_relay(env, rlay); 167 env->sc_relaycount = 0; 168 } 169 if (what & CONFIG_PROTOS && env->sc_protos != NULL) { 170 while ((proto = TAILQ_FIRST(env->sc_protos)) != NULL) { 171 TAILQ_REMOVE(env->sc_protos, proto, entry); 172 while ((rule = TAILQ_FIRST(&proto->rules)) != NULL) 173 rule_delete(&proto->rules, rule); 174 proto->rulecount = 0; 175 } 176 } 177 if (what & CONFIG_PROTOS && env->sc_protos != NULL) { 178 while ((proto = TAILQ_FIRST(env->sc_protos)) != NULL) { 179 TAILQ_REMOVE(env->sc_protos, proto, entry); 180 free(proto->style); 181 free(proto->tlscapass); 182 free(proto); 183 } 184 env->sc_protocount = 0; 185 } 186 if (what & CONFIG_RTS && env->sc_rts != NULL) { 187 while ((rt = TAILQ_FIRST(env->sc_rts)) != NULL) { 188 TAILQ_REMOVE(env->sc_rts, rt, rt_entry); 189 while ((nr = TAILQ_FIRST(&rt->rt_netroutes)) != NULL) { 190 TAILQ_REMOVE(&rt->rt_netroutes, nr, nr_entry); 191 TAILQ_REMOVE(env->sc_routes, nr, nr_route); 192 free(nr); 193 env->sc_routecount--; 194 } 195 free(rt); 196 } 197 env->sc_routercount = 0; 198 } 199 if (what & CONFIG_ROUTES && env->sc_routes != NULL) { 200 while ((nr = TAILQ_FIRST(env->sc_routes)) != NULL) { 201 if ((rt = nr->nr_router) != NULL) 202 TAILQ_REMOVE(&rt->rt_netroutes, nr, nr_entry); 203 TAILQ_REMOVE(env->sc_routes, nr, nr_route); 204 free(nr); 205 } 206 env->sc_routecount = 0; 207 } 208 } 209 210 int 211 config_setreset(struct relayd *env, u_int reset) 212 { 213 struct privsep *ps = env->sc_ps; 214 int id; 215 216 for (id = 0; id < PROC_MAX; id++) { 217 if ((reset & ps->ps_what[id]) == 0 || 218 id == privsep_process) 219 continue; 220 proc_compose(ps, id, IMSG_CTL_RESET, &reset, sizeof(reset)); 221 } 222 223 return (0); 224 } 225 226 int 227 config_getreset(struct relayd *env, struct imsg *imsg) 228 { 229 u_int mode; 230 231 IMSG_SIZE_CHECK(imsg, &mode); 232 memcpy(&mode, imsg->data, sizeof(mode)); 233 234 config_purge(env, mode); 235 236 return (0); 237 } 238 239 int 240 config_getcfg(struct relayd *env, struct imsg *imsg) 241 { 242 struct privsep *ps = env->sc_ps; 243 struct table *tb; 244 struct host *h, *ph; 245 u_int what; 246 247 if (IMSG_DATA_SIZE(imsg) != sizeof(struct relayd_config)) 248 return (0); /* ignore */ 249 250 /* Update runtime flags */ 251 memcpy(&env->sc_conf, imsg->data, sizeof(env->sc_conf)); 252 253 what = ps->ps_what[privsep_process]; 254 255 if (what & CONFIG_TABLES) { 256 /* Update the tables */ 257 TAILQ_FOREACH(tb, env->sc_tables, entry) { 258 TAILQ_FOREACH(h, &tb->hosts, entry) { 259 if (h->conf.parentid && (ph = host_find(env, 260 h->conf.parentid)) != NULL) { 261 SLIST_INSERT_HEAD(&ph->children, 262 h, child); 263 } 264 } 265 } 266 } 267 268 if (env->sc_conf.flags & (F_TLS|F_TLSCLIENT)) { 269 ssl_init(env); 270 if (what & CONFIG_CA_ENGINE) 271 ca_engine_init(env); 272 } 273 274 if (privsep_process != PROC_PARENT) 275 proc_compose(env->sc_ps, PROC_PARENT, IMSG_CFG_DONE, NULL, 0); 276 277 return (0); 278 } 279 280 int 281 config_settable(struct relayd *env, struct table *tb) 282 { 283 struct privsep *ps = env->sc_ps; 284 struct host *host; 285 int id, c; 286 struct iovec iov[2]; 287 288 for (id = 0; id < PROC_MAX; id++) { 289 if ((ps->ps_what[id] & CONFIG_TABLES) == 0 || 290 id == privsep_process) 291 continue; 292 293 /* XXX need to send table to pfe for control socket */ 294 if (id == PROC_HCE && tb->conf.check == CHECK_NOCHECK) 295 continue; 296 297 DPRINTF("%s: sending table %s %d to %s", __func__, 298 tb->conf.name, tb->conf.id, env->sc_ps->ps_title[id]); 299 300 c = 0; 301 iov[c].iov_base = &tb->conf; 302 iov[c++].iov_len = sizeof(tb->conf); 303 if (tb->sendbuf != NULL) { 304 iov[c].iov_base = tb->sendbuf; 305 iov[c++].iov_len = strlen(tb->sendbuf); 306 } 307 308 proc_composev(ps, id, IMSG_CFG_TABLE, iov, c); 309 310 TAILQ_FOREACH(host, &tb->hosts, entry) { 311 proc_compose(ps, id, IMSG_CFG_HOST, 312 &host->conf, sizeof(host->conf)); 313 } 314 } 315 316 return (0); 317 } 318 319 int 320 config_gettable(struct relayd *env, struct imsg *imsg) 321 { 322 struct table *tb; 323 size_t sb; 324 u_int8_t *p = imsg->data; 325 size_t s; 326 327 if ((tb = calloc(1, sizeof(*tb))) == NULL) 328 return (-1); 329 330 IMSG_SIZE_CHECK(imsg, &tb->conf); 331 memcpy(&tb->conf, p, sizeof(tb->conf)); 332 s = sizeof(tb->conf); 333 334 sb = IMSG_DATA_SIZE(imsg) - s; 335 if (sb > 0) { 336 if ((tb->sendbuf = get_string(p + s, sb)) == NULL) { 337 free(tb); 338 return (-1); 339 } 340 } 341 342 TAILQ_INIT(&tb->hosts); 343 TAILQ_INSERT_TAIL(env->sc_tables, tb, entry); 344 345 env->sc_tablecount++; 346 347 DPRINTF("%s: %s %d received table %d (%s)", __func__, 348 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 349 tb->conf.id, tb->conf.name); 350 351 return (0); 352 } 353 354 int 355 config_gethost(struct relayd *env, struct imsg *imsg) 356 { 357 struct table *tb; 358 struct host *host; 359 360 if ((host = calloc(1, sizeof(*host))) == NULL) 361 return (-1); 362 363 IMSG_SIZE_CHECK(imsg, &host->conf); 364 memcpy(&host->conf, imsg->data, sizeof(host->conf)); 365 366 if (host_find(env, host->conf.id) != NULL) { 367 log_debug("%s: host %d already exists", 368 __func__, host->conf.id); 369 free(host); 370 return (-1); 371 } 372 373 if ((tb = table_find(env, host->conf.tableid)) == NULL) { 374 log_debug("%s: " 375 "received host for unknown table %d", __func__, 376 host->conf.tableid); 377 free(host); 378 return (-1); 379 } 380 381 host->tablename = tb->conf.name; 382 host->cte.s = -1; 383 384 SLIST_INIT(&host->children); 385 TAILQ_INSERT_TAIL(&tb->hosts, host, entry); 386 TAILQ_INSERT_TAIL(&env->sc_hosts, host, globalentry); 387 388 DPRINTF("%s: %s %d received host %s for table %s", __func__, 389 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 390 host->conf.name, tb->conf.name); 391 392 return (0); 393 } 394 395 int 396 config_setrdr(struct relayd *env, struct rdr *rdr) 397 { 398 struct privsep *ps = env->sc_ps; 399 struct address *virt; 400 int id; 401 402 for (id = 0; id < PROC_MAX; id++) { 403 if ((ps->ps_what[id] & CONFIG_RDRS) == 0 || 404 id == privsep_process) 405 continue; 406 407 DPRINTF("%s: sending rdr %s to %s", __func__, 408 rdr->conf.name, ps->ps_title[id]); 409 410 proc_compose(ps, id, IMSG_CFG_RDR, 411 &rdr->conf, sizeof(rdr->conf)); 412 413 TAILQ_FOREACH(virt, &rdr->virts, entry) { 414 virt->rdrid = rdr->conf.id; 415 proc_compose(ps, id, IMSG_CFG_VIRT, 416 virt, sizeof(*virt)); 417 } 418 } 419 420 return (0); 421 } 422 423 int 424 config_getrdr(struct relayd *env, struct imsg *imsg) 425 { 426 struct rdr *rdr; 427 428 if ((rdr = calloc(1, sizeof(*rdr))) == NULL) 429 return (-1); 430 431 IMSG_SIZE_CHECK(imsg, &rdr->conf); 432 memcpy(&rdr->conf, imsg->data, sizeof(rdr->conf)); 433 434 if ((rdr->table = table_find(env, rdr->conf.table_id)) == NULL) { 435 log_debug("%s: table not found", __func__); 436 free(rdr); 437 return (-1); 438 } 439 if ((rdr->backup = table_find(env, rdr->conf.backup_id)) == NULL) { 440 rdr->conf.backup_id = EMPTY_TABLE; 441 rdr->backup = &env->sc_empty_table; 442 } 443 444 TAILQ_INIT(&rdr->virts); 445 TAILQ_INSERT_TAIL(env->sc_rdrs, rdr, entry); 446 447 env->sc_rdrcount++; 448 449 DPRINTF("%s: %s %d received rdr %s", __func__, 450 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 451 rdr->conf.name); 452 453 return (0); 454 } 455 456 int 457 config_getvirt(struct relayd *env, struct imsg *imsg) 458 { 459 struct rdr *rdr; 460 struct address *virt; 461 462 IMSG_SIZE_CHECK(imsg, virt); 463 464 if ((virt = calloc(1, sizeof(*virt))) == NULL) 465 return (-1); 466 memcpy(virt, imsg->data, sizeof(*virt)); 467 468 if ((rdr = rdr_find(env, virt->rdrid)) == NULL) { 469 log_debug("%s: rdr not found", __func__); 470 free(virt); 471 return (-1); 472 } 473 474 TAILQ_INSERT_TAIL(&rdr->virts, virt, entry); 475 476 DPRINTF("%s: %s %d received address for rdr %s", __func__, 477 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 478 rdr->conf.name); 479 480 return (0); 481 } 482 483 int 484 config_setrt(struct relayd *env, struct router *rt) 485 { 486 struct privsep *ps = env->sc_ps; 487 struct netroute *nr; 488 int id; 489 490 for (id = 0; id < PROC_MAX; id++) { 491 if ((ps->ps_what[id] & CONFIG_RTS) == 0 || 492 id == privsep_process) 493 continue; 494 495 DPRINTF("%s: sending router %s to %s tbl %d", __func__, 496 rt->rt_conf.name, ps->ps_title[id], rt->rt_conf.gwtable); 497 498 proc_compose(ps, id, IMSG_CFG_ROUTER, 499 &rt->rt_conf, sizeof(rt->rt_conf)); 500 501 TAILQ_FOREACH(nr, &rt->rt_netroutes, nr_entry) { 502 proc_compose(ps, id, IMSG_CFG_ROUTE, 503 &nr->nr_conf, sizeof(nr->nr_conf)); 504 } 505 } 506 507 return (0); 508 } 509 510 int 511 config_getrt(struct relayd *env, struct imsg *imsg) 512 { 513 struct router *rt; 514 515 if ((rt = calloc(1, sizeof(*rt))) == NULL) 516 return (-1); 517 518 IMSG_SIZE_CHECK(imsg, &rt->rt_conf); 519 memcpy(&rt->rt_conf, imsg->data, sizeof(rt->rt_conf)); 520 521 if ((rt->rt_gwtable = table_find(env, rt->rt_conf.gwtable)) == NULL) { 522 log_debug("%s: table not found", __func__); 523 free(rt); 524 return (-1); 525 } 526 527 TAILQ_INIT(&rt->rt_netroutes); 528 TAILQ_INSERT_TAIL(env->sc_rts, rt, rt_entry); 529 530 env->sc_routercount++; 531 532 DPRINTF("%s: %s %d received router %s", __func__, 533 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 534 rt->rt_conf.name); 535 536 return (0); 537 } 538 539 int 540 config_getroute(struct relayd *env, struct imsg *imsg) 541 { 542 struct router *rt; 543 struct netroute *nr; 544 545 if ((nr = calloc(1, sizeof(*nr))) == NULL) 546 return (-1); 547 548 IMSG_SIZE_CHECK(imsg, &nr->nr_conf); 549 memcpy(&nr->nr_conf, imsg->data, sizeof(nr->nr_conf)); 550 551 if (route_find(env, nr->nr_conf.id) != NULL) { 552 log_debug("%s: route %d already exists", 553 __func__, nr->nr_conf.id); 554 free(nr); 555 return (-1); 556 } 557 558 if ((rt = router_find(env, nr->nr_conf.routerid)) == NULL) { 559 log_debug("%s: received route for unknown router", __func__); 560 free(nr); 561 return (-1); 562 } 563 564 nr->nr_router = rt; 565 566 TAILQ_INSERT_TAIL(env->sc_routes, nr, nr_route); 567 TAILQ_INSERT_TAIL(&rt->rt_netroutes, nr, nr_entry); 568 569 env->sc_routecount++; 570 571 DPRINTF("%s: %s %d received route %d for router %s", __func__, 572 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 573 nr->nr_conf.id, rt->rt_conf.name); 574 575 return (0); 576 } 577 578 int 579 config_setproto(struct relayd *env, struct protocol *proto) 580 { 581 struct privsep *ps = env->sc_ps; 582 int id; 583 struct iovec iov[IOV_MAX]; 584 size_t c; 585 586 for (id = 0; id < PROC_MAX; id++) { 587 if ((ps->ps_what[id] & CONFIG_PROTOS) == 0 || 588 id == privsep_process) 589 continue; 590 591 DPRINTF("%s: sending protocol %s to %s", __func__, 592 proto->name, ps->ps_title[id]); 593 594 c = 0; 595 iov[c].iov_base = proto; 596 iov[c++].iov_len = sizeof(*proto); 597 598 if (proto->style != NULL) { 599 iov[c].iov_base = proto->style; 600 iov[c++].iov_len = strlen(proto->style); 601 } 602 603 proc_composev(ps, id, IMSG_CFG_PROTO, iov, c); 604 } 605 606 return (0); 607 } 608 609 int 610 config_setrule(struct relayd *env, struct protocol *proto) 611 { 612 struct privsep *ps = env->sc_ps; 613 struct relay_rule *rule; 614 struct iovec iov[IOV_MAX]; 615 int id; 616 size_t c, i; 617 618 for (id = 0; id < PROC_MAX; id++) { 619 if ((ps->ps_what[id] & CONFIG_PROTOS) == 0 || 620 id == privsep_process) 621 continue; 622 623 DPRINTF("%s: sending rules %s to %s", __func__, 624 proto->name, ps->ps_title[id]); 625 626 /* Now send all the rules */ 627 TAILQ_FOREACH(rule, &proto->rules, rule_entry) { 628 rule->rule_protoid = proto->id; 629 bzero(&rule->rule_ctl, sizeof(rule->rule_ctl)); 630 c = 0; 631 iov[c].iov_base = rule; 632 iov[c++].iov_len = sizeof(*rule); 633 for (i = 1; i < KEY_TYPE_MAX; i++) { 634 if (rule->rule_kv[i].kv_key != NULL) { 635 rule->rule_ctl.kvlen[i].key = 636 strlen(rule->rule_kv[i].kv_key); 637 iov[c].iov_base = 638 rule->rule_kv[i].kv_key; 639 iov[c++].iov_len = 640 rule->rule_ctl.kvlen[i].key; 641 } else 642 rule->rule_ctl.kvlen[i].key = -1; 643 if (rule->rule_kv[i].kv_value != NULL) { 644 rule->rule_ctl.kvlen[i].value = 645 strlen(rule->rule_kv[i].kv_value); 646 iov[c].iov_base = 647 rule->rule_kv[i].kv_value; 648 iov[c++].iov_len = 649 rule->rule_ctl.kvlen[i].value; 650 } else 651 rule->rule_ctl.kvlen[i].value = -1; 652 } 653 654 proc_composev(ps, id, IMSG_CFG_RULE, iov, c); 655 } 656 } 657 658 return (0); 659 } 660 661 int 662 config_getproto(struct relayd *env, struct imsg *imsg) 663 { 664 struct protocol *proto; 665 size_t styl; 666 size_t s; 667 u_int8_t *p = imsg->data; 668 669 if ((proto = calloc(1, sizeof(*proto))) == NULL) 670 return (-1); 671 672 IMSG_SIZE_CHECK(imsg, proto); 673 memcpy(proto, p, sizeof(*proto)); 674 s = sizeof(*proto); 675 676 styl = IMSG_DATA_SIZE(imsg) - s; 677 if (styl > 0) { 678 if ((proto->style = get_string(p + s, styl)) == NULL) { 679 free(proto); 680 return (-1); 681 } 682 } 683 684 TAILQ_INIT(&proto->rules); 685 proto->tlscapass = NULL; 686 687 TAILQ_INSERT_TAIL(env->sc_protos, proto, entry); 688 689 env->sc_protocount++; 690 691 DPRINTF("%s: %s %d received protocol %s", __func__, 692 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 693 proto->name); 694 695 return (0); 696 } 697 698 int 699 config_getrule(struct relayd *env, struct imsg *imsg) 700 { 701 struct protocol *proto; 702 struct relay_rule *rule; 703 size_t s, i; 704 u_int8_t *p = imsg->data; 705 ssize_t len; 706 707 if ((rule = calloc(1, sizeof(*rule))) == NULL) 708 return (-1); 709 710 IMSG_SIZE_CHECK(imsg, rule); 711 memcpy(rule, p, sizeof(*rule)); 712 s = sizeof(*rule); 713 len = IMSG_DATA_SIZE(imsg) - s; 714 715 if ((proto = proto_find(env, rule->rule_protoid)) == NULL) { 716 free(rule); 717 return (-1); 718 } 719 720 #define GETKV(_n, _f) { \ 721 if (rule->rule_ctl.kvlen[_n]._f >= 0) { \ 722 /* Also accept "empty" 0-length strings */ \ 723 if ((len < rule->rule_ctl.kvlen[_n]._f) || \ 724 (rule->rule_kv[_n].kv_##_f = \ 725 get_string(p + s, \ 726 rule->rule_ctl.kvlen[_n]._f)) == NULL) { \ 727 free(rule); \ 728 return (-1); \ 729 } \ 730 s += rule->rule_ctl.kvlen[_n]._f; \ 731 len -= rule->rule_ctl.kvlen[_n]._f; \ 732 \ 733 DPRINTF("%s: %s %s (len %ld, option %d): %s", __func__, \ 734 #_n, #_f, rule->rule_ctl.kvlen[_n]._f, \ 735 rule->rule_kv[_n].kv_option, \ 736 rule->rule_kv[_n].kv_##_f); \ 737 } \ 738 } 739 740 memset(&rule->rule_kv[0], 0, sizeof(struct kv)); 741 for (i = 1; i < KEY_TYPE_MAX; i++) { 742 TAILQ_INIT(&rule->rule_kv[i].kv_children); 743 GETKV(i, key); 744 GETKV(i, value); 745 } 746 747 if (rule->rule_labelname[0]) 748 rule->rule_label = label_name2id(rule->rule_labelname); 749 750 if (rule->rule_tagname[0]) 751 rule->rule_tag = tag_name2id(rule->rule_tagname); 752 753 if (rule->rule_taggedname[0]) 754 rule->rule_tagged = tag_name2id(rule->rule_taggedname); 755 756 rule->rule_id = proto->rulecount++; 757 758 TAILQ_INSERT_TAIL(&proto->rules, rule, rule_entry); 759 760 DPRINTF("%s: %s %d received rule %u for protocol %s", __func__, 761 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 762 rule->rule_id, proto->name); 763 764 return (0); 765 } 766 767 int 768 config_setrelay(struct relayd *env, struct relay *rlay) 769 { 770 struct privsep *ps = env->sc_ps; 771 struct ctl_relaytable crt; 772 struct relay_table *rlt; 773 struct relay_config rl; 774 int id; 775 int fd, n, m; 776 struct iovec iov[6]; 777 size_t c; 778 u_int what; 779 780 /* opens listening sockets etc. */ 781 if (relay_privinit(rlay) == -1) 782 return (-1); 783 784 for (id = 0; id < PROC_MAX; id++) { 785 what = ps->ps_what[id]; 786 787 if ((what & CONFIG_RELAYS) == 0 || id == privsep_process) 788 continue; 789 790 DPRINTF("%s: sending relay %s to %s fd %d", __func__, 791 rlay->rl_conf.name, ps->ps_title[id], rlay->rl_s); 792 793 memcpy(&rl, &rlay->rl_conf, sizeof(rl)); 794 795 c = 0; 796 iov[c].iov_base = &rl; 797 iov[c++].iov_len = sizeof(rl); 798 if (rl.tls_cert_len) { 799 iov[c].iov_base = rlay->rl_tls_cert; 800 iov[c++].iov_len = rl.tls_cert_len; 801 } 802 if ((what & CONFIG_CA_ENGINE) == 0 && 803 rl.tls_key_len) { 804 iov[c].iov_base = rlay->rl_tls_key; 805 iov[c++].iov_len = rl.tls_key_len; 806 } else 807 rl.tls_key_len = 0; 808 if (rl.tls_ca_len) { 809 iov[c].iov_base = rlay->rl_tls_ca; 810 iov[c++].iov_len = rl.tls_ca_len; 811 } 812 if (rl.tls_cacert_len) { 813 iov[c].iov_base = rlay->rl_tls_cacert; 814 iov[c++].iov_len = rl.tls_cacert_len; 815 } 816 if ((what & CONFIG_CA_ENGINE) == 0 && 817 rl.tls_cakey_len) { 818 iov[c].iov_base = rlay->rl_tls_cakey; 819 iov[c++].iov_len = rl.tls_cakey_len; 820 } else 821 rl.tls_cakey_len = 0; 822 823 if (id == PROC_RELAY) { 824 /* XXX imsg code will close the fd after 1st call */ 825 n = -1; 826 proc_range(ps, id, &n, &m); 827 for (n = 0; n < m; n++) { 828 if ((fd = dup(rlay->rl_s)) == -1) 829 return (-1); 830 proc_composev_imsg(ps, id, n, 831 IMSG_CFG_RELAY, -1, fd, iov, c); 832 } 833 } else { 834 proc_composev(ps, id, IMSG_CFG_RELAY, iov, c); 835 } 836 837 if ((what & CONFIG_TABLES) == 0) 838 continue; 839 840 /* Now send the tables associated to this relay */ 841 TAILQ_FOREACH(rlt, &rlay->rl_tables, rlt_entry) { 842 crt.id = rlt->rlt_table->conf.id; 843 crt.relayid = rlay->rl_conf.id; 844 crt.mode = rlt->rlt_mode; 845 crt.flags = rlt->rlt_flags; 846 847 c = 0; 848 iov[c].iov_base = &crt; 849 iov[c++].iov_len = sizeof(crt); 850 851 proc_composev(ps, id, IMSG_CFG_RELAY_TABLE, iov, c); 852 } 853 } 854 855 close(rlay->rl_s); 856 rlay->rl_s = -1; 857 858 return (0); 859 } 860 861 int 862 config_getrelay(struct relayd *env, struct imsg *imsg) 863 { 864 struct privsep *ps = env->sc_ps; 865 struct relay *rlay; 866 u_int8_t *p = imsg->data; 867 size_t s; 868 869 if ((rlay = calloc(1, sizeof(*rlay))) == NULL) 870 return (-1); 871 872 IMSG_SIZE_CHECK(imsg, &rlay->rl_conf); 873 memcpy(&rlay->rl_conf, p, sizeof(rlay->rl_conf)); 874 s = sizeof(rlay->rl_conf); 875 876 rlay->rl_s = imsg->fd; 877 878 if (ps->ps_what[privsep_process] & CONFIG_PROTOS) { 879 if (rlay->rl_conf.proto == EMPTY_ID) 880 rlay->rl_proto = &env->sc_proto_default; 881 else if ((rlay->rl_proto = 882 proto_find(env, rlay->rl_conf.proto)) == NULL) { 883 log_debug("%s: unknown protocol", __func__); 884 goto fail; 885 } 886 } 887 888 if ((off_t)(IMSG_DATA_SIZE(imsg) - s) < 889 (rlay->rl_conf.tls_cert_len + 890 rlay->rl_conf.tls_key_len + 891 rlay->rl_conf.tls_ca_len + 892 rlay->rl_conf.tls_cacert_len + 893 rlay->rl_conf.tls_cakey_len)) { 894 log_debug("%s: invalid message length", __func__); 895 goto fail; 896 } 897 898 if (rlay->rl_conf.tls_cert_len) { 899 if ((rlay->rl_tls_cert = get_data(p + s, 900 rlay->rl_conf.tls_cert_len)) == NULL) 901 goto fail; 902 s += rlay->rl_conf.tls_cert_len; 903 } 904 if (rlay->rl_conf.tls_key_len) { 905 if ((rlay->rl_tls_key = get_data(p + s, 906 rlay->rl_conf.tls_key_len)) == NULL) 907 goto fail; 908 s += rlay->rl_conf.tls_key_len; 909 } 910 if (rlay->rl_conf.tls_ca_len) { 911 if ((rlay->rl_tls_ca = get_data(p + s, 912 rlay->rl_conf.tls_ca_len)) == NULL) 913 goto fail; 914 s += rlay->rl_conf.tls_ca_len; 915 } 916 if (rlay->rl_conf.tls_cacert_len) { 917 if ((rlay->rl_tls_cacert = get_data(p + s, 918 rlay->rl_conf.tls_cacert_len)) == NULL) 919 goto fail; 920 s += rlay->rl_conf.tls_cacert_len; 921 } 922 if (rlay->rl_conf.tls_cakey_len) { 923 if ((rlay->rl_tls_cakey = get_data(p + s, 924 rlay->rl_conf.tls_cakey_len)) == NULL) 925 goto fail; 926 s += rlay->rl_conf.tls_cakey_len; 927 } 928 929 TAILQ_INIT(&rlay->rl_tables); 930 TAILQ_INSERT_TAIL(env->sc_relays, rlay, rl_entry); 931 932 env->sc_relaycount++; 933 934 DPRINTF("%s: %s %d received relay %s", __func__, 935 ps->ps_title[privsep_process], ps->ps_instance, 936 rlay->rl_conf.name); 937 938 return (0); 939 940 fail: 941 free(rlay->rl_tls_cert); 942 free(rlay->rl_tls_key); 943 free(rlay->rl_tls_ca); 944 close(rlay->rl_s); 945 free(rlay); 946 return (-1); 947 } 948 949 int 950 config_getrelaytable(struct relayd *env, struct imsg *imsg) 951 { 952 struct relay_table *rlt = NULL; 953 struct ctl_relaytable crt; 954 struct relay *rlay; 955 struct table *table; 956 u_int8_t *p = imsg->data; 957 958 IMSG_SIZE_CHECK(imsg, &crt); 959 memcpy(&crt, p, sizeof(crt)); 960 961 if ((rlay = relay_find(env, crt.relayid)) == NULL) { 962 log_debug("%s: unknown relay", __func__); 963 goto fail; 964 } 965 966 if ((table = table_find(env, crt.id)) == NULL) { 967 log_debug("%s: unknown table", __func__); 968 goto fail; 969 } 970 971 if ((rlt = calloc(1, sizeof(*rlt))) == NULL) 972 goto fail; 973 974 rlt->rlt_table = table; 975 rlt->rlt_mode = crt.mode; 976 rlt->rlt_flags = crt.flags; 977 978 TAILQ_INSERT_TAIL(&rlay->rl_tables, rlt, rlt_entry); 979 980 DPRINTF("%s: %s %d received relay table %s for relay %s", __func__, 981 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 982 table->conf.name, rlay->rl_conf.name); 983 984 return (0); 985 986 fail: 987 free(rlt); 988 return (-1); 989 } 990