<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">--- doc/example-config/conf.d/10-ssl.conf.orig	2011-12-13 14:38:27.000000000 +0300
+++ doc/example-config/conf.d/10-ssl.conf	2014-11-12 17:02:11.099183165 +0300
@@ -37,5 +37,8 @@
 # entirely.
 #ssl_parameters_regenerate = 168
 
+# SSL protocols to use
+#ssl_protocols = !SSLv2 !SSLv3
+
 # SSL ciphers to use
 #ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL
--- src/login-common/login-settings.c.orig	2012-02-09 20:32:48.000000000 +0300
+++ src/login-common/login-settings.c	2014-11-12 17:04:31.862715871 +0300
@@ -31,6 +31,7 @@
 	DEF(SET_STR, ssl_key),
 	DEF(SET_STR, ssl_key_password),
 	DEF(SET_STR, ssl_cipher_list),
+	DEF(SET_STR, ssl_protocols),
 	DEF(SET_STR, ssl_cert_username_field),
 	DEF(SET_STR, ssl_client_cert),
 	DEF(SET_STR, ssl_client_key),
@@ -62,6 +63,7 @@
 	.ssl_key = "",
 	.ssl_key_password = "",
 	.ssl_cipher_list = "ALL:!LOW:!SSLv2:!EXP:!aNULL",
+	.ssl_protocols = "!SSLv2 !SSLv3",
 	.ssl_cert_username_field = "commonName",
 	.ssl_client_cert = "",
 	.ssl_client_key = "",
--- src/login-common/login-settings.h.orig	2012-02-09 20:32:48.000000000 +0300
+++ src/login-common/login-settings.h	2014-11-12 17:04:57.913369657 +0300
@@ -13,6 +13,7 @@
 	const char *ssl_key;
 	const char *ssl_key_password;
 	const char *ssl_cipher_list;
+	const char *ssl_protocols;
 	const char *ssl_cert_username_field;
 	const char *ssl_client_cert;
 	const char *ssl_client_key;
--- src/login-common/ssl-proxy-openssl.c.orig	2012-05-14 21:08:02.000000000 +0300
+++ src/login-common/ssl-proxy-openssl.c	2014-11-12 17:15:30.299304760 +0300
@@ -88,6 +88,7 @@
 	const char *key;
 	const char *ca;
 	const char *cipher_list;
+	const char *protocols;
 	bool verify_client_cert;
 };
 
@@ -139,6 +140,8 @@
 		return 1;
 	if (null_strcmp(ctx1-&gt;cipher_list, ctx2-&gt;cipher_list) != 0)
 		return 1;
+	if (null_strcmp(ctx1-&gt;protocols, ctx2-&gt;protocols) != 0)
+		return 1;
 
 	return ctx1-&gt;verify_client_cert == ctx2-&gt;verify_client_cert ? 0 : 1;
 }
@@ -606,6 +609,7 @@
 	lookup_ctx.key = set-&gt;ssl_key;
 	lookup_ctx.ca = set-&gt;ssl_ca;
 	lookup_ctx.cipher_list = set-&gt;ssl_cipher_list;
+	lookup_ctx.protocols = set-&gt;ssl_protocols;
 	lookup_ctx.verify_client_cert = set-&gt;ssl_verify_client_cert;
 
 	ctx = hash_table_lookup(ssl_servers, &amp;lookup_ctx);
@@ -1021,8 +1025,7 @@
 
 	/* enable all SSL workarounds, except empty fragments as it
 	   makes SSL more vulnerable against attacks */
-	SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 |
-			    (SSL_OP_ALL &amp; ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
+	SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL &amp; ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
 #ifdef SSL_MODE_RELEASE_BUFFERS
     SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
 #endif
@@ -1196,6 +1199,57 @@
 }
 #endif
 
+enum {
+	DOVECOT_SSL_PROTO_SSLv2 = 0x01,
+	DOVECOT_SSL_PROTO_SSLv3 = 0x02,
+	DOVECOT_SSL_PROTO_TLSv1 = 0x04,
+	DOVECOT_SSL_PROTO_ALL = 0x07
+};
+
+static void
+ssl_proxy_ctx_set_protocols(struct ssl_server_context *ssl_ctx,
+			    const char *protocols)
+{
+	const char *const *tmp;
+	int proto, op = 0, include = 0, exclude = 0;
+	bool neg;
+
+	tmp = t_strsplit_spaces(protocols, " ");
+	for (; *tmp != NULL; tmp++) {
+		const char *name = *tmp;
+
+		if (*name != '!')
+			neg = FALSE;
+		else {
+			name++;
+			neg = TRUE;
+		}
+		if (strcasecmp(name, SSL_TXT_SSLV2) == 0)
+			proto = DOVECOT_SSL_PROTO_SSLv2;
+		else if (strcasecmp(name, SSL_TXT_SSLV3) == 0)
+			proto = DOVECOT_SSL_PROTO_SSLv3;
+		else if (strcasecmp(name, SSL_TXT_TLSV1) == 0)
+			proto = DOVECOT_SSL_PROTO_TLSv1;
+		else {
+			i_fatal("Invalid ssl_protocols setting: "
+				"Unknown protocol '%s'", name);
+		}
+		if (neg)
+			exclude |= proto;
+		else
+			include |= proto;
+	}
+	if (include != 0) {
+		/* exclude everything, except those that are included
+		(and let excludes still override those) */
+		exclude |= DOVECOT_SSL_PROTO_ALL &amp; ~include;
+	}
+	if ((exclude &amp; DOVECOT_SSL_PROTO_SSLv2) != 0) op |= SSL_OP_NO_SSLv2;
+	if ((exclude &amp; DOVECOT_SSL_PROTO_SSLv3) != 0) op |= SSL_OP_NO_SSLv3;
+	if ((exclude &amp; DOVECOT_SSL_PROTO_TLSv1) != 0) op |= SSL_OP_NO_TLSv1;
+	SSL_CTX_set_options(ssl_ctx-&gt;ctx, op);
+}
+
 static struct ssl_server_context *
 ssl_server_context_init(const struct login_settings *set)
 {
@@ -1211,6 +1265,7 @@
 	ctx-&gt;key = p_strdup(pool, set-&gt;ssl_key);
 	ctx-&gt;ca = p_strdup(pool, set-&gt;ssl_ca);
 	ctx-&gt;cipher_list = p_strdup(pool, set-&gt;ssl_cipher_list);
+	ctx-&gt;protocols = p_strdup(pool, set-&gt;ssl_protocols);
 	ctx-&gt;verify_client_cert = set-&gt;ssl_verify_client_cert;
 
 	ctx-&gt;ctx = ssl_ctx = SSL_CTX_new(SSLv23_server_method());
@@ -1222,6 +1277,7 @@
 		i_fatal("Can't set cipher list to '%s': %s",
 			ctx-&gt;cipher_list, ssl_last_error());
 	}
+	ssl_proxy_ctx_set_protocols(ctx, ctx-&gt;protocols);
 
 	if (ssl_proxy_ctx_use_certificate_chain(ctx-&gt;ctx, ctx-&gt;cert) != 1) {
 		i_fatal("Can't load ssl_cert: %s",
</pre></body></html>