dovecot-2.2: lib-ssl-iostream now dynamically loads openssl libr...

dovecot at dovecot.org dovecot at dovecot.org
Tue Nov 6 01:04:47 EET 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/68d21f872fd7
changeset: 15379:68d21f872fd7
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Nov 06 01:04:24 2012 +0200
description:
lib-ssl-iostream now dynamically loads openssl library instead of linking to it.
This allowed removing the separate libdovecot-ssl library. In future if
GnuTLS/NSS support is added it would also allow switching between them
dynamically.

diffstat:

 configure.ac                                    |    6 +-
 src/auth/Makefile.am                            |    3 +-
 src/lib-dovecot/Makefile.am                     |   18 +-
 src/lib-master/Makefile.am                      |    6 +-
 src/lib-ssl-iostream/Makefile.am                |   21 +-
 src/lib-ssl-iostream/iostream-openssl-common.c  |  135 ++++++++++++
 src/lib-ssl-iostream/iostream-openssl-context.c |   98 ++------
 src/lib-ssl-iostream/iostream-openssl-params.c  |   14 +-
 src/lib-ssl-iostream/iostream-openssl.c         |  268 +++++++++--------------
 src/lib-ssl-iostream/iostream-openssl.h         |   40 ++-
 src/lib-ssl-iostream/iostream-ssl-private.h     |   40 +++
 src/lib-ssl-iostream/iostream-ssl.c             |  147 +++++++++++++
 src/lib-ssl-iostream/istream-openssl.c          |    6 +-
 src/lib-ssl-iostream/ostream-openssl.c          |   16 +-
 src/login-common/Makefile.am                    |    5 +
 15 files changed, 520 insertions(+), 303 deletions(-)

diffs (truncated from 1509 to 300 lines):

diff -r 94778985bb6a -r 68d21f872fd7 configure.ac
--- a/configure.ac	Mon Nov 05 18:16:56 2012 +0200
+++ b/configure.ac	Tue Nov 06 01:04:24 2012 +0200
@@ -2499,17 +2499,15 @@
   LIBDOVECOT="$LIBDOVECOT_DEPS"
   LIBDOVECOT_STORAGE_DEPS='$(top_builddir)/src/lib-storage/libdovecot-storage.la $(top_builddir)/src/lib-imap-storage/libimap-storage.la'
   LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/libdovecot-login.la'
-  LIBDOVECOT_SSL='$(top_builddir)/src/lib-master/libmaster_ssl.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la'
   LIBDOVECOT_COMPRESS='$(top_builddir)/src/lib-compression/libcompression.la'
   LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/libdovecot-lda.la'
 else
-  LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib-test/libtest.la $(top_builddir)/src/lib/liblib.la'
+  LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la $(top_builddir)/src/lib-test/libtest.la $(top_builddir)/src/lib/liblib.la'
   LIBDOVECOT="$LIBDOVECOT_DEPS \$(LIBICONV)"
   LIBDOVECOT_STORAGE_LAST='$(top_builddir)/src/lib-storage/list/libstorage_list.la $(top_builddir)/src/lib-storage/index/libstorage_index.la $(top_builddir)/src/lib-storage/libstorage.la $(top_builddir)/src/lib-index/libindex.la $(top_builddir)/src/lib-imap-storage/libimap-storage.la'
   LIBDOVECOT_STORAGE_FIRST='$(top_builddir)/src/lib-storage/libstorage_service.la $(top_builddir)/src/lib-storage/register/libstorage_register.la'
   LIBDOVECOT_STORAGE_DEPS="$LIBDOVECOT_STORAGE_FIRST $LINKED_STORAGE_LIBS $LIBDOVECOT_STORAGE_LAST"
-  LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la'
-  LIBDOVECOT_SSL='$(top_builddir)/src/lib-master/libmaster_ssl.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la'
+  LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la'
   LIBDOVECOT_COMPRESS='$(top_builddir)/src/lib-compression/libcompression.la'
   LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/liblda.la'
 fi
diff -r 94778985bb6a -r 68d21f872fd7 src/auth/Makefile.am
--- a/src/auth/Makefile.am	Mon Nov 05 18:16:56 2012 +0200
+++ b/src/auth/Makefile.am	Tue Nov 06 01:04:24 2012 +0200
@@ -176,8 +176,7 @@
 libauthdb_imap_la_LDFLAGS = -module -avoid-version
 libauthdb_imap_la_LIBADD = \
 	../lib-imap-client/libimap_client.la \
