summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2017-11-27 21:06:27 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2017-11-27 21:06:27 +0000
commit54c5001bf783774434ec92bb01e1218c0d2403ea (patch)
tree6fb2e0e93e206fc7a540c9e9473ca8931c744c74 /usr.sbin
parentdef2e7bd562f959373eded254154792b5a178b05 (diff)
Use file descriptor passing to load certificates into the relays. Especially
the ca file (having all the trusted certs in them) can be so big that loading via imsg fails. OK beck@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/relayd/ca.c32
-rw-r--r--usr.sbin/relayd/config.c164
-rw-r--r--usr.sbin/relayd/parse.y15
-rw-r--r--usr.sbin/relayd/relay.c89
-rw-r--r--usr.sbin/relayd/relayd.c8
-rw-r--r--usr.sbin/relayd/relayd.h26
6 files changed, 225 insertions, 109 deletions
diff --git a/usr.sbin/relayd/ca.c b/usr.sbin/relayd/ca.c
index b5835d503b2..b1d9b61fc32 100644
--- a/usr.sbin/relayd/ca.c
+++ b/usr.sbin/relayd/ca.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ca.c,v 1.28 2017/08/09 21:31:16 claudio Exp $ */
+/* $OpenBSD: ca.c,v 1.29 2017/11/27 21:06:25 claudio Exp $ */
/*
* Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
@@ -109,18 +109,23 @@ void
ca_launch(void)
{
char hash[TLS_CERT_HASH_SIZE];
+ char *buf;
BIO *in = NULL;
EVP_PKEY *pkey = NULL;
struct relay *rlay;
X509 *cert = NULL;
+ off_t len;
TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) == 0)
continue;
- if (rlay->rl_conf.tls_cert_len) {
- if ((in = BIO_new_mem_buf(rlay->rl_tls_cert,
- rlay->rl_conf.tls_cert_len)) == NULL)
+ if (rlay->rl_tls_cert_fd != -1) {
+ if ((buf = relay_load_fd(rlay->rl_tls_cert_fd,
+ &len)) == NULL)
+ fatalx("ca_launch: cert");
+
+ if ((in = BIO_new_mem_buf(buf, len)) == NULL)
fatalx("ca_launch: cert");
if ((cert = PEM_read_bio_X509(in, NULL,
@@ -131,8 +136,7 @@ ca_launch(void)
BIO_free(in);
X509_free(cert);
- purge_key(&rlay->rl_tls_cert,
- rlay->rl_conf.tls_cert_len);
+ purge_key(&buf, len);
}
if (rlay->rl_conf.tls_key_len) {
if ((in = BIO_new_mem_buf(rlay->rl_tls_key,
@@ -153,9 +157,12 @@ ca_launch(void)
rlay->rl_conf.tls_key_len);
}
- if (rlay->rl_conf.tls_cacert_len) {
- if ((in = BIO_new_mem_buf(rlay->rl_tls_cacert,
- rlay->rl_conf.tls_cacert_len)) == NULL)
+ if (rlay->rl_tls_cacert_fd != -1) {
+ if ((buf = relay_load_fd(rlay->rl_tls_cacert_fd,
+ &len)) == NULL)
+ fatalx("ca_launch: cacert");
+
+ if ((in = BIO_new_mem_buf(buf, len)) == NULL)
fatalx("ca_launch: cacert");
if ((cert = PEM_read_bio_X509(in, NULL,
@@ -166,8 +173,7 @@ ca_launch(void)
BIO_free(in);
X509_free(cert);
- purge_key(&rlay->rl_tls_cacert,
- rlay->rl_conf.tls_cacert_len);
+ purge_key(&buf, len);
}
if (rlay->rl_conf.tls_cakey_len) {
if ((in = BIO_new_mem_buf(rlay->rl_tls_cakey,
@@ -187,6 +193,7 @@ ca_launch(void)
purge_key(&rlay->rl_tls_cakey,
rlay->rl_conf.tls_cakey_len);
}
+ close(rlay->rl_tls_ca_fd);
}
}
@@ -197,6 +204,9 @@ ca_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_CFG_RELAY:
config_getrelay(env, imsg);
break;
+ case IMSG_CFG_RELAY_FD:
+ config_getrelayfd(env, imsg);
+ break;
case IMSG_CFG_DONE:
config_getcfg(env, imsg);
break;
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);
+}
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y
index 791e689aa26..f5837896286 100644
--- a/usr.sbin/relayd/parse.y
+++ b/usr.sbin/relayd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.218 2017/11/16 14:24:34 bluhm Exp $ */
+/* $OpenBSD: parse.y,v 1.219 2017/11/27 21:06:26 claudio Exp $ */
/*
* Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -99,7 +99,6 @@ objid_t last_relay_id = 0;
objid_t last_proto_id = 0;
objid_t last_rt_id = 0;
objid_t last_nr_id = 0;
-objid_t last_key_id = 0;
static struct rdr *rdr = NULL;
static struct table *table = NULL;
@@ -1669,6 +1668,9 @@ relay : RELAY STRING {
r->rl_proto = NULL;
r->rl_conf.proto = EMPTY_ID;
r->rl_conf.dstretry = 0;
+ r->rl_tls_cert_fd = -1;
+ r->rl_tls_ca_fd = -1;
+ r->rl_tls_cacert_fd = -1;
TAILQ_INIT(&r->rl_tables);
if (last_relay_id == INT_MAX) {
yyerror("too many relays defined");
@@ -3201,10 +3203,8 @@ int
relay_id(struct relay *rl)
{
rl->rl_conf.id = ++last_relay_id;
- rl->rl_conf.tls_keyid = ++last_key_id;
- rl->rl_conf.tls_cakeyid = ++last_key_id;
- if (last_relay_id == INT_MAX || last_key_id == INT_MAX)
+ if (last_relay_id == INT_MAX)
return (-1);
return (0);
@@ -3224,8 +3224,9 @@ relay_inherit(struct relay *ra, struct relay *rb)
rb->rl_conf.flags =
(ra->rl_conf.flags & ~F_TLS) | (rc.flags & F_TLS);
if (!(rb->rl_conf.flags & F_TLS)) {
- rb->rl_tls_cert = NULL;
- rb->rl_conf.tls_cert_len = 0;
+ rb->rl_tls_cert_fd = -1;
+ rb->rl_tls_cacert_fd = -1;
+ rb->rl_tls_ca_fd = -1;
rb->rl_tls_key = NULL;
rb->rl_conf.tls_key_len = 0;
}
diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c
index ed6662651d0..398f502525d 100644
--- a/usr.sbin/relayd/relay.c
+++ b/usr.sbin/relayd/relay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relay.c,v 1.229 2017/11/27 17:35:49 claudio Exp $ */
+/* $OpenBSD: relay.c,v 1.230 2017/11/27 21:06:26 claudio Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -81,7 +81,6 @@ void relay_tls_connected(struct ctl_relay_event *);
void relay_tls_readcb(int, short, void *);
void relay_tls_writecb(int, short, void *);
-char *relay_load_file(const char *, off_t *);
extern void bufferevent_read_pressure_cb(struct evbuffer *, size_t,
size_t, void *);
@@ -1923,6 +1922,9 @@ relay_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_CFG_RELAY_TABLE:
config_getrelaytable(env, imsg);
break;
+ case IMSG_CFG_RELAY_FD:
+ config_getrelayfd(env, imsg);
+ break;
case IMSG_CFG_DONE:
config_getcfg(env, imsg);
break;
@@ -2037,6 +2039,8 @@ relay_tls_ctx_create(struct relay *rlay)
struct tls *tls = NULL;
const char *fake_key;
int fake_keylen;
+ char *buf = NULL, *cabuf = NULL;
+ off_t len = 0, calen = 0;
if ((tls_cfg = tls_config_new()) == NULL) {
log_warnx("unable to allocate TLS config");
@@ -2060,13 +2064,20 @@ relay_tls_ctx_create(struct relay *rlay)
*/
tls_config_insecure_noverifyname(tls_client_cfg);
- if (rlay->rl_tls_ca != NULL) {
- if (tls_config_set_ca_mem(tls_client_cfg,
- rlay->rl_tls_ca, rlay->rl_conf.tls_ca_len) != 0) {
+ if (rlay->rl_tls_ca_fd != -1) {
+ if ((buf = relay_load_fd(rlay->rl_tls_ca_fd, &len)) ==
+ NULL) {
+ log_warn("failed to read root certificates");
+ goto err;
+ }
+
+ if (tls_config_set_ca_mem(tls_client_cfg, buf, len) !=
+ 0) {
log_warnx("failed to set root certificates: %s",
tls_config_error(tls_client_cfg));
goto err;
}
+ purge_key(&buf, len);
} else {
/* No root cert available so disable the checking */
tls_config_insecure_noverifycert(tls_client_cfg);
@@ -2087,31 +2098,38 @@ relay_tls_ctx_create(struct relay *rlay)
*/
tls_config_skip_private_key_check(tls_cfg);
- if ((fake_keylen = ssl_ctx_fake_private_key(rlay->rl_tls_cert,
- rlay->rl_conf.tls_cert_len, &fake_key)) == -1) {
+ if ((buf = relay_load_fd(rlay->rl_tls_cert_fd, &len)) == NULL) {
+ log_warn("failed to load tls certificate");
+ goto err;
+ }
+
+ if ((fake_keylen = ssl_ctx_fake_private_key(buf, len,
+ &fake_key)) == -1) {
/* error already printed */
goto err;
}
- if (tls_config_set_keypair_ocsp_mem(tls_cfg,
- rlay->rl_tls_cert, rlay->rl_conf.tls_cert_len,
+ if (tls_config_set_keypair_ocsp_mem(tls_cfg, buf, len,
fake_key, fake_keylen, NULL, 0) != 0) {
log_warnx("failed to set tls certificate: %s",
tls_config_error(tls_cfg));
goto err;
}
- if (rlay->rl_conf.tls_cacert_len) {
+
+ if (rlay->rl_tls_cacert_fd != -1) {
+ if ((cabuf = relay_load_fd(rlay->rl_tls_cacert_fd,
+ &calen)) == NULL) {
+ log_warn("failed to load tls CA certificate");
+ goto err;
+ }
log_debug("%s: loading CA certificate", __func__);
- if (!ssl_load_pkey(
- rlay->rl_tls_cacert, rlay->rl_conf.tls_cacert_len,
+ if (!ssl_load_pkey(cabuf, calen,
&rlay->rl_tls_cacertx509, &rlay->rl_tls_capkey))
goto err;
/* loading certificate public key */
log_debug("%s: loading certificate", __func__);
- if (!ssl_load_pkey(
- rlay->rl_tls_cert, rlay->rl_conf.tls_cert_len,
- NULL, &rlay->rl_tls_pkey))
+ if (!ssl_load_pkey(buf, len, NULL, &rlay->rl_tls_pkey))
goto err;
}
@@ -2128,11 +2146,15 @@ relay_tls_ctx_create(struct relay *rlay)
}
rlay->rl_tls_cfg = tls_cfg;
rlay->rl_tls_ctx = tls;
+
+ purge_key(&cabuf, calen);
+ purge_key(&buf, len);
}
- /* The text versions of the keys/certs are not needed anymore */
- purge_key(&rlay->rl_tls_cert, rlay->rl_conf.tls_cert_len);
- purge_key(&rlay->rl_tls_cacert, rlay->rl_conf.tls_cacert_len);
+ /* The fd for the keys/certs are not needed anymore */
+ close(rlay->rl_tls_cert_fd);
+ close(rlay->rl_tls_cacert_fd);
+ close(rlay->rl_tls_ca_fd);
if (rlay->rl_tls_client_cfg == NULL)
tls_config_free(tls_client_cfg);
@@ -2141,6 +2163,9 @@ relay_tls_ctx_create(struct relay *rlay)
return (0);
err:
+ purge_key(&cabuf, calen);
+ purge_key(&buf, len);
+
tls_config_free(tls_client_cfg);
tls_config_free(tls_cfg);
return (-1);
@@ -2547,21 +2572,21 @@ relay_cmp_af(struct sockaddr_storage *a, struct sockaddr_storage *b)
}
char *
-relay_load_file(const char *name, off_t *len)
+relay_load_fd(int fd, off_t *len)
{
+ char *buf = NULL;
struct stat st;
off_t size;
- u_int8_t *buf = NULL;
- int fd;
+ ssize_t rv;
- if ((fd = open(name, O_RDONLY)) == -1)
- return (NULL);
if (fstat(fd, &st) != 0)
goto fail;
size = st.st_size;
if ((buf = calloc(1, size + 1)) == NULL)
goto fail;
- if (read(fd, buf, size) != size)
+ if (lseek(fd, 0, SEEK_SET) != 0)
+ goto fail;
+ if ((rv = read(fd, buf, size)) != size)
goto fail;
close(fd);
@@ -2585,16 +2610,14 @@ relay_load_certfiles(struct relay *rlay)
if (rlay->rl_conf.flags & F_TLSCLIENT) {
if (strlen(proto->tlsca)) {
- if ((rlay->rl_tls_ca =
- relay_load_file(proto->tlsca,
- &rlay->rl_conf.tls_ca_len)) == NULL)
+ if ((rlay->rl_tls_ca_fd =
+ open(proto->tlsca, O_RDONLY)) == -1)
return (-1);
log_debug("%s: using ca %s", __func__, proto->tlsca);
}
if (strlen(proto->tlscacert)) {
- if ((rlay->rl_tls_cacert =
- relay_load_file(proto->tlscacert,
- &rlay->rl_conf.tls_cacert_len)) == NULL)
+ if ((rlay->rl_tls_cacert_fd =
+ open(proto->tlscacert, O_RDONLY)) == -1)
return (-1);
log_debug("%s: using ca certificate %s", __func__,
proto->tlscacert);
@@ -2619,13 +2642,11 @@ relay_load_certfiles(struct relay *rlay)
if (snprintf(certfile, sizeof(certfile),
"/etc/ssl/%s:%u.crt", hbuf, useport) == -1)
return (-1);
- if ((rlay->rl_tls_cert = relay_load_file(certfile,
- &rlay->rl_conf.tls_cert_len)) == NULL) {
+ if ((rlay->rl_tls_cert_fd = open(certfile, O_RDONLY)) == -1) {
if (snprintf(certfile, sizeof(certfile),
"/etc/ssl/%s.crt", hbuf) == -1)
return (-1);
- if ((rlay->rl_tls_cert = relay_load_file(certfile,
- &rlay->rl_conf.tls_cert_len)) == NULL)
+ if ((rlay->rl_tls_cert_fd = open(certfile, O_RDONLY)) == -1)
return (-1);
useport = 0;
}
diff --git a/usr.sbin/relayd/relayd.c b/usr.sbin/relayd/relayd.c
index 7583da79efe..cb7567d6486 100644
--- a/usr.sbin/relayd/relayd.c
+++ b/usr.sbin/relayd/relayd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.c,v 1.169 2017/05/31 04:14:34 jsg Exp $ */
+/* $OpenBSD: relayd.c,v 1.170 2017/11/27 21:06:26 claudio Exp $ */
/*
* Copyright (c) 2007 - 2016 Reyk Floeter <reyk@openbsd.org>
@@ -294,9 +294,7 @@ parent_configure(struct relayd *env)
TAILQ_FOREACH(rlay, env->sc_relays, rl_entry) {
/* Check for TLS Inspection */
if ((rlay->rl_conf.flags & (F_TLS|F_TLSCLIENT)) ==
- (F_TLS|F_TLSCLIENT) &&
- rlay->rl_conf.tls_cacert_len &&
- rlay->rl_conf.tls_cakey_len)
+ (F_TLS|F_TLSCLIENT) && rlay->rl_tls_cacert_fd != -1)
rlay->rl_conf.flags |= F_TLSINSPECT;
config_setrelay(env, rlay);
@@ -571,9 +569,7 @@ purge_relay(struct relayd *env, struct relay *rlay)
if (rlay->rl_dstbev != NULL)
bufferevent_free(rlay->rl_dstbev);
- purge_key(&rlay->rl_tls_cert, rlay->rl_conf.tls_cert_len);
purge_key(&rlay->rl_tls_key, rlay->rl_conf.tls_key_len);
- purge_key(&rlay->rl_tls_ca, rlay->rl_conf.tls_ca_len);
purge_key(&rlay->rl_tls_cakey, rlay->rl_conf.tls_cakey_len);
if (rlay->rl_tls_pkey != NULL) {
diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h
index a4fda62d2e9..a88730ab4cd 100644
--- a/usr.sbin/relayd/relayd.h
+++ b/usr.sbin/relayd/relayd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.h,v 1.243 2017/11/15 19:03:26 benno Exp $ */
+/* $OpenBSD: relayd.h,v 1.244 2017/11/27 21:06:26 claudio Exp $ */
/*
* Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org>
@@ -90,6 +90,7 @@
#define CONFIG_ROUTES 0x10
#define CONFIG_RTS 0x20
#define CONFIG_CA_ENGINE 0x40
+#define CONFIG_CERTS 0x80
#define CONFIG_ALL 0xff
#define SMALL_READ_BUF_SIZE 1024
@@ -136,6 +137,14 @@ struct ctl_relaytable {
u_int32_t flags;
};
+struct ctl_relayfd {
+ objid_t relayid;
+ int type;
+};
+#define RELAY_FD_CERT 1
+#define RELAY_FD_CACERT 2
+#define RELAY_FD_CAFILE 3
+
struct ctl_script {
objid_t host;
int retval;
@@ -759,13 +768,8 @@ struct relay_config {
struct timeval timeout;
enum forwardmode fwdmode;
union hashkey hashkey;
- off_t tls_cert_len;
off_t tls_key_len;
- objid_t tls_keyid;
- off_t tls_ca_len;
- off_t tls_cacert_len;
off_t tls_cakey_len;
- objid_t tls_cakeyid;
};
struct relay {
@@ -789,11 +793,11 @@ struct relay {
struct tls_config *rl_tls_client_cfg;
struct tls *rl_tls_ctx;
- char *rl_tls_cert;
+ int rl_tls_cert_fd;
+ int rl_tls_ca_fd;
+ int rl_tls_cacert_fd;
char *rl_tls_key;
EVP_PKEY *rl_tls_pkey;
- char *rl_tls_ca;
- char *rl_tls_cacert;
X509 *rl_tls_cacertx509;
char *rl_tls_cakey;
EVP_PKEY *rl_tls_capkey;
@@ -960,6 +964,8 @@ enum imsg_type {
IMSG_CFG_RULE,
IMSG_CFG_RELAY,
IMSG_CFG_RELAY_TABLE,
+ IMSG_CFG_RELAY_CERT,
+ IMSG_CFG_RELAY_FD,
IMSG_CFG_DONE,
IMSG_CA_PRIVENC,
IMSG_CA_PRIVDEC,
@@ -1163,6 +1169,7 @@ void relay(struct privsep *, struct privsep_proc *);
int relay_privinit(struct relay *);
void relay_notify_done(struct host *, const char *);
int relay_session_cmp(struct rsession *, struct rsession *);
+char *relay_load_fd(int, off_t *);
int relay_load_certfiles(struct relay *);
void relay_close(struct rsession *, const char *);
void relay_natlook(int, short, void *);
@@ -1423,5 +1430,6 @@ int config_getrule(struct relayd *, struct imsg *);
int config_setrelay(struct relayd *, struct relay *);
int config_getrelay(struct relayd *, struct imsg *);
int config_getrelaytable(struct relayd *, struct imsg *);
+int config_getrelayfd(struct relayd *, struct imsg *);
#endif /* RELAYD_H */