Can I merge this for jessie?

On Nov 11, christian mock <c...@tahina.priv.at> wrote:

> Source: inn2
> Severity: wishlist
> Tags: patch
> 
> Dear Maintainer,
> 
> INN, at the moment, supports TLS connections to nnrpd, but does not
> allow any configuration besides the certificate and key.
> 
> This means that Wheezy's nnrpd is currently susceptible to the CRIME
> (because TLS compression is on) and POODLE (because SSLv3 is
> supported) attacks, should those be exploitable with NNTP. In
> addition, it supports weak symmetrical ciphers (40 and 56 bit key
> length). 
> 
> I've patched nnrpd to allow for detailed TLS configuration: protocol
> versions, cipher suites, compression and whether the client or server
> choses the cipher can now be configured. With the default
> configuration, TLS behaviour is unchanged, as to not break existing
> setups.
> 
> This patch is to be integrated upstream[0], but ideally I'd like it
> to be in the next Wheezy point release because I consider the current
> TLS config to be insecure.
> 
> The patch, as attached, is against a clean 2.5.4 upstream source, but
> I'd be happy to provide a patch for quilt if you tell me which package
> version I should target.
> 
> regards,
> 
> cm.
> 
> [0] https://lists.isc.org/pipermail/inn-workers/2014-November/018339.html

