On Fri, May 14, 2021 at 03:38:12PM +0200, Eric Faurot wrote:
> 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.

I'm ok with this.

Two small points to consider:

Perhaps using -T as in nc(1) might make sense?  (On the other hand,
ftp(1) uses -S which is already taken but not documented in smtp(1)).

Is it worth using getsubopt(3)?

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

Reply via email to