just go for it. see who screams ok beck@
On Sunday, 24 April 2016, Sebastian Benoit <[email protected]> wrote: > Jonathan Matthew([email protected] <javascript:;>) on 2016.04.18 07:17:55 > +1000: > > On Sun, Apr 10, 2016 at 04:36:15PM +1000, Jonathan Matthew wrote: > > > A while back (s2k15?), reyk@ suggested I take a look at converting > ldapd to use > > > libtls rather than the openssl api. Today I finally got around to it, > > > resulting in the diff below. Most of the diff just removes ssl.c and > > > ssl_privsep.c, and replaces some of it with evbuffer_tls.c (copied from > > > syslogd, unmodified). A reasonable amount of code just went away > because > > > libtls is sensible. The few remaining bits of ssl.c moved to wherever > seemed > > > most suitable. > > > > > > I've tested a few things with the openldap clients, which apparently > only do > > > starttls, and otherwise checked that it negotiates ssl successfully. > > > > > > ok? > > > > ldapd is too boring? > > :) > > ok from me, but i cant test it. > > > > > > > > > > > > Index: Makefile > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/Makefile,v > > > retrieving revision 1.12 > > > diff -u -p -u -p -r1.12 Makefile > > > --- Makefile 16 Jul 2014 20:07:03 -0000 1.12 > > > +++ Makefile 10 Apr 2016 06:15:50 -0000 > > > @@ -5,11 +5,11 @@ MAN= ldapd.8 ldapd.conf.5 > > > SRCS= ber.c log.c control.c \ > > > util.c ldapd.c ldape.c conn.c attributes.c namespace.c \ > > > btree.c filter.c search.c parse.y \ > > > - auth.c modify.c index.c ssl.c ssl_privsep.c \ > > > + auth.c modify.c index.c evbuffer_tls.c \ > > > validate.c uuid.c schema.c imsgev.c syntax.c matching.c > > > > > > -LDADD= -levent -lssl -lcrypto -lz -lutil > > > -DPADD= ${LIBEVENT} ${LIBCRYPTO} ${LIBSSL} ${LIBZ} > ${LIBUTIL} > > > +LDADD= -ltls -levent -lz -lutil > > > +DPADD= ${LIBEVENT} ${LIBTLS} ${LIBCRYPTO} ${LIBSSL} > ${LIBZ} ${LIBUTIL} > > > CFLAGS+= -I${.CURDIR} -g > > > CFLAGS+= -Wall -Wstrict-prototypes -Wmissing-prototypes > > > CFLAGS+= -Wmissing-declarations > > > Index: btree.c > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/btree.c,v > > > retrieving revision 1.36 > > > diff -u -p -u -p -r1.36 btree.c > > > --- btree.c 20 Mar 2016 00:01:22 -0000 1.36 > > > +++ btree.c 10 Apr 2016 06:15:51 -0000 > > > @@ -34,6 +34,8 @@ > > > #include <time.h> > > > #include <unistd.h> > > > > > > +#include <openssl/sha.h> > > > + > > > #include "btree.h" > > > > > > /* #define DEBUG */ > > > Index: btree.h > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/btree.h,v > > > retrieving revision 1.6 > > > diff -u -p -u -p -r1.6 btree.h > > > --- btree.h 2 Jul 2010 01:43:00 -0000 1.6 > > > +++ btree.h 10 Apr 2016 06:15:51 -0000 > > > @@ -19,8 +19,6 @@ > > > #ifndef _btree_h_ > > > #define _btree_h_ > > > > > > -#include <openssl/sha.h> > > > - > > > struct mpage; > > > struct cursor; > > > struct btree_txn; > > > Index: conn.c > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/conn.c,v > > > retrieving revision 1.12 > > > diff -u -p -u -p -r1.12 conn.c > > > --- conn.c 2 Nov 2015 06:32:51 -0000 1.12 > > > +++ conn.c 10 Apr 2016 06:15:51 -0000 > > > @@ -26,6 +26,7 @@ > > > #include "ldapd.h" > > > > > > int conn_dispatch(struct conn *conn); > > > +int conn_tls_init(struct conn *); > > > unsigned long ldap_application(struct ber_element *elm); > > > > > > struct conn_list conn_list; > > > @@ -61,7 +62,7 @@ conn_close(struct conn *conn) > > > /* Cancel any queued requests on this connection. */ > > > namespace_cancel_conn(conn); > > > > > > - ssl_session_destroy(conn); > > > + tls_free(conn->tls); > > > > > > TAILQ_REMOVE(&conn_list, conn, next); > > > ber_free(&conn->ber); > > > @@ -225,9 +226,8 @@ conn_write(struct bufferevent *bev, void > > > conn_close(conn); > > > else if (conn->s_flags & F_STARTTLS) { > > > conn->s_flags &= ~F_STARTTLS; > > > - bufferevent_free(conn->bev); > > > - conn->bev = NULL; > > > - ssl_session_init(conn); > > > + if (conn_tls_init(conn) == -1) > > > + conn_close(conn); > > > } > > > } > > > > > > @@ -296,24 +296,22 @@ conn_accept(int fd, short event, void *d > > > goto giveup; > > > } > > > conn->ber.fd = -1; > > > - conn->s_l = l; > > > ber_set_application(&conn->ber, ldap_application); > > > conn->fd = afd; > > > conn->listener = l; > > > > > > - if (l->flags & F_LDAPS) { > > > - ssl_session_init(conn); > > > - } else { > > > - conn->bev = bufferevent_new(afd, conn_read, conn_write, > > > - conn_err, conn); > > > - if (conn->bev == NULL) { > > > - log_warn("conn_accept: bufferevent_new"); > > > - free(conn); > > > - goto giveup; > > > - } > > > - bufferevent_enable(conn->bev, EV_READ); > > > - bufferevent_settimeout(conn->bev, 0, 60); > > > + conn->bev = bufferevent_new(afd, conn_read, conn_write, > > > + conn_err, conn); > > > + if (conn->bev == NULL) { > > > + log_warn("conn_accept: bufferevent_new"); > > > + free(conn); > > > + goto giveup; > > > } > > > + bufferevent_enable(conn->bev, EV_READ); > > > + bufferevent_settimeout(conn->bev, 0, 60); > > > + if (conn->s_flags & F_LDAPS) > > > + if (conn_tls_init(conn) == -1) > > > + conn_close(conn); > > > > > > TAILQ_INIT(&conn->searches); > > > TAILQ_INSERT_HEAD(&conn_list, conn, next); > > > @@ -365,4 +363,25 @@ conn_close_any() > > > } > > > > > > return -1; > > > +} > > > + > > > +int > > > +conn_tls_init(struct conn *conn) > > > +{ > > > + struct listener *l = conn->listener; > > > + > > > + if (!(l->flags & F_SSL)) > > > + return 0; > > > + > > > + log_debug("conn_tls_init: switching to TLS"); > > > + > > > + if (tls_accept_socket(l->tls, &conn->tls, conn->fd) < 0) { > > > + log_debug("tls_accept_socket failed"); > > > + return -1; > > > + } > > > + > > > + conn->s_flags |= F_SECURE; > > > + buffertls_set(&conn->buftls, conn->bev, conn->tls, conn->fd); > > > + buffertls_accept(&conn->buftls, conn->fd); > > > + return 0; > > > } > > > Index: evbuffer_tls.c > > > =================================================================== > > > RCS file: evbuffer_tls.c > > > diff -N evbuffer_tls.c > > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > > +++ evbuffer_tls.c 10 Apr 2016 06:15:51 -0000 > > > @@ -0,0 +1,350 @@ > > > +/* $OpenBSD: evbuffer_tls.c,v 1.9 2015/10/09 16:58:25 bluhm Exp $ */ > > > + > > > +/* > > > + * Copyright (c) 2002-2004 Niels Provos <[email protected]> > > > + * Copyright (c) 2014-2015 Alexander Bluhm <[email protected]> > > > + * All rights reserved. > > > + * > > > + * Redistribution and use in source and binary forms, with or without > > > + * modification, are permitted provided that the following conditions > > > + * are met: > > > + * 1. Redistributions of source code must retain the above copyright > > > + * notice, this list of conditions and the following disclaimer. > > > + * 2. Redistributions in binary form must reproduce the above > copyright > > > + * notice, this list of conditions and the following disclaimer in > the > > > + * documentation and/or other materials provided with the > distribution. > > > + * 3. The name of the author may not be used to endorse or promote > products > > > + * derived from this software without specific prior written > permission. > > > + * > > > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS > OR > > > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > WARRANTIES > > > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > DISCLAIMED. > > > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > > > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES > (INCLUDING, BUT > > > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS > OF USE, > > > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON > ANY > > > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > > > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE > USE OF > > > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > > > + */ > > > + > > > +#include <sys/types.h> > > > +#include <sys/time.h> > > > +#include <sys/ioctl.h> > > > + > > > +#include <errno.h> > > > +#include <event.h> > > > +#include <stdio.h> > > > +#include <stdlib.h> > > > +#include <string.h> > > > +#include <tls.h> > > > + > > > +#include "evbuffer_tls.h" > > > + > > > +/* prototypes */ > > > + > > > +void bufferevent_read_pressure_cb(struct evbuffer *, size_t, size_t, > void *); > > > +static void buffertls_readcb(int, short, void *); > > > +static void buffertls_writecb(int, short, void *); > > > +static void buffertls_handshakecb(int, short, void *); > > > +int evtls_read(struct evbuffer *, int, int, struct tls *); > > > +int evtls_write(struct evbuffer *, int, struct tls *); > > > + > > > +static int > > > +bufferevent_add(struct event *ev, int timeout) > > > +{ > > > + struct timeval tv, *ptv = NULL; > > > + > > > + if (timeout) { > > > + timerclear(&tv); > > > + tv.tv_sec = timeout; > > > + ptv = &tv; > > > + } > > > + > > > + return (event_add(ev, ptv)); > > > +} > > > + > > > +static void > > > +buffertls_readcb(int fd, short event, void *arg) > > > +{ > > > + struct buffertls *buftls = arg; > > > + struct bufferevent *bufev = buftls->bt_bufev; > > > + struct tls *ctx = buftls->bt_ctx; > > > + int res = 0; > > > + short what = EVBUFFER_READ; > > > + size_t len; > > > + int howmuch = -1; > > > + > > > + if (event == EV_TIMEOUT) { > > > + what |= EVBUFFER_TIMEOUT; > > > + goto error; > > > + } > > > + > > > + /* > > > + * If we have a high watermark configured then we don't want to > > > + * read more data than would make us reach the watermark. > > > + */ > > > + if (bufev->wm_read.high != 0) { > > > + howmuch = bufev->wm_read.high - > EVBUFFER_LENGTH(bufev->input); > > > + /* we might have lowered the watermark, stop reading */ > > > + if (howmuch <= 0) { > > > + struct evbuffer *buf = bufev->input; > > > + event_del(&bufev->ev_read); > > > + evbuffer_setcb(buf, > > > + bufferevent_read_pressure_cb, bufev); > > > + return; > > > + } > > > + } > > > + > > > + res = evtls_read(bufev->input, fd, howmuch, ctx); > > > + switch (res) { > > > + case TLS_WANT_POLLIN: > > > + bufferevent_add(&bufev->ev_read, bufev->timeout_read); > > > + return; > > > + case TLS_WANT_POLLOUT: > > > + event_del(&bufev->ev_write); > > > + event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_readcb, > > > + buftls); > > > + bufferevent_add(&bufev->ev_write, bufev->timeout_write); > > > + return; > > > + case -1: > > > + what |= EVBUFFER_ERROR; > > > + break; > > > + case 0: > > > + what |= EVBUFFER_EOF; > > > + break; > > > + } > > > + if (res <= 0) > > > + goto error; > > > + > > > + event_del(&bufev->ev_write); > > > + event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, > buftls); > > > + if (bufev->enabled & EV_READ) > > > + bufferevent_add(&bufev->ev_read, bufev->timeout_read); > > > + if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & > EV_WRITE) > > > + bufferevent_add(&bufev->ev_write, bufev->timeout_write); > > > + > > > + /* See if this callbacks meets the water marks */ > > > + len = EVBUFFER_LENGTH(bufev->input); > > > + if (bufev->wm_read.low != 0 && len < bufev->wm_read.low) > > > + return; > > > + if (bufev->wm_read.high != 0 && len >= bufev->wm_read.high) { > > > + struct evbuffer *buf = bufev->input; > > > + event_del(&bufev->ev_read); > > > + > > > + /* Now schedule a callback for us when the buffer changes > */ > > > + evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev); > > > + } > > > + > > > + /* Invoke the user callback - must always be called last */ > > > + if (bufev->readcb != NULL) > > > + (*bufev->readcb)(bufev, bufev->cbarg); > > > + return; > > > + > > > + error: > > > + (*bufev->errorcb)(bufev, what, bufev->cbarg); > > > +} > > > + > > > +static void > > > +buffertls_writecb(int fd, short event, void *arg) > > > +{ > > > + struct buffertls *buftls = arg; > > > + struct bufferevent *bufev = buftls->bt_bufev; > > > + struct tls *ctx = buftls->bt_ctx; > > > + int res = 0; > > > + short what = EVBUFFER_WRITE; > > > + > > > + if (event == EV_TIMEOUT) { > > > + what |= EVBUFFER_TIMEOUT; > > > + goto error; > > > + } > > > + > > > + if (EVBUFFER_LENGTH(bufev->output) != 0) { > > > + res = evtls_write(bufev->output, fd, ctx); > > > + switch (res) { > > > + case TLS_WANT_POLLIN: > > > + event_del(&bufev->ev_read); > > > + event_set(&bufev->ev_read, fd, EV_READ, > > > + buffertls_writecb, buftls); > > > + bufferevent_add(&bufev->ev_read, > bufev->timeout_read); > > > + return; > > > + case TLS_WANT_POLLOUT: > > > + bufferevent_add(&bufev->ev_write, > bufev->timeout_write); > > > + return; > > > + case -1: > > > + what |= EVBUFFER_ERROR; > > > + break; > > > + case 0: > > > + what |= EVBUFFER_EOF; > > > + break; > > > + } > > > + if (res <= 0) > > > + goto error; > > > + } > > > + > > > + event_del(&bufev->ev_read); > > > + event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb, buftls); > > > + if (bufev->enabled & EV_READ) > > > + bufferevent_add(&bufev->ev_read, bufev->timeout_read); > > > + if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & > EV_WRITE) > > > + bufferevent_add(&bufev->ev_write, bufev->timeout_write); > > > + > > > + /* > > > + * Invoke the user callback if our buffer is drained or below the > > > + * low watermark. > > > + */ > > > + if (bufev->writecb != NULL && > > > + EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low) > > > + (*bufev->writecb)(bufev, bufev->cbarg); > > > + > > > + return; > > > + > > > + error: > > > + (*bufev->errorcb)(bufev, what, bufev->cbarg); > > > +} > > > + > > > +static void > > > +buffertls_handshakecb(int fd, short event, void *arg) > > > +{ > > > + struct buffertls *buftls = arg; > > > + struct bufferevent *bufev = buftls->bt_bufev; > > > + struct tls *ctx = buftls->bt_ctx; > > > + int res = 0; > > > + short what = EVBUFFER_HANDSHAKE; > > > + > > > + if (event == EV_TIMEOUT) { > > > + what |= EVBUFFER_TIMEOUT; > > > + goto error; > > > + } > > > + > > > + res = tls_handshake(ctx); > > > + switch (res) { > > > + case TLS_WANT_POLLIN: > > > + bufferevent_add(&bufev->ev_read, bufev->timeout_read); > > > + return; > > > + case TLS_WANT_POLLOUT: > > > + bufferevent_add(&bufev->ev_write, bufev->timeout_write); > > > + return; > > > + case -1: > > > + what |= EVBUFFER_ERROR; > > > + break; > > > + } > > > + if (res < 0) > > > + goto error; > > > + > > > + /* Handshake was successful, change to read and write callback. */ > > > + event_del(&bufev->ev_read); > > > + event_del(&bufev->ev_write); > > > + event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb, buftls); > > > + event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, > buftls); > > > + if (bufev->enabled & EV_READ) > > > + bufferevent_add(&bufev->ev_read, bufev->timeout_read); > > > + if (EVBUFFER_LENGTH(bufev->output) != 0 && bufev->enabled & > EV_WRITE) > > > + bufferevent_add(&bufev->ev_write, bufev->timeout_write); > > > + > > > + return; > > > + > > > + error: > > > + (*bufev->errorcb)(bufev, what, bufev->cbarg); > > > +} > > > + > > > +void > > > +buffertls_set(struct buffertls *buftls, struct bufferevent *bufev, > > > + struct tls *ctx, int fd) > > > +{ > > > + bufferevent_setfd(bufev, fd); > > > + event_set(&bufev->ev_read, fd, EV_READ, buffertls_readcb, buftls); > > > + event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_writecb, > buftls); > > > + buftls->bt_bufev = bufev; > > > + buftls->bt_ctx = ctx; > > > +} > > > + > > > +void > > > +buffertls_accept(struct buffertls *buftls, int fd) > > > +{ > > > + struct bufferevent *bufev = buftls->bt_bufev; > > > + > > > + event_del(&bufev->ev_read); > > > + event_del(&bufev->ev_write); > > > + event_set(&bufev->ev_read, fd, EV_READ, buffertls_handshakecb, > buftls); > > > + event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_handshakecb, > > > + buftls); > > > + bufferevent_add(&bufev->ev_read, bufev->timeout_read); > > > +} > > > + > > > +void > > > +buffertls_connect(struct buffertls *buftls, int fd) > > > +{ > > > + struct bufferevent *bufev = buftls->bt_bufev; > > > + > > > + event_del(&bufev->ev_read); > > > + event_del(&bufev->ev_write); > > > + event_set(&bufev->ev_read, fd, EV_READ, buffertls_handshakecb, > buftls); > > > + event_set(&bufev->ev_write, fd, EV_WRITE, buffertls_handshakecb, > > > + buftls); > > > + bufferevent_add(&bufev->ev_write, bufev->timeout_write); > > > +} > > > + > > > +/* > > > + * Reads data from a file descriptor into a buffer. > > > + */ > > > + > > > +#define EVBUFFER_MAX_READ 4096 > > > + > > > +int > > > +evtls_read(struct evbuffer *buf, int fd, int howmuch, struct tls *ctx) > > > +{ > > > + u_char *p; > > > + size_t oldoff = buf->off; > > > + int n = EVBUFFER_MAX_READ; > > > + > > > + if (ioctl(fd, FIONREAD, &n) == -1 || n <= 0) { > > > + n = EVBUFFER_MAX_READ; > > > + } else if (n > EVBUFFER_MAX_READ && n > howmuch) { > > > + /* > > > + * It's possible that a lot of data is available for > > > + * reading. We do not want to exhaust resources > > > + * before the reader has a chance to do something > > > + * about it. If the reader does not tell us how much > > > + * data we should read, we artifically limit it. > > > + */ > > > + if ((size_t)n > buf->totallen << 2) > > > + n = buf->totallen << 2; > > > + if (n < EVBUFFER_MAX_READ) > > > + n = EVBUFFER_MAX_READ; > > > + } > > > + if (howmuch < 0 || howmuch > n) > > > + howmuch = n; > > > + > > > + /* If we don't have FIONREAD, we might waste some space here */ > > > + if (evbuffer_expand(buf, howmuch) == -1) > > > + return (-1); > > > + > > > + /* We can append new data at this point */ > > > + p = buf->buffer + buf->off; > > > + > > > + n = tls_read(ctx, p, howmuch); > > > + if (n <= 0) > > > + return (n); > > > + > > > + buf->off += n; > > > + > > > + /* Tell someone about changes in this buffer */ > > > + if (buf->off != oldoff && buf->cb != NULL) > > > + (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); > > > + > > > + return (n); > > > +} > > > + > > > +int > > > +evtls_write(struct evbuffer *buffer, int fd, struct tls *ctx) > > > +{ > > > + int n; > > > + > > > + n = tls_write(ctx, buffer->buffer, buffer->off); > > > + if (n <= 0) > > > + return (n); > > > + evbuffer_drain(buffer, n); > > > + > > > + return (n); > > > +} > > > Index: evbuffer_tls.h > > > =================================================================== > > > RCS file: evbuffer_tls.h > > > diff -N evbuffer_tls.h > > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > > +++ evbuffer_tls.h 10 Apr 2016 06:15:51 -0000 > > > @@ -0,0 +1,37 @@ > > > +/* $OpenBSD: evbuffer_tls.h,v 1.5 2015/10/09 16:58:25 bluhm Exp $ */ > > > + > > > +/* > > > + * Copyright (c) 2014-2015 Alexander Bluhm <[email protected]> > > > + * > > > + * Permission to use, copy, modify, and distribute this software for > any > > > + * purpose with or without fee is hereby granted, provided that the > above > > > + * copyright notice and this permission notice appear in all copies. > > > + * > > > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL > WARRANTIES > > > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > > > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE > LIABLE FOR > > > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY > DAMAGES > > > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN > AN > > > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING > OUT OF > > > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > > > + */ > > > + > > > +#ifndef _EVBUFFER_TLS_H_ > > > +#define _EVBUFFER_TLS_H_ > > > + > > > +#define EVBUFFER_HANDSHAKE 0x04 > > > + > > > +struct bufferevent; > > > +struct tls; > > > + > > > +struct buffertls { > > > + struct bufferevent *bt_bufev; > > > + struct tls *bt_ctx; > > > +}; > > > + > > > +void buffertls_set(struct buffertls *, struct bufferevent *, > struct tls *, > > > + int); > > > +void buffertls_accept(struct buffertls *, int); > > > +void buffertls_connect(struct buffertls *, int); > > > + > > > +#endif /* _EVBUFFER_TLS_H_ */ > > > Index: ldapd.c > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/ldapd.c,v > > > retrieving revision 1.19 > > > diff -u -p -u -p -r1.19 ldapd.c > > > --- ldapd.c 4 Feb 2016 12:48:06 -0000 1.19 > > > +++ ldapd.c 10 Apr 2016 06:15:51 -0000 > > > @@ -163,7 +163,7 @@ main(int argc, char *argv[]) > > > > > > log_verbose(verbose); > > > stats.started_at = time(0); > > > - ssl_init(); > > > + tls_init(); > > > > > > if (parse_config(conffile) != 0) > > > exit(2); > > > Index: ldapd.h > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/ldapd.h,v > > > retrieving revision 1.25 > > > diff -u -p -u -p -r1.25 ldapd.h > > > --- ldapd.h 2 Nov 2015 06:32:51 -0000 1.25 > > > +++ ldapd.h 10 Apr 2016 06:15:51 -0000 > > > @@ -30,11 +30,13 @@ > > > #include <limits.h> > > > #include <pwd.h> > > > #include <stdarg.h> > > > +#include <tls.h> > > > > > > #include "aldap.h" > > > #include "schema.h" > > > #include "btree.h" > > > #include "imsgev.h" > > > +#include "evbuffer_tls.h" > > > > > > #define CONFFILE "/etc/ldapd.conf" > > > #define LDAPD_USER "_ldapd" > > > @@ -203,7 +205,7 @@ struct listener { > > > struct event evt; > > > char ssl_cert_name[PATH_MAX]; > > > struct ssl *ssl; > > > - void *ssl_ctx; > > > + struct tls *tls; > > > TAILQ_ENTRY(listener) entry; > > > }; > > > TAILQ_HEAD(listenerlist, listener); > > > @@ -223,12 +225,8 @@ struct conn { > > > struct listener *listener; /* where it connected from > */ > > > > > > /* SSL support */ > > > - struct event s_ev; > > > - struct timeval s_tv; > > > - struct listener *s_l; > > > - void *s_ssl; > > > - unsigned char *s_buf; > > > - int s_buflen; > > > + struct tls *tls; > > > + struct buffertls buftls; > > > unsigned int s_flags; > > > }; > > > TAILQ_HEAD(conn_list, conn) conn_list; > > > @@ -236,11 +234,12 @@ TAILQ_HEAD(conn_list, conn) conn_list; > > > struct ssl { > > > SPLAY_ENTRY(ssl) ssl_nodes; > > > char ssl_name[PATH_MAX]; > > > - char *ssl_cert; > > > - off_t ssl_cert_len; > > > - char *ssl_key; > > > - off_t ssl_key_len; > > > + uint8_t *ssl_cert; > > > + size_t ssl_cert_len; > > > + uint8_t *ssl_key; > > > + size_t ssl_key_len; > > > uint8_t flags; > > > + struct tls_config *config; > > > }; > > > > > > struct ldapd_config > > > @@ -461,6 +460,9 @@ int authorized(struct conn > *conn, str > > > /* parse.y */ > > > int parse_config(char *filename); > > > int cmdline_symset(char *s); > > > +int ssl_cmp(struct ssl *, struct ssl *); > > > +SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp); > > > + > > > > > > /* log.c */ > > > void log_init(int); > > > @@ -498,21 +500,6 @@ int unindex_entry(struct > namespace *n > > > struct ber_element *elm); > > > int index_to_dn(struct namespace *ns, struct > btval *indx, > > > struct btval *dn); > > > - > > > -/* ssl.c */ > > > -void ssl_init(void); > > > -void ssl_transaction(struct conn *); > > > - > > > -void ssl_session_init(struct conn *); > > > -void ssl_session_destroy(struct conn *); > > > -int ssl_load_certfile(struct ldapd_config *, const char *, > u_int8_t); > > > -void ssl_setup(struct ldapd_config *, struct listener *); > > > -int ssl_cmp(struct ssl *, struct ssl *); > > > -SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp); > > > - > > > -/* ssl_privsep.c */ > > > -int ssl_ctx_use_private_key(void *, char *, off_t); > > > -int ssl_ctx_use_certificate_chain(void *, char *, off_t); > > > > > > /* validate.c */ > > > int validate_entry(const char *dn, struct ber_element *entry, > int relax); > > > Index: ldape.c > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/ldape.c,v > > > retrieving revision 1.23 > > > diff -u -p -u -p -r1.23 ldape.c > > > --- ldape.c 24 Dec 2015 17:47:57 -0000 1.23 > > > +++ ldape.c 10 Apr 2016 06:15:51 -0000 > > > @@ -341,6 +341,7 @@ ldape(struct passwd *pw, char *csockpath > > > struct event ev_sigterm; > > > struct event ev_sigchld; > > > struct event ev_sighup; > > > + struct ssl key; > > > char host[128]; > > > mode_t old_umask = 0; > > > > > > @@ -424,7 +425,24 @@ ldape(struct passwd *pw, char *csockpath > > > event_add(&l->ev, NULL); > > > evtimer_set(&l->evt, conn_accept, l); > > > > > > - ssl_setup(conf, l); > > > + if (l->flags & F_SSL) { > > > + if (strlcpy(key.ssl_name, l->ssl_cert_name, > > > + sizeof(key.ssl_name)) >= sizeof(key.ssl_name)) > > > + fatal("ldape: certificate name truncated"); > > > + > > > + l->ssl = SPLAY_FIND(ssltree, conf->sc_ssl, &key); > > > + if (l->ssl == NULL) > > > + fatal("ldape: certificate tree corrupted"); > > > + > > > + l->tls = tls_server(); > > > + if (l->tls == NULL) > > > + fatal("ldape: couldn't allocate tls > context"); > > > + > > > + if (tls_configure(l->tls, l->ssl->config)) { > > > + log_warn("ldape: %s", tls_error(l->tls)); > > > + fatal("ldape: couldn't configure tls"); > > > + } > > > + } > > > } > > > > > > TAILQ_FOREACH(ns, &conf->namespaces, next) { > > > Index: parse.y > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/parse.y,v > > > retrieving revision 1.16 > > > diff -u -p -u -p -r1.16 parse.y > > > --- parse.y 20 Nov 2014 05:51:20 -0000 1.16 > > > +++ parse.y 10 Apr 2016 06:15:51 -0000 > > > @@ -77,6 +77,7 @@ int host(const char *, const char *, > > > struct listenerlist *, int, in_port_t, u_int8_t); > > > int interface(const char *, const char *, > > > struct listenerlist *, int, in_port_t, u_int8_t); > > > +int load_certfile(struct ldapd_config *, const char > *, u_int8_t); > > > > > > TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); > > > struct sym { > > > @@ -91,6 +92,8 @@ char *symget(const char *); > > > > > > struct ldapd_config *conf; > > > > > > +SPLAY_GENERATE(ssltree, ssl, ssl_nodes, ssl_cmp); > > > + > > > static struct aci *mk_aci(int type, int rights, enum scope scope, > > > char *target, char *subject); > > > > > > @@ -181,7 +184,7 @@ conf_main : LISTEN ON STRING port ssl ce > > > cert = ($6 != NULL) ? $6 : $3; > > > > > > if (($5 == F_STARTTLS || $5 == F_LDAPS) && > > > - ssl_load_certfile(conf, cert, F_SCERT) < 0) { > > > + load_certfile(conf, cert, F_SCERT) < 0) { > > > yyerror("cannot load certificate: %s", > cert); > > > free($6); > > > free($3); > > > @@ -1167,3 +1170,84 @@ namespace_new(const char *suffix) > > > return ns; > > > } > > > > > > +int > > > +ssl_cmp(struct ssl *s1, struct ssl *s2) > > > +{ > > > + return (strcmp(s1->ssl_name, s2->ssl_name)); > > > +} > > > + > > > +int > > > +load_certfile(struct ldapd_config *env, const char *name, u_int8_t > flags) > > > +{ > > > + struct ssl *s; > > > + struct ssl key; > > > + char certfile[PATH_MAX]; > > > + > > > + if (strlcpy(key.ssl_name, name, sizeof(key.ssl_name)) > > > + >= sizeof(key.ssl_name)) { > > > + log_warn("load_certfile: certificate name truncated"); > > > + return -1; > > > + } > > > + > > > + s = SPLAY_FIND(ssltree, env->sc_ssl, &key); > > > + if (s != NULL) { > > > + s->flags |= flags; > > > + return 0; > > > + } > > > + > > > + if ((s = calloc(1, sizeof(*s))) == NULL) > > > + fatal(NULL); > > > + > > > + s->flags = flags; > > > + (void)strlcpy(s->ssl_name, key.ssl_name, sizeof(s->ssl_name)); > > > + > > > + s->config = tls_config_new(); > > > + if (s->config == NULL) > > > + goto err; > > > + > > > + tls_config_set_protocols(s->config, TLS_PROTOCOLS_ALL); > > > + if (tls_config_set_ciphers(s->config, "compat")) > > > + goto err; > > > + > > > + if ((name[0] == '/' && > > > + !bsnprintf(certfile, sizeof(certfile), "%s.crt", name)) || > > > + !bsnprintf(certfile, sizeof(certfile), > "/etc/ldap/certs/%s.crt", > > > + name)) { > > > + log_warn("load_certfile: path truncated"); > > > + goto err; > > > + } > > > + > > > + log_debug("loading certificate file %s", certfile); > > > + s->ssl_cert = tls_load_file(certfile, &s->ssl_cert_len, NULL); > > > + if (s->ssl_cert == NULL) > > > + goto err; > > > + > > > + if (tls_config_set_cert_mem(s->config, s->ssl_cert, > s->ssl_cert_len)) > > > + goto err; > > > + > > > + if ((name[0] == '/' && > > > + !bsnprintf(certfile, sizeof(certfile), "%s.key", name)) || > > > + !bsnprintf(certfile, sizeof(certfile), > "/etc/ldap/certs/%s.key", > > > + name)) { > > > + log_warn("load_certfile: path truncated"); > > > + goto err; > > > + } > > > + > > > + log_debug("loading key file %s", certfile); > > > + s->ssl_key = tls_load_file(certfile, &s->ssl_key_len, NULL); > > > + if (s->ssl_key == NULL) > > > + goto err; > > > + > > > + if (tls_config_set_key_mem(s->config, s->ssl_key, s->ssl_key_len)) > > > + goto err; > > > + > > > + SPLAY_INSERT(ssltree, env->sc_ssl, s); > > > + > > > + return (0); > > > +err: > > > + free(s->ssl_cert); > > > + free(s->ssl_key); > > > + tls_config_free(s->config); > > > + free(s); > > > + return (-1); > > > +} > > > Index: ssl.c > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/ssl.c,v > > > retrieving revision 1.10 > > > diff -u -p -u -p -r1.10 ssl.c > > > --- ssl.c 30 Dec 2015 15:59:55 -0000 1.10 > > > +++ ssl.c 10 Apr 2016 06:15:51 -0000 > > > @@ -1,565 +0,0 @@ > > > -/* $OpenBSD: ssl.c,v 1.10 2015/12/30 15:59:55 benno Exp $ */ > > > - > > > -/* > > > - * Copyright (c) 2008 Pierre-Yves Ritschard <[email protected]> > > > - * Copyright (c) 2008 Reyk Floeter <[email protected]> > > > - * > > > - * Permission to use, copy, modify, and distribute this software for > any > > > - * purpose with or without fee is hereby granted, provided that the > above > > > - * copyright notice and this permission notice appear in all copies. > > > - * > > > - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL > WARRANTIES > > > - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > > > - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE > LIABLE FOR > > > - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY > DAMAGES > > > - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN > AN > > > - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING > OUT OF > > > - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > > > - */ > > > - > > > -#include <sys/types.h> > > > -#include <sys/queue.h> > > > -#include <sys/tree.h> > > > -#include <sys/socket.h> > > > -#include <sys/stat.h> > > > -#include <sys/time.h> > > > - > > > -#include <ctype.h> > > > -#include <event.h> > > > -#include <fcntl.h> > > > -#include <pwd.h> > > > -#include <stdio.h> > > > -#include <stdlib.h> > > > -#include <string.h> > > > -#include <unistd.h> > > > - > > > -#include <openssl/ssl.h> > > > -#include <openssl/engine.h> > > > -#include <openssl/err.h> > > > -#include <openssl/dh.h> > > > -#include <openssl/bn.h> > > > - > > > -#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) > > > - > > > -#include "ldapd.h" > > > - > > > -#define SSL_CIPHERS "HIGH:!aNULL" > > > - > > > -void ssl_error(const char *); > > > -char *ssl_load_file(const char *, off_t *); > > > -SSL_CTX *ssl_ctx_create(void); > > > -void ssl_session_accept(int, short, void *); > > > -void ssl_read(int, short, void *); > > > -void ssl_write(int, short, void *); > > > -int ssl_bufferevent_add(struct event *, int); > > > - > > > -DH *get_dh1024(void); > > > -void ssl_set_ephemeral_key_exchange(SSL_CTX *, DH *); > > > - > > > -extern void bufferevent_read_pressure_cb(struct evbuffer *, > size_t, > > > - size_t, void *); > > > - > > > -void > > > -ssl_read(int fd, short event, void *p) > > > -{ > > > - struct bufferevent *bufev = p; > > > - struct conn *s = bufev->cbarg; > > > - int ret; > > > - int ssl_err; > > > - short what; > > > - size_t len; > > > - char rbuf[IBUF_READ_SIZE]; > > > - int howmuch = IBUF_READ_SIZE; > > > - > > > - what = EVBUFFER_READ; > > > - > > > - if (event == EV_TIMEOUT) { > > > - what |= EVBUFFER_TIMEOUT; > > > - goto err; > > > - } > > > - > > > - if (bufev->wm_read.high != 0) > > > - howmuch = MINIMUM(sizeof(rbuf), bufev->wm_read.high); > > > - > > > - ret = SSL_read(s->s_ssl, rbuf, howmuch); > > > - if (ret <= 0) { > > > - ssl_err = SSL_get_error(s->s_ssl, ret); > > > - > > > - switch (ssl_err) { > > > - case SSL_ERROR_WANT_READ: > > > - goto retry; > > > - case SSL_ERROR_WANT_WRITE: > > > - goto retry; > > > - default: > > > - if (ret == 0) > > > - what |= EVBUFFER_EOF; > > > - else { > > > - ssl_error("ssl_read"); > > > - what |= EVBUFFER_ERROR; > > > - } > > > - goto err; > > > - } > > > - } > > > - > > > - if (evbuffer_add(bufev->input, rbuf, ret) == -1) { > > > - what |= EVBUFFER_ERROR; > > > - goto err; > > > - } > > > - > > > - ssl_bufferevent_add(&bufev->ev_read, bufev->timeout_read); > > > - > > > - len = EVBUFFER_LENGTH(bufev->input); > > > - if (bufev->wm_read.low != 0 && len < bufev->wm_read.low) > > > - return; > > > - if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) { > > > - struct evbuffer *buf = bufev->input; > > > - event_del(&bufev->ev_read); > > > - evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev); > > > - return; > > > - } > > > - > > > - if (bufev->readcb != NULL) > > > - (*bufev->readcb)(bufev, bufev->cbarg); > > > - return; > > > - > > > -retry: > > > - ssl_bufferevent_add(&bufev->ev_read, bufev->timeout_read); > > > - return; > > > - > > > -err: > > > - (*bufev->errorcb)(bufev, what, bufev->cbarg); > > > -} > > > - > > > - > > > -void > > > -ssl_write(int fd, short event, void *p) > > > -{ > > > - struct bufferevent *bufev = p; > > > - struct conn *s = bufev->cbarg; > > > - int ret; > > > - int ssl_err; > > > - short what; > > > - > > > - what = EVBUFFER_WRITE; > > > - > > > - if (event == EV_TIMEOUT) { > > > - what |= EV_TIMEOUT; > > > - goto err; > > > - } > > > - > > > - if (EVBUFFER_LENGTH(bufev->output)) { > > > - if (s->s_buf == NULL) { > > > - s->s_buflen = EVBUFFER_LENGTH(bufev->output); > > > - if ((s->s_buf = malloc(s->s_buflen)) == NULL) { > > > - what |= EVBUFFER_ERROR; > > > - goto err; > > > - } > > > - memcpy(s->s_buf, EVBUFFER_DATA(bufev->output), > > > - s->s_buflen); > > > - } > > > - > > > - ret = SSL_write(s->s_ssl, s->s_buf, s->s_buflen); > > > - if (ret <= 0) { > > > - ssl_err = SSL_get_error(s->s_ssl, ret); > > > - > > > - switch (ssl_err) { > > > - case SSL_ERROR_WANT_READ: > > > - goto retry; > > > - case SSL_ERROR_WANT_WRITE: > > > - goto retry; > > > - default: > > > - if (ret == 0) > > > - what |= EVBUFFER_EOF; > > > - else { > > > - ssl_error("ssl_write"); > > > - what |= EVBUFFER_ERROR; > > > - } > > > - goto err; > > > - } > > > - } > > > - evbuffer_drain(bufev->output, ret); > > > - } > > > - if (s->s_buf != NULL) { > > > - free(s->s_buf); > > > - s->s_buf = NULL; > > > - s->s_buflen = 0; > > > - } > > > - if (EVBUFFER_LENGTH(bufev->output) != 0) > > > - ssl_bufferevent_add(&bufev->ev_write, > bufev->timeout_write); > > > - > > > - if (bufev->writecb != NULL && > > > - EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low) > > > - (*bufev->writecb)(bufev, bufev->cbarg); > > > - return; > > > - > > > -retry: > > > - if (s->s_buflen != 0) > > > - ssl_bufferevent_add(&bufev->ev_write, > bufev->timeout_write); > > > - return; > > > - > > > -err: > > > - if (s->s_buf != NULL) { > > > - free(s->s_buf); > > > - s->s_buf = NULL; > > > - s->s_buflen = 0; > > > - } > > > - (*bufev->errorcb)(bufev, what, bufev->cbarg); > > > -} > > > - > > > -int > > > -ssl_bufferevent_add(struct event *ev, int timeout) > > > -{ > > > - struct timeval tv; > > > - struct timeval *ptv = NULL; > > > - > > > - if (timeout) { > > > - timerclear(&tv); > > > - tv.tv_sec = timeout; > > > - ptv = &tv; > > > - } > > > - > > > - return (event_add(ev, ptv)); > > > -} > > > - > > > -int > > > -ssl_cmp(struct ssl *s1, struct ssl *s2) > > > -{ > > > - return (strcmp(s1->ssl_name, s2->ssl_name)); > > > -} > > > - > > > -SPLAY_GENERATE(ssltree, ssl, ssl_nodes, ssl_cmp); > > > - > > > -char * > > > -ssl_load_file(const char *name, off_t *len) > > > -{ > > > - struct stat st; > > > - off_t size; > > > - char *buf = NULL; > > > - int fd; > > > - > > > - 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) > > > - goto fail; > > > - close(fd); > > > - > > > - *len = size + 1; > > > - return (buf); > > > - > > > -fail: > > > - free(buf); > > > - close(fd); > > > - return (NULL); > > > -} > > > - > > > -SSL_CTX * > > > -ssl_ctx_create(void) > > > -{ > > > - SSL_CTX *ctx; > > > - > > > - ctx = SSL_CTX_new(SSLv23_method()); > > > - if (ctx == NULL) { > > > - ssl_error("ssl_ctx_create"); > > > - fatal("ssl_ctx_create: could not create SSL context"); > > > - } > > > - > > > - SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); > > > - SSL_CTX_set_timeout(ctx, LDAPD_SESSION_TIMEOUT); > > > - SSL_CTX_set_options(ctx, SSL_OP_ALL); > > > - SSL_CTX_set_options(ctx, > > > - SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); > > > - > > > - if (!SSL_CTX_set_cipher_list(ctx, SSL_CIPHERS)) { > > > - ssl_error("ssl_ctx_create"); > > > - fatal("ssl_ctx_create: could not set cipher list"); > > > - } > > > - return (ctx); > > > -} > > > - > > > -int > > > -ssl_load_certfile(struct ldapd_config *env, const char *name, > u_int8_t flags) > > > -{ > > > - struct ssl *s; > > > - struct ssl key; > > > - char certfile[PATH_MAX]; > > > - > > > - if (strlcpy(key.ssl_name, name, sizeof(key.ssl_name)) > > > - >= sizeof(key.ssl_name)) { > > > - log_warn("ssl_load_certfile: certificate name truncated"); > > > - return -1; > > > - } > > > - > > > - s = SPLAY_FIND(ssltree, env->sc_ssl, &key); > > > - if (s != NULL) { > > > - s->flags |= flags; > > > - return 0; > > > - } > > > - > > > - if ((s = calloc(1, sizeof(*s))) == NULL) > > > - fatal(NULL); > > > - > > > - s->flags = flags; > > > - (void)strlcpy(s->ssl_name, key.ssl_name, sizeof(s->ssl_name)); > > > - > > > - if ((name[0] == '/' && > > > - !bsnprintf(certfile, sizeof(certfile), "%s.crt", name)) || > > > - !bsnprintf(certfile, sizeof(certfile), > "/etc/ldap/certs/%s.crt", > > > - name)) { > > > - log_warn("ssl_load_certfile: path truncated"); > > > - free(s); > > > - return -1; > > > - } > > > - > > > - log_debug("loading certificate file %s", certfile); > > > - if ((s->ssl_cert = ssl_load_file(certfile, &s->ssl_cert_len)) == > NULL) { > > > - free(s); > > > - return (-1); > > > - } > > > - > > > - if ((name[0] == '/' && > > > - !bsnprintf(certfile, sizeof(certfile), "%s.key", name)) || > > > - !bsnprintf(certfile, sizeof(certfile), > "/etc/ldap/certs/%s.key", > > > - name)) { > > > - log_warn("ssl_load_certfile: path truncated"); > > > - free(s->ssl_cert); > > > - free(s); > > > - return -1; > > > - } > > > - > > > - log_debug("loading key file %s", certfile); > > > - if ((s->ssl_key = ssl_load_file(certfile, &s->ssl_key_len)) == > NULL) { > > > - free(s->ssl_cert); > > > - free(s); > > > - return (-1); > > > - } > > > - > > > - SPLAY_INSERT(ssltree, env->sc_ssl, s); > > > - > > > - return (0); > > > -} > > > - > > > -void > > > -ssl_init(void) > > > -{ > > > - SSL_library_init(); > > > - SSL_load_error_strings(); > > > - > > > - OpenSSL_add_all_algorithms(); > > > - > > > - /* Init hardware crypto engines. */ > > > - ENGINE_load_builtin_engines(); > > > - ENGINE_register_all_complete(); > > > -} > > > - > > > -void > > > -ssl_setup(struct ldapd_config *env, struct listener *l) > > > -{ > > > - struct ssl key; > > > - > > > - if (!(l->flags & F_SSL)) > > > - return; > > > - > > > - if (strlcpy(key.ssl_name, l->ssl_cert_name, sizeof(key.ssl_name)) > > > - >= sizeof(key.ssl_name)) > > > - fatal("ssl_setup: certificate name truncated"); > > > - > > > - if ((l->ssl = SPLAY_FIND(ssltree, env->sc_ssl, &key)) == NULL) > > > - fatal("ssl_setup: certificate tree corrupted"); > > > - > > > - l->ssl_ctx = ssl_ctx_create(); > > > - > > > - if (!ssl_ctx_use_certificate_chain(l->ssl_ctx, > > > - l->ssl->ssl_cert, l->ssl->ssl_cert_len)) > > > - goto err; > > > - if (!ssl_ctx_use_private_key(l->ssl_ctx, > > > - l->ssl->ssl_key, l->ssl->ssl_key_len)) > > > - goto err; > > > - > > > - if (!SSL_CTX_check_private_key(l->ssl_ctx)) > > > - goto err; > > > - if (!SSL_CTX_set_session_id_context(l->ssl_ctx, > > > - (const unsigned char *)l->ssl_cert_name, > strlen(l->ssl_cert_name) + 1)) > > > - goto err; > > > - > > > - ssl_set_ephemeral_key_exchange(l->ssl_ctx, get_dh1024()); > > > - > > > - log_debug("ssl_setup: ssl setup finished for listener: %p", l); > > > - return; > > > - > > > -err: > > > - SSL_CTX_free(l->ssl_ctx); > > > - ssl_error("ssl_setup"); > > > - fatal("ssl_setup: cannot set SSL up"); > > > -} > > > - > > > -void > > > -ssl_error(const char *where) > > > -{ > > > - unsigned long code; > > > - char errbuf[128]; > > > - extern int debug; > > > - > > > - if (!debug) > > > - return; > > > - for (; (code = ERR_get_error()) != 0 ;) { > > > - ERR_error_string_n(code, errbuf, sizeof(errbuf)); > > > - log_debug("SSL library error: %s: %s", where, errbuf); > > > - } > > > -} > > > - > > > -void > > > -ssl_session_accept(int fd, short event, void *p) > > > -{ > > > - struct conn *s = p; > > > - int ret; > > > - int ssl_err; > > > - > > > - if (event == EV_TIMEOUT) { > > > - log_debug("ssl_session_accept: session timed out"); > > > - conn_close(s); > > > - return; > > > - } > > > - > > > - log_debug("ssl_session_accept: accepting client"); > > > - ret = SSL_accept(s->s_ssl); > > > - if (ret <= 0) { > > > - ssl_err = SSL_get_error(s->s_ssl, ret); > > > - > > > - switch (ssl_err) { > > > - case SSL_ERROR_WANT_READ: > > > - goto retry; > > > - case SSL_ERROR_WANT_WRITE: > > > - goto retry; > > > - case SSL_ERROR_ZERO_RETURN: > > > - case SSL_ERROR_SYSCALL: > > > - if (ret == 0) { > > > - conn_close(s); > > > - return; > > > - } > > > - /* FALLTHROUGH */ > > > - default: > > > - ssl_error("ssl_session_accept"); > > > - conn_close(s); > > > - return; > > > - } > > > - } > > > - > > > - log_debug("ssl_session_accept: accepted ssl client"); > > > - s->s_flags |= F_SECURE; > > > - > > > - s->bev = bufferevent_new(s->fd, conn_read, conn_write, conn_err, > s); > > > - if (s->bev == NULL) { > > > - log_warn("ssl_session_accept: bufferevent_new"); > > > - conn_close(s); > > > - return; > > > - } > > > - bufferevent_settimeout(s->bev, 0, 60); > > > - > > > - event_set(&s->bev->ev_read, s->fd, EV_READ, ssl_read, s->bev); > > > - event_set(&s->bev->ev_write, s->fd, EV_WRITE, ssl_write, s->bev); > > > - bufferevent_enable(s->bev, EV_READ); > > > - > > > - return; > > > -retry: > > > - event_add(&s->s_ev, &s->s_tv); > > > -} > > > - > > > -void > > > -ssl_session_init(struct conn *s) > > > -{ > > > - struct listener *l; > > > - SSL *ssl; > > > - > > > - l = s->s_l; > > > - > > > - if (!(l->flags & F_SSL)) > > > - return; > > > - > > > - log_debug("ssl_session_init: switching to SSL"); > > > - ssl = SSL_new(l->ssl_ctx); > > > - if (ssl == NULL) > > > - goto err; > > > - > > > - if (!SSL_set_ssl_method(ssl, SSLv23_server_method())) > > > - goto err; > > > - if (!SSL_set_fd(ssl, s->fd)) > > > - goto err; > > > - SSL_set_accept_state(ssl); > > > - > > > - s->s_ssl = ssl; > > > - > > > - s->s_tv.tv_sec = LDAPD_SESSION_TIMEOUT; > > > - s->s_tv.tv_usec = 0; > > > - event_set(&s->s_ev, s->fd, EV_READ|EV_TIMEOUT, ssl_session_accept, > s); > > > - event_add(&s->s_ev, &s->s_tv); > > > - return; > > > - > > > - err: > > > - SSL_free(ssl); > > > - ssl_error("ssl_session_init"); > > > -} > > > - > > > -void > > > -ssl_session_destroy(struct conn *s) > > > -{ > > > - SSL_free(s->s_ssl); > > > -} > > > - > > > -/* From OpenSSL's documentation: > > > - * > > > - * If "strong" primes were used to generate the DH parameters, it is > > > - * not strictly necessary to generate a new key for each handshake > > > - * but it does improve forward secrecy. > > > - * > > > - * -- gilles@ > > > - */ > > > -DH * > > > -get_dh1024(void) > > > -{ > > > - DH *dh; > > > - unsigned char dh1024_p[] = { > > > - 0xAD,0x37,0xBB,0x26,0x75,0x01,0x27,0x75, > > > - 0x06,0xB5,0xE7,0x1E,0x1F,0x2B,0xBC,0x51, > > > - 0xC0,0xF4,0xEB,0x42,0x7A,0x2A,0x83,0x1E, > > > - 0xE8,0xD1,0xD8,0xCC,0x9E,0xE6,0x15,0x1D, > > > - 0x06,0x46,0x50,0x94,0xB9,0xEE,0xB6,0x89, > > > - 0xB7,0x3C,0xAC,0x07,0x5E,0x29,0x37,0xCC, > > > - 0x8F,0xDF,0x48,0x56,0x85,0x83,0x26,0x02, > > > - 0xB8,0xB6,0x63,0xAF,0x2D,0x4A,0x57,0x93, > > > - 0x6B,0x54,0xE1,0x8F,0x28,0x76,0x9C,0x5D, > > > - 0x90,0x65,0xD1,0x07,0xFE,0x5B,0x05,0x65, > > > - 0xDA,0xD2,0xE2,0xAF,0x23,0xCA,0x2F,0xD6, > > > - 0x4B,0xD2,0x04,0xFE,0xDF,0x21,0x2A,0xE1, > > > - 0xCD,0x1B,0x70,0x76,0xB3,0x51,0xA4,0xC9, > > > - 0x2B,0x68,0xE3,0xDD,0xCB,0x97,0xDA,0x59, > > > - 0x50,0x93,0xEE,0xDB,0xBF,0xC7,0xFA,0xA7, > > > - 0x47,0xC4,0x4D,0xF0,0xC6,0x09,0x4A,0x4B > > > - }; > > > - unsigned char dh1024_g[] = { > > > - 0x02 > > > - }; > > > - > > > - if ((dh = DH_new()) == NULL) > > > - return NULL; > > > - > > > - dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); > > > - dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); > > > - if (dh->p == NULL || dh->g == NULL) { > > > - DH_free(dh); > > > - return NULL; > > > - } > > > - > > > - return dh; > > > -} > > > - > > > -void > > > -ssl_set_ephemeral_key_exchange(SSL_CTX *ctx, DH *dh) > > > -{ > > > - if (dh == NULL || !SSL_CTX_set_tmp_dh(ctx, dh)) > > > - fatal("ssl_set_ephemeral_key_exchange: cannot set tmp dh"); > > > -} > > > Index: ssl_privsep.c > > > =================================================================== > > > RCS file: /cvs/src/usr.sbin/ldapd/ssl_privsep.c,v > > > retrieving revision 1.4 > > > diff -u -p -u -p -r1.4 ssl_privsep.c > > > --- ssl_privsep.c 28 Jan 2015 15:50:30 -0000 1.4 > > > +++ ssl_privsep.c 10 Apr 2016 06:15:51 -0000 > > > @@ -1,172 +0,0 @@ > > > -/* $OpenBSD: ssl_privsep.c,v 1.4 2015/01/28 15:50:30 reyk Exp $ > */ > > > - > > > -/* Copyright (C) 1995-1998 Eric Young ([email protected]) > > > - * All rights reserved. > > > - * > > > - * This package is an SSL implementation written > > > - * by Eric Young ([email protected]). > > > - * The implementation was written so as to conform with Netscapes SSL. > > > - * > > > - * This library is free for commercial and non-commercial use as long > as > > > - * the following conditions are aheared to. The following conditions > > > - * apply to all code found in this distribution, be it the RC4, RSA, > > > - * lhash, DES, etc., code; not just the SSL code. The SSL > documentation > > > - * included with this distribution is covered by the same copyright > terms > > > - * except that the holder is Tim Hudson ([email protected]). > > > - * > > > - * Copyright remains Eric Young's, and as such any Copyright notices > in > > > - * the code are not to be removed. > > > - * If this package is used in a product, Eric Young should be given > attribution > > > - * as the author of the parts of the library used. > > > - * This can be in the form of a textual message at program startup or > > > - * in documentation (online or textual) provided with the package. > > > - * > > > - * Redistribution and use in source and binary forms, with or without > > > - * modification, are permitted provided that the following conditions > > > - * are met: > > > - * 1. Redistributions of source code must retain the copyright > > > - * notice, this list of conditions and the following disclaimer. > > > - * 2. Redistributions in binary form must reproduce the above > copyright > > > - * notice, this list of conditions and the following disclaimer in > the > > > - * documentation and/or other materials provided with the > distribution. > > > - * 3. All advertising materials mentioning features or use of this > software > > > - * must display the following acknowledgement: > > > - * "This product includes cryptographic software written by > > > - * Eric Young ([email protected])" > > > - * The word 'cryptographic' can be left out if the rouines from > the library > > > - * being used are not cryptographic related :-). > > > - * 4. If you include any Windows specific code (or a derivative > thereof) from > > > - * the apps directory (application code) you must include an > acknowledgement: > > > - * "This product includes software written by Tim Hudson ( > [email protected])" > > > - * > > > - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND > > > - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > > > - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > > > - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE > LIABLE > > > - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL > > > - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS > > > - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > INTERRUPTION) > > > - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > CONTRACT, STRICT > > > - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN > ANY WAY > > > - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > POSSIBILITY OF > > > - * SUCH DAMAGE. > > > - * > > > - * The licence and distribution terms for any publically available > version or > > > - * derivative of this code cannot be changed. i.e. this code cannot > simply be > > > - * copied and put under another distribution licence > > > - * [including the GNU Public Licence.] > > > - */ > > > - > > > -/* > > > - * SSL operations needed when running in a privilege separated > environment. > > > - * Adapted from openssl's ssl_rsa.c by Pierre-Yves Ritschard . > > > - */ > > > - > > > -#include <sys/types.h> > > > -#include <sys/uio.h> > > > - > > > -#include <unistd.h> > > > -#include <stdio.h> > > > - > > > -#include <openssl/err.h> > > > -#include <openssl/bio.h> > > > -#include <openssl/objects.h> > > > -#include <openssl/evp.h> > > > -#include <openssl/x509.h> > > > -#include <openssl/pem.h> > > > -#include <openssl/ssl.h> > > > - > > > -int ssl_ctx_use_private_key(SSL_CTX *, char *, off_t); > > > -int ssl_ctx_use_certificate_chain(SSL_CTX *, char *, off_t); > > > - > > > -int > > > -ssl_ctx_use_private_key(SSL_CTX *ctx, char *buf, off_t len) > > > -{ > > > - int ret; > > > - BIO *in; > > > - EVP_PKEY *pkey; > > > - > > > - ret = 0; > > > - > > > - if ((in = BIO_new_mem_buf(buf, len)) == NULL) { > > > - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); > > > - return 0; > > > - } > > > - > > > - pkey = PEM_read_bio_PrivateKey(in, NULL, > > > - ctx->default_passwd_callback, > > > - ctx->default_passwd_callback_userdata); > > > - > > > - if (pkey == NULL) { > > > - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_PEM_LIB); > > > - goto end; > > > - } > > > - ret = SSL_CTX_use_PrivateKey(ctx, pkey); > > > - EVP_PKEY_free(pkey); > > > -end: > > > - if (in != NULL) > > > - BIO_free(in); > > > - return ret; > > > -} > > > - > > > -int > > > -ssl_ctx_use_certificate_chain(SSL_CTX *ctx, char *buf, off_t len) > > > -{ > > > - int ret; > > > - BIO *in; > > > - X509 *x; > > > - X509 *ca; > > > - unsigned long err; > > > - > > > - ret = 0; > > > - x = ca = NULL; > > > - > > > - if ((in = BIO_new_mem_buf(buf, len)) == NULL) { > > > - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, > ERR_R_BUF_LIB); > > > - goto end; > > > - } > > > - > > > - if ((x = PEM_read_bio_X509(in, NULL, > > > - ctx->default_passwd_callback, > > > - ctx->default_passwd_callback_userdata)) == NULL) { > > > - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, > ERR_R_PEM_LIB); > > > - goto end; > > > - } > > > - > > > - if (!SSL_CTX_use_certificate(ctx, x) || ERR_peek_error() != 0) > > > - goto end; > > > - > > > - /* If we could set up our certificate, now proceed to > > > - * the CA certificates. > > > - */ > > > - > > > - if (ctx->extra_certs != NULL) { > > > - sk_X509_pop_free(ctx->extra_certs, X509_free); > > > - ctx->extra_certs = NULL; > > > - } > > > - > > > - while ((ca = PEM_read_bio_X509(in, NULL, > > > - ctx->default_passwd_callback, > > > - ctx->default_passwd_callback_userdata)) != NULL) { > > > - > > > - if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) > > > - goto end; > > > - -- > >