> diff --git a/doc/pod/inn.conf.pod b/doc/pod/inn.conf.pod
> index f8f5f79..98ebd6e 100644
> --- a/doc/pod/inn.conf.pod
> +++ b/doc/pod/inn.conf.pod
> @@ -1054,6 +1054,28 @@ I<pathetc>/key.pem.
>  This file must only be readable by the news user or B<nnrpd> will refuse to
>  use it.
>  
> +=item I<tlsprotocols>
> +
> +The list of TLS protocol versions to support. Valid protocols are
> +B<SSLv2>, B<SSLv3>, B<TLSv1>, B<TLSv1.1> and B<TLSv1.2>. The default
> +value is B<[ SSLv3 TLSv1 TLSv1.1 TLSv1.2 ]>.
> +
> +=item I<tlsciphers>
> +
> +The string describing the cipher suites OpenSSL will support. See
> +OpenSSL's B<cipher> command documentation for details. The default is
> +unset, which uses OpenSSL's default cipher suite list.
> +
> +=item I<tlsprefer_server_ciphers>
> +
> +Whether to let the client or the server decide the preferred cipher.
> +This is a boolean and the default is false.
> +
> +=item I<tlscompression>
> +
> +Whether to enable or disable TLS compression support (boolean). The
> +default is true.
> +
>  =back
>  
>  =head2 Monitoring
> diff --git a/doc/pod/news.pod b/doc/pod/news.pod
> index 4315b3f..64cd93b 100644
> --- a/doc/pod/news.pod
> +++ b/doc/pod/news.pod
> @@ -1,3 +1,17 @@
> +=head1 Changes in TLS configuration
> +
> +=over 2
> +
> +=item *
> +
> +New parameters used by B<nnrpd> to fine-tune the TLS configuration:
> +I<tlsprotocols>, I<tlsciphers>, I<tlsprefer_server_ciphers> and
> +I<tls_compression>. If you've been using TLS with B<nnrpd> before, be
> +aware that the defaults of those parameters may differ from the
> +previous defaults (which depended on your OpenSSL version).
> +
> +=back
> +
>  =head1 Changes in 2.5.4
>  
>  =over 2
> diff --git a/doc/pod/nnrpd.pod b/doc/pod/nnrpd.pod
> index 9c13821..32698ae 100644
> --- a/doc/pod/nnrpd.pod
> +++ b/doc/pod/nnrpd.pod
> @@ -224,6 +224,12 @@ run B<nnrpd>.  (Change the path to B<nnrpd> to match 
> your installation.)
>  You may need to replace C<nntps> with C<563> if C<nntps> isn't
>  defined in F</etc/services> on your system.
>  
> +Optionally, you may set the I<tlsprotocols>, I<tlsciphers>,
> +I<tlsprefer_server_ciphers> and I<tlscompression> parameters in
> +F<inn.conf> to fine-tune the behaviour of the TLS negotiation whenever
> +a new attack on the TLS protocol or some supported cipher suite is
> +discovered.
> +
>  =head1 PROTOCOL DIFFERENCES
>  
>  B<nnrpd> implements the NNTP commands defined in S<RFC 3977> (NNTP),
> diff --git a/include/inn/innconf.h b/include/inn/innconf.h
> index ee16620..669255c 100644
> --- a/include/inn/innconf.h
> +++ b/include/inn/innconf.h
> @@ -127,6 +127,10 @@ struct innconf {
>      char *tlscapath;            /* Path to a directory of CA certificates */
>      char *tlscertfile;          /* Path to the SSL certificate to use */
>      char *tlskeyfile;           /* Path to the key for the certificate */
> +    bool tlsprefer_server_ciphers; /* Make server select the cipher */
> +    bool tlscompression;                /* Turn TLS compression on/off */
> +    struct vector *tlsprotocols;               /* List of supported TLS 
> versions */
> +    char *tlsciphers;                  /* openssl-style cipher string */
>  #endif /* HAVE_SSL */
>  
>      /* Monitoring */
> diff --git a/lib/innconf.c b/lib/innconf.c
> index ded674c..9e6183d 100644
> --- a/lib/innconf.c
> +++ b/lib/innconf.c
> @@ -231,6 +231,10 @@ const struct config config_table[] = {
>      { K(tlscapath),               STRING  (NULL) },
>      { K(tlscertfile),             STRING  (NULL) },
>      { K(tlskeyfile),              STRING  (NULL) },
> +    { K(tlsprefer_server_ciphers), BOOL  (false) },
> +    { K(tlscompression),          BOOL    (true) },
> +    { K(tlsprotocols),            LIST    (NULL) },
> +    { K(tlsciphers),              STRING  (NULL) },
>  #endif /* HAVE_SSL */
>  
>      /* The following settings are used by nnrpd and rnews. */
> diff --git a/nnrpd/tls.c b/nnrpd/tls.c
> index 62b1a51..22a00c7 100644
> --- a/nnrpd/tls.c
> +++ b/nnrpd/tls.c
> @@ -425,7 +425,9 @@ set_cert_stuff(SSL_CTX * ctx, char *cert_file, char 
> *key_file)
>  int
>  tls_init_serverengine(int verifydepth, int askcert, int requirecert,
>                        char *tls_CAfile, char *tls_CApath, char 
> *tls_cert_file,
> -                      char *tls_key_file)
> +                      char *tls_key_file, int prefer_server_ciphers,
> +                   int tls_compression, struct vector *tls_proto_vect,
> +                   char *tls_ciphers)
>  {
>      int     off = 0;
>      int     verify_flags = SSL_VERIFY_NONE;
> @@ -434,6 +436,8 @@ tls_init_serverengine(int verifydepth, int askcert, int 
> requirecert,
>      char   *s_cert_file;
>      char   *s_key_file;
>      struct stat buf;
> +    int    tls_protos = 0;
> +    int    i;
>  
>      if (tls_serverengine)
>        return (0);                            /* Already running. */
> @@ -493,6 +497,70 @@ tls_init_serverengine(int verifydepth, int askcert, int 
> requirecert,
>      SSL_CTX_set_tmp_dh_callback(CTX, tmp_dh_cb);
>      SSL_CTX_set_options(CTX, SSL_OP_SINGLE_DH_USE);
>  
> +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
> +    if(prefer_server_ciphers) {
> +      SSL_CTX_set_options(CTX, SSL_OP_CIPHER_SERVER_PREFERENCE);
> +    }
> +#endif
> +
> +    if((tls_proto_vect != NULL) && (tls_proto_vect->count > 0)) {
> +      for(i = 0; i < tls_proto_vect->count; i++) {
> +     if(tls_proto_vect->strings[i] != NULL) {
> +       if(strcmp(tls_proto_vect->strings[i], "SSLv2") == 0)
> +         tls_protos |= INN_TLS_SSLv2;
> +       else if(strcmp(tls_proto_vect->strings[i], "SSLv3") == 0)
> +         tls_protos |= INN_TLS_SSLv3;
> +       else if(strcmp(tls_proto_vect->strings[i], "TLSv1") == 0)
> +         tls_protos |= INN_TLS_TLSv1;
> +       else if(strcmp(tls_proto_vect->strings[i], "TLSv1.1") == 0)
> +         tls_protos |= INN_TLS_TLSv1_1;
> +       else if(strcmp(tls_proto_vect->strings[i], "TLSv1.2") == 0)
> +         tls_protos |= INN_TLS_TLSv1_2;
> +       else
> +         syslog(L_ERROR, "TLS engine: unknown protocol '%s' in tlsprotocols",
> +                tls_proto_vect->strings[i]);
> +     }
> +      }
> +    } else {
> +      tls_protos = (INN_TLS_SSLv3 | INN_TLS_TLSv1 | INN_TLS_TLSv1_1 | 
> INN_TLS_TLSv1_2);
> +    }
> +
> +    if(!(tls_protos & INN_TLS_SSLv2)) {
> +      SSL_CTX_set_options(CTX, SSL_OP_NO_SSLv2);
> +    }
> +
> +    if(!(tls_protos & INN_TLS_SSLv3)) {
> +      SSL_CTX_set_options(CTX, SSL_OP_NO_SSLv3);
> +    }
> +
> +    if(!(tls_protos & INN_TLS_TLSv1)) {
> +      SSL_CTX_set_options(CTX, SSL_OP_NO_TLSv1);
> +    }
> +
> +#ifdef SSL_OP_NO_TLSv1_1
> +    if(!(tls_protos & INN_TLS_TLSv1_1)) {
> +      SSL_CTX_set_options(CTX, SSL_OP_NO_TLSv1_1);
> +    }
> +#endif
> +
> +#ifdef SSL_OP_NO_TLSv1_2
> +    if(!(tls_protos & INN_TLS_TLSv1_2)) {
> +      SSL_CTX_set_options(CTX, SSL_OP_NO_TLSv1_2);
> +    }
> +#endif
> +
> +    if(tls_ciphers)
> +      if(SSL_CTX_set_cipher_list(CTX, tls_ciphers) == 0) {
> +     syslog(L_ERROR, "TLS engine: cannot set cipher list");
> +     return (-1);
> +      }
> +
> +#ifdef SSL_OP_NO_COMPRESSION
> +    if(!tls_compression) {
> +      SSL_CTX_set_options(CTX, SSL_OP_NO_COMPRESSION);
> +    }
> +#endif
> +
>      verify_depth = verifydepth;
>      if (askcert!=0)
>       verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
> @@ -529,7 +597,11 @@ tls_init(void)
>                                      innconf->tlscafile,
>                                      innconf->tlscapath,
>                                      innconf->tlscertfile,
> -                                    innconf->tlskeyfile);
> +                                    innconf->tlskeyfile,
> +                                    innconf->tlsprefer_server_ciphers,
> +                                    innconf->tlscompression,
> +                                    innconf->tlsprotocols,
> +                                    innconf->tlsciphers);
>      if (ssl_result == -1) {
>          Reply("%d Error initializing TLS\r\n",
>                initialSSL ? NNTP_FAIL_TERMINATING : NNTP_ERR_STARTTLS);
> diff --git a/nnrpd/tls.h b/nnrpd/tls.h
> index 90c8edb..012434d 100644
> --- a/nnrpd/tls.h
> +++ b/nnrpd/tls.h
> @@ -27,6 +27,13 @@
>  #include <openssl/x509.h>
>  #include <openssl/ssl.h>
>  
> +/* protocol support */
> +#define INN_TLS_SSLv2 1
> +#define INN_TLS_SSLv3 2
> +#define INN_TLS_TLSv1 4
> +#define INN_TLS_TLSv1_1 8
> +#define INN_TLS_TLSv1_2 16
> +
>  /* Init TLS engine. */
>  int tls_init_serverengine(int verifydepth, /* Depth to verify. */
>                         int askcert,     /* 1 = Verify client. */
> @@ -34,7 +41,11 @@ int tls_init_serverengine(int verifydepth, /* Depth to 
> verify. */
>                         char *tls_CAfile,
>                         char *tls_CApath,
>                         char *tls_cert_file,
> -                       char *tls_key_file);
> +                       char *tls_key_file,
> +                       int prefer_server_ciphers,
> +                       int tls_compression,
> +                       struct vector *tls_protocols,
> +                       char *tls_ciphers);
>  
>  /* Init TLS. */
>  int tls_init(void);
> diff --git a/samples/inn.conf.in b/samples/inn.conf.in
> index d92423e..b8d4115 100644
> --- a/samples/inn.conf.in
> +++ b/samples/inn.conf.in
> @@ -137,6 +137,10 @@ backofftrigger:              10000
>  #tlscapath:                  @sysconfdir@
>  #tlscertfile:                @sysconfdir@/cert.pem
>  #tlskeyfile:                 @sysconfdir@/key.pem
> +#tlsprotocols:                    [ SSLv3 TLSv1 TLSv1.1 TLSv1.2 ]
> +#tlsciphers:              
> +#tlsprefer_server_ciphers:   false
> +#tlscompression:          true
>  
>  # Monitoring
>  


-- 
ciao,
Marco

Attachment: pgpenX_g1md7N.pgp
Description: PGP signature

Reply via email to