summaryrefslogtreecommitdiff
path: root/usr.sbin/relayd/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/relayd/config.c')
-rw-r--r--usr.sbin/relayd/config.c164
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);
+}