1 /* $OpenBSD: config.c,v 1.3 2012/05/08 15:10:15 benno Exp $ */ 2 3 /* 4 * Copyright (c) 2011 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/socket.h> 21 #include <sys/stat.h> 22 #include <sys/queue.h> 23 #include <sys/uio.h> 24 25 #include <net/if.h> 26 #include <net/pfvar.h> 27 #include <netinet/in.h> 28 #include <arpa/inet.h> 29 #include <arpa/nameser.h> 30 #include <net/route.h> 31 32 #include <ctype.h> 33 #include <unistd.h> 34 #include <err.h> 35 #include <errno.h> 36 #include <event.h> 37 #include <limits.h> 38 #include <stdint.h> 39 #include <stdarg.h> 40 #include <stdio.h> 41 #include <netdb.h> 42 #include <string.h> 43 #include <ifaddrs.h> 44 45 #include <openssl/ssl.h> 46 47 #include "relayd.h" 48 49 int 50 config_init(struct relayd *env) 51 { 52 struct privsep *ps = env->sc_ps; 53 u_int what; 54 55 /* Global configuration */ 56 if (privsep_process == PROC_PARENT) { 57 env->sc_timeout.tv_sec = CHECK_TIMEOUT / 1000; 58 env->sc_timeout.tv_usec = (CHECK_TIMEOUT % 1000) * 1000; 59 env->sc_interval.tv_sec = CHECK_INTERVAL; 60 env->sc_interval.tv_usec = 0; 61 env->sc_prefork_relay = RELAY_NUMPROC; 62 env->sc_statinterval.tv_sec = RELAY_STATINTERVAL; 63 64 ps->ps_what[PROC_PARENT] = CONFIG_ALL; 65 ps->ps_what[PROC_PFE] = CONFIG_ALL & ~CONFIG_PROTOS; 66 ps->ps_what[PROC_HCE] = CONFIG_TABLES; 67 ps->ps_what[PROC_RELAY] = 68 CONFIG_TABLES|CONFIG_RELAYS|CONFIG_PROTOS; 69 } 70 71 /* Other configuration */ 72 what = ps->ps_what[privsep_process]; 73 if (what & CONFIG_TABLES) { 74 if ((env->sc_tables = 75 calloc(1, sizeof(*env->sc_tables))) == NULL) 76 return (-1); 77 TAILQ_INIT(env->sc_tables); 78 79 memset(&env->sc_empty_table, 0, sizeof(env->sc_empty_table)); 80 env->sc_empty_table.conf.id = EMPTY_TABLE; 81 env->sc_empty_table.conf.flags |= F_DISABLE; 82 (void)strlcpy(env->sc_empty_table.conf.name, "empty", 83 sizeof(env->sc_empty_table.conf.name)); 84 85 } 86 if (what & CONFIG_RDRS) { 87 if ((env->sc_rdrs = 88 calloc(1, sizeof(*env->sc_rdrs))) == NULL) 89 return (-1); 90 TAILQ_INIT(env->sc_rdrs); 91 92 } 93 if (what & CONFIG_RELAYS) { 94 if ((env->sc_relays = 95 calloc(1, sizeof(*env->sc_relays))) == NULL) 96 return (-1); 97 TAILQ_INIT(env->sc_relays); 98 } 99 if (what & CONFIG_PROTOS) { 100 if ((env->sc_protos = 101 calloc(1, sizeof(*env->sc_protos))) == NULL) 102 return (-1); 103 TAILQ_INIT(env->sc_protos); 104 105 bzero(&env->sc_proto_default, sizeof(env->sc_proto_default)); 106 env->sc_proto_default.id = EMPTY_ID; 107 env->sc_proto_default.flags = F_USED; 108 env->sc_proto_default.cache = RELAY_CACHESIZE; 109 env->sc_proto_default.tcpflags = TCPFLAG_DEFAULT; 110 env->sc_proto_default.tcpbacklog = RELAY_BACKLOG; 111 env->sc_proto_default.sslflags = SSLFLAG_DEFAULT; 112 (void)strlcpy(env->sc_proto_default.sslciphers, 113 SSLCIPHERS_DEFAULT, 114 sizeof(env->sc_proto_default.sslciphers)); 115 env->sc_proto_default.type = RELAY_PROTO_TCP; 116 (void)strlcpy(env->sc_proto_default.name, "default", 117 sizeof(env->sc_proto_default.name)); 118 RB_INIT(&env->sc_proto_default.request_tree); 119 RB_INIT(&env->sc_proto_default.response_tree); 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 *rlay; 146 struct netroute *nr; 147 struct router *rt; 148 u_int what; 149 150 what = ps->ps_what[privsep_process] & reset; 151 152 if (what & CONFIG_TABLES && env->sc_tables != NULL) { 153 while ((table = TAILQ_FIRST(env->sc_tables)) != NULL) 154 purge_table(env->sc_tables, table); 155 env->sc_tablecount = 0; 156 } 157 if (what & CONFIG_RDRS && env->sc_rdrs != NULL) { 158 while ((rdr = TAILQ_FIRST(env->sc_rdrs)) != NULL) { 159 TAILQ_REMOVE(env->sc_rdrs, rdr, entry); 160 while ((virt = TAILQ_FIRST(&rdr->virts)) != NULL) { 161 TAILQ_REMOVE(&rdr->virts, virt, entry); 162 free(virt); 163 } 164 free(rdr); 165 } 166 env->sc_rdrcount = 0; 167 } 168 if (what & CONFIG_RELAYS && env->sc_relays != NULL) { 169 while ((rlay = TAILQ_FIRST(env->sc_relays)) != NULL) 170 purge_relay(env, rlay); 171 env->sc_relaycount = 0; 172 } 173 if (what & CONFIG_PROTOS && env->sc_protos != NULL) { 174 while ((proto = TAILQ_FIRST(env->sc_protos)) != NULL) { 175 TAILQ_REMOVE(env->sc_protos, proto, entry); 176 purge_tree(&proto->request_tree); 177 purge_tree(&proto->response_tree); 178 if (proto->style != NULL) 179 free(proto->style); 180 free(proto); 181 } 182 env->sc_protocount = 0; 183 } 184 if (what & CONFIG_RTS && env->sc_rts != NULL) { 185 while ((rt = TAILQ_FIRST(env->sc_rts)) != NULL) { 186 TAILQ_REMOVE(env->sc_rts, rt, rt_entry); 187 while ((nr = TAILQ_FIRST(&rt->rt_netroutes)) != NULL) { 188 TAILQ_REMOVE(&rt->rt_netroutes, nr, nr_entry); 189 TAILQ_REMOVE(env->sc_routes, nr, nr_route); 190 free(nr); 191 env->sc_routecount--; 192 } 193 free(rt); 194 } 195 env->sc_routercount = 0; 196 } 197 if (what & CONFIG_ROUTES && env->sc_routes != NULL) { 198 while ((nr = TAILQ_FIRST(env->sc_routes)) != NULL) { 199 if ((rt = nr->nr_router) != NULL) 200 TAILQ_REMOVE(&rt->rt_netroutes, nr, nr_entry); 201 TAILQ_REMOVE(env->sc_routes, nr, nr_route); 202 free(nr); 203 } 204 env->sc_routecount = 0; 205 } 206 } 207 208 int 209 config_setreset(struct relayd *env, u_int reset) 210 { 211 struct privsep *ps = env->sc_ps; 212 int id; 213 214 for (id = 0; id < PROC_MAX; id++) { 215 if ((reset & ps->ps_what[id]) == 0 || 216 id == privsep_process) 217 continue; 218 proc_compose_imsg(ps, id, -1, IMSG_CTL_RESET, -1, 219 &reset, sizeof(reset)); 220 } 221 222 return (0); 223 } 224 225 int 226 config_getreset(struct relayd *env, struct imsg *imsg) 227 { 228 u_int mode; 229 230 IMSG_SIZE_CHECK(imsg, &mode); 231 memcpy(&mode, imsg->data, sizeof(mode)); 232 233 config_purge(env, mode); 234 235 return (0); 236 } 237 238 int 239 config_getcfg(struct relayd *env, struct imsg *imsg) 240 { 241 struct privsep *ps = env->sc_ps; 242 struct table *tb; 243 struct host *h, *ph; 244 struct ctl_flags cf; 245 246 if (IMSG_DATA_SIZE(imsg) != sizeof(cf)) 247 return (0); /* ignore */ 248 249 /* Update runtime flags */ 250 memcpy(&cf, imsg->data, sizeof(cf)); 251 env->sc_opts = cf.cf_opts; 252 env->sc_flags = cf.cf_flags; 253 254 if (ps->ps_what[privsep_process] & CONFIG_TABLES) { 255 /* Update the tables */ 256 TAILQ_FOREACH(tb, env->sc_tables, entry) { 257 TAILQ_FOREACH(h, &tb->hosts, entry) { 258 if (h->conf.parentid && (ph = host_find(env, 259 h->conf.parentid)) != NULL) { 260 SLIST_INSERT_HEAD(&ph->children, 261 h, child); 262 } 263 } 264 } 265 } 266 267 if (env->sc_flags & (F_SSL|F_SSLCLIENT)) 268 ssl_init(env); 269 270 if (privsep_process != PROC_PARENT) 271 proc_compose_imsg(env->sc_ps, PROC_PARENT, -1, 272 IMSG_CFG_DONE, -1, NULL, 0); 273 274 return (0); 275 } 276 277 int 278 config_settable(struct relayd *env, struct table *tb) 279 { 280 struct privsep *ps = env->sc_ps; 281 struct host *host; 282 int id, c; 283 struct iovec iov[2]; 284 285 for (id = 0; id < PROC_MAX; id++) { 286 if ((ps->ps_what[id] & CONFIG_TABLES) == 0 || 287 id == privsep_process) 288 continue; 289 290 /* XXX need to send table to pfe for control socket */ 291 if (id == PROC_HCE && tb->conf.check == CHECK_NOCHECK) 292 continue; 293 294 DPRINTF("%s: sending table %s %d to %s", __func__, 295 tb->conf.name, tb->conf.id, env->sc_ps->ps_title[id]); 296 297 c = 0; 298 iov[c].iov_base = &tb->conf; 299 iov[c++].iov_len = sizeof(tb->conf); 300 if (tb->sendbuf != NULL) { 301 iov[c].iov_base = tb->sendbuf; 302 iov[c++].iov_len = strlen(tb->sendbuf); 303 } 304 305 proc_composev_imsg(ps, id, -1, IMSG_CFG_TABLE, -1, iov, c); 306 307 TAILQ_FOREACH(host, &tb->hosts, entry) { 308 proc_compose_imsg(ps, id, -1, IMSG_CFG_HOST, -1, 309 &host->conf, sizeof(host->conf)); 310 } 311 } 312 313 return (0); 314 } 315 316 int 317 config_gettable(struct relayd *env, struct imsg *imsg) 318 { 319 struct table *tb; 320 size_t sb; 321 u_int8_t *p = imsg->data; 322 size_t s; 323 324 if ((tb = calloc(1, sizeof(*tb))) == NULL) 325 return (-1); 326 327 IMSG_SIZE_CHECK(imsg, &tb->conf); 328 memcpy(&tb->conf, p, sizeof(tb->conf)); 329 s = sizeof(tb->conf); 330 331 sb = IMSG_DATA_SIZE(imsg) - s; 332 if (sb > 0) { 333 if ((tb->sendbuf = get_string(p + s, sb)) == NULL) { 334 free(tb); 335 return (-1); 336 } 337 } 338 339 TAILQ_INIT(&tb->hosts); 340 TAILQ_INSERT_TAIL(env->sc_tables, tb, entry); 341 342 env->sc_tablecount++; 343 344 DPRINTF("%s: %s %d received table %d (%s)", __func__, 345 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 346 tb->conf.id, tb->conf.name); 347 348 return (0); 349 } 350 351 int 352 config_gethost(struct relayd *env, struct imsg *imsg) 353 { 354 struct table *tb; 355 struct host *host; 356 357 if ((host = calloc(1, sizeof(*host))) == NULL) 358 return (-1); 359 360 IMSG_SIZE_CHECK(imsg, &host->conf); 361 memcpy(&host->conf, imsg->data, sizeof(host->conf)); 362 363 if (host_find(env, host->conf.id) != NULL) { 364 log_debug("%s: host %d already exists", 365 __func__, host->conf.id); 366 free(host); 367 return (-1); 368 } 369 370 if ((tb = table_find(env, host->conf.tableid)) == NULL) { 371 log_debug("%s: " 372 "received host for unknown table %d", __func__, 373 host->conf.tableid); 374 free(host); 375 return (-1); 376 } 377 378 host->tablename = tb->conf.name; 379 host->cte.s = -1; 380 381 SLIST_INIT(&host->children); 382 TAILQ_INSERT_TAIL(&tb->hosts, host, entry); 383 384 DPRINTF("%s: %s %d received host %s for table %s", __func__, 385 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 386 host->conf.name, tb->conf.name); 387 388 return (0); 389 } 390 391 int 392 config_setrdr(struct relayd *env, struct rdr *rdr) 393 { 394 struct privsep *ps = env->sc_ps; 395 struct address *virt; 396 int id; 397 398 for (id = 0; id < PROC_MAX; id++) { 399 if ((ps->ps_what[id] & CONFIG_RDRS) == 0 || 400 id == privsep_process) 401 continue; 402 403 DPRINTF("%s: sending rdr %s to %s", __func__, 404 rdr->conf.name, ps->ps_title[id]); 405 406 proc_compose_imsg(ps, id, -1, IMSG_CFG_RDR, -1, 407 &rdr->conf, sizeof(rdr->conf)); 408 409 TAILQ_FOREACH(virt, &rdr->virts, entry) { 410 virt->rdrid = rdr->conf.id; 411 proc_compose_imsg(ps, id, -1, IMSG_CFG_VIRT, -1, 412 virt, sizeof(*virt)); 413 } 414 } 415 416 return (0); 417 } 418 419 int 420 config_getrdr(struct relayd *env, struct imsg *imsg) 421 { 422 struct rdr *rdr; 423 424 if ((rdr = calloc(1, sizeof(*rdr))) == NULL) 425 return (-1); 426 427 IMSG_SIZE_CHECK(imsg, &rdr->conf); 428 memcpy(&rdr->conf, imsg->data, sizeof(rdr->conf)); 429 430 if ((rdr->table = table_find(env, rdr->conf.table_id)) == NULL) { 431 log_debug("%s: table not found", __func__); 432 free(rdr); 433 return (-1); 434 } 435 if ((rdr->backup = table_find(env, rdr->conf.backup_id)) == NULL) { 436 rdr->conf.backup_id = EMPTY_TABLE; 437 rdr->backup = &env->sc_empty_table; 438 } 439 440 TAILQ_INIT(&rdr->virts); 441 TAILQ_INSERT_TAIL(env->sc_rdrs, rdr, entry); 442 443 env->sc_rdrcount++; 444 445 DPRINTF("%s: %s %d received rdr %s", __func__, 446 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 447 rdr->conf.name); 448 449 return (0); 450 } 451 452 int 453 config_getvirt(struct relayd *env, struct imsg *imsg) 454 { 455 struct rdr *rdr; 456 struct address *virt; 457 458 IMSG_SIZE_CHECK(imsg, virt); 459 460 if ((virt = calloc(1, sizeof(*virt))) == NULL) 461 return (-1); 462 memcpy(virt, imsg->data, sizeof(*virt)); 463 464 if ((rdr = rdr_find(env, virt->rdrid)) == NULL) { 465 log_debug("%s: rdr not found", __func__); 466 free(virt); 467 return (-1); 468 } 469 470 TAILQ_INSERT_TAIL(&rdr->virts, virt, entry); 471 472 DPRINTF("%s: %s %d received address for rdr %s", __func__, 473 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 474 rdr->conf.name); 475 476 return (0); 477 } 478 479 int 480 config_setrt(struct relayd *env, struct router *rt) 481 { 482 struct privsep *ps = env->sc_ps; 483 struct netroute *nr; 484 int id; 485 486 for (id = 0; id < PROC_MAX; id++) { 487 if ((ps->ps_what[id] & CONFIG_RTS) == 0 || 488 id == privsep_process) 489 continue; 490 491 DPRINTF("%s: sending router %s to %s tbl %d", __func__, 492 rt->rt_conf.name, ps->ps_title[id], rt->rt_conf.gwtable); 493 494 proc_compose_imsg(ps, id, -1, IMSG_CFG_ROUTER, -1, 495 &rt->rt_conf, sizeof(rt->rt_conf)); 496 497 TAILQ_FOREACH(nr, &rt->rt_netroutes, nr_entry) { 498 proc_compose_imsg(ps, id, -1, IMSG_CFG_ROUTE, -1, 499 &nr->nr_conf, sizeof(nr->nr_conf)); 500 } 501 } 502 503 return (0); 504 } 505 506 int 507 config_getrt(struct relayd *env, struct imsg *imsg) 508 { 509 struct router *rt; 510 511 if ((rt = calloc(1, sizeof(*rt))) == NULL) 512 return (-1); 513 514 IMSG_SIZE_CHECK(imsg, &rt->rt_conf); 515 memcpy(&rt->rt_conf, imsg->data, sizeof(rt->rt_conf)); 516 517 if ((rt->rt_gwtable = table_find(env, rt->rt_conf.gwtable)) == NULL) { 518 log_debug("%s: table not found", __func__); 519 free(rt); 520 return (-1); 521 } 522 523 TAILQ_INIT(&rt->rt_netroutes); 524 TAILQ_INSERT_TAIL(env->sc_rts, rt, rt_entry); 525 526 env->sc_routercount++; 527 528 DPRINTF("%s: %s %d received router %s", __func__, 529 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 530 rt->rt_conf.name); 531 532 return (0); 533 } 534 535 int 536 config_getroute(struct relayd *env, struct imsg *imsg) 537 { 538 struct router *rt; 539 struct netroute *nr; 540 541 if ((nr = calloc(1, sizeof(*nr))) == NULL) 542 return (-1); 543 544 IMSG_SIZE_CHECK(imsg, &nr->nr_conf); 545 memcpy(&nr->nr_conf, imsg->data, sizeof(nr->nr_conf)); 546 547 if (route_find(env, nr->nr_conf.id) != NULL) { 548 log_debug("%s: route %d already exists", 549 __func__, nr->nr_conf.id); 550 free(nr); 551 return (-1); 552 } 553 554 if ((rt = router_find(env, nr->nr_conf.routerid)) == NULL) { 555 log_debug("%s: received route for unknown router", __func__); 556 free(nr); 557 return (-1); 558 } 559 560 nr->nr_router = rt; 561 562 TAILQ_INSERT_TAIL(env->sc_routes, nr, nr_route); 563 TAILQ_INSERT_TAIL(&rt->rt_netroutes, nr, nr_entry); 564 565 env->sc_routecount++; 566 567 DPRINTF("%s: %s %d received route %d for router %s", __func__, 568 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 569 nr->nr_conf.id, rt->rt_conf.name); 570 571 return (0); 572 } 573 574 int 575 config_setproto(struct relayd *env, struct protocol *proto) 576 { 577 struct privsep *ps = env->sc_ps; 578 int id; 579 struct iovec iov[2]; 580 size_t c; 581 582 for (id = 0; id < PROC_MAX; id++) { 583 if ((ps->ps_what[id] & CONFIG_PROTOS) == 0 || 584 id == privsep_process) 585 continue; 586 587 DPRINTF("%s: sending protocol %s to %s", __func__, 588 proto->name, ps->ps_title[id]); 589 590 c = 0; 591 iov[c].iov_base = proto; 592 iov[c++].iov_len = sizeof(*proto); 593 594 if (proto->style != NULL) { 595 iov[c].iov_base = proto->style; 596 iov[c++].iov_len = strlen(proto->style); 597 } 598 599 /* XXX struct protocol should be split */ 600 proc_composev_imsg(ps, id, -1, IMSG_CFG_PROTO, -1, iov, c); 601 602 /* Now send all the protocol key/value nodes */ 603 if (config_setprotonode(env, id, proto, 604 RELAY_DIR_REQUEST) == -1 || 605 config_setprotonode(env, id, proto, 606 RELAY_DIR_RESPONSE) == -1) 607 return (-1); 608 } 609 610 return (0); 611 } 612 613 int 614 config_getproto(struct relayd *env, struct imsg *imsg) 615 { 616 struct protocol *proto; 617 size_t styl; 618 size_t s; 619 u_int8_t *p = imsg->data; 620 621 if ((proto = calloc(1, sizeof(*proto))) == NULL) 622 return (-1); 623 624 IMSG_SIZE_CHECK(imsg, proto); 625 memcpy(proto, p, sizeof(*proto)); 626 s = sizeof(*proto); 627 628 styl = IMSG_DATA_SIZE(imsg) - s; 629 if (styl > 0) { 630 if ((proto->style = get_string(p + s, styl)) == NULL) { 631 free(proto); 632 return (-1); 633 } 634 } 635 636 proto->request_nodes = 0; 637 proto->response_nodes = 0; 638 RB_INIT(&proto->request_tree); 639 RB_INIT(&proto->response_tree); 640 641 TAILQ_INSERT_TAIL(env->sc_protos, proto, entry); 642 643 env->sc_protocount++; 644 645 DPRINTF("%s: %s %d received protocol %s", __func__, 646 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 647 proto->name); 648 649 return (0); 650 } 651 652 int 653 config_setprotonode(struct relayd *env, enum privsep_procid id, 654 struct protocol *proto, enum direction dir) 655 { 656 struct privsep *ps = env->sc_ps; 657 struct iovec iov[IOV_MAX]; 658 size_t c, sz; 659 struct protonode *proot, *pn; 660 struct proto_tree *tree; 661 662 if (dir == RELAY_DIR_RESPONSE) 663 tree = &proto->response_tree; 664 else 665 tree = &proto->request_tree; 666 667 sz = c = 0; 668 RB_FOREACH(proot, proto_tree, tree) { 669 PROTONODE_FOREACH(pn, proot, entry) { 670 pn->conf.protoid = proto->id; 671 pn->conf.dir = dir; 672 pn->conf.keylen = pn->key ? strlen(pn->key) : 0; 673 pn->conf.valuelen = pn->value ? strlen(pn->value) : 0; 674 if (pn->label != 0 && pn->labelname == NULL) 675 pn->labelname = strdup(pn_id2name(pn->label)); 676 pn->conf.labelnamelen = pn->labelname ? strlen(pn->labelname) : 0; 677 678 pn->conf.len = sizeof(*pn) + 679 pn->conf.keylen + pn->conf.valuelen + pn->conf.labelnamelen; 680 681 if (pn->conf.len > (MAX_IMSGSIZE - IMSG_HEADER_SIZE)) 682 return (-1); 683 684 if (c && ((c + 3) >= IOV_MAX || (sz + pn->conf.len) > 685 (MAX_IMSGSIZE - IMSG_HEADER_SIZE))) { 686 proc_composev_imsg(ps, id, -1, 687 IMSG_CFG_PROTONODE, -1, iov, c); 688 c = sz = 0; 689 } 690 691 iov[c].iov_base = pn; 692 iov[c++].iov_len = sizeof(*pn); 693 if (pn->conf.keylen) { 694 iov[c].iov_base = pn->key; 695 iov[c++].iov_len = pn->conf.keylen; 696 } 697 if (pn->conf.valuelen) { 698 iov[c].iov_base = pn->value; 699 iov[c++].iov_len = pn->conf.valuelen; 700 } 701 if (pn->conf.labelnamelen) { 702 iov[c].iov_base = pn->labelname; 703 iov[c++].iov_len = pn->conf.labelnamelen; 704 } 705 sz += pn->conf.len; 706 } 707 } 708 709 if (c && sz) 710 proc_composev_imsg(ps, id, -1, IMSG_CFG_PROTONODE, -1, iov, c); 711 712 return (0); 713 } 714 715 int 716 config_getprotonode(struct relayd *env, struct imsg *imsg) 717 { 718 struct protocol *proto = NULL; 719 struct protonode pn; 720 size_t z, s, c = 0; 721 u_int8_t *p = imsg->data; 722 723 bzero(&pn, sizeof(pn)); 724 725 IMSG_SIZE_CHECK(imsg, &pn); 726 for (z = 0; z < (IMSG_DATA_SIZE(imsg) - sizeof(pn)); z += pn.conf.len) { 727 s = z; 728 memcpy(&pn, p + s, sizeof(pn)); 729 s += sizeof(pn); 730 731 if ((proto = proto_find(env, pn.conf.protoid)) == NULL) { 732 log_debug("%s: unknown protocol %d", __func__, 733 pn.conf.protoid); 734 return (-1); 735 } 736 737 pn.key = pn.value = pn.labelname = NULL; 738 bzero(&pn.entry, sizeof(pn.entry)); 739 bzero(&pn.nodes, sizeof(pn.nodes)); 740 bzero(&pn.head, sizeof(pn.head)); 741 742 if (pn.conf.keylen) { 743 if ((pn.key = get_string(p + s, 744 pn.conf.keylen)) == NULL) { 745 log_debug("%s: failed to get key", __func__); 746 return (-1); 747 } 748 s += pn.conf.keylen; 749 } 750 if (pn.conf.valuelen) { 751 if ((pn.value = get_string(p + s, 752 pn.conf.valuelen)) == NULL) { 753 log_debug("%s: failed to get value", __func__); 754 if (pn.key != NULL) 755 free(pn.key); 756 return (-1); 757 } 758 s += pn.conf.valuelen; 759 } 760 if (pn.conf.labelnamelen) { 761 if ((pn.labelname = get_string(p + s, 762 pn.conf.labelnamelen)) == NULL) { 763 log_debug("%s: failed to get labelname", __func__); 764 return (-1); 765 } 766 s += pn.conf.labelnamelen; 767 } 768 769 if (protonode_add(pn.conf.dir, proto, &pn) == -1) { 770 if (pn.key != NULL) 771 free(pn.key); 772 if (pn.value != NULL) 773 free(pn.value); 774 if (pn.labelname != NULL) 775 free(pn.labelname); 776 log_debug("%s: failed to add protocol node", __func__); 777 return (-1); 778 } 779 c++; 780 } 781 782 if (!c) 783 return (0); 784 785 DPRINTF("%s: %s %d received %d nodes for protocol %s", __func__, 786 env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, 787 c, proto->name); 788 789 return (0); 790 } 791 792 int 793 config_setrelay(struct relayd *env, struct relay *rlay) 794 { 795 struct privsep *ps = env->sc_ps; 796 int id; 797 int fd, n, m; 798 struct iovec iov[4]; 799 size_t c; 800 801 /* opens listening sockets etc. */ 802 if (relay_privinit(rlay) == -1) 803 return (-1); 804 805 for (id = 0; id < PROC_MAX; id++) { 806 if ((ps->ps_what[id] & CONFIG_RELAYS) == 0 || 807 id == privsep_process) 808 continue; 809 810 DPRINTF("%s: sending relay %s to %s fd %d", __func__, 811 rlay->rl_conf.name, ps->ps_title[id], rlay->rl_s); 812 813 c = 0; 814 iov[c].iov_base = &rlay->rl_conf; 815 iov[c++].iov_len = sizeof(rlay->rl_conf); 816 if (rlay->rl_conf.ssl_cert_len) { 817 iov[c].iov_base = rlay->rl_ssl_cert; 818 iov[c++].iov_len = rlay->rl_conf.ssl_cert_len; 819 } 820 if (rlay->rl_conf.ssl_key_len) { 821 iov[c].iov_base = rlay->rl_ssl_key; 822 iov[c++].iov_len = rlay->rl_conf.ssl_key_len; 823 } 824 if (rlay->rl_conf.ssl_ca_len) { 825 iov[c].iov_base = rlay->rl_ssl_ca; 826 iov[c++].iov_len = rlay->rl_conf.ssl_ca_len; 827 } 828 829 if (id == PROC_RELAY) { 830 /* XXX imsg code will close the fd after 1st call */ 831 n = -1; 832 proc_range(ps, id, &n, &m); 833 for (n = 0; n < m; n++) { 834 if ((fd = dup(rlay->rl_s)) == -1) 835 return (-1); 836 proc_composev_imsg(ps, id, n, 837 IMSG_CFG_RELAY, fd, iov, c); 838 } 839 } else { 840 proc_composev_imsg(ps, id, -1, IMSG_CFG_RELAY, -1, 841 iov, c); 842 } 843 } 844 845 close(rlay->rl_s); 846 rlay->rl_s = -1; 847 848 return (0); 849 } 850 851 int 852 config_getrelay(struct relayd *env, struct imsg *imsg) 853 { 854 struct privsep *ps = env->sc_ps; 855 struct relay *rlay; 856 u_int8_t *p = imsg->data; 857 size_t s; 858 859 if ((rlay = calloc(1, sizeof(*rlay))) == NULL) 860 return (-1); 861 862 IMSG_SIZE_CHECK(imsg, &rlay->rl_conf); 863 memcpy(&rlay->rl_conf, p, sizeof(rlay->rl_conf)); 864 s = sizeof(rlay->rl_conf); 865 866 rlay->rl_s = imsg->fd; 867 868 if (ps->ps_what[privsep_process] & CONFIG_PROTOS) { 869 if (rlay->rl_conf.proto == EMPTY_ID) 870 rlay->rl_proto = &env->sc_proto_default; 871 else if ((rlay->rl_proto = 872 proto_find(env, rlay->rl_conf.proto)) == NULL) { 873 log_debug("%s: unknown protocol", __func__); 874 goto fail; 875 } 876 } 877 878 if (rlay->rl_conf.dsttable != EMPTY_ID && 879 (rlay->rl_dsttable = table_find(env, 880 rlay->rl_conf.dsttable)) == NULL) { 881 log_debug("%s: unknown table", __func__); 882 goto fail; 883 } 884 885 rlay->rl_backuptable = &env->sc_empty_table; 886 if (rlay->rl_conf.backuptable != EMPTY_ID && 887 (rlay->rl_backuptable = table_find(env, 888 rlay->rl_conf.backuptable)) == NULL) { 889 log_debug("%s: unknown backup table", __func__); 890 goto fail; 891 } 892 893 if ((u_int)(IMSG_DATA_SIZE(imsg) - s) < 894 (rlay->rl_conf.ssl_cert_len + 895 rlay->rl_conf.ssl_key_len + 896 rlay->rl_conf.ssl_ca_len)) { 897 log_debug("%s: invalid message length", __func__); 898 goto fail; 899 } 900 901 if (rlay->rl_conf.ssl_cert_len) { 902 if ((rlay->rl_ssl_cert = get_data(p + s, 903 rlay->rl_conf.ssl_cert_len)) == NULL) 904 goto fail; 905 s += rlay->rl_conf.ssl_cert_len; 906 } 907 if (rlay->rl_conf.ssl_key_len) { 908 if ((rlay->rl_ssl_key = get_data(p + s, 909 rlay->rl_conf.ssl_key_len)) == NULL) 910 goto fail; 911 s += rlay->rl_conf.ssl_key_len; 912 } 913 if (rlay->rl_conf.ssl_ca_len) { 914 if ((rlay->rl_ssl_ca = get_data(p + s, 915 rlay->rl_conf.ssl_ca_len)) == NULL) 916 goto fail; 917 s += rlay->rl_conf.ssl_ca_len; 918 } 919 920 TAILQ_INSERT_TAIL(env->sc_relays, rlay, rl_entry); 921 922 env->sc_relaycount++; 923 924 DPRINTF("%s: %s %d received relay %s", __func__, 925 ps->ps_title[privsep_process], ps->ps_instance, 926 rlay->rl_conf.name); 927 928 return (0); 929 930 fail: 931 if (rlay->rl_ssl_cert) 932 free(rlay->rl_ssl_cert); 933 if (rlay->rl_ssl_key) 934 free(rlay->rl_ssl_key); 935 if (rlay->rl_ssl_ca) 936 free(rlay->rl_ssl_ca); 937 close(rlay->rl_s); 938 free(rlay); 939 return (-1); 940 } 941