summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsing <jsing@openbsd.org>2015-07-15 16:00:39 +0000
committerjsing <jsing@openbsd.org>2015-07-15 16:00:39 +0000
commit6f8bdc862b4eba8f72d51aae2c7b53ff1f510f55 (patch)
tree71221807b09baaa31ea27a5fdbf4d02fd0a46308
parenttypo in manual page. (diff)
downloadwireguard-openbsd-6f8bdc862b4eba8f72d51aae2c7b53ff1f510f55.tar.xz
wireguard-openbsd-6f8bdc862b4eba8f72d51aae2c7b53ff1f510f55.zip
Send the TLS certificate and key via separate imsgs, rather than
including them in the IMSG_CFG_SERVER imsg. This allows the certificate and key to each be almost 16KB (the maximum size for an imsg), rather than having a combined total of less than 16KB (which can be reached with large keys, certificate bundles or by including text versions of certificates). ok reyk@
-rw-r--r--usr.sbin/httpd/config.c148
-rw-r--r--usr.sbin/httpd/httpd.h15
-rw-r--r--usr.sbin/httpd/server.c5
3 files changed, 142 insertions, 26 deletions
diff --git a/usr.sbin/httpd/config.c b/usr.sbin/httpd/config.c
index bd4dab2d5e0..3c889906410 100644
--- a/usr.sbin/httpd/config.c
+++ b/usr.sbin/httpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.38 2015/07/15 14:39:13 jsing Exp $ */
+/* $OpenBSD: config.c,v 1.39 2015/07/15 16:00:39 jsing Exp $ */
/*
* Copyright (c) 2011 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -193,14 +193,6 @@ config_setserver(struct httpd *env, struct server *srv)
iov[c].iov_base = srv->srv_conf.return_uri;
iov[c++].iov_len = srv->srv_conf.return_uri_len;
}
- if (srv->srv_conf.tls_cert_len != 0) {
- iov[c].iov_base = srv->srv_conf.tls_cert;
- iov[c++].iov_len = srv->srv_conf.tls_cert_len;
- }
- if (srv->srv_conf.tls_key_len != 0) {
- iov[c].iov_base = srv->srv_conf.tls_key;
- iov[c++].iov_len = srv->srv_conf.tls_key_len;
- }
if (id == PROC_SERVER &&
(srv->srv_conf.flags & SRVFLAG_LOCATION) == 0) {
@@ -220,6 +212,9 @@ config_setserver(struct httpd *env, struct server *srv)
return (-1);
}
}
+
+ /* Configure TLS if necessary. */
+ config_settls(env, srv);
} else {
if (proc_composev_imsg(ps, id, -1, IMSG_CFG_SERVER, -1,
iov, c) != 0) {
@@ -235,6 +230,72 @@ config_setserver(struct httpd *env, struct server *srv)
}
int
+config_settls(struct httpd *env, struct server *srv)
+{
+ struct privsep *ps = env->sc_ps;
+ struct tls_config tls;
+ struct iovec iov[2];
+ size_t c;
+
+ if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0)
+ return (0);
+
+ log_debug("%s: configuring TLS for %s", __func__, srv->srv_conf.name);
+
+ if (srv->srv_conf.tls_cert_len != 0) {
+ DPRINTF("%s: sending TLS cert \"%s[%u]\" to %s fd %d", __func__,
+ srv->srv_conf.name, srv->srv_conf.id,
+ ps->ps_title[PROC_SERVER], srv->srv_s);
+
+ memset(&tls, 0, sizeof(tls));
+ tls.id = srv->srv_conf.id;
+ tls.port = srv->srv_conf.port;
+ memcpy(&tls.ss, &srv->srv_conf.ss, sizeof(tls.ss));
+ tls.tls_cert_len = srv->srv_conf.tls_cert_len;
+
+ c = 0;
+ iov[c].iov_base = &tls;
+ iov[c++].iov_len = sizeof(tls);
+ iov[c].iov_base = srv->srv_conf.tls_cert;
+ iov[c++].iov_len = srv->srv_conf.tls_cert_len;
+
+ if (proc_composev_imsg(ps, PROC_SERVER, -1, IMSG_CFG_TLS, -1,
+ iov, c) != 0) {
+ log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
+ "`%s'", __func__, srv->srv_conf.name);
+ return (-1);
+ }
+ }
+
+ if (srv->srv_conf.tls_key_len != 0) {
+ DPRINTF("%s: sending TLS key \"%s[%u]\" to %s fd %d", __func__,
+ srv->srv_conf.name, srv->srv_conf.id,
+ ps->ps_title[PROC_SERVER], srv->srv_s);
+
+ memset(&tls, 0, sizeof(tls));
+ tls.id = srv->srv_conf.id;
+ tls.port = srv->srv_conf.port;
+ memcpy(&tls.ss, &srv->srv_conf.ss, sizeof(tls.ss));
+ tls.tls_key_len = srv->srv_conf.tls_key_len;
+
+ c = 0;
+ iov[c].iov_base = &tls;
+ iov[c++].iov_len = sizeof(tls);
+ iov[c].iov_base = srv->srv_conf.tls_key;
+ iov[c++].iov_len = srv->srv_conf.tls_key_len;
+
+ if (proc_composev_imsg(ps, PROC_SERVER, -1, IMSG_CFG_TLS, -1,
+ iov, c) != 0) {
+ log_warn("%s: failed to compose IMSG_CFG_TLS imsg for "
+ "`%s'", __func__, srv->srv_conf.name);
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+int
config_getserver_auth(struct httpd *env, struct server_config *srv_conf)
{
struct privsep *ps = env->sc_ps;
@@ -422,9 +483,7 @@ config_getserver(struct httpd *env, struct imsg *imsg)
/* Reset these variables to avoid free'ing invalid pointers */
serverconfig_reset(&srv_conf);
- if ((IMSG_DATA_SIZE(imsg) - s) <
- (srv_conf.tls_cert_len + srv_conf.tls_key_len +
- srv_conf.return_uri_len)) {
+ if ((IMSG_DATA_SIZE(imsg) - s) < (size_t)srv_conf.return_uri_len) {
log_debug("%s: invalid message length", __func__);
goto fail;
}
@@ -475,18 +534,6 @@ config_getserver(struct httpd *env, struct imsg *imsg)
goto fail;
s += srv->srv_conf.return_uri_len;
}
- if (srv->srv_conf.tls_cert_len != 0) {
- if ((srv->srv_conf.tls_cert = get_data(p + s,
- srv->srv_conf.tls_cert_len)) == NULL)
- goto fail;
- s += srv->srv_conf.tls_cert_len;
- }
- if (srv->srv_conf.tls_key_len != 0) {
- if ((srv->srv_conf.tls_key = get_data(p + s,
- srv->srv_conf.tls_key_len)) == NULL)
- goto fail;
- s += srv->srv_conf.tls_key_len;
- }
return (0);
@@ -501,6 +548,59 @@ config_getserver(struct httpd *env, struct imsg *imsg)
}
int
+config_gettls(struct httpd *env, struct imsg *imsg)
+{
+#ifdef DEBUG
+ struct privsep *ps = env->sc_ps;
+#endif
+ struct server *srv = NULL;
+ struct tls_config tls_conf;
+ u_int8_t *p = imsg->data;
+ size_t s;
+
+ IMSG_SIZE_CHECK(imsg, &tls_conf);
+ memcpy(&tls_conf, p, sizeof(tls_conf));
+ s = sizeof(tls_conf);
+
+ if ((IMSG_DATA_SIZE(imsg) - s) <
+ (tls_conf.tls_cert_len + tls_conf.tls_key_len)) {
+ log_debug("%s: invalid message length", __func__);
+ goto fail;
+ }
+
+ /* Find server with matching listening socket. */
+ if ((srv = server_byaddr((struct sockaddr *)
+ &tls_conf.ss, tls_conf.port)) == NULL) {
+ log_debug("%s: server not found", __func__);
+ goto fail;
+ }
+
+ DPRINTF("%s: %s %d TLS configuration \"%s[%u]\"", __func__,
+ ps->ps_title[privsep_process], ps->ps_instance,
+ srv->srv_conf.name, srv->srv_conf.id);
+
+ if (tls_conf.tls_cert_len != 0) {
+ srv->srv_conf.tls_cert_len = tls_conf.tls_cert_len;
+ if ((srv->srv_conf.tls_cert = get_data(p + s,
+ tls_conf.tls_cert_len)) == NULL)
+ goto fail;
+ s += tls_conf.tls_cert_len;
+ }
+ if (tls_conf.tls_key_len != 0) {
+ srv->srv_conf.tls_key_len = tls_conf.tls_key_len;
+ if ((srv->srv_conf.tls_key = get_data(p + s,
+ tls_conf.tls_key_len)) == NULL)
+ goto fail;
+ s += tls_conf.tls_key_len;
+ }
+
+ return (0);
+
+ fail:
+ return (-1);
+}
+
+int
config_setmedia(struct httpd *env, struct media_type *media)
{
struct privsep *ps = env->sc_ps;
diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h
index 20d75a78334..664f17c6764 100644
--- a/usr.sbin/httpd/httpd.h
+++ b/usr.sbin/httpd/httpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: httpd.h,v 1.84 2015/06/23 15:23:14 reyk Exp $ */
+/* $OpenBSD: httpd.h,v 1.85 2015/07/15 16:00:39 jsing Exp $ */
/*
* Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -201,6 +201,7 @@ enum imsg_type {
IMSG_CTL_START,
IMSG_CTL_REOPEN,
IMSG_CFG_SERVER,
+ IMSG_CFG_TLS,
IMSG_CFG_MEDIA,
IMSG_CFG_AUTH,
IMSG_CFG_DONE,
@@ -442,6 +443,16 @@ struct server_config {
};
TAILQ_HEAD(serverhosts, server_config);
+struct tls_config {
+ u_int32_t id;
+
+ in_port_t port;
+ struct sockaddr_storage ss;
+
+ size_t tls_cert_len;
+ size_t tls_key_len;
+};
+
struct server {
TAILQ_ENTRY(server) srv_entry;
struct server_config srv_conf;
@@ -680,7 +691,9 @@ int config_setreset(struct httpd *, u_int);
int config_getreset(struct httpd *, struct imsg *);
int config_getcfg(struct httpd *, struct imsg *);
int config_setserver(struct httpd *, struct server *);
+int config_settls(struct httpd *, struct server *);
int config_getserver(struct httpd *, struct imsg *);
+int config_gettls(struct httpd *, struct imsg *);
int config_setmedia(struct httpd *, struct media_type *);
int config_getmedia(struct httpd *, struct imsg *);
int config_setauth(struct httpd *, struct auth *);
diff --git a/usr.sbin/httpd/server.c b/usr.sbin/httpd/server.c
index 15d19450a36..d28b67b90c6 100644
--- a/usr.sbin/httpd/server.c
+++ b/usr.sbin/httpd/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.65 2015/07/15 14:49:42 jsing Exp $ */
+/* $OpenBSD: server.c,v 1.66 2015/07/15 16:00:39 jsing Exp $ */
/*
* Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -1134,6 +1134,9 @@ server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_CFG_SERVER:
config_getserver(env, imsg);
break;
+ case IMSG_CFG_TLS:
+ config_gettls(env, imsg);
+ break;
case IMSG_CFG_DONE:
config_getcfg(env, imsg);
break;