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) {