From a040621a54501da80c6f4a6bda761d891f47cb1c Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 9 Apr 2021 16:43:43 +0000 Subject: [PATCH] allow to specify tls ciphers and protocols on listeners ok tb@ --- usr.sbin/smtpd/config.c | 4 +++- usr.sbin/smtpd/mta.c | 14 +++++++++----- usr.sbin/smtpd/parse.y | 34 ++++++++++++++++++++++++++++++++-- usr.sbin/smtpd/smtp.c | 18 +++++++++++++++--- usr.sbin/smtpd/smtpd.conf.5 | 16 ++++++++++++++-- usr.sbin/smtpd/smtpd.h | 4 +++- 6 files changed, 76 insertions(+), 14 deletions(-) diff --git a/usr.sbin/smtpd/config.c b/usr.sbin/smtpd/config.c index 73a76aca8fe..c9f7afa95f8 100644 --- a/usr.sbin/smtpd/config.c +++ b/usr.sbin/smtpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.54 2021/03/05 12:37:32 eric Exp $ */ +/* $OpenBSD: config.c,v 1.55 2021/04/09 16:43:43 eric Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard @@ -252,6 +252,8 @@ purge_config(uint8_t what) if (what & PURGE_LISTENERS) { while ((l = TAILQ_FIRST(env->sc_listeners)) != NULL) { TAILQ_REMOVE(env->sc_listeners, l, entry); + free(l->tls_ciphers); + free(l->tls_protocols); free(l->pki); free(l); } diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c index 4339481f0a7..bd5585bacf8 100644 --- a/usr.sbin/smtpd/mta.c +++ b/usr.sbin/smtpd/mta.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mta.c,v 1.237 2021/04/02 06:30:55 eric Exp $ */ +/* $OpenBSD: mta.c,v 1.238 2021/04/09 16:43:43 eric Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard @@ -508,10 +508,14 @@ mta_setup_dispatcher(struct dispatcher *dispatcher) if (ciphers && tls_config_set_ciphers(config, ciphers) == -1) err(1, "%s", tls_config_error(config)); - if (remote->tls_protocols && - (tls_config_parse_protocols(&protos, remote->tls_protocols) == -1 - || tls_config_set_protocols(config, protos) == -1)) - err(1, "%s", tls_config_error(config)); + if (remote->tls_protocols) { + if (tls_config_parse_protocols(&protos, + remote->tls_protocols) == -1) + err(1, "failed to parse protocols \"%s\"", + remote->tls_protocols); + if (tls_config_set_protocols(config, protos) == -1) + err(1, "%s", tls_config_error(config)); + } if (remote->pki) { pki = dict_get(env->sc_pki_dict, remote->pki); diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y index e813279dffb..f654d76922f 100644 --- a/usr.sbin/smtpd/parse.y +++ b/usr.sbin/smtpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.286 2021/03/31 17:47:16 eric Exp $ */ +/* $OpenBSD: parse.y,v 1.287 2021/04/09 16:43:43 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -137,6 +137,8 @@ static struct listen_opts { char *filtername; char *pki[PKI_MAX]; int pkicount; + char *tls_ciphers; + char *tls_protocols; char *ca; uint16_t auth; struct table *authtable; @@ -2333,6 +2335,20 @@ opt_if_listen : INET4 { listen_opts.options |= LO_SSL; listen_opts.ssl = F_STARTTLS|F_STARTTLS_REQUIRE|F_TLS_VERIFY; } + | CIPHERS STRING { + if (listen_opts.tls_ciphers) { + yyerror("ciphers already specified"); + YYERROR; + } + listen_opts.tls_ciphers = $2; + } + | PROTOCOLS STRING { + if (listen_opts.tls_protocols) { + yyerror("protocols already specified"); + YYERROR; + } + listen_opts.tls_protocols = $2; + } | PKI STRING { if (listen_opts.pkicount == PKI_MAX) { yyerror("too many pki specified"); @@ -2516,7 +2532,11 @@ listen : LISTEN { memset(&listen_opts, 0, sizeof listen_opts); listen_opts.family = AF_UNSPEC; listen_opts.flags |= F_EXT_DSN; - } ON listener_type + } ON listener_type { + free(listen_opts.tls_protocols); + free(listen_opts.tls_ciphers); + memset(&listen_opts, 0, sizeof listen_opts); + } ; table : TABLE STRING STRING { @@ -3312,6 +3332,16 @@ config_listener(struct listener *h, struct listen_opts *lo) } } + if (lo->tls_ciphers != NULL && + (h->tls_ciphers = strdup(lo->tls_ciphers)) == NULL) { + fatal("strdup"); + } + + if (lo->tls_protocols != NULL && + (h->tls_protocols = strdup(lo->tls_protocols)) == NULL) { + fatal("strdup"); + } + if (lo->ca != NULL) { if (!lowercase(h->ca_name, lo->ca, sizeof(h->ca_name))) { log_warnx("ca name too long: %s", lo->ca); diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c index 5ca11adb870..a2371f75611 100644 --- a/usr.sbin/smtpd/smtp.c +++ b/usr.sbin/smtpd/smtp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp.c,v 1.168 2021/03/10 17:25:59 eric Exp $ */ +/* $OpenBSD: smtp.c,v 1.169 2021/04/09 16:43:43 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -169,6 +169,8 @@ smtp_setup_listener_tls(struct listener *l) { static const char *dheparams[] = { "none", "auto", "legacy" }; struct tls_config *config; + const char *ciphers; + uint32_t protos; struct pki *pki; struct ca *ca; int i; @@ -176,9 +178,19 @@ smtp_setup_listener_tls(struct listener *l) if ((config = tls_config_new()) == NULL) fatal("smtpd: tls_config_new"); - if (env->sc_tls_ciphers && - tls_config_set_ciphers(config, env->sc_tls_ciphers) == -1) + ciphers = env->sc_tls_ciphers; + if (l->tls_ciphers) + ciphers = l->tls_ciphers; + if (ciphers && tls_config_set_ciphers(config, ciphers) == -1) + err(1, "%s", tls_config_error(config)); + + if (l->tls_protocols) { + if (tls_config_parse_protocols(&protos, l->tls_protocols) == -1) + err(1, "failed to parse protocols \"%s\"", + l->tls_protocols); + if (tls_config_set_protocols(config, protos) == -1) err(1, "%s", tls_config_error(config)); + } pki = l->pki[0]; if (pki == NULL) diff --git a/usr.sbin/smtpd/smtpd.conf.5 b/usr.sbin/smtpd/smtpd.conf.5 index 74def422d02..ca4cd64fb05 100644 --- a/usr.sbin/smtpd/smtpd.conf.5 +++ b/usr.sbin/smtpd/smtpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: smtpd.conf.5,v 1.259 2021/03/31 17:47:16 eric Exp $ +.\" $OpenBSD: smtpd.conf.5,v 1.260 2021/04/09 16:43:43 eric Exp $ .\" .\" Copyright (c) 2008 Janne Johansson .\" Copyright (c) 2009 Jacek Masiulaniec @@ -17,7 +17,7 @@ .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .\" -.Dd $Mdocdate: March 31 2021 $ +.Dd $Mdocdate: April 9 2021 $ .Dt SMTPD.CONF 5 .Os .Sh NAME @@ -527,6 +527,18 @@ With the .Cm verify option, clients must also provide a valid certificate to establish an SMTP session. +.It Cm protocols Ar protostr +Define the protocol versions to be used for TLS sessions. +Refer to the +.Xr tls_config_parse_protocols 3 +manpage for the format of +.Ar protostr . +.It Cm ciphers Ar cipherstr +Define the list of ciphers that may be used for TLS sessions. +Refer to the +.Xr tls_config_set_ciphers 3 +manpage for the format of +.Ar cipherstr . .El .It Ic listen on Cm socket Op Ar options Listen for incoming SMTP connections on the Unix domain socket diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index d36e33285e5..b6556ac0188 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.664 2021/03/31 19:09:19 eric Exp $ */ +/* $OpenBSD: smtpd.h,v 1.665 2021/04/09 16:43:43 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -543,6 +543,8 @@ struct listener { int local; /* there must be a better way */ + char *tls_protocols; + char *tls_ciphers; struct tls *tls; struct pki **pki; int pkicount; -- 2.20.1