changeset 14516:36cde186aec6

*-login: If client certificate isn't valid, log the reason why.
author Timo Sirainen <tss@iki.fi>
date Wed, 25 Apr 2012 21:28:16 +0300
parents 3893f2b7e4ab
children c2b7767afc38
files src/login-common/login-proxy.c src/login-common/ssl-proxy-openssl.c src/login-common/ssl-proxy.c src/login-common/ssl-proxy.h
diffstat 4 files changed, 38 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/login-common/login-proxy.c	Wed Apr 25 21:26:25 2012 +0300
+++ b/src/login-common/login-proxy.c	Wed Apr 25 21:28:16 2012 +0300
@@ -516,8 +516,9 @@
 
 	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));
+			"proxy: Received invalid SSL certificate from %s:%u: %s",
+			proxy->host, proxy->port,
+			ssl_proxy_get_cert_error(proxy->ssl_server_proxy)));
 	} 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",
--- a/src/login-common/ssl-proxy-openssl.c	Wed Apr 25 21:26:25 2012 +0300
+++ b/src/login-common/ssl-proxy-openssl.c	Wed Apr 25 21:28:16 2012 +0300
@@ -66,6 +66,7 @@
 	ssl_handshake_callback_t *handshake_callback;
 	void *handshake_context;
 
+	const char *cert_error;
 	char *last_error;
 	unsigned int handshaked:1;
 	unsigned int destroyed:1;
@@ -754,6 +755,12 @@
 #endif
 }
 
+const char *ssl_proxy_get_cert_error(struct ssl_proxy *proxy)
+{
+	return proxy->cert_error != NULL ? proxy->cert_error :
+		"(Unknown error)";
+}
+
 void ssl_proxy_free(struct ssl_proxy **_proxy)
 {
 	struct ssl_proxy *proxy = *_proxy;
@@ -849,32 +856,40 @@
 {
 	SSL *ssl;
         struct ssl_proxy *proxy;
+	char buf[1024];
+	X509_NAME *subject;
 
 	ssl = X509_STORE_CTX_get_ex_data(ctx,
 					 SSL_get_ex_data_X509_STORE_CTX_idx());
 	proxy = SSL_get_ex_data(ssl, extdata_index);
 	proxy->cert_received = TRUE;
 
-	if (proxy->set->verbose_ssl ||
-	    (proxy->set->auth_verbose && !preverify_ok)) {
-		char buf[1024];
-		X509_NAME *subject;
-
-		subject = X509_get_subject_name(ctx->current_cert);
-		(void)X509_NAME_oneline(subject, buf, sizeof(buf));
-		buf[sizeof(buf)-1] = '\0'; /* just in case.. */
-		if (!preverify_ok)
-			i_info("Invalid certificate: %s: %s", X509_verify_cert_error_string(ctx->error),buf);
-		else
-			i_info("Valid certificate: %s", buf);
-	}
-	if (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL && proxy->client_proxy) {
+	if (proxy->client_proxy && ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL) {
 		/* no CRL given with the CA list. don't worry about it. */
 		preverify_ok = 1;
 	}
 	if (!preverify_ok)
 		proxy->cert_broken = TRUE;
 
+	subject = X509_get_subject_name(ctx->current_cert);
+	(void)X509_NAME_oneline(subject, buf, sizeof(buf));
+	buf[sizeof(buf)-1] = '\0'; /* just in case.. */
+
+	if (proxy->cert_error == NULL) {
+		proxy->cert_error = p_strdup_printf(proxy->client->pool, "%s: %s",
+			X509_verify_cert_error_string(ctx->error), buf);
+	}
+
+	if (proxy->set->verbose_ssl ||
+	    (proxy->set->auth_verbose && !preverify_ok)) {
+		if (preverify_ok)
+			i_info("Valid certificate: %s", buf);
+		else {
+			i_info("Invalid certificate: %s: %s",
+			       X509_verify_cert_error_string(ctx->error), buf);
+		}
+	}
+
 	/* Return success anyway, because if ssl_require_client_cert=no we
 	   could still allow authentication. */
 	return 1;
--- a/src/login-common/ssl-proxy.c	Wed Apr 25 21:26:25 2012 +0300
+++ b/src/login-common/ssl-proxy.c	Wed Apr 25 21:28:16 2012 +0300
@@ -79,6 +79,11 @@
 	return NULL;
 }
 
+const char *ssl_proxy_get_cert_error(struct ssl_proxy *proxy ATTR_UNUSED)
+{
+	return "";
+}
+
 void ssl_proxy_free(struct ssl_proxy **proxy ATTR_UNUSED) {}
 
 unsigned int ssl_proxy_get_count(void)
--- a/src/login-common/ssl-proxy.h	Wed Apr 25 21:26:25 2012 +0300
+++ b/src/login-common/ssl-proxy.h	Wed Apr 25 21:28:16 2012 +0300
@@ -30,6 +30,7 @@
 const char *ssl_proxy_get_last_error(const struct ssl_proxy *proxy) ATTR_PURE;
 const char *ssl_proxy_get_security_string(struct ssl_proxy *proxy);
 const char *ssl_proxy_get_compression(struct ssl_proxy *proxy);
+const char *ssl_proxy_get_cert_error(struct ssl_proxy *proxy);
 void ssl_proxy_free(struct ssl_proxy **proxy);
 
 /* Return number of active SSL proxies */