summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2021-04-09 16:43:44 +0000
committerEric Faurot <eric@cvs.openbsd.org>2021-04-09 16:43:44 +0000
commitb62858496a2f725103703c9f41d3acb98e90e870 (patch)
treede027548b10c4bde30a8d973777591d5b834bca2
parenta19e7027d8e0c24ac518d03f2187af8fcee84cfa (diff)
allow to specify tls ciphers and protocols on listeners
ok tb@
-rw-r--r--usr.sbin/smtpd/config.c4
-rw-r--r--usr.sbin/smtpd/mta.c14
-rw-r--r--usr.sbin/smtpd/parse.y34
-rw-r--r--usr.sbin/smtpd/smtp.c18
-rw-r--r--usr.sbin/smtpd/smtpd.conf.516
-rw-r--r--usr.sbin/smtpd/smtpd.h4
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 <pyr@openbsd.org>
@@ -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 <pyr@openbsd.org>
@@ -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 <gilles@poolp.org>
@@ -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 <gilles@poolp.org>
@@ -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 <jj@openbsd.org>
.\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -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 <gilles@poolp.org>
@@ -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;