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