dovecot-2.2: Added ssl_client_ca_file to specify the CA certs as...

dovecot at dovecot.org dovecot at dovecot.org
Sun Apr 7 20:28:53 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/f0c997709b4d
changeset: 16232:f0c997709b4d
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Apr 07 20:28:31 2013 +0300
description:
Added ssl_client_ca_file to specify the CA certs as a file instead of as a dir.
This is required for Redhat-based systems where there isn't a CA directory
like in Debian/Ubuntu.

diffstat:

 src/doveadm/doveadm-fs.c                        |   1 +
 src/doveadm/doveadm-settings.c                  |   2 +
 src/doveadm/doveadm-settings.h                  |   1 +
 src/doveadm/dsync/doveadm-dsync.c               |   1 +
 src/lib-http/http-client.c                      |   2 +
 src/lib-http/http-client.h                      |   2 +-
 src/lib-http/test-http-client.c                 |   3 +-
 src/lib-imap-client/imapc-client.c              |   2 +
 src/lib-imap-client/imapc-client.h              |   2 +-
 src/lib-ssl-iostream/iostream-openssl-context.c |  66 ++++++++++++++++--------
 src/lib-ssl-iostream/iostream-ssl.h             |   2 +-
 src/lib-storage/index/imapc/imapc-storage.c     |   1 +
 src/lib-storage/index/pop3c/pop3c-client.c      |   2 +
 src/lib-storage/index/pop3c/pop3c-client.h      |   2 +-
 src/lib-storage/index/pop3c/pop3c-storage.c     |   1 +
 src/lib-storage/mail-storage-settings.c         |   2 +
 src/lib-storage/mail-storage-settings.h         |   1 +
 17 files changed, 65 insertions(+), 28 deletions(-)

diffs (truncated from 304 to 300 lines):

diff -r de165567386d -r f0c997709b4d src/doveadm/doveadm-fs.c
--- a/src/doveadm/doveadm-fs.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/doveadm/doveadm-fs.c	Sun Apr 07 20:28:31 2013 +0300
@@ -24,6 +24,7 @@
 
 	memset(&ssl_set, 0, sizeof(ssl_set));
 	ssl_set.ca_dir = doveadm_settings->ssl_client_ca_dir;
+	ssl_set.ca_file = doveadm_settings->ssl_client_ca_file;
 	ssl_set.verbose = doveadm_debug;
 
 	memset(&fs_set, 0, sizeof(fs_set));
diff -r de165567386d -r f0c997709b4d src/doveadm/doveadm-settings.c
--- a/src/doveadm/doveadm-settings.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/doveadm/doveadm-settings.c	Sun Apr 07 20:28:31 2013 +0300
@@ -65,6 +65,7 @@
 	DEF(SET_STR, dsync_alt_char),
 	DEF(SET_STR, dsync_remote_cmd),
 	DEF(SET_STR, ssl_client_ca_dir),
+	DEF(SET_STR, ssl_client_ca_file),
 
 	{ SET_STRLIST, "plugin", offsetof(struct doveadm_settings, plugin_envs), NULL },
 
@@ -84,6 +85,7 @@
 	.dsync_alt_char = "_",
 	.dsync_remote_cmd = "ssh -l%{login} %{host} doveadm dsync-server -u%u -U",
 	.ssl_client_ca_dir = "",
+	.ssl_client_ca_file = "",
 
 	.plugin_envs = ARRAY_INIT
 };
diff -r de165567386d -r f0c997709b4d src/doveadm/doveadm-settings.h
--- a/src/doveadm/doveadm-settings.h	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/doveadm/doveadm-settings.h	Sun Apr 07 20:28:31 2013 +0300
@@ -14,6 +14,7 @@
 	const char *dsync_alt_char;
 	const char *dsync_remote_cmd;
 	const char *ssl_client_ca_dir;
+	const char *ssl_client_ca_file;
 
 	ARRAY(const char *) plugin_envs;
 };
diff -r de165567386d -r f0c997709b4d src/doveadm/dsync/doveadm-dsync.c
--- a/src/doveadm/dsync/doveadm-dsync.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/doveadm/dsync/doveadm-dsync.c	Sun Apr 07 20:28:31 2013 +0300
@@ -619,6 +619,7 @@
 
 	memset(&ssl_set, 0, sizeof(ssl_set));
 	ssl_set.ca_dir = mail_set->ssl_client_ca_dir;
