Use file descriptor passing to load certificates into the relays. Especially
authorclaudio <claudio@openbsd.org>
Mon, 27 Nov 2017 21:06:25 +0000 (21:06 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 27 Nov 2017 21:06:25 +0000 (21:06 +0000)
the ca file (having all the trusted certs in them) can be so big that loading
via imsg fails.
OK beck@

usr.sbin/relayd/ca.c
usr.sbin/relayd/config.c
usr.sbin/relayd/parse.y
usr.sbin/relayd/relay.c
usr.sbin/relayd/relayd.c
usr.sbin/relayd/relayd.h

index b5835d5..b1d9b61 100644 (file)
@@ -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;
index cf5dcf9..29ffa05 100644 (file)
@@ -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);
+}
index 791e689..f583789 100644 (file)
@@ -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;
        }
index ed66626..398f502 100644 (file)
@@ -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;
        }
index 7583da7..cb7567d 100644 (file)
@@ -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) {
index a4fda62..a88730a 100644 (file)
@@ -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 */