dovecot-2.2: openssl: optionally disable TLS compression

dovecot at dovecot.org dovecot at dovecot.org
Thu Jul 3 16:19:13 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/cea292767b95
changeset: 17585:cea292767b95
user:      Phil Carmody <phil at dovecot.fi>
date:      Thu Jul 03 19:17:16 2014 +0300
description:
openssl: optionally disable TLS compression
Make ssl compression optional, but enabled by default. Other ssl options
might be tweakable in the future, so have a single ssl_options string,
and explode it into individual flags. (Compare postfix configuration.)
Based on an idea by Andreas Schulze <sca at andreasschulze.de>

Signed-off-by: Phil Carmody <phil at dovecot.fi>

diffstat:

 src/lib-master/master-service-ssl-settings.c    |  22 +++++++++++++++++++++-
 src/lib-master/master-service-ssl-settings.h    |   7 +++++++
 src/lib-master/master-service-ssl.c             |   1 +
 src/lib-ssl-iostream/iostream-openssl-context.c |   8 ++++++--
 src/lib-ssl-iostream/iostream-ssl.h             |   1 +
 src/login-common/ssl-proxy-openssl.c            |  10 +++++++---
 6 files changed, 43 insertions(+), 6 deletions(-)

diffs (154 lines):

diff -r 7a60541913e9 -r cea292767b95 src/lib-master/master-service-ssl-settings.c
--- a/src/lib-master/master-service-ssl-settings.c	Thu Jul 03 19:12:02 2014 +0300
+++ b/src/lib-master/master-service-ssl-settings.c	Thu Jul 03 19:17:16 2014 +0300
@@ -28,6 +28,7 @@
 	DEF(SET_BOOL, ssl_require_crl),
 	DEF(SET_BOOL, verbose_ssl),
 	DEF(SET_BOOL, ssl_prefer_server_ciphers),
+	DEF(SET_STR, ssl_options), /* parsed as a string to set bools */
 
 	SETTING_DEFINE_LIST_END
 };
@@ -49,7 +50,8 @@
 	.ssl_verify_client_cert = FALSE,
 	.ssl_require_crl = TRUE,
 	.verbose_ssl = FALSE,
-	.ssl_prefer_server_ciphers = FALSE
+	.ssl_prefer_server_ciphers = FALSE,
+	.ssl_options = "",
 };
 
 const struct setting_parser_info master_service_ssl_setting_parser_info = {
@@ -98,6 +100,24 @@
 		*error_r = "ssl_verify_client_cert set, but ssl_ca not";
 		return FALSE;
 	}
+
+	/* Now explode the ssl_options string into individual flags */
+	/* First set them all to defaults */
+	set->parsed_opts.compression = TRUE;
+
+	/* Then modify anything specified in the string */
+	const char **opts = t_strsplit_spaces(set->ssl_options, ", ");
+	const char *opt;
+	while ((opt = *opts++) != NULL) {
+		if (strcasecmp(opt, "no_compression") == 0) {
+			set->parsed_opts.compression = FALSE;
+		} else {
+			*error_r = t_strdup_printf("ssl_options: unknown flag: '%s'",
+						   opt);
+			return FALSE;
+		}
+	}
+
 	return TRUE;
 #endif
 }
diff -r 7a60541913e9 -r cea292767b95 src/lib-master/master-service-ssl-settings.h
--- a/src/lib-master/master-service-ssl-settings.h	Thu Jul 03 19:12:02 2014 +0300
+++ b/src/lib-master/master-service-ssl-settings.h	Thu Jul 03 19:17:16 2014 +0300
@@ -13,10 +13,17 @@
 	const char *ssl_protocols;
 	const char *ssl_cert_username_field;
 	const char *ssl_crypto_device;
+	const char *ssl_options;
+
 	bool ssl_verify_client_cert;
 	bool ssl_require_crl;
 	bool verbose_ssl;
 	bool ssl_prefer_server_ciphers;
+
+	/* These are derived from ssl_options, not set directly */
+	struct {
+		bool compression;
+	} parsed_opts;
 };
 
 extern const struct setting_parser_info master_service_ssl_setting_parser_info;
