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