1 /* $OpenBSD: relayd.c,v 1.199 2026/06/03 19:26:56 rsadowski Exp $ */
4 * Copyright (c) 2007 - 2016 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/types.h>
21 #include <sys/queue.h>
22 #include <sys/socket.h>
25 #include <sys/resource.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
53 #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b))
55 __dead void usage(void);
57 int parent_configure(struct relayd *);
58 void parent_configure_done(struct relayd *);
59 void parent_reload(struct relayd *, u_int, const char *);
60 void parent_sig_handler(int, short, void *);
61 void parent_shutdown(struct relayd *);
62 int parent_dispatch_pfe(int, struct privsep_proc *, struct imsg *);
63 int parent_dispatch_hce(int, struct privsep_proc *, struct imsg *);
64 int parent_dispatch_relay(int, struct privsep_proc *,
66 int parent_dispatch_ca(int, struct privsep_proc *,
68 int bindany(struct ctl_bindany *);
69 void parent_tls_ticket_rekey(int, short, void *);
71 struct relayd *relayd_env;
73 static struct privsep_proc procs[] = {
74 { "pfe", PROC_PFE, parent_dispatch_pfe, pfe },
75 { "hce", PROC_HCE, parent_dispatch_hce, hce },
76 { "relay", PROC_RELAY, parent_dispatch_relay, relay },
77 { "ca", PROC_CA, parent_dispatch_ca, ca }
80 enum privsep_procid privsep_process;
83 parent_sig_handler(int sig, short event, void *arg)
85 struct privsep *ps = arg;
90 parent_shutdown(ps->ps_env);
93 log_info("%s: reload requested with SIGHUP", __func__);
96 * This is safe because libevent uses async signal handlers
97 * that run in the event loop and not in signal context.
99 parent_reload(ps->ps_env, CONFIG_RELOAD, NULL);
106 fatalx("unexpected signal");
113 extern char *__progname;
115 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n",
121 main(int argc, char *argv[])
124 int debug = 0, verbose = 0;
128 const char *conffile = CONF_FILE;
129 enum privsep_procid proc_id = PROC_PARENT;
130 int proc_instance = 0;
131 const char *errp, *title = NULL;
134 while ((c = getopt(argc, argv, "dD:nI:P:f:v")) != -1) {
140 if (cmdline_symset(optarg) < 0)
141 log_warnx("could not parse macro definition %s",
146 opts |= RELAYD_OPT_NOACTION;
153 opts |= RELAYD_OPT_VERBOSE;
157 proc_id = proc_getid(procs, nitems(procs), title);
158 if (proc_id == PROC_MAX)
159 fatalx("invalid process name");
162 proc_instance = strtonum(optarg, 0,
163 PROC_MAX_INSTANCES, &errp);
165 fatalx("invalid process instance");
172 /* log to stderr until daemonized */
173 log_init(debug ? debug : 1, LOG_DAEMON);
179 if ((env = calloc(1, sizeof(*env))) == NULL ||
180 (ps = calloc(1, sizeof(*ps))) == NULL)
186 TAILQ_INIT(&ps->ps_rcsocks);
187 env->sc_conffile = conffile;
188 env->sc_conf.opts = opts;
189 TAILQ_INIT(&env->sc_hosts);
190 TAILQ_INIT(&env->sc_sessions);
191 env->sc_rtable = getrtable();
192 /* initialize the TLS session id to a random key for all relay procs */
193 arc4random_buf(env->sc_conf.tls_sid, sizeof(env->sc_conf.tls_sid));
195 if (parse_config(env->sc_conffile, env) == -1)
199 env->sc_conf.opts |= RELAYD_OPT_LOGUPDATE;
202 errx(1, "need root privileges");
204 if ((ps->ps_pw = getpwnam(RELAYD_USER)) == NULL)
205 errx(1, "unknown user %s", RELAYD_USER);
207 log_init(debug, LOG_DAEMON);
208 log_setverbose(verbose);
210 if (env->sc_conf.opts & RELAYD_OPT_NOACTION)
213 ps->ps_instances[PROC_RELAY] = env->sc_conf.prefork_relay;
214 ps->ps_instances[PROC_CA] = env->sc_conf.prefork_relay;
215 ps->ps_instance = proc_instance;
217 ps->ps_title[proc_id] = title;
219 /* only the parent returns */
220 proc_init(ps, procs, nitems(procs), debug, argc0, argv, proc_id);
222 log_procinit("parent");
224 if (ps->ps_noaction == 0)
227 if (unveil("/", "rx") == -1)
229 if (env->sc_conf.flags & F_AGENTX) {
230 if (unveil(env->sc_conf.agentx_path, "w") == -1)
231 err(1, "unveil %s", env->sc_conf.agentx_path);
233 if (unveil(AGENTX_MASTER_PATH, "w") == -1)
234 err(1, "unveil %s", env->sc_conf.agentx_path);
236 if (unveil(NULL, NULL) == -1)
241 signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps);
242 signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps);
243 signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps);
244 signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps);
245 signal_set(&ps->ps_evsigusr1, SIGUSR1, parent_sig_handler, ps);
247 signal_add(&ps->ps_evsigint, NULL);
248 signal_add(&ps->ps_evsigterm, NULL);
249 signal_add(&ps->ps_evsighup, NULL);
250 signal_add(&ps->ps_evsigpipe, NULL);
251 signal_add(&ps->ps_evsigusr1, NULL);
256 if (load_config(env->sc_conffile, env) == -1) {
257 proc_kill(env->sc_ps);
261 if (env->sc_conf.opts & RELAYD_OPT_NOACTION) {
262 fprintf(stderr, "configuration OK\n");
263 proc_kill(env->sc_ps);
267 /* rekey the TLS tickets before pushing the config */
268 parent_tls_ticket_rekey(0, 0, env);
269 if (parent_configure(env) == -1)
270 fatalx("configuration failed");
276 parent_shutdown(env);
283 parent_configure(struct relayd *env)
288 struct protocol *proto;
293 TAILQ_FOREACH(tb, env->sc_tables, entry)
294 config_settable(env, tb);
295 TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
296 config_setrdr(env, rdr);
297 TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
298 config_setrt(env, rt);
299 TAILQ_FOREACH(proto, env->sc_protos, entry)
300 config_setproto(env, proto);
301 TAILQ_FOREACH(proto, env->sc_protos, entry)
302 config_setrule(env, proto);
303 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
304 /* Check for TLS Inspection */
305 if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) ==
306 (F_TLS|F_TLSCLIENT) && rlay->rl_tls_cacert_fd != -1)
307 rlay->rl_conf.flags |= F_TLSINSPECT;
309 config_setrelay(env, rlay);
312 /* HCE, PFE, CA and the relays need to reload their config. */
313 env->sc_reload = 2 + (2 * env->sc_conf.prefork_relay);
315 for (id = 0; id < PROC_MAX; id++) {
316 if (id == privsep_process)
318 proc_compose_imsg(env->sc_ps, id, -1, IMSG_CFG_DONE, -1,
319 -1, &env->sc_conf, sizeof(env->sc_conf));
324 config_purge(env, CONFIG_ALL & ~CONFIG_RELAYS);
329 parent_reload(struct relayd *env, u_int reset, const char *filename)
331 if (env->sc_reload) {
332 log_debug("%s: already in progress: %d pending",
333 __func__, env->sc_reload);
337 /* Switch back to the default config file */
338 if (filename == NULL || *filename == '\0')
339 filename = env->sc_conffile;
341 log_debug("%s: level %d config file %s", __func__, reset, filename);
343 config_purge(env, CONFIG_ALL);
345 if (reset == CONFIG_RELOAD) {
346 if (load_config(filename, env) == -1) {
347 log_debug("%s: failed to load config file %s",
351 config_setreset(env, CONFIG_ALL);
353 if (parent_configure(env) == -1) {
354 log_debug("%s: failed to commit config from %s",
358 config_setreset(env, reset);
362 parent_configure_done(struct relayd *env)
366 if (env->sc_reload == 0) {
367 log_warnx("%s: configuration already finished", __func__);
372 if (env->sc_reload == 0) {
373 for (id = 0; id < PROC_MAX; id++) {
374 if (id == privsep_process)
377 proc_compose(env->sc_ps, id, IMSG_CTL_START, NULL, 0);
383 parent_shutdown(struct relayd *env)
385 config_purge(env, CONFIG_ALL);
387 proc_kill(env->sc_ps);
388 control_cleanup(&env->sc_ps->ps_csock);
389 carp_demote_shutdown();
394 log_info("parent terminating, pid %d", getpid());
400 parent_dispatch_pfe(int fd, struct privsep_proc *p, struct imsg *imsg)
402 struct privsep *ps = p->p_ps;
403 struct relayd *env = ps->ps_env;
404 struct ctl_demote demote;
405 struct ctl_netroute crt;
409 switch (imsg->hdr.type) {
411 IMSG_SIZE_CHECK(imsg, &demote);
412 memcpy(&demote, imsg->data, sizeof(demote));
413 demote.group[sizeof(demote.group) - 1] = '\0';
414 carp_demote_set(demote.group, demote.level);
417 IMSG_SIZE_CHECK(imsg, &crt);
418 memcpy(&crt, imsg->data, sizeof(crt));
419 crt.host.name[sizeof(crt.host.name) - 1] = '\0';
420 crt.rt.name[sizeof(crt.rt.name) - 1] = '\0';
421 crt.rt.label[sizeof(crt.rt.label) - 1] = '\0';
422 pfe_route(env, &crt);
425 IMSG_SIZE_CHECK(imsg, &v);
426 memcpy(&v, imsg->data, sizeof(v));
427 parent_reload(env, v, NULL);
429 case IMSG_CTL_RELOAD:
430 if (IMSG_DATA_SIZE(imsg) > 0)
431 str = get_string(imsg->data, IMSG_DATA_SIZE(imsg));
432 parent_reload(env, CONFIG_RELOAD, str);
435 case IMSG_CTL_SHUTDOWN:
436 parent_shutdown(env);
439 parent_configure_done(env);
441 case IMSG_AGENTXSOCK:
442 agentx_setsock(env, p->p_id);
452 parent_dispatch_hce(int fd, struct privsep_proc *p, struct imsg *imsg)
454 struct privsep *ps = p->p_ps;
455 struct relayd *env = ps->ps_env;
456 struct ctl_script scr;
458 switch (imsg->hdr.type) {
460 IMSG_SIZE_CHECK(imsg, &scr);
461 bcopy(imsg->data, &scr, sizeof(scr));
462 scr.name[sizeof(scr.name) - 1] = '\0';
463 scr.path[sizeof(scr.path) - 1] = '\0';
464 scr.retval = script_exec(env, &scr);
465 proc_compose(ps, PROC_HCE, IMSG_SCRIPT, &scr, sizeof(scr));
468 parent_configure_done(env);
478 parent_dispatch_relay(int fd, struct privsep_proc *p, struct imsg *imsg)
480 struct privsep *ps = p->p_ps;
481 struct relayd *env = ps->ps_env;
482 struct ctl_bindany bnd;
485 switch (imsg->hdr.type) {
487 IMSG_SIZE_CHECK(imsg, &bnd);
488 bcopy(imsg->data, &bnd, sizeof(bnd));
489 if (bnd.bnd_proc < 0 || bnd.bnd_proc > env->sc_conf.prefork_relay)
490 fatalx("%s: invalid relay proc", __func__);
491 switch (bnd.bnd_proto) {
496 fatalx("%s: requested socket "
497 "for invalid protocol", __func__);
501 proc_compose_imsg(ps, PROC_RELAY, bnd.bnd_proc,
502 IMSG_BINDANY, -1, s, &bnd.bnd_id, sizeof(bnd.bnd_id));
505 parent_configure_done(env);
515 parent_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg)
517 struct privsep *ps = p->p_ps;
518 struct relayd *env = ps->ps_env;
520 switch (imsg->hdr.type) {
522 parent_configure_done(env);
532 purge_table(struct relayd *env, struct tablelist *head, struct table *table)
536 while ((host = TAILQ_FIRST(&table->hosts)) != NULL) {
537 TAILQ_REMOVE(&table->hosts, host, entry);
538 TAILQ_REMOVE(&env->sc_hosts, host, globalentry);
539 if (event_initialized(&host->cte.ev)) {
540 event_del(&host->cte.ev);
543 ibuf_free(host->cte.buf);
544 tls_free(host->cte.tls);
547 free(table->sendbuf);
548 ibuf_free(table->sendbinbuf);
549 tls_config_free(table->tls_cfg);
552 TAILQ_REMOVE(head, table, entry);
557 purge_key(char **key, off_t len)
565 purge_relay(struct relayd *env, struct relay *rlay)
567 struct rsession *con;
568 struct relay_table *rlt;
569 struct relay_cert *cert, *tmpcert;
571 /* shutdown and remove relay */
572 if (event_initialized(&rlay->rl_ev))
573 event_del(&rlay->rl_ev);
575 TAILQ_REMOVE(env->sc_relays, rlay, rl_entry);
577 /* cleanup sessions */
579 SPLAY_ROOT(&rlay->rl_sessions)) != NULL)
580 relay_close(con, NULL, 0);
583 if (rlay->rl_bev != NULL)
584 bufferevent_free(rlay->rl_bev);
585 if (rlay->rl_dstbev != NULL)
586 bufferevent_free(rlay->rl_dstbev);
588 purge_key(&rlay->rl_tls_cakey, rlay->rl_conf.tls_cakey_len);
590 if (rlay->rl_tls_pkey != NULL) {
591 EVP_PKEY_free(rlay->rl_tls_pkey);
592 rlay->rl_tls_pkey = NULL;
594 if (rlay->rl_tls_cacertx509 != NULL) {
595 X509_free(rlay->rl_tls_cacertx509);
596 rlay->rl_tls_cacertx509 = NULL;
598 if (rlay->rl_tls_capkey != NULL) {
599 EVP_PKEY_free(rlay->rl_tls_capkey);
600 rlay->rl_tls_capkey = NULL;
603 tls_free(rlay->rl_tls_ctx);
604 tls_config_free(rlay->rl_tls_cfg);
605 tls_config_free(rlay->rl_tls_client_cfg);
607 while ((rlt = TAILQ_FIRST(&rlay->rl_tables))) {
608 TAILQ_REMOVE(&rlay->rl_tables, rlt, rlt_entry);
612 TAILQ_FOREACH_SAFE(cert, env->sc_certs, cert_entry, tmpcert) {
613 if (rlay->rl_conf.id != cert->cert_relayid)
615 if (cert->cert_fd != -1)
616 close(cert->cert_fd);
617 if (cert->cert_key_fd != -1)
618 close(cert->cert_key_fd);
619 if (cert->cert_ocsp_fd != -1)
620 close(cert->cert_ocsp_fd);
621 if (cert->cert_pkey != NULL)
622 EVP_PKEY_free(cert->cert_pkey);
623 TAILQ_REMOVE(env->sc_certs, cert, cert_entry);
631 kv_add(struct kvtree *keys, char *key, char *value, int unique)
633 struct kv *kv, *oldkv;
637 if ((kv = calloc(1, sizeof(*kv))) == NULL)
639 if ((kv->kv_key = strdup(key)) == NULL)
642 (kv->kv_value = strdup(value)) == NULL)
644 TAILQ_INIT(&kv->kv_children);
646 if ((oldkv = RB_INSERT(kvtree, keys, kv)) != NULL) {
648 * return error if the key should occur only once,
649 * or add it to a list attached to the key's node.
653 TAILQ_INSERT_TAIL(&oldkv->kv_children, kv, kv_entry);
654 kv->kv_parent = oldkv;
666 kv_set(struct kv *kv, char *fmt, ...)
674 ret = vasprintf(&value, fmt, ap);
679 /* Remove all children */
680 while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) {
681 TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry);
686 /* Set the new value */
688 kv->kv_value = value;
694 kv_setkey(struct kv *kv, char *fmt, ...)
701 ret = vasprintf(&key, fmt, ap);
713 kv_delete(struct kvtree *keys, struct kv *kv)
717 RB_REMOVE(kvtree, keys, kv);
719 /* Remove all children */
720 while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) {
721 TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry);
731 kv_purge(struct kvtree *keys)
735 while ((kv = RB_MIN(kvtree, keys)) != NULL)
740 kv_free(struct kv *kv)
743 * This function does not clear memory referenced by
744 * kv_children or stuff on the tailqs. Use kv_delete() instead.
749 memset(kv, 0, sizeof(*kv));
753 kv_inherit(struct kv *dst, struct kv *src)
755 memset(dst, 0, sizeof(*dst));
756 memcpy(dst, src, sizeof(*dst));
757 TAILQ_INIT(&dst->kv_children);
759 if (src->kv_key != NULL) {
760 if ((dst->kv_key = strdup(src->kv_key)) == NULL) {
765 if (src->kv_value != NULL) {
766 if ((dst->kv_value = strdup(src->kv_value)) == NULL) {
772 if (src->kv_match != NULL)
773 dst->kv_match = src->kv_match;
774 if (src->kv_matchtree != NULL)
775 dst->kv_matchtree = src->kv_matchtree;
781 kv_log(struct rsession *con, struct kv *kv, u_int16_t labelid,
786 if (con->se_log == NULL)
788 if (asprintf(&msg, " %s%s%s%s%s%s%s",
789 dir == RELAY_DIR_REQUEST ? "[" : "{",
790 labelid == 0 ? "" : label_id2name(labelid),
791 labelid == 0 ? "" : ", ",
792 kv->kv_key == NULL ? "(unknown)" : kv->kv_key,
793 kv->kv_value == NULL ? "" : ": ",
794 kv->kv_value == NULL ? "" : kv->kv_value,
795 dir == RELAY_DIR_REQUEST ? "]" : "}") == -1)
797 if (evbuffer_add(con->se_log, msg, strlen(msg)) == -1) {
807 kv_find(struct kvtree *keys, struct kv *kv)
812 if (kv->kv_flags & KV_FLAG_GLOBBING) {
813 /* Test header key using shell globbing rules */
814 key = kv->kv_key == NULL ? "" : kv->kv_key;
815 RB_FOREACH(match, kvtree, keys) {
816 if (fnmatch(key, match->kv_key, FNM_CASEFOLD) == 0)
820 /* Fast tree-based lookup only works without globbing */
821 match = RB_FIND(kvtree, keys, kv);
828 kv_find_value(struct kvtree *keys, char *key, const char *value,
831 struct kv *match, kv;
832 char *val = NULL, *next, *ptr;
836 if ((match = RB_FIND(kvtree, keys, &kv)) == NULL)
839 if (match->kv_value == NULL)
843 if (strcasecmp(match->kv_value, value) == 0)
846 if ((val = strdup(match->kv_value)) == NULL)
848 for (next = ptr = val; ptr != NULL;
849 ptr = strsep(&next, delim)) {
850 /* strip whitespace */
851 ptr += strspn(ptr, " \t");
852 len = strcspn(ptr, " \t");
853 if (strncasecmp(ptr, value, len) == 0)
863 DPRINTF("%s: matched %s: %s", __func__, key, value);
870 kv_cmp(struct kv *a, struct kv *b)
872 return (strcasecmp(a->kv_key, b->kv_key));
875 RB_GENERATE(kvtree, kv, kv_node, kv_cmp);
878 rule_add(struct protocol *proto, struct relay_rule *rule, const char *rulefile)
880 struct relay_rule *r = NULL;
881 struct kv *kv = NULL;
887 for (i = 0; i < KEY_TYPE_MAX; i++) {
888 kv = &rule->rule_kv[i];
889 if (kv->kv_type != i)
892 switch (kv->kv_option) {
894 /* log action needs a key or a file to be specified */
895 if (kv->kv_key == NULL && rulefile == NULL &&
896 (kv->kv_key = strdup("*")) == NULL)
903 switch (kv->kv_type) {
907 if (rule->rule_dir != RELAY_DIR_REQUEST)
914 if (kv->kv_value != NULL && strchr(kv->kv_value, '$') != NULL)
915 kv->kv_flags |= KV_FLAG_MACRO;
916 if (kv->kv_key != NULL && strpbrk(kv->kv_key, "*?[") != NULL)
917 kv->kv_flags |= KV_FLAG_GLOBBING;
920 if (rulefile == NULL) {
921 TAILQ_INSERT_TAIL(&proto->rules, rule, rule_entry);
925 if ((fp = fopen(rulefile, "r")) == NULL)
928 while (fgets(buf, sizeof(buf), fp) != NULL) {
929 /* strip whitespace and newline characters */
930 buf[strcspn(buf, "\r\n\t ")] = '\0';
931 if (!strlen(buf) || buf[0] == '#')
934 if ((r = rule_inherit(rule)) == NULL)
937 for (i = 0; i < KEY_TYPE_MAX; i++) {
939 if (kv->kv_type != i)
942 if ((kv->kv_key = strdup(buf)) == NULL) {
949 TAILQ_INSERT_TAIL(&proto->rules, r, rule_entry);
963 rule_inherit(struct relay_rule *rule)
965 struct relay_rule *r;
969 if ((r = calloc(1, sizeof(*r))) == NULL)
971 memcpy(r, rule, sizeof(*r));
973 for (i = 0; i < KEY_TYPE_MAX; i++) {
974 kv = &rule->rule_kv[i];
975 if (kv->kv_type != i)
977 if (kv_inherit(&r->rule_kv[i], kv) == NULL) {
983 if (r->rule_label > 0)
984 label_ref(r->rule_label);
986 tag_ref(r->rule_tag);
987 if (r->rule_tagged > 0)
988 tag_ref(r->rule_tagged);
994 rule_free(struct relay_rule *rule)
998 for (i = 0; i < KEY_TYPE_MAX; i++)
999 kv_free(&rule->rule_kv[i]);
1000 if (rule->rule_label > 0)
1001 label_unref(rule->rule_label);
1002 if (rule->rule_tag > 0)
1003 tag_unref(rule->rule_tag);
1004 if (rule->rule_tagged > 0)
1005 tag_unref(rule->rule_tagged);
1009 rule_delete(struct relay_rules *rules, struct relay_rule *rule)
1011 TAILQ_REMOVE(rules, rule, rule_entry);
1017 rule_settable(struct relay_rules *rules, struct relay_table *rlt)
1019 struct relay_rule *r;
1020 char pname[TABLE_NAME_SIZE];
1022 if (rlt->rlt_table == NULL || strlcpy(pname, rlt->rlt_table->conf.name,
1023 sizeof(pname)) >= sizeof(pname))
1026 pname[strcspn(pname, ":")] = '\0';
1028 TAILQ_FOREACH(r, rules, rule_entry) {
1029 if (r->rule_tablename[0] &&
1030 strcmp(pname, r->rule_tablename) == 0)
1031 r->rule_table = rlt;
1040 host_find(struct relayd *env, objid_t id)
1042 struct table *table;
1045 TAILQ_FOREACH(table, env->sc_tables, entry)
1046 TAILQ_FOREACH(host, &table->hosts, entry)
1047 if (host->conf.id == id)
1053 table_find(struct relayd *env, objid_t id)
1055 struct table *table;
1057 TAILQ_FOREACH(table, env->sc_tables, entry)
1058 if (table->conf.id == id)
1064 rdr_find(struct relayd *env, objid_t id)
1068 TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
1069 if (rdr->conf.id == id)
1075 relay_find(struct relayd *env, objid_t id)
1079 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1080 if (rlay->rl_conf.id == id)
1086 proto_find(struct relayd *env, objid_t id)
1090 TAILQ_FOREACH(p, env->sc_protos, entry)
1097 session_find(struct relayd *env, objid_t id)
1100 struct rsession *con;
1102 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1103 SPLAY_FOREACH(con, session_tree, &rlay->rl_sessions)
1104 if (con->se_id == id)
1110 route_find(struct relayd *env, objid_t id)
1112 struct netroute *nr;
1114 TAILQ_FOREACH(nr, env->sc_routes, nr_route)
1115 if (nr->nr_conf.id == id)
1121 router_find(struct relayd *env, objid_t id)
1125 TAILQ_FOREACH(rt, env->sc_rts, rt_entry)
1126 if (rt->rt_conf.id == id)
1132 host_findbyname(struct relayd *env, const char *name)
1134 struct table *table;
1137 TAILQ_FOREACH(table, env->sc_tables, entry)
1138 TAILQ_FOREACH(host, &table->hosts, entry)
1139 if (strcmp(host->conf.name, name) == 0)
1145 table_findbyname(struct relayd *env, const char *name)
1147 struct table *table;
1149 TAILQ_FOREACH(table, env->sc_tables, entry)
1150 if (strcmp(table->conf.name, name) == 0)
1156 table_findbyconf(struct relayd *env, struct table *tb)
1158 struct table *table;
1159 struct table_config a, b;
1161 bcopy(&tb->conf, &a, sizeof(a));
1163 a.flags &= ~(F_USED|F_BACKUP);
1165 TAILQ_FOREACH(table, env->sc_tables, entry) {
1166 bcopy(&table->conf, &b, sizeof(b));
1168 b.flags &= ~(F_USED|F_BACKUP);
1171 * Compare two tables and return the existing table if
1172 * the configuration seems to be the same.
1174 if (bcmp(&a, &b, sizeof(b)) == 0 &&
1175 ((tb->sendbuf == NULL && table->sendbuf == NULL) ||
1176 (tb->sendbuf != NULL && table->sendbuf != NULL &&
1177 strcmp(tb->sendbuf, table->sendbuf) == 0)))
1184 rdr_findbyname(struct relayd *env, const char *name)
1188 TAILQ_FOREACH(rdr, env->sc_rdrs, entry)
1189 if (strcmp(rdr->conf.name, name) == 0)
1195 relay_findbyname(struct relayd *env, const char *name)
1199 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1200 if (strcmp(rlay->rl_conf.name, name) == 0)
1206 relay_findbyaddr(struct relayd *env, struct relay_config *rc)
1210 TAILQ_FOREACH(rlay, env->sc_relays, rl_entry)
1211 if (bcmp(&rlay->rl_conf.ss, &rc->ss, sizeof(rc->ss)) == 0 &&
1212 rlay->rl_conf.port == rc->port)
1218 pkey_find(struct relayd *env, char * hash)
1220 struct ca_pkey *pkey;
1222 TAILQ_FOREACH(pkey, env->sc_pkeys, pkey_entry)
1223 if (strcmp(hash, pkey->pkey_hash) == 0)
1224 return (pkey->pkey);
1229 pkey_add(struct relayd *env, EVP_PKEY *pkey, char *hash)
1231 struct ca_pkey *ca_pkey;
1233 if (env->sc_pkeys == NULL)
1236 if ((ca_pkey = calloc(1, sizeof(*ca_pkey))) == NULL)
1239 ca_pkey->pkey = pkey;
1240 if (strlcpy(ca_pkey->pkey_hash, hash, sizeof(ca_pkey->pkey_hash)) >=
1241 sizeof(ca_pkey->pkey_hash)) {
1246 TAILQ_INSERT_TAIL(env->sc_pkeys, ca_pkey, pkey_entry);
1252 cert_add(struct relayd *env, objid_t id)
1254 static objid_t last_cert_id = 0;
1255 struct relay_cert *cert;
1257 if ((cert = calloc(1, sizeof(*cert))) == NULL)
1261 id = ++last_cert_id;
1262 if (id == INT_MAX) {
1263 log_warnx("too many tls keypairs defined");
1270 cert->cert_key_fd = -1;
1271 cert->cert_ocsp_fd = -1;
1273 TAILQ_INSERT_TAIL(env->sc_certs, cert, cert_entry);
1279 cert_find(struct relayd *env, objid_t id)
1281 struct relay_cert *cert;
1283 TAILQ_FOREACH(cert, env->sc_certs, cert_entry)
1284 if (cert->cert_id == id)
1290 relay_load_fd(int fd, off_t *len)
1297 if (fstat(fd, &st) != 0)
1300 if ((buf = calloc(1, size + 1)) == NULL)
1302 if (pread(fd, buf, size, 0) != size)
1319 relay_load_certfiles(struct relayd *env, struct relay *rlay, const struct keyname *name)
1321 char certfile[PATH_MAX];
1322 char hbuf[PATH_MAX];
1323 struct protocol *proto = rlay->rl_proto;
1324 struct relay_cert *cert;
1325 int useport = htons(rlay->rl_conf.port);
1326 int cert_fd = -1, key_fd = -1, ocsp_fd = -1, ret = 0;
1328 if (rlay->rl_conf.flags & F_TLSCLIENT) {
1329 if (strlen(proto->tlsca) && rlay->rl_tls_ca_fd == -1) {
1330 if ((rlay->rl_tls_ca_fd =
1331 open(proto->tlsca, O_RDONLY)) == -1)
1333 log_debug("%s: using ca %s", __func__, proto->tlsca);
1335 if (strlen(proto->tlscacert) && rlay->rl_tls_cacert_fd == -1) {
1336 if ((rlay->rl_tls_cacert_fd =
1337 open(proto->tlscacert, O_RDONLY)) == -1)
1339 log_debug("%s: using ca certificate %s", __func__,
1342 if (strlen(proto->tlscakey) && !rlay->rl_conf.tls_cakey_len &&
1343 proto->tlscapass != NULL) {
1344 if ((rlay->rl_tls_cakey =
1345 ssl_load_key(env, proto->tlscakey,
1346 &rlay->rl_conf.tls_cakey_len,
1347 proto->tlscapass)) == NULL)
1349 log_debug("%s: using ca key %s", __func__,
1354 if ((rlay->rl_conf.flags & F_TLS) == 0)
1357 if (strlen(proto->tlsclientca) && rlay->rl_tls_client_ca_fd == -1) {
1358 if ((rlay->rl_tls_client_ca_fd =
1359 open(proto->tlsclientca, O_RDONLY)) == -1)
1361 log_debug("%s: using client ca %s", __func__,
1362 proto->tlsclientca);
1366 print_host(&rlay->rl_conf.ss, hbuf, sizeof(hbuf)) == NULL)
1368 else if (name != NULL &&
1369 strlcpy(hbuf, name->name, sizeof(hbuf)) >= sizeof(hbuf))
1372 if (name != NULL && strcmp(name->certificate, "") != 0) {
1373 if (strlcpy(certfile, name->certificate, sizeof(certfile))
1374 >= sizeof(certfile)) {
1375 log_warnx("certificate truncated");
1380 ret = snprintf(certfile, sizeof(certfile),
1381 "/etc/ssl/%s:%u.crt", hbuf, useport);
1383 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1386 if ((cert_fd = open(certfile, O_RDONLY)) == -1) {
1388 ret = snprintf(certfile, sizeof(certfile),
1389 "/etc/ssl/%s.crt", hbuf);
1391 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1393 if ((cert_fd = open(certfile, O_RDONLY)) == -1)
1397 log_debug("%s: using certificate %s", __func__, certfile);
1399 if (name != NULL && strcmp(name->key, "") != 0) {
1400 if (strlcpy(certfile, name->key, sizeof(certfile))
1401 >= sizeof(certfile)) {
1402 log_warnx("certificate key truncated");
1408 ret = snprintf(certfile, sizeof(certfile),
1409 "/etc/ssl/private/%s:%u.key",
1412 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1415 ret = snprintf(certfile, sizeof(certfile),
1416 "/etc/ssl/private/%s.key", hbuf);
1418 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1422 if ((key_fd = open(certfile, O_RDONLY)) == -1)
1424 log_debug("%s: using private key %s", __func__, certfile);
1426 if (name != NULL && strcmp(name->ocsp, "") != 0) {
1427 if (strlcpy(certfile, name->ocsp, sizeof(certfile))
1428 >= sizeof(certfile)) {
1429 log_warnx("certificate ocsp truncated");
1436 ret = snprintf(certfile, sizeof(certfile),
1437 "/etc/ssl/%s:%u.ocsp",
1440 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1443 ret = snprintf(certfile, sizeof(certfile),
1444 "/etc/ssl/%s.ocsp", hbuf);
1446 if (ret < 0 || (size_t)ret >= sizeof(certfile))
1450 if ((ocsp_fd = open(certfile, O_RDONLY)) != -1)
1451 log_debug("%s: using OCSP staple file %s", __func__, certfile);
1453 if ((cert = cert_add(env, 0)) == NULL)
1456 cert->cert_relayid = rlay->rl_conf.id;
1457 cert->cert_fd = cert_fd;
1458 cert->cert_key_fd = key_fd;
1459 cert->cert_ocsp_fd = ocsp_fd;
1475 event_again(struct event *ev, int fd, short event,
1476 void (*fn)(int, short, void *),
1477 struct timeval *start, struct timeval *end, void *arg)
1479 struct timeval tv_next, tv_now, tv;
1481 getmonotime(&tv_now);
1482 bcopy(end, &tv_next, sizeof(tv_next));
1483 timersub(&tv_now, start, &tv_now);
1484 timersub(&tv_next, &tv_now, &tv_next);
1486 bzero(&tv, sizeof(tv));
1487 if (timercmp(&tv_next, &tv, >))
1488 bcopy(&tv_next, &tv, sizeof(tv));
1491 event_set(ev, fd, event, fn, arg);
1496 expand_string(char *label, size_t len, const char *srch, const char *repl)
1501 if ((tmp = calloc(1, len)) == NULL) {
1502 log_debug("%s: calloc", __func__);
1506 while ((q = strstr(p, srch)) != NULL) {
1508 if ((strlcat(tmp, p, len) >= len) ||
1509 (strlcat(tmp, repl, len) >= len)) {
1510 log_debug("%s: string too long", __func__);
1517 if (strlcat(tmp, p, len) >= len) {
1518 log_debug("%s: string too long", __func__);
1522 (void)strlcpy(label, tmp, len); /* always fits */
1529 translate_string(char *str)
1534 reader = writer = str;
1537 if (*reader == '\\') {
1547 *writer++ = *reader;
1550 *writer++ = *reader;
1557 digeststr(enum digest_type type, const u_int8_t *data, size_t len, char *buf)
1561 return (SHA1Data(data, len, buf));
1564 return (MD5Data(data, len, buf));
1573 canonicalize_host(const char *host, char *name, size_t len)
1575 struct sockaddr_in sin4;
1576 struct sockaddr_in6 sin6;
1585 * Canonicalize an IPv4/6 address
1587 if (inet_pton(AF_INET, host, &sin4) == 1)
1588 return (inet_ntop(AF_INET, &sin4, name, len));
1589 if (inet_pton(AF_INET6, host, &sin6) == 1)
1590 return (inet_ntop(AF_INET6, &sin6, name, len));
1593 * Canonicalize a hostname
1596 /* 1. remove repeated dots and convert upper case to lower case */
1597 plen = strlen(host);
1599 for (i = j = 0; i < plen; i++) {
1602 c = tolower((unsigned char)host[i]);
1603 if ((c == '.') && (j == 0 || name[j - 1] == '.'))
1608 /* 2. remove trailing dots */
1609 for (i = j; i > 0; i--) {
1610 if (name[i - 1] != '.')
1626 parse_url(const char *url, char **protoptr, char **hostptr, char **pathptr)
1628 char *p, *proto = NULL, *host = NULL, *path = NULL;
1630 /* return error if it is not a URL */
1631 if ((p = strstr(url, ":/")) == NULL ||
1632 (strcspn(url, ":/") != (size_t)(p - url)))
1636 if ((proto = strdup(url)) == NULL)
1638 p = proto + (p - url);
1641 p += strspn(p, ":/");
1642 if (*p == '\0' || (host = strdup(p)) == NULL)
1646 /* find and copy path or default to "/" */
1647 if ((p = strchr(host, '/')) == NULL)
1649 if ((path = strdup(p)) == NULL)
1652 /* strip path after host */
1653 host[strcspn(host, "/")] = '\0';
1655 DPRINTF("%s: %s proto %s, host %s, path %s", __func__,
1656 url, proto, host, path);
1672 bindany(struct ctl_bindany *bnd)
1679 if (relay_socket_af(&bnd->bnd_ss, bnd->bnd_port) == -1)
1681 if ((s = socket(bnd->bnd_ss.ss_family,
1682 bnd->bnd_proto == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM,
1683 bnd->bnd_proto)) == -1)
1685 if (setsockopt(s, SOL_SOCKET, SO_BINDANY,
1686 &v, sizeof(v)) == -1)
1688 if (bind(s, (struct sockaddr *)&bnd->bnd_ss,
1689 bnd->bnd_ss.ss_len) == -1)
1701 map6to4(struct sockaddr_storage *in6)
1703 struct sockaddr_storage out4;
1704 struct sockaddr_in *sin4 = (struct sockaddr_in *)&out4;
1705 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)in6;
1707 bzero(sin4, sizeof(*sin4));
1708 sin4->sin_len = sizeof(*sin4);
1709 sin4->sin_family = AF_INET;
1710 sin4->sin_port = sin6->sin6_port;
1712 bcopy(&sin6->sin6_addr.s6_addr[12], &sin4->sin_addr.s_addr,
1713 sizeof(sin4->sin_addr));
1715 if (sin4->sin_addr.s_addr == INADDR_ANY ||
1716 sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1717 IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1720 bcopy(&out4, in6, sizeof(*in6));
1726 map4to6(struct sockaddr_storage *in4, struct sockaddr_storage *map)
1728 struct sockaddr_storage out6;
1729 struct sockaddr_in *sin4 = (struct sockaddr_in *)in4;
1730 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&out6;
1731 struct sockaddr_in6 *map6 = (struct sockaddr_in6 *)map;
1733 if (sin4->sin_addr.s_addr == INADDR_ANY ||
1734 sin4->sin_addr.s_addr == INADDR_BROADCAST ||
1735 IN_MULTICAST(ntohl(sin4->sin_addr.s_addr)))
1738 bcopy(map6, sin6, sizeof(*sin6));
1739 sin6->sin6_len = sizeof(*sin6);
1740 sin6->sin6_family = AF_INET6;
1741 sin6->sin6_port = sin4->sin_port;
1743 bcopy(&sin4->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12],
1744 sizeof(sin4->sin_addr));
1746 bcopy(&out6, in4, sizeof(*in4));
1752 socket_rlimit(int maxfd)
1756 if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
1757 fatal("%s: failed to get resource limit", __func__);
1758 log_debug("%s: max open files %llu", __func__, rl.rlim_max);
1761 * Allow the maximum number of open file descriptors for this
1762 * login class (which should be the class "daemon" by default).
1765 rl.rlim_cur = rl.rlim_max;
1767 rl.rlim_cur = MAXIMUM(rl.rlim_max, (rlim_t)maxfd);
1768 if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
1769 fatal("%s: failed to set resource limit", __func__);
1773 get_string(u_int8_t *ptr, size_t len)
1777 for (i = 0; i < len; i++)
1778 if (!(isprint((unsigned char)ptr[i]) ||
1779 isspace((unsigned char)ptr[i])))
1782 return strndup(ptr, i);
1786 get_data(u_int8_t *ptr, size_t len)
1790 if ((data = malloc(len)) == NULL)
1792 memcpy(data, ptr, len);
1798 sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen)
1800 struct sockaddr_in *a4, *b4;
1801 struct sockaddr_in6 *a6, *b6;
1802 u_int32_t av[4], bv[4], mv[4];
1804 if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC)
1806 else if (a->sa_family > b->sa_family)
1808 else if (a->sa_family < b->sa_family)
1811 if (prefixlen == -1)
1812 memset(&mv, 0xff, sizeof(mv));
1814 switch (a->sa_family) {
1816 a4 = (struct sockaddr_in *)a;
1817 b4 = (struct sockaddr_in *)b;
1819 av[0] = a4->sin_addr.s_addr;
1820 bv[0] = b4->sin_addr.s_addr;
1821 if (prefixlen != -1)
1822 mv[0] = prefixlen2mask(prefixlen);
1824 if ((av[0] & mv[0]) > (bv[0] & mv[0]))
1826 if ((av[0] & mv[0]) < (bv[0] & mv[0]))
1830 a6 = (struct sockaddr_in6 *)a;
1831 b6 = (struct sockaddr_in6 *)b;
1833 memcpy(&av, &a6->sin6_addr.s6_addr, 16);
1834 memcpy(&bv, &b6->sin6_addr.s6_addr, 16);
1835 if (prefixlen != -1)
1836 prefixlen2mask6(prefixlen, mv);
1838 if ((av[3] & mv[3]) > (bv[3] & mv[3]))
1840 if ((av[3] & mv[3]) < (bv[3] & mv[3]))
1842 if ((av[2] & mv[2]) > (bv[2] & mv[2]))
1844 if ((av[2] & mv[2]) < (bv[2] & mv[2]))
1846 if ((av[1] & mv[1]) > (bv[1] & mv[1]))
1848 if ((av[1] & mv[1]) < (bv[1] & mv[1]))
1850 if ((av[0] & mv[0]) > (bv[0] & mv[0]))
1852 if ((av[0] & mv[0]) < (bv[0] & mv[0]))
1861 prefixlen2mask(u_int8_t prefixlen)
1869 return (htonl(0xffffffff << (32 - prefixlen)));
1873 prefixlen2mask6(u_int8_t prefixlen, u_int32_t *mask)
1875 static struct in6_addr s6;
1878 if (prefixlen > 128)
1881 bzero(&s6, sizeof(s6));
1882 for (i = 0; i < prefixlen / 8; i++)
1883 s6.s6_addr[i] = 0xff;
1886 s6.s6_addr[prefixlen / 8] = 0xff00 >> i;
1888 memcpy(mask, &s6, sizeof(s6));
1894 accept_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
1895 int reserve, volatile int *counter)
1898 if (getdtablecount() + reserve +
1899 *counter >= getdtablesize()) {
1904 if ((ret = accept4(sockfd, addr, addrlen, SOCK_NONBLOCK)) > -1) {
1906 DPRINTF("%s: inflight incremented, now %d",__func__, *counter);
1912 parent_tls_ticket_rekey(int fd, short events, void *arg)
1914 static struct event rekeyev;
1915 struct relayd *env = arg;
1917 struct relay_ticket_key key;
1919 log_debug("%s: rekeying tickets", __func__);
1921 key.tt_keyrev = arc4random();
1922 arc4random_buf(key.tt_key, sizeof(key.tt_key));
1924 proc_compose_imsg(env->sc_ps, PROC_RELAY, -1, IMSG_TLSTICKET_REKEY,
1925 -1, -1, &key, sizeof(key));
1927 evtimer_set(&rekeyev, parent_tls_ticket_rekey, env);
1929 tv.tv_sec = TLS_SESSION_LIFETIME / 4;
1930 evtimer_add(&rekeyev, &tv);