You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
4.7 KiB
146 lines
4.7 KiB
Some servers have problem when connection uses TLS 1.0 or SSL 3.0. |
|
Since openssl offers TLS 1.1 and 1.2, we would like to use these |
|
when connecting to server, while having ability to disable these |
|
protocols if needed. |
|
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=957840 |
|
|
|
Upstream related bug report: |
|
http://dev.mutt.org/trac/ticket/3571 |
|
|
|
diff -up mutt-1.5.21/init.h.tlsv1v2 mutt-1.5.21/init.h |
|
--- mutt-1.5.21/init.h.tlsv1v2 2013-06-27 12:46:14.120389035 +0200 |
|
+++ mutt-1.5.21/init.h 2013-06-27 12:47:28.020387743 +0200 |
|
@@ -2970,6 +2970,18 @@ struct option_t MuttVars[] = { |
|
** This variable specifies whether to attempt to use TLSv1 in the |
|
** SSL authentication process. |
|
*/ |
|
+ { "ssl_use_tlsv1_1", DT_BOOL, R_NONE, OPTTLSV1_1, 1 }, |
|
+ /* |
|
+ ** .pp |
|
+ ** This variable specifies whether to attempt to use TLSv1.1 in the |
|
+ ** SSL authentication process. |
|
+ */ |
|
+ { "ssl_use_tlsv1_2", DT_BOOL, R_NONE, OPTTLSV1_2, 1 }, |
|
+ /* |
|
+ ** .pp |
|
+ ** This variable specifies whether to attempt to use TLSv1.2 in the |
|
+ ** SSL authentication process. |
|
+ */ |
|
#ifdef USE_SSL_OPENSSL |
|
{ "ssl_usesystemcerts", DT_BOOL, R_NONE, OPTSSLSYSTEMCERTS, 1 }, |
|
/* |
|
diff -up mutt-1.5.21/mutt.h.tlsv1v2 mutt-1.5.21/mutt.h |
|
--- mutt-1.5.21/mutt.h.tlsv1v2 2010-09-13 19:19:55.000000000 +0200 |
|
+++ mutt-1.5.21/mutt.h 2013-06-27 12:47:28.020387743 +0200 |
|
@@ -376,6 +376,8 @@ enum |
|
# endif /* USE_SSL_GNUTLS */ |
|
OPTSSLV3, |
|
OPTTLSV1, |
|
+ OPTTLSV1_1, |
|
+ OPTTLSV1_2, |
|
OPTSSLFORCETLS, |
|
OPTSSLVERIFYDATES, |
|
OPTSSLVERIFYHOST, |
|
diff -up mutt-1.5.21/mutt_ssl.c.tlsv1v2 mutt-1.5.21/mutt_ssl.c |
|
--- mutt-1.5.21/mutt_ssl.c.tlsv1v2 2010-08-25 18:31:40.000000000 +0200 |
|
+++ mutt-1.5.21/mutt_ssl.c 2013-06-27 12:47:28.021387743 +0200 |
|
@@ -106,6 +106,18 @@ int mutt_ssl_starttls (CONNECTION* conn) |
|
dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL_CTX\n")); |
|
goto bail_ssldata; |
|
} |
|
+#ifdef SSL_OP_NO_TLSv1_1 |
|
+ if (!option(OPTTLSV1_1)) |
|
+ { |
|
+ SSL_CTX_set_options(ssldata->ctx, SSL_OP_NO_TLSv1_1); |
|
+ } |
|
+#endif |
|
+#ifdef SSL_OP_NO_TLSv1_2 |
|
+ if (!option(OPTTLSV1_2)) |
|
+ { |
|
+ SSL_CTX_set_options(ssldata->ctx, SSL_OP_NO_TLSv1_2); |
|
+ } |
|
+#endif |
|
|
|
ssl_get_client_cert(ssldata, conn); |
|
|
|
@@ -303,6 +315,21 @@ static int ssl_socket_open (CONNECTION * |
|
{ |
|
SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1); |
|
} |
|
+ /* TLSv1.1/1.2 support was added in OpenSSL 1.0.1, but some OS distros such |
|
+ * as Fedora 17 are on OpenSSL 1.0.0. |
|
+ */ |
|
+#ifdef SSL_OP_NO_TLSv1_1 |
|
+ if (!option(OPTTLSV1_1)) |
|
+ { |
|
+ SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1_1); |
|
+ } |
|
+#endif |
|
+#ifdef SSL_OP_NO_TLSv1_2 |
|
+ if (!option(OPTTLSV1_2)) |
|
+ { |
|
+ SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1_2); |
|
+ } |
|
+#endif |
|
if (!option(OPTSSLV2)) |
|
{ |
|
SSL_CTX_set_options(data->ctx, SSL_OP_NO_SSLv2); |
|
diff -up mutt-1.5.21/mutt_ssl_gnutls.c.tlsv1v2 mutt-1.5.21/mutt_ssl_gnutls.c |
|
--- mutt-1.5.21/mutt_ssl_gnutls.c.tlsv1v2 2013-06-27 12:46:14.123389035 +0200 |
|
+++ mutt-1.5.21/mutt_ssl_gnutls.c 2013-06-27 12:47:28.018387743 +0200 |
|
@@ -238,7 +238,11 @@ err_crt: |
|
gnutls_x509_crt_deinit (clientcrt); |
|
} |
|
|
|
-static int protocol_priority[] = {GNUTLS_TLS1, GNUTLS_SSL3, 0}; |
|
+/* This array needs to be large enough to hold all the possible values support |
|
+ * by Mutt. The initialized values are just placeholders--the array gets |
|
+ * overwrriten in tls_negotiate() depending on the $ssl_use_* options. |
|
+ */ |
|
+static int protocol_priority[] = {GNUTLS_TLS1_2, GNUTLS_TLS1_1, GNUTLS_TLS1, GNUTLS_SSL3, 0}; |
|
|
|
/* tls_negotiate: After TLS state has been initialised, attempt to negotiate |
|
* TLS over the wire, including certificate checks. */ |
|
@@ -246,6 +250,7 @@ static int tls_negotiate (CONNECTION * c |
|
{ |
|
tlssockdata *data; |
|
int err; |
|
+ size_t nproto = 0; /* number of tls/ssl protocols */ |
|
|
|
data = (tlssockdata *) safe_calloc (1, sizeof (tlssockdata)); |
|
conn->sockdata = data; |
|
@@ -286,22 +291,22 @@ static int tls_negotiate (CONNECTION * c |
|
/* set socket */ |
|
gnutls_transport_set_ptr (data->state, (gnutls_transport_ptr)conn->fd); |
|
|
|
+ if (option(OPTTLSV1_2)) |
|
+ protocol_priority[nproto++] = GNUTLS_TLS1_2; |
|
+ if (option(OPTTLSV1_1)) |
|
+ protocol_priority[nproto++] = GNUTLS_TLS1_1; |
|
+ if (option(OPTTLSV1)) |
|
+ protocol_priority[nproto++] = GNUTLS_TLS1; |
|
+ if (option(OPTSSLV3)) |
|
+ protocol_priority[nproto++] = GNUTLS_SSL3; |
|
+ protocol_priority[nproto] = 0; |
|
+ |
|
/* disable TLS/SSL protocols as needed */ |
|
- if (!option(OPTTLSV1) && !option(OPTSSLV3)) |
|
+ if (nproto == 0) |
|
{ |
|
mutt_error (_("All available protocols for TLS/SSL connection disabled")); |
|
goto fail; |
|
} |
|
- else if (!option(OPTTLSV1)) |
|
- { |
|
- protocol_priority[0] = GNUTLS_SSL3; |
|
- protocol_priority[1] = 0; |
|
- } |
|
- else if (!option(OPTSSLV3)) |
|
- { |
|
- protocol_priority[0] = GNUTLS_TLS1; |
|
- protocol_priority[1] = 0; |
|
- } |
|
/* |
|
else |
|
use the list set above
|
|
|