+	ssl_set.ca_file = mail_set->ssl_client_ca_file;
 	ssl_set.verify_remote_cert = TRUE;
 	ssl_set.crypto_device = mail_set->ssl_crypto_device;
 
diff -r de165567386d -r f0c997709b4d src/lib-http/http-client.c
--- a/src/lib-http/http-client.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-http/http-client.c	Sun Apr 07 20:28:31 2013 +0300
@@ -82,6 +82,7 @@
 	if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0')
 		client->set.rawlog_dir = p_strdup(pool, set->rawlog_dir);
 	client->set.ssl_ca_dir = p_strdup(pool, set->ssl_ca_dir);
+	client->set.ssl_ca_file = p_strdup(pool, set->ssl_ca_file);
 	client->set.ssl_ca = p_strdup(pool, set->ssl_ca);
 	client->set.ssl_crypto_device = p_strdup(pool, set->ssl_crypto_device);
 	client->set.ssl_allow_invalid_cert = set->ssl_allow_invalid_cert;
@@ -192,6 +193,7 @@
 
 	memset(&ssl_set, 0, sizeof(ssl_set));
 	ssl_set.ca_dir = client->set.ssl_ca_dir;
+	ssl_set.ca_file = client->set.ssl_ca_file;
 	ssl_set.ca = client->set.ssl_ca;
 	ssl_set.verify_remote_cert = TRUE;
 	ssl_set.crypto_device = client->set.ssl_crypto_device;
