dovecot-2.1: login proxy: Verify that remote hostname matches SS...

dovecot at dovecot.org dovecot at dovecot.org
Tue Nov 8 23:30:38 EET 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/7e3afd2252fd
changeset: 13675:7e3afd2252fd
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Nov 08 23:40:54 2011 +0200
description:
login proxy: Verify that remote hostname matches SSL cert, unless ssl=any-cert

diffstat:

 configure.in                            |   2 +-
 src/lib-ssl-iostream/iostream-openssl.c |  17 +++++++++++------
 src/lib-ssl-iostream/iostream-openssl.h |   1 +
 src/login-common/Makefile.am            |   3 ++-
 src/login-common/login-proxy.c          |  18 ++++++++++++------
 src/login-common/ssl-proxy-openssl.c    |   6 ++++++
 src/login-common/ssl-proxy.c            |   6 ++++++
 src/login-common/ssl-proxy.h            |   1 +
 8 files changed, 40 insertions(+), 14 deletions(-)

diffs (167 lines):

diff -r 439ba86c91fc -r 7e3afd2252fd configure.in
--- a/configure.in	Tue Nov 08 22:49:57 2011 +0200
+++ b/configure.in	Tue Nov 08 23:40:54 2011 +0200
@@ -2487,7 +2487,7 @@
   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'
   LIBDOVECOT_STORAGE_FIRST='$(top_builddir)/src/lib-storage/libstorage_service.la $(top_builddir)/src/lib-storage/register/libstorage_register.la'
   LIBDOVECOT_STORAGE="$LIBDOVECOT_STORAGE_FIRST $LINKED_STORAGE_LIBS $LIBDOVECOT_STORAGE_LAST"
-  LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la'
+  LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la'
   LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/liblda.la'
 fi
 LIBDOVECOT_SQL='$(top_builddir)/src/lib-sql/libsql.la'
diff -r 439ba86c91fc -r 7e3afd2252fd src/lib-ssl-iostream/iostream-openssl.c
--- a/src/lib-ssl-iostream/iostream-openssl.c	Tue Nov 08 22:49:57 2011 +0200
+++ b/src/lib-ssl-iostream/iostream-openssl.c	Tue Nov 08 23:40:54 2011 +0200
@@ -492,8 +492,7 @@
 	return asn1_string_to_c(str);
 }
 
-int ssl_iostream_cert_match_name(struct ssl_iostream *ssl_io,
-				 const char *verify_name)
+int openssl_cert_match_name(SSL *ssl, const char *verify_name)
 {
 	X509 *cert;
 	STACK_OF(GENERAL_NAME) *gnames;
@@ -502,10 +501,7 @@
 	bool dns_names = FALSE;
 	unsigned int i, count;
 
-	if (!ssl_iostream_has_valid_client_cert(ssl_io))
-		return -1;
-
-	cert = SSL_get_peer_certificate(ssl_io->ssl);
+	cert = SSL_get_peer_certificate(ssl);
 	i_assert(cert != NULL);
 
 	/* verify against SubjectAltNames */
@@ -529,6 +525,15 @@
 	return strcmp(get_cname(cert), verify_name) == 0 ? 0 : -1;
 }
 
