Hello.
This diff allows to specify protcols and ciphers in smtp(1).
I thought it was cleaner to added a generic -O option flag for this.
Eric.
Index: smtp.1
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtp.1,v
retrieving revision 1.9
diff -u -p -r1.9 smtp.1
--- smtp.1 13 Feb 2021 08:07:48 -0000 1.9
+++ smtp.1 14 May 2021 13:25:59 -0000
@@ -26,6 +26,7 @@
.Op Fl a Ar authfile
.Op Fl F Ar from
.Op Fl H Ar helo
+.Op Fl O Ar option
.Op Fl s Ar server
.Op Ar recipient ...
.Sh DESCRIPTION
@@ -63,6 +64,31 @@ Display usage.
Do not actually execute a transaction,
just try to establish an SMTP session and quit.
When this option is given, no message is read from the standard input.
+.It Fl O Ar option
+Set additional configuration options that don't have a specific flag.
+The
+.Ar option
+string has the form
+.Sm off
+.Ar name No = Ar value
+.Sm on
+where
+.Ar name
+is one of the following:
+.Bl -tag -width "protocols"
+.It protocols
+Specify the protocols to use for tls connections.
+Refer to
+.Xr tls_config_parse_protocols 3
+for
+.Ar value .
+.It ciphers
+Specify the allowed ciphers for tls connections.
+Refer to
+.Xr tls_config_set_ciphers 3
+for
+.Ar value .
+.El
.It Fl s Ar server
Specify the server to connect to and connection parameters.
The format is
Index: smtpc.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpc.c,v
retrieving revision 1.15
diff -u -p -r1.15 smtpc.c
--- smtpc.c 10 Apr 2021 10:19:19 -0000 1.15
+++ smtpc.c 14 May 2021 13:31:45 -0000
@@ -48,22 +48,45 @@ 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] "
+ "[-O option] "
"[-s server] [recipient ...]\n", __progname);
exit(1);
}
+static void
+parse_option(char *opt)
+{
+ char *v;
+
+ v = strchr(opt, '=');
+ if (v == NULL)
+ fatalx("invalid option string \"%s\"", opt);
+ *v++ = '\0';
+
+ if (!strcmp(opt, "ciphers"))
+ ciphers = v;
+ else if (!strcmp(opt, "protocols"))
+ protocols = v;
+ else
+ fatalx("unknown option \"%s\"", opt);
+}
+
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 +114,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:O:S:a:hns:v")) != -1) {
switch (ch) {
case 'C':
params.tls_verify = 0;
@@ -102,6 +125,9 @@ main(int argc, char **argv)
case 'H':
params.helo = optarg;
break;
+ case 'O':
+ parse_option(optarg);
+ break;
case 'S':
servname = optarg;
break;
@@ -159,6 +185,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) {