Re: smtp: more tls options

2021-05-23 Thread Theo Buehler
On Sat, May 22, 2021 at 04:08:55PM +0200, Eric Faurot wrote:
> The new -T option in smtp(1) allows to plug more TLS parameters easily.
> For completeness and consistency, this diff adds the following:
> 
>  cafile=:  override the default root certificates
>  nosni:  disable SNI completely
>  noverify:  synonym for -C that can be recycled
>  servername=:  synonym for -S (undocumented) that can be recycled too

ok tb



smtp: more tls options

2021-05-22 Thread Eric Faurot
The new -T option in smtp(1) allows to plug more TLS parameters easily.
For completeness and consistency, this diff adds the following:

 cafile=:  override the default root certificates
 nosni:  disable SNI completely
 noverify:  synonym for -C that can be recycled
 servername=:  synonym for -S (undocumented) that can be recycled too

Eric.

Index: smtp.1
===
RCS file: /cvs/src/usr.sbin/smtpd/smtp.1,v
retrieving revision 1.11
diff -u -p -r1.11 smtp.1
--- smtp.1  22 May 2021 12:16:06 -  1.11
+++ smtp.1  22 May 2021 12:49:17 -
@@ -53,6 +53,10 @@ This option requires a TLS or STARTTLS
 .Ar server .
 .It Fl C
 Do not require server certificate to be valid.
+This flag is deprecated.
+Use
+.Dq Fl T No noverify
+instead.
 .It Fl F Ar from
 Set the return-path (MAIL FROM) for the SMTP transaction.
 Default to the current username.
@@ -105,12 +109,21 @@ Refer to
 .Xr tls_config_set_ciphers 3
 for
 .Ar value .
+.It noverify
+Do not require server certificate to be valid.
+.It nosni
+Disable Server Name Indication (SNI).
 .It protocols Ns = Ns Ar value
 Specify the protocols to use.
 Refer to
 .Xr tls_config_parse_protocols 3
 for
 .Ar value .
+.It servername Ns = Ns Ar value
+Use
+.Ar value
+for Server Name Indication (SNI).
+Defaults to the specified server hostname.
 .El
 .It Fl v
 Be more verbose.
Index: smtpc.c
===
RCS file: /cvs/src/usr.sbin/smtpd/smtpc.c,v
retrieving revision 1.16
diff -u -p -r1.16 smtpc.c
--- smtpc.c 22 May 2021 09:09:07 -  1.16
+++ smtpc.c 22 May 2021 12:36:11 -
@@ -48,6 +48,8 @@ static struct smtp_mail mail;
 static const char *servname = NULL;
 static struct tls_config *tls_config;
 
+static int nosni = 0;
+static const char *cafile = NULL;
 static const char *protocols = NULL;
 static const char *ciphers = NULL;
 
@@ -65,25 +67,53 @@ static void
 parse_tls_options(char *opt)
 {
static char * const tokens[] = {
-#define CIPHERS 0
+#define CAFILE 0
+   "cafile",
+#define CIPHERS 1
"ciphers",
-#define PROTOCOLS 1
+#define NOSNI 2
+   "nosni",
+#define NOVERIFY 3
+   "noverify",
+#define PROTOCOLS 4
"protocols",
+#define SERVERNAME 5
+   "servername",
NULL };
char *value;
 
while (*opt) {
switch (getsubopt(, tokens, )) {
+   case CAFILE:
+   if (value == NULL)
+   fatalx("missing value for cafile");
+   cafile = value;
+   break;
case CIPHERS:
if (value == NULL)
fatalx("missing value for ciphers");
ciphers = value;
break;
+   case NOSNI:
+   if (value != NULL)
+   fatalx("no value expected for nosni");
+   nosni = 1;
+   break;
+   case NOVERIFY:
+   if (value != NULL)
+   fatalx("no value expected for noverify");
+   params.tls_verify = 0;
+   break;
case PROTOCOLS:
if (value == NULL)
fatalx("missing value for protocols");
protocols = value;
break;
+   case SERVERNAME:
+   if (value == NULL)
+   fatalx("missing value for servername");
+   servname = value;
+   break;
case -1:
if (suboptarg)
fatalx("invalid TLS option \"%s\"", suboptarg);
@@ -208,7 +238,10 @@ main(int argc, char **argv)
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)
+
+   if (cafile == NULL)
+   cafile = tls_default_ca_cert_file();
+   if (tls_config_set_ca_file(tls_config, cafile) == -1)
fatal("tls_set_ca_file");
if (!params.tls_verify) {
tls_config_insecure_noverifycert(tls_config);
@@ -332,7 +365,8 @@ parse_server(char *server)
 
if (servname == NULL)
servname = host;
-   params.tls_servname = servname;
+   if (nosni == 0)
+   params.tls_servname = servname;
 
memset(, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;