diff -r 7a60541913e9 -r cea292767b95 src/lib-master/master-service-ssl.c
--- a/src/lib-master/master-service-ssl.c	Thu Jul 03 19:12:02 2014 +0300
+++ b/src/lib-master/master-service-ssl.c	Thu Jul 03 19:17:16 2014 +0300
@@ -120,6 +120,7 @@
 	ssl_set.verbose = set->verbose_ssl;
 	ssl_set.verify_remote_cert = set->ssl_verify_client_cert;
 	ssl_set.prefer_server_ciphers = set->ssl_prefer_server_ciphers;
+	ssl_set.compression = set->parsed_opts.compression;
 
 	if (ssl_iostream_context_init_server(&ssl_set, &service->ssl_ctx,
 					     &error) < 0) {
diff -r 7a60541913e9 -r cea292767b95 src/lib-ssl-iostream/iostream-openssl-context.c
--- a/src/lib-ssl-iostream/iostream-openssl-context.c	Thu Jul 03 19:12:02 2014 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl-context.c	Thu Jul 03 19:17:16 2014 +0300
@@ -499,12 +499,16 @@
 				 const struct ssl_iostream_settings *set,
 				 const char **error_r)
 {
+	long ssl_ops = SSL_OP_NO_SSLv2 |
+		(SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
+
 	ctx->pool = pool_alloconly_create("ssl iostream context", 4096);
 
 	/* enable all SSL workarounds, except empty fragments as it
 	   makes SSL more vulnerable against attacks */
-	SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 |
-			    (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
+	if (!set->compression)
+		ssl_ops |= SSL_OP_NO_COMPRESSION;
+	SSL_CTX_set_options(ctx->ssl_ctx, ssl_ops);
 #ifdef SSL_MODE_RELEASE_BUFFERS
 	SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
 #endif
diff -r 7a60541913e9 -r cea292767b95 src/lib-ssl-iostream/iostream-ssl.h
--- a/src/lib-ssl-iostream/iostream-ssl.h	Thu Jul 03 19:12:02 2014 +0300
+++ b/src/lib-ssl-iostream/iostream-ssl.h	Thu Jul 03 19:17:16 2014 +0300
@@ -18,6 +18,7 @@
 	bool verify_remote_cert; /* neither/both */
 	bool require_valid_cert; /* stream-only */
 	bool prefer_server_ciphers;
+	bool compression;
 };
 
 /* Returns 0 if ok, -1 and sets error_r if failed. The returned error string
diff -r 7a60541913e9 -r cea292767b95 src/login-common/ssl-proxy-openssl.c
--- a/src/login-common/ssl-proxy-openssl.c	Thu Jul 03 19:12:02 2014 +0300
+++ b/src/login-common/ssl-proxy-openssl.c	Thu Jul 03 19:17:16 2014 +0300
@@ -101,6 +101,7 @@
 	const char *protocols;
 	bool verify_client_cert;
 	bool prefer_server_ciphers;
+	bool compression;
 };
 
 static int extdata_index;
@@ -640,6 +641,7 @@
 		login_set->auth_ssl_require_client_cert ||
 		login_set->auth_ssl_username_from_cert;
 	lookup_ctx.prefer_server_ciphers = set->ssl_prefer_server_ciphers;
+	lookup_ctx.compression = set->parsed_opts.compression;
 
 	ctx = hash_table_lookup(ssl_servers, &lookup_ctx);
 	if (ctx == NULL)
@@ -1011,11 +1013,12 @@
 {
 	X509_STORE *store;
 	STACK_OF(X509_NAME) *xnames = NULL;
-
 	/* enable all SSL workarounds, except empty fragments as it
 	   makes SSL more vulnerable against attacks */
-	SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL &
-			    ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
+	long ssl_ops = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+	if (!set->parsed_opts.compression)
+		ssl_ops |= SSL_OP_NO_COMPRESSION;
+	SSL_CTX_set_options(ssl_ctx, ssl_ops);
 
 #ifdef SSL_MODE_RELEASE_BUFFERS
 	SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
@@ -1286,6 +1289,7 @@
 		login_set->auth_ssl_require_client_cert ||
 		login_set->auth_ssl_username_from_cert;
 	ctx->prefer_server_ciphers = ssl_set->ssl_prefer_server_ciphers;
+	ctx->compression = ssl_set->parsed_opts.compression;
 
 	ctx->ctx = ssl_ctx = SSL_CTX_new(SSLv23_server_method());
 	if (ssl_ctx == NULL)


More information about the dovecot-cvs mailing list