-	../lib-ssl-iostream/libssl_iostream.la \
-	$(LIBDOVECOT) $(SSL_LIBS)
+	$(LIBDOVECOT)
 libauthdb_imap_la_CPPFLAGS = \
 	$(AM_CPPFLAGS) \
 	-I$(top_srcdir)/src/lib-imap \
diff -r 94778985bb6a -r 68d21f872fd7 src/lib-dovecot/Makefile.am
--- a/src/lib-dovecot/Makefile.am	Mon Nov 05 18:16:56 2012 +0200
+++ b/src/lib-dovecot/Makefile.am	Tue Nov 06 01:04:24 2012 +0200
@@ -8,32 +8,18 @@
 	../lib-fs/libfs.la \
 	../lib-charset/libcharset.la \
 	../lib-master/libmaster.la \
+	../lib-ssl-iostream/libssl_iostream.la
 	../lib-test/libtest.la \
 	../lib/liblib.la
 
-ssl_libs = \
-	../lib-master/libmaster_ssl.la \
-	../lib-ssl-iostream/libssl_iostream.la
-
-pkglib_LTLIBRARIES = libdovecot.la libdovecot-ssl.la
+pkglib_LTLIBRARIES = libdovecot.la
 
 libdovecot_la_SOURCES = 
-libdovecot_ssl_la_SOURCES = 
 
 libdovecot_la_LIBADD = \
 	$(libs) \
 	$(MODULE_LIBS) \
 	$(LTLIBICONV)
 
-libdovecot_ssl_la_LIBADD = \
-	libdovecot.la \
-	../lib/liblib.la \
-	$(MODULE_LIBS) \
-	$(ssl_libs) \
-	$(SSL_LIBS)
-
 libdovecot_la_DEPENDENCIES = $(libs)
-libdovecot_ssl_la_DEPENDENCIES = $(ssl_libs) libdovecot.la
-
 libdovecot_la_LDFLAGS = -export-dynamic
-libdovecot_ssl_la_LDFLAGS = -export-dynamic
diff -r 94778985bb6a -r 68d21f872fd7 src/lib-master/Makefile.am
--- a/src/lib-master/Makefile.am	Mon Nov 05 18:16:56 2012 +0200
+++ b/src/lib-master/Makefile.am	Tue Nov 06 01:04:24 2012 +0200
@@ -1,6 +1,6 @@
 pkgsysconfdir = $(sysconfdir)/dovecot
 
-noinst_LTLIBRARIES = libmaster.la libmaster_ssl.la
+noinst_LTLIBRARIES = libmaster.la
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/lib \
@@ -22,13 +22,11 @@
 	master-service.c \
 	master-service-settings.c \
 	master-service-settings-cache.c \
+	master-service-ssl.c \
 	master-service-ssl-settings.c \
 	mountpoint-list.c \
 	syslog-util.c
 
-libmaster_ssl_la_SOURCES = \
-	master-service-ssl.c
-
 headers = \
 	anvil-client.h \
 	ipc-client.h \
diff -r 94778985bb6a -r 68d21f872fd7 src/lib-ssl-iostream/Makefile.am
--- a/src/lib-ssl-iostream/Makefile.am	Mon Nov 05 18:16:56 2012 +0200
+++ b/src/lib-ssl-iostream/Makefile.am	Tue Nov 06 01:04:24 2012 +0200
@@ -1,29 +1,34 @@
 noinst_LTLIBRARIES = libssl_iostream.la
 
+NOPLUGIN_LDFLAGS =
+
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/lib \
-	-I$(top_srcdir)/src/lib-test
+	-I$(top_srcdir)/src/lib-test \
+	-DMODULE_DIR=\""$(moduledir)"\"
 
 if BUILD_OPENSSL
-ssl_sources = \
+module_LTLIBRARIES = libssl_iostream_openssl.la
+
+libssl_iostream_openssl_la_LDFLAGS = -module -avoid-version
+libssl_iostream_openssl_la_LIBADD = $(SSL_LIBS)
+libssl_iostream_openssl_la_SOURCES = \
 	iostream-openssl.c \
+	iostream-openssl-common.c \
 	iostream-openssl-context.c \
 	iostream-openssl-params.c \
 	istream-openssl.c \
 	ostream-openssl.c
