diff options
Diffstat (limited to 'usr.sbin/relayd/config.c')
-rw-r--r-- | usr.sbin/relayd/config.c | 164 |
1 files changed, 122 insertions, 42 deletions
diff --git a/usr.sbin/relayd/config.c b/usr.sbin/relayd/config.c index cf5dcf9ef27..29ffa053061 100644 --- a/usr.sbin/relayd/config.c +++ b/usr.sbin/relayd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.33 2017/09/14 08:59:54 jsg Exp $ */ +/* $OpenBSD: config.c,v 1.34 2017/11/27 21:06:26 claudio Exp $ */ /* * Copyright (c) 2011 - 2014 Reyk Floeter <reyk@openbsd.org> @@ -47,10 +47,10 @@ config_init(struct relayd *env) } ps->ps_what[PROC_PARENT] = CONFIG_ALL; - ps->ps_what[PROC_PFE] = CONFIG_ALL & ~CONFIG_PROTOS; + ps->ps_what[PROC_PFE] = CONFIG_ALL & ~(CONFIG_PROTOS|CONFIG_CERTS); ps->ps_what[PROC_HCE] = CONFIG_TABLES; - ps->ps_what[PROC_CA] = CONFIG_RELAYS; - ps->ps_what[PROC_RELAY] = CONFIG_RELAYS| + ps->ps_what[PROC_CA] = CONFIG_RELAYS|CONFIG_CERTS; + ps->ps_what[PROC_RELAY] = CONFIG_RELAYS|CONFIG_CERTS| CONFIG_TABLES|CONFIG_PROTOS|CONFIG_CA_ENGINE; /* Other configuration */ @@ -771,6 +771,25 @@ config_getrule(struct relayd *env, struct imsg *imsg) return (0); } +static int +config_setrelayfd(struct privsep *ps, int id, int n, int rlay_id, int type, + int ofd) +{ + struct ctl_relayfd rfd; + int fd; + + rfd.relayid = rlay_id; + rfd.type = type; + + if ((fd = dup(ofd)) == -1) + return (-1); + if (proc_compose_imsg(ps, id, n, IMSG_CFG_RELAY_FD, -1, fd, + &rfd, sizeof(rfd)) != 0) + return (-1); + + return (0); +} + int config_setrelay(struct relayd *env, struct relay *rlay) { @@ -802,24 +821,13 @@ config_setrelay(struct relayd *env, struct relay *rlay) c = 0; iov[c].iov_base = &rl; iov[c++].iov_len = sizeof(rl); - if (rl.tls_cert_len) { - iov[c].iov_base = rlay->rl_tls_cert; - iov[c++].iov_len = rl.tls_cert_len; - } + if ((what & CONFIG_CA_ENGINE) == 0 && rl.tls_key_len) { iov[c].iov_base = rlay->rl_tls_key; iov[c++].iov_len = rl.tls_key_len; } else rl.tls_key_len = 0; - if (rl.tls_ca_len) { - iov[c].iov_base = rlay->rl_tls_ca; - iov[c++].iov_len = rl.tls_ca_len; - } - if (rl.tls_cacert_len) { - iov[c].iov_base = rlay->rl_tls_cacert; - iov[c++].iov_len = rl.tls_cacert_len; - } if ((what & CONFIG_CA_ENGINE) == 0 && rl.tls_cakey_len) { iov[c].iov_base = rlay->rl_tls_cakey; @@ -841,7 +849,6 @@ config_setrelay(struct relayd *env, struct relay *rlay) __func__, rlay->rl_conf.name); return (-1); } - /* Prevent fd exhaustion in the parent. */ if (proc_flush_imsg(ps, id, n) == -1) { log_warn("%s: failed to flush " @@ -860,6 +867,48 @@ config_setrelay(struct relayd *env, struct relay *rlay) } } + + if (what & CONFIG_CERTS) { + n = -1; + proc_range(ps, id, &n, &m); + for (n = 0; n < m; n++) { + if (rlay->rl_tls_cert_fd != -1 && + config_setrelayfd(ps, id, n, + rlay->rl_conf.id, RELAY_FD_CERT, + rlay->rl_tls_cert_fd) == -1) { + log_warn("%s: fd passing failed for " + "`%s'", __func__, + rlay->rl_conf.name); + return (-1); + } + if (rlay->rl_tls_ca_fd != -1 && + config_setrelayfd(ps, id, n, + rlay->rl_conf.id, RELAY_FD_CACERT, + rlay->rl_tls_ca_fd) == -1) { + log_warn("%s: fd passing failed for " + "`%s'", __func__, + rlay->rl_conf.name); + return (-1); + } + if (rlay->rl_tls_cacert_fd != -1 && + config_setrelayfd(ps, id, n, + rlay->rl_conf.id, RELAY_FD_CAFILE, + rlay->rl_tls_cacert_fd) == -1) { + log_warn("%s: fd passing failed for " + "`%s'", __func__, + rlay->rl_conf.name); + return (-1); + } + /* Prevent fd exhaustion in the parent. */ + if (proc_flush_imsg(ps, id, n) == -1) { + log_warn("%s: failed to flush " + "IMSG_CFG_RELAY imsg for `%s'", + __func__, rlay->rl_conf.name); + return (-1); + } + } + } + if ((what & CONFIG_TABLES) == 0) continue; @@ -883,6 +932,18 @@ config_setrelay(struct relayd *env, struct relay *rlay) close(rlay->rl_s); rlay->rl_s = -1; } + if (rlay->rl_tls_cert_fd != -1) { + close(rlay->rl_tls_cert_fd); + rlay->rl_tls_cert_fd = -1; + } + if (rlay->rl_tls_cacert_fd != -1) { + close(rlay->rl_tls_cacert_fd); + rlay->rl_tls_cacert_fd = -1; + } + if (rlay->rl_tls_ca_fd != -1) { + close(rlay->rl_tls_ca_fd); + rlay->rl_tls_ca_fd = -1; + } return (0); } @@ -903,6 +964,9 @@ config_getrelay(struct relayd *env, struct imsg *imsg) s = sizeof(rlay->rl_conf); rlay->rl_s = imsg->fd; + rlay->rl_tls_cert_fd = -1; + rlay->rl_tls_ca_fd = -1; + rlay->rl_tls_cacert_fd = -1; if (ps->ps_what[privsep_process] & CONFIG_PROTOS) { if (rlay->rl_conf.proto == EMPTY_ID) @@ -915,39 +979,17 @@ config_getrelay(struct relayd *env, struct imsg *imsg) } if ((off_t)(IMSG_DATA_SIZE(imsg) - s) < - (rlay->rl_conf.tls_cert_len + - rlay->rl_conf.tls_key_len + - rlay->rl_conf.tls_ca_len + - rlay->rl_conf.tls_cacert_len + - rlay->rl_conf.tls_cakey_len)) { + (rlay->rl_conf.tls_key_len + rlay->rl_conf.tls_cakey_len)) { log_debug("%s: invalid message length", __func__); goto fail; } - if (rlay->rl_conf.tls_cert_len) { - if ((rlay->rl_tls_cert = get_data(p + s, - rlay->rl_conf.tls_cert_len)) == NULL) - goto fail; - s += rlay->rl_conf.tls_cert_len; - } if (rlay->rl_conf.tls_key_len) { if ((rlay->rl_tls_key = get_data(p + s, rlay->rl_conf.tls_key_len)) == NULL) goto fail; s += rlay->rl_conf.tls_key_len; } - if (rlay->rl_conf.tls_ca_len) { - if ((rlay->rl_tls_ca = get_data(p + s, - rlay->rl_conf.tls_ca_len)) == NULL) - goto fail; - s += rlay->rl_conf.tls_ca_len; - } - if (rlay->rl_conf.tls_cacert_len) { - if ((rlay->rl_tls_cacert = get_data(p + s, - rlay->rl_conf.tls_cacert_len)) == NULL) - goto fail; - s += rlay->rl_conf.tls_cacert_len; - } if (rlay->rl_conf.tls_cakey_len) { if ((rlay->rl_tls_cakey = get_data(p + s, rlay->rl_conf.tls_cakey_len)) == NULL) @@ -967,9 +1009,8 @@ config_getrelay(struct relayd *env, struct imsg *imsg) return (0); fail: - free(rlay->rl_tls_cert); free(rlay->rl_tls_key); - free(rlay->rl_tls_ca); + free(rlay->rl_tls_cakey); close(rlay->rl_s); free(rlay); return (-1); @@ -1016,3 +1057,42 @@ config_getrelaytable(struct relayd *env, struct imsg *imsg) free(rlt); return (-1); } + +int +config_getrelayfd(struct relayd *env, struct imsg *imsg) +{ + struct relay_table *rlt = NULL; + struct ctl_relayfd crfd; + struct relay *rlay; + u_int8_t *p = imsg->data; + + IMSG_SIZE_CHECK(imsg, &crfd); + memcpy(&crfd, p, sizeof(crfd)); + + if ((rlay = relay_find(env, crfd.relayid)) == NULL) { + log_debug("%s: unknown relay", __func__); + goto fail; + } + + switch (crfd.type) { + case RELAY_FD_CERT: + rlay->rl_tls_cert_fd = imsg->fd; + break; + case RELAY_FD_CACERT: + rlay->rl_tls_ca_fd = imsg->fd; + break; + case RELAY_FD_CAFILE: + rlay->rl_tls_cacert_fd = imsg->fd; + break; + } + + DPRINTF("%s: %s %d received relay fd %d type %d for relay %s", __func__, + env->sc_ps->ps_title[privsep_process], env->sc_ps->ps_instance, + imsg->fd, crfd.type, rlay->rl_conf.name); + + return (0); + + fail: + free(rlt); + return (-1); +} |