summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2021-05-22 09:09:08 +0000
committerEric Faurot <eric@cvs.openbsd.org>2021-05-22 09:09:08 +0000
commit5e4a38ef003829b872f4cb53c2143b24d2fc5e76 (patch)
tree63094d39468aba8d34d6586bc8e182bd6c4222d9 /usr.sbin/smtpd
parentb40a6d863ae85c8604c6888a1ef42696681afd97 (diff)
allow to specify TLS ciphers and protocols in smtp(1)
improvements from jmc@ schwarze@ tb@ ok tb@
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/smtp.125
-rw-r--r--usr.sbin/smtpd/smtpc.c55
2 files changed, 75 insertions, 5 deletions
diff --git a/usr.sbin/smtpd/smtp.1 b/usr.sbin/smtpd/smtp.1
index 10740653b68..f020fe607f9 100644
--- a/usr.sbin/smtpd/smtp.1
+++ b/usr.sbin/smtpd/smtp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: smtp.1,v 1.9 2021/02/13 08:07:48 jmc Exp $
+.\" $OpenBSD: smtp.1,v 1.10 2021/05/22 09:09:07 eric Exp $
.\"
.\" Copyright (c) 2018, Eric Faurot <eric@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: February 13 2021 $
+.Dd $Mdocdate: May 22 2021 $
.Dt SMTP 1
.Os
.Sh NAME
@@ -27,6 +27,7 @@
.Op Fl F Ar from
.Op Fl H Ar helo
.Op Fl s Ar server
+.Op Fl T Ar params
.Op Ar recipient ...
.Sh DESCRIPTION
The
@@ -91,6 +92,26 @@ SMTP session with forced TLS on connection.
.Pp
Defaults to
.Dq smtp://localhost:25 .
+.It Fl T Ar params
+Set specific parameters for TLS sessions.
+The
+.Ar params
+string is a comma or space separated list of options.
+The available options are:
+.Bl -tag -width Ds
+.It protocols Ns = Ns Ar value
+Specify the protocols to use.
+Refer to
+.Xr tls_config_parse_protocols 3
+for
+.Ar value .
+.It ciphers Ns = Ns Ar value
+Specify the allowed ciphers.
+Refer to
+.Xr tls_config_set_ciphers 3
+for
+.Ar value .
+.El
.It Fl v
Be more verbose.
This option can be specified multiple times.
diff --git a/usr.sbin/smtpd/smtpc.c b/usr.sbin/smtpd/smtpc.c
index ca48604feb5..4bf64fc4d46 100644
--- a/usr.sbin/smtpd/smtpc.c
+++ b/usr.sbin/smtpd/smtpc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpc.c,v 1.15 2021/04/10 10:19:19 eric Exp $ */
+/* $OpenBSD: smtpc.c,v 1.16 2021/05/22 09:09:07 eric Exp $ */
/*
* Copyright (c) 2018 Eric Faurot <eric@openbsd.org>
@@ -48,22 +48,57 @@ static struct smtp_mail mail;
static const char *servname = NULL;
static struct tls_config *tls_config;
+static const char *protocols = NULL;
+static const char *ciphers = NULL;
+
static void
usage(void)
{
extern char *__progname;
fprintf(stderr, "usage: %s [-Chnv] [-a authfile] [-F from] [-H helo] "
- "[-s server] [recipient ...]\n", __progname);
+ "[-s server] [-T params] [recipient ...]\n", __progname);
exit(1);
}
+static void
+parse_tls_options(char *opt)
+{
+ static char * const tokens[] = {
+#define CIPHERS 0
+ "ciphers",
+#define PROTOCOLS 1
+ "protocols",
+ NULL };
+ char *value;
+
+ while (*opt) {
+ switch (getsubopt(&opt, tokens, &value)) {
+ case CIPHERS:
+ if (value == NULL)
+ fatalx("missing value for ciphers");
+ ciphers = value;
+ break;
+ case PROTOCOLS:
+ if (value == NULL)
+ fatalx("missing value for protocols");
+ protocols = value;
+ break;
+ case -1:
+ if (suboptarg)
+ fatalx("invalid TLS option \"%s\"", suboptarg);
+ fatalx("missing TLS option");
+ }
+ }
+}
+
int
main(int argc, char **argv)
{
char hostname[256];
FILE *authfile;
int ch, i;
+ uint32_t protos;
char *server = "localhost";
char *authstr = NULL;
size_t alloc = 0;
@@ -91,7 +126,7 @@ main(int argc, char **argv)
memset(&mail, 0, sizeof(mail));
mail.from = pw->pw_name;
- while ((ch = getopt(argc, argv, "CF:H:S:a:hns:v")) != -1) {
+ while ((ch = getopt(argc, argv, "CF:H:S:T:a:hns:v")) != -1) {
switch (ch) {
case 'C':
params.tls_verify = 0;
@@ -105,6 +140,9 @@ main(int argc, char **argv)
case 'S':
servname = optarg;
break;
+ case 'T':
+ parse_tls_options(optarg);
+ break;
case 'a':
if ((authfile = fopen(optarg, "r")) == NULL)
fatal("%s: open", optarg);
@@ -159,6 +197,17 @@ main(int argc, char **argv)
tls_config = tls_config_new();
if (tls_config == NULL)
fatal("tls_config_new");
+
+ if (protocols) {
+ if (tls_config_parse_protocols(&protos, protocols) == -1)
+ fatalx("failed to parse protocol '%s'", protocols);
+ if (tls_config_set_protocols(tls_config, protos) == -1)
+ fatalx("tls_config_set_protocols: %s",
+ tls_config_error(tls_config));
+ }
+ if (ciphers && tls_config_set_ciphers(tls_config, ciphers) == -1)
+ fatalx("tls_config_set_ciphers: %s",
+ tls_config_error(tls_config));
if (tls_config_set_ca_file(tls_config, tls_default_ca_cert_file()) == -1)
fatal("tls_set_ca_file");
if (!params.tls_verify) {