diff -r de165567386d -r f0c997709b4d src/lib-http/http-client.h
--- a/src/lib-http/http-client.h	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-http/http-client.h	Sun Apr 07 20:28:31 2013 +0300
@@ -33,7 +33,7 @@
 struct http_client_settings {
 	const char *dns_client_socket_path;
 
-	const char *ssl_ca_dir, *ssl_ca;
+	const char *ssl_ca_dir, *ssl_ca_file, *ssl_ca;
 	const char *ssl_crypto_device;
 	bool ssl_allow_invalid_cert;
 
diff -r de165567386d -r f0c997709b4d src/lib-http/test-http-client.c
--- a/src/lib-http/test-http-client.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-http/test-http-client.c	Sun Apr 07 20:28:31 2013 +0300
@@ -329,7 +329,8 @@
 	memset(&http_set, 0, sizeof(http_set));
 	http_set.dns_client_socket_path = "/var/run/dovecot/dns-client";
 	http_set.ssl_allow_invalid_cert = TRUE;
-	http_set.ssl_ca_dir = "/etc/ssl/certs";
+	http_set.ssl_ca_dir = "/etc/ssl/certs"; /* debian */
+	http_set.ssl_ca_file = "/etc/pki/tls/cert.pem"; /* redhat */
 	http_set.max_idle_time_msecs = 5*1000;
 	http_set.max_parallel_connections = 4;
 	http_set.max_pipelined_requests = 4;
diff -r de165567386d -r f0c997709b4d src/lib-imap-client/imapc-client.c
--- a/src/lib-imap-client/imapc-client.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-imap-client/imapc-client.c	Sun Apr 07 20:28:31 2013 +0300
@@ -63,10 +63,12 @@
 	if (set->ssl_mode != IMAPC_CLIENT_SSL_MODE_NONE) {
 		client->set.ssl_mode = set->ssl_mode;
 		client->set.ssl_ca_dir = p_strdup(pool, set->ssl_ca_dir);
+		client->set.ssl_ca_file = p_strdup(pool, set->ssl_ca_file);
 		client->set.ssl_verify = set->ssl_verify;
 
 		memset(&ssl_set, 0, sizeof(ssl_set));
 		ssl_set.ca_dir = set->ssl_ca_dir;
+		ssl_set.ca_file = set->ssl_ca_file;
 		ssl_set.verify_remote_cert = set->ssl_verify;
 		ssl_set.crypto_device = set->ssl_crypto_device;
 
diff -r de165567386d -r f0c997709b4d src/lib-imap-client/imapc-client.h
--- a/src/lib-imap-client/imapc-client.h	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-imap-client/imapc-client.h	Sun Apr 07 20:28:31 2013 +0300
@@ -62,7 +62,7 @@
 	const char *temp_path_prefix;
 
 	enum imapc_client_ssl_mode ssl_mode;
-	const char *ssl_ca_dir;
+	const char *ssl_ca_dir, *ssl_ca_file;
 	bool ssl_verify;
 
 	const char *rawlog_dir;
diff -r de165567386d -r f0c997709b4d src/lib-ssl-iostream/iostream-openssl-context.c
--- a/src/lib-ssl-iostream/iostream-openssl-context.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl-context.c	Sun Apr 07 20:28:31 2013 +0300
@@ -311,13 +311,51 @@
 #endif
 
 static int
+ssl_iostream_context_load_ca(struct ssl_iostream_context *ctx,
+			     const struct ssl_iostream_settings *set,
+			     const char **error_r)
+{
+	X509_STORE *store;
+	STACK_OF(X509_NAME) *xnames = NULL;
+	const char *ca_file, *ca_dir;
+	bool have_ca = FALSE;
+
+	if (set->ca != NULL) {
+		store = SSL_CTX_get_cert_store(ctx->ssl_ctx);
+		if (load_ca(store, set->ca, &xnames) < 0) {
+			*error_r = t_strdup_printf("Couldn't parse ssl_ca: %s",
+						   openssl_iostream_error());
+			return -1;
+		}
+		ssl_iostream_ctx_verify_remote_cert(ctx, xnames);
+		have_ca = TRUE;
+	}
+	ca_file = set->ca_file == NULL || *set->ca_file == '\0' ?
+		NULL : set->ca_file;
+	ca_dir = set->ca_dir == NULL || *set->ca_dir == '\0' ?
+		NULL : set->ca_dir;
+	if (ca_file != NULL || ca_dir != NULL) {
+		if (!SSL_CTX_load_verify_locations(ctx->ssl_ctx, ca_file, ca_dir)) {
+			*error_r = t_strdup_printf(
+				"Can't load CA certs from directory %s: %s",
+				set->ca_dir, openssl_iostream_error());
+			return -1;
+		}
+		have_ca = TRUE;
+	}
+
+	if (!have_ca) {
+		*error_r = "Can't verify remote certs without CA";
+		return -1;
+	}
+	return 0;
+}
+
+static int
 ssl_iostream_context_set(struct ssl_iostream_context *ctx,
 			 const struct ssl_iostream_settings *set,
 			 const char **error_r)
 {
-	X509_STORE *store;
-	STACK_OF(X509_NAME) *xnames = NULL;
-
 	ctx->set = ssl_iostream_settings_dup(ctx->pool, set);
 	if (set->cipher_list != NULL &&
 	    !SSL_CTX_set_cipher_list(ctx->ssl_ctx, set->cipher_list)) {
@@ -342,27 +380,9 @@
 	}
 
 	/* set trusted CA certs */
-	if (!set->verify_remote_cert) {
-		/* no CA */
-	} else if (set->ca != NULL) {
-		store = SSL_CTX_get_cert_store(ctx->ssl_ctx);
-		if (load_ca(store, set->ca, &xnames) < 0) {
-			*error_r = t_strdup_printf("Couldn't parse ssl_ca: %s",
-						   openssl_iostream_error());
+	if (set->verify_remote_cert) {
+		if (ssl_iostream_context_load_ca(ctx, set, error_r) < 0)
 			return -1;
-		}
-		ssl_iostream_ctx_verify_remote_cert(ctx, xnames);
-	} else if (set->ca_dir != NULL) {
-		if (!SSL_CTX_load_verify_locations(ctx->ssl_ctx, NULL,
-						   set->ca_dir)) {
-			*error_r = t_strdup_printf(
-				"Can't load CA certs from directory %s: %s",
-				set->ca_dir, openssl_iostream_error());
-			return -1;
-		}
-	} else {
-		*error_r = "Can't verify remote certs without CA";
-		return -1;
 	}
 
 	if (set->cert_username_field != NULL) {
diff -r de165567386d -r f0c997709b4d src/lib-ssl-iostream/iostream-ssl.h
--- a/src/lib-ssl-iostream/iostream-ssl.h	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-ssl-iostream/iostream-ssl.h	Sun Apr 07 20:28:31 2013 +0300
@@ -7,7 +7,7 @@
 struct ssl_iostream_settings {
 	const char *protocols;
 	const char *cipher_list;
-	const char *ca, *ca_dir; /* context-only */
+	const char *ca, *ca_file, *ca_dir; /* context-only */
 	const char *cert;
 	const char *key;
 	const char *key_password;
diff -r de165567386d -r f0c997709b4d src/lib-storage/index/imapc/imapc-storage.c
--- a/src/lib-storage/index/imapc/imapc-storage.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Sun Apr 07 20:28:31 2013 +0300
@@ -251,6 +251,7 @@
 	set.temp_path_prefix = str_c(str);
 
 	set.ssl_ca_dir = _storage->set->ssl_client_ca_dir;
+	set.ssl_ca_file = _storage->set->ssl_client_ca_file;
 	set.ssl_verify = storage->set->imapc_ssl_verify;
 	if (strcmp(storage->set->imapc_ssl, "imaps") == 0)
 		set.ssl_mode = IMAPC_CLIENT_SSL_MODE_IMMEDIATE;
diff -r de165567386d -r f0c997709b4d src/lib-storage/index/pop3c/pop3c-client.c
--- a/src/lib-storage/index/pop3c/pop3c-client.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-storage/index/pop3c/pop3c-client.c	Sun Apr 07 20:28:31 2013 +0300
@@ -95,10 +95,12 @@
 	if (set->ssl_mode != POP3C_CLIENT_SSL_MODE_NONE) {
 		client->set.ssl_mode = set->ssl_mode;
 		client->set.ssl_ca_dir = p_strdup(pool, set->ssl_ca_dir);
+		client->set.ssl_ca_file = p_strdup(pool, set->ssl_ca_file);
 		client->set.ssl_verify = set->ssl_verify;
 
 		memset(&ssl_set, 0, sizeof(ssl_set));
 		ssl_set.ca_dir = set->ssl_ca_dir;
+		ssl_set.ca_file = set->ssl_ca_file;
 		ssl_set.verify_remote_cert = set->ssl_verify;
 		ssl_set.crypto_device = set->ssl_crypto_device;
 
diff -r de165567386d -r f0c997709b4d src/lib-storage/index/pop3c/pop3c-client.h
--- a/src/lib-storage/index/pop3c/pop3c-client.h	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-storage/index/pop3c/pop3c-client.h	Sun Apr 07 20:28:31 2013 +0300
@@ -31,7 +31,7 @@
 	const char *temp_path_prefix;
 
 	enum pop3c_client_ssl_mode ssl_mode;
-	const char *ssl_ca_dir;
+	const char *ssl_ca_dir, *ssl_ca_file;
 	bool ssl_verify;
 
 	const char *rawlog_dir;
diff -r de165567386d -r f0c997709b4d src/lib-storage/index/pop3c/pop3c-storage.c
--- a/src/lib-storage/index/pop3c/pop3c-storage.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-storage/index/pop3c/pop3c-storage.c	Sun Apr 07 20:28:31 2013 +0300
@@ -74,6 +74,7 @@
 		mail_user_home_expand(storage->user, set->pop3c_rawlog_dir);
 
 	client_set.ssl_ca_dir = storage->set->ssl_client_ca_dir;
+	client_set.ssl_ca_file = storage->set->ssl_client_ca_file;
 	client_set.ssl_verify = set->pop3c_ssl_verify;
 	if (strcmp(set->pop3c_ssl, "pop3s") == 0)
 		client_set.ssl_mode = POP3C_CLIENT_SSL_MODE_IMMEDIATE;
diff -r de165567386d -r f0c997709b4d src/lib-storage/mail-storage-settings.c
--- a/src/lib-storage/mail-storage-settings.c	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-storage/mail-storage-settings.c	Sun Apr 07 20:28:31 2013 +0300
@@ -54,6 +54,7 @@
 	DEF(SET_STR, pop3_uidl_format),
 
 	DEF(SET_STR, ssl_client_ca_dir),
+	DEF(SET_STR, ssl_client_ca_file),
 	DEF(SET_STR, ssl_crypto_device),
 
 	SETTING_DEFINE_LIST_END
@@ -89,6 +90,7 @@
 	.pop3_uidl_format = "%08Xu%08Xv",
 
 	.ssl_client_ca_dir = "",
+	.ssl_client_ca_file = "",
 	.ssl_crypto_device = ""
 };
 
diff -r de165567386d -r f0c997709b4d src/lib-storage/mail-storage-settings.h
--- a/src/lib-storage/mail-storage-settings.h	Sun Apr 07 20:06:42 2013 +0300
+++ b/src/lib-storage/mail-storage-settings.h	Sun Apr 07 20:28:31 2013 +0300
@@ -39,6 +39,7 @@
 	const char *pop3_uidl_format;
 
 	const char *ssl_client_ca_dir;


More information about the dovecot-cvs mailing list