-else
-ssl_sources = \
-	iostream-ssl-none.c
 endif
 
 libssl_iostream_la_SOURCES = \
+	iostream-ssl.c \
 	$(ssl_sources)
-libssl_iostream_la_LIBADD = \
-	$(SSL_LIBS)
 
 headers = \
 	iostream-openssl.h \
-	iostream-ssl.h
+	iostream-ssl.h \
+	iostream-ssl-private.h
 
 pkginc_libdir=$(pkgincludedir)
 pkginc_lib_HEADERS = $(headers)
diff -r 94778985bb6a -r 68d21f872fd7 src/lib-ssl-iostream/iostream-openssl-common.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-ssl-iostream/iostream-openssl-common.c	Tue Nov 06 01:04:24 2012 +0200
@@ -0,0 +1,135 @@
+/* Copyright (c) 2009-2012 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "iostream-openssl.h"
+
+#include <openssl/x509v3.h>
+
+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 const char *asn1_string_to_c(ASN1_STRING *asn_str)
+{
+	const char *cstr;
+	unsigned int len;
+
+	len = ASN1_STRING_length(asn_str);
+	cstr = t_strndup(ASN1_STRING_data(asn_str), len);
+	if (strlen(cstr) != len) {
+		/* NULs in the name - could be some MITM attack.
+		   never allow. */
+		return "";
+	}
+	return cstr;
+}
+
+static const char *get_general_dns_name(const GENERAL_NAME *name)
+{
+	if (ASN1_STRING_type(name->d.ia5) != V_ASN1_IA5STRING)
+		return "";
+
+	return asn1_string_to_c(name->d.ia5);
+}
+
+static const char *get_cname(X509 *cert)
+{
+	X509_NAME *name;
+	X509_NAME_ENTRY *entry;
+	ASN1_STRING *str;
+	int cn_idx;
+
+	name = X509_get_subject_name(cert);
+	if (name == NULL)
+		return "";
+	cn_idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
+	if (cn_idx == -1)
+		return "";
+	entry = X509_NAME_get_entry(name, cn_idx);
+	i_assert(entry != NULL);
+	str = X509_NAME_ENTRY_get_data(entry);
+	i_assert(str != NULL);
+	return asn1_string_to_c(str);
+}
+
+int openssl_cert_match_name(SSL *ssl, const char *verify_name)
+{
+	X509 *cert;
+	STACK_OF(GENERAL_NAME) *gnames;
+	const GENERAL_NAME *gn;
+	const char *dnsname;
+	bool dns_names = FALSE;
+	unsigned int i, count;
+	int ret;
+
+	cert = SSL_get_peer_certificate(ssl);
+	i_assert(cert != NULL);
+
+	/* verify against SubjectAltNames */
+	gnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
+	count = gnames == NULL ? 0 : sk_GENERAL_NAME_num(gnames);
+	for (i = 0; i < count; i++) {
+		gn = sk_GENERAL_NAME_value(gnames, i);
+		if (gn->type == GEN_DNS) {
+			dns_names = TRUE;
+			dnsname = get_general_dns_name(gn);
+			if (strcmp(dnsname, verify_name) == 0)
+				break;
+		}
+	}
+	sk_GENERAL_NAME_pop_free(gnames, GENERAL_NAME_free);
+
+	/* verify against CommonName only when there wasn't any DNS
+	   SubjectAltNames */
+	if (dns_names)
+		ret = i < count ? 0 : -1;
+	else
+		ret = strcmp(get_cname(cert), verify_name) == 0 ? 0 : -1;
+	X509_free(cert);
+	return ret;
+}
diff -r 94778985bb6a -r 68d21f872fd7 src/lib-ssl-iostream/iostream-openssl-context.c
--- a/src/lib-ssl-iostream/iostream-openssl-context.c	Mon Nov 05 18:16:56 2012 +0200
+++ b/src/lib-ssl-iostream/iostream-openssl-context.c	Tue Nov 06 01:04:24 2012 +0200
@@ -23,7 +23,7 @@
 
 static void ssl_iostream_init_global(const struct ssl_iostream_settings *set);
 
-const char *ssl_iostream_error(void)
+const char *openssl_iostream_error(void)
 {
 	unsigned long err;
 	char *buf;
@@ -44,7 +44,7 @@
 	return buf;
 }


More information about the dovecot-cvs mailing list