+int ssl_iostream_cert_match_name(struct ssl_iostream *ssl_io,
+				 const char *verify_name)
+{
+	if (!ssl_iostream_has_valid_client_cert(ssl_io))
+		return -1;
+
+	return openssl_cert_match_name(ssl_io->ssl, verify_name);
+}
+
 int ssl_iostream_handshake(struct ssl_iostream *ssl_io)
 {
 	int ret;
diff -r 439ba86c91fc -r 7e3afd2252fd src/lib-ssl-iostream/iostream-openssl.h
--- a/src/lib-ssl-iostream/iostream-openssl.h	Tue Nov 08 22:49:57 2011 +0200
+++ b/src/lib-ssl-iostream/iostream-openssl.h	Tue Nov 08 23:40:54 2011 +0200
@@ -60,6 +60,7 @@
 int ssl_iostream_load_key(const struct ssl_iostream_settings *set,
 			  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);
 
 /* Sync plain_input/plain_output streams with BIOs. Returns TRUE if at least
    one byte was read/written. */
diff -r 439ba86c91fc -r 7e3afd2252fd src/login-common/Makefile.am
--- a/src/login-common/Makefile.am	Tue Nov 08 22:49:57 2011 +0200
+++ b/src/login-common/Makefile.am	Tue Nov 08 23:40:54 2011 +0200
@@ -6,6 +6,7 @@
 	-I$(top_srcdir)/src/lib-auth \
 	-I$(top_srcdir)/src/lib-dns \
 	-I$(top_srcdir)/src/lib-master \
+	-I$(top_srcdir)/src/lib-ssl-iostream \
 	-DPKG_STATEDIR=\""$(statedir)"\"
 
 liblogin_la_SOURCES = \
@@ -39,6 +40,6 @@
 
 pkglib_LTLIBRARIES = libdovecot-login.la
 libdovecot_login_la_SOURCES = 
-libdovecot_login_la_LIBADD = liblogin.la ../lib-dovecot/libdovecot.la
+libdovecot_login_la_LIBADD = liblogin.la ../lib-ssl-iostream/libssl_iostream.la ../lib-dovecot/libdovecot.la
 libdovecot_login_la_DEPENDENCIES = liblogin.la
 libdovecot_login_la_LDFLAGS = -export-dynamic
diff -r 439ba86c91fc -r 7e3afd2252fd src/login-common/login-proxy.c
--- a/src/login-common/login-proxy.c	Tue Nov 08 22:49:57 2011 +0200
+++ b/src/login-common/login-proxy.c	Tue Nov 08 23:40:54 2011 +0200
@@ -507,18 +507,24 @@
 {
 	struct login_proxy *proxy = context;
 
-	if ((proxy->ssl_flags & PROXY_SSL_FLAG_ANY_CERT) != 0 ||
-	    ssl_proxy_has_valid_client_cert(proxy->ssl_server_proxy))
+	if ((proxy->ssl_flags & PROXY_SSL_FLAG_ANY_CERT) != 0)
 		return 0;
 
-	if (!ssl_proxy_has_broken_client_cert(proxy->ssl_server_proxy)) {
+	if (ssl_proxy_has_broken_client_cert(proxy->ssl_server_proxy)) {
+		client_log_err(proxy->client, t_strdup_printf(
+			"proxy: Received invalid SSL certificate from %s:%u",
+			proxy->host, proxy->port));
+	} else if (!ssl_proxy_has_valid_client_cert(proxy->ssl_server_proxy)) {
 		client_log_err(proxy->client, t_strdup_printf(
 			"proxy: SSL certificate not received from %s:%u",
 			proxy->host, proxy->port));
+	} else if (ssl_proxy_cert_match_name(proxy->ssl_server_proxy,
+					     proxy->host) < 0) {
+		client_log_err(proxy->client, t_strdup_printf(
+			"proxy: hostname doesn't match SSL certificate at %s:%u",
+			proxy->host, proxy->port));
 	} else {
-		client_log_err(proxy->client, t_strdup_printf(
-			"proxy: Received invalid SSL certificate from %s:%u",
-			proxy->host, proxy->port));
+		return 0;
 	}
 	proxy->disconnecting = TRUE;
 	return -1;
diff -r 439ba86c91fc -r 7e3afd2252fd src/login-common/ssl-proxy-openssl.c
--- a/src/login-common/ssl-proxy-openssl.c	Tue Nov 08 22:49:57 2011 +0200
+++ b/src/login-common/ssl-proxy-openssl.c	Tue Nov 08 23:40:54 2011 +0200
@@ -19,6 +19,7 @@
 
 #ifdef HAVE_OPENSSL
 
+#include "iostream-openssl.h"
 #include <openssl/crypto.h>
 #include <openssl/x509.h>
 #include <openssl/pem.h>
@@ -665,6 +666,11 @@
 	return proxy->cert_received && proxy->cert_broken;
 }
 
+int ssl_proxy_cert_match_name(struct ssl_proxy *proxy, const char *verify_name)
+{
+	return openssl_cert_match_name(proxy->ssl, verify_name);
+}
+
 const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy)
 {
 	X509 *x509;
diff -r 439ba86c91fc -r 7e3afd2252fd src/login-common/ssl-proxy.c
--- a/src/login-common/ssl-proxy.c	Tue Nov 08 22:49:57 2011 +0200
+++ b/src/login-common/ssl-proxy.c	Tue Nov 08 23:40:54 2011 +0200
@@ -46,6 +46,12 @@
 	return FALSE;
 }
 
+int ssl_proxy_cert_match_name(struct ssl_proxy *proxy ATTR_UNUSED,
+			      const char *verify_name ATTR_UNUSED)
+{
+	return -1;
+}
+
 const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy ATTR_UNUSED)
 {
 	return NULL;
diff -r 439ba86c91fc -r 7e3afd2252fd src/login-common/ssl-proxy.h
--- a/src/login-common/ssl-proxy.h	Tue Nov 08 22:49:57 2011 +0200
+++ b/src/login-common/ssl-proxy.h	Tue Nov 08 23:40:54 2011 +0200
@@ -24,6 +24,7 @@
 void ssl_proxy_set_client(struct ssl_proxy *proxy, struct client *client);
 bool ssl_proxy_has_valid_client_cert(const struct ssl_proxy *proxy) ATTR_PURE;
 bool ssl_proxy_has_broken_client_cert(struct ssl_proxy *proxy);
+int ssl_proxy_cert_match_name(struct ssl_proxy *proxy, const char *verify_name);
 const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy);
 bool ssl_proxy_is_handshaked(const struct ssl_proxy *proxy) ATTR_PURE;
 const char *ssl_proxy_get_last_error(const struct ssl_proxy *proxy) ATTR_PURE;


More information about the dovecot-cvs mailing list