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