dovecot-2.2: lib-ssl-iostream: Added protocols setting.

dovecot at dovecot.org dovecot at dovecot.org
Sat Jul 28 17:56:05 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/69626d2ce3f0
changeset: 14723:69626d2ce3f0
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Jul 28 17:36:27 2012 +0300
description:
lib-ssl-iostream: Added protocols setting.

diffstat:

 src/lib-ssl-iostream/iostream-openssl-context.c |  52 +++++++++++++++++++++++++
 src/lib-ssl-iostream/iostream-openssl.c         |   7 ++-
 src/lib-ssl-iostream/iostream-openssl.h         |   3 +
 src/lib-ssl-iostream/iostream-ssl.h             |  11 ++--
 4 files changed, 67 insertions(+), 6 deletions(-)

diffs (134 lines):

diff -r 76d492963638 -r 69626d2ce3f0 src/lib-ssl-iostream/iostream-openssl-context.c
--- a/src/lib-ssl-iostream/iostream-openssl-context.c	Sat Jul 28 17:34:11 2012 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl-context.c	Sat Jul 28 17:36:27 2012 +0300
@@ -278,6 +278,7 @@
 	struct ssl_iostream_settings *new_set;
 
 	new_set = p_new(pool, struct ssl_iostream_settings, 1);
+	new_set->protocols = p_strdup(pool, old_set->protocols);
 	new_set->cipher_list = p_strdup(pool, old_set->cipher_list);
 	new_set->cert = p_strdup(pool, old_set->cert);
 	new_set->key = p_strdup(pool, old_set->key);
@@ -287,6 +288,55 @@
 	return new_set;
 }
 
+enum {
+	DOVECOT_SSL_PROTO_SSLv2	= 0x01,
+	DOVECOT_SSL_PROTO_SSLv3	= 0x02,
+	DOVECOT_SSL_PROTO_TLSv1	= 0x04,
+	DOVECOT_SSL_PROTO_ALL	= 0x07
+};
+
+int openssl_get_protocol_options(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 & ~include;
+	}
+	if ((exclude & DOVECOT_SSL_PROTO_SSLv2) != 0) op |= SSL_OP_NO_SSLv2;
+	if ((exclude & DOVECOT_SSL_PROTO_SSLv3) != 0) op |= SSL_OP_NO_SSLv3;
+	if ((exclude & DOVECOT_SSL_PROTO_TLSv1) != 0) op |= SSL_OP_NO_TLSv1;
+	return op;
+}
+
 static int
 ssl_iostream_context_set(struct ssl_iostream_context *ctx,
 			 const struct ssl_iostream_settings *set)
@@ -302,6 +352,8 @@
 			ssl_iostream_error());
 		return -1;
 	}
+	SSL_CTX_set_options(ctx->ssl_ctx,
+			    openssl_get_protocol_options(ctx->set->protocols));
 
 	if (set->cert != NULL &&
 	    ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->cert) < 0) {
diff -r 76d492963638 -r 69626d2ce3f0 src/lib-ssl-iostream/iostream-openssl.c
--- a/src/lib-ssl-iostream/iostream-openssl.c	Sat Jul 28 17:34:11 2012 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl.c	Sat Jul 28 17:36:27 2012 +0300
@@ -133,8 +133,13 @@
 				ssl_iostream_error());
 		}
 		return -1;
+	}
+	if (set->protocols != NULL) {
+		SSL_clear_options(ssl_io->ssl, OPENSSL_ALL_PROTOCOL_OPTIONS);
+		SSL_set_options(ssl_io->ssl,
+				openssl_get_protocol_options(set->protocols));
+	}
 
-	}
 	if (set->cert != NULL && strcmp(ctx_set->cert, set->cert) != 0) {
 		if (ssl_iostream_use_certificate(ssl_io, set->cert) < 0)
 			return -1;
diff -r 76d492963638 -r 69626d2ce3f0 src/lib-ssl-iostream/iostream-openssl.h
--- a/src/lib-ssl-iostream/iostream-openssl.h	Sat Jul 28 17:34:11 2012 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl.h	Sat Jul 28 17:36:27 2012 +0300
@@ -61,6 +61,9 @@
 			  const char *key_source, EVP_PKEY **pkey_r);
 const char *ssl_iostream_get_use_certificate_error(const char *cert);
 int openssl_cert_match_name(SSL *ssl, const char *verify_name);
+int openssl_get_protocol_options(const char *protocols);
+#define OPENSSL_ALL_PROTOCOL_OPTIONS \
+	(SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1)
 
 /* Sync plain_input/plain_output streams with BIOs. Returns TRUE if at least
    one byte was read/written. */
diff -r 76d492963638 -r 69626d2ce3f0 src/lib-ssl-iostream/iostream-ssl.h
--- a/src/lib-ssl-iostream/iostream-ssl.h	Sat Jul 28 17:34:11 2012 +0300
+++ b/src/lib-ssl-iostream/iostream-ssl.h	Sat Jul 28 17:36:27 2012 +0300
@@ -5,17 +5,18 @@
 struct ssl_iostream_context;
 
 struct ssl_iostream_settings {
+	const char *protocols;
 	const char *cipher_list;
-	const char *ca, *ca_dir;
+	const char *ca, *ca_dir; /* context-only */
 	const char *cert;
 	const char *key;
 	const char *key_password;
 	const char *cert_username_field;
-	const char *crypto_device;
+	const char *crypto_device; /* context-only */
 
-	bool verbose, verbose_invalid_cert;
-	bool verify_remote_cert;
-	bool require_valid_cert;
+	bool verbose, verbose_invalid_cert; /* stream-only */
+	bool verify_remote_cert; /* neither/both */
+	bool require_valid_cert; /* stream-only */
 };
 
 int io_stream_create_ssl(struct ssl_iostream_context *ctx, const char *source,


More information about the dovecot-cvs mailing list