I don't remember anymore if this is actually a useful patch for someone,
or if it's just the beginnings of change to move SSL cert verification into
dovecot-auth. As it is, it doesn't look really useful.

Index: lib-auth/auth-client.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-auth/auth-client.h,v
retrieving revision 1.12
diff -u -r1.12 auth-client.h
--- lib-auth/auth-client.h	14 Jan 2006 18:47:23 -0000	1.12
+++ lib-auth/auth-client.h	15 Jan 2006 14:11:17 -0000
@@ -8,8 +8,7 @@
 struct auth_request;
 
 enum auth_request_flags {
-	AUTH_REQUEST_FLAG_SECURED		= 0x01,
-	AUTH_REQUEST_FLAG_VALID_CLIENT_CERT	= 0x02,
+	AUTH_REQUEST_FLAG_SECURED		= 0x01
 };
 
 struct auth_mech_desc {
@@ -25,7 +24,7 @@
 struct auth_request_info {
 	const char *mech;
 	const char *service;
-	const char *cert_username;
+	const char *cert;
 	enum auth_request_flags flags;
 
 	struct ip_addr local_ip, remote_ip;
Index: lib-auth/auth-server-request.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-auth/auth-server-request.c,v
retrieving revision 1.25
diff -u -r1.25 auth-server-request.c
--- lib-auth/auth-server-request.c	14 Jan 2006 18:47:23 -0000	1.25
+++ lib-auth/auth-server-request.c	15 Jan 2006 14:11:17 -0000
@@ -15,7 +15,7 @@
 
 	unsigned int id;
 
-	char *mech, *service, *cert_username;
+	char *mech, *service, *cert;
         enum auth_request_flags flags;
 	struct ip_addr local_ip, remote_ip;
 
@@ -67,19 +67,6 @@
 	}
 }
 
-static bool is_valid_string(const char *str)
-{
-	const char *p;
-
-	/* make sure we're not sending any characters that have a special
-	   meaning. */
-	for (p = str; *p != '\0'; p++) {
-		if (*p == '\t' || *p == '\n' || *p == '\r')
-			return FALSE;
-	}
-	return TRUE;
-}
-
 static bool auth_server_send_new_request(struct auth_server_connection *conn,
 					 struct auth_request *request)
 {
@@ -93,22 +80,15 @@
 		    request->id, request->mech, request->service);
 	if ((request->flags & AUTH_REQUEST_FLAG_SECURED) != 0)
 		str_append(str, "\tsecured");
-	if ((request->flags & AUTH_REQUEST_FLAG_VALID_CLIENT_CERT) != 0)
-		str_append(str, "\tvalid-client-cert");
 
-	if (request->cert_username != NULL) {
-		if (!is_valid_string(request->cert_username)) {
-			t_pop();
-			return FALSE;
-		}
-		str_printfa(str, "\tcert_username=%s", request->cert_username);
-	}
 	if (request->local_ip.family != 0)
 		str_printfa(str, "\tlip=%s", net_ip2addr(&request->local_ip));
 	if (request->remote_ip.family != 0)
 		str_printfa(str, "\trip=%s", net_ip2addr(&request->remote_ip));
 	if (request->initial_resp_base64 != NULL)
 		str_printfa(str, "\tresp=%s", request->initial_resp_base64);
+	if (request->cert != NULL)
+		str_printfa(str, "\tcert=%s", request->cert);
 	str_append_c(str, '\n');
 
 	ret = o_stream_send(conn->output, str_data(str), str_len(str));
@@ -329,7 +309,7 @@
 	request->conn = conn;
 	request->mech = i_strdup(request_info->mech);
 	request->service = i_strdup(request_info->service);
-	request->cert_username = i_strdup(request_info->cert_username);
+	request->cert = i_strdup(request_info->cert);
 	request->flags = request_info->flags;
 	request->local_ip = request_info->local_ip;
 	request->remote_ip = request_info->remote_ip;
@@ -367,7 +347,7 @@
 	i_free(request->plaintext_data);
 	i_free(request->mech);
 	i_free(request->service);
-	i_free(request->cert_username);
+	i_free(request->cert);
 	i_free(request);
 }
 
Index: login-common/sasl-server.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/login-common/sasl-server.c,v
retrieving revision 1.10
diff -u -r1.10 sasl-server.c
--- login-common/sasl-server.c	13 Jan 2006 20:26:39 -0000	1.10
+++ login-common/sasl-server.c	15 Jan 2006 14:11:17 -0000
@@ -3,6 +3,7 @@
 #include "common.h"
 #include "base64.h"
 #include "buffer.h"
+#include "str.h"
 #include "str-sanitize.h"
 #include "auth-client.h"
 #include "ssl-proxy.h"
@@ -14,9 +15,6 @@
 {
         enum auth_request_flags auth_flags = 0;
 
-	if (client->proxy != NULL &&
-	    ssl_proxy_has_valid_client_cert(client->proxy))
-		auth_flags |= AUTH_REQUEST_FLAG_VALID_CLIENT_CERT;
 	if (client->secured)
 		auth_flags |= AUTH_REQUEST_FLAG_SECURED;
 	return auth_flags;
@@ -103,6 +101,28 @@
 	}
 }
 
+static const char *get_client_cert(struct client *client)
+{
+	buffer_t *buf;
+	string_t *str;
+
+	if (client->proxy == NULL ||
+	    !ssl_proxy_has_valid_client_cert(client->proxy))
+		return NULL;
+
+	buf = buffer_create_dynamic(default_pool, 1024);
+	if (!ssl_proxy_get_client_cert(client->proxy, buf)) {
+		buffer_free(buf);
+		return NULL;
+	}
+
+	/* okay, we have the certificate. now we need it base64 encoded */
+	str = t_str_new(MAX_BASE64_ENCODED_SIZE(buf->used));
+	base64_encode(buf->data, buf->used, str);
+	buffer_free(buf);
+	return str_c(str);
+}
+
 void sasl_server_auth_begin(struct client *client,
 			    const char *service, const char *mech_name,
 			    const char *initial_resp_base64,
@@ -134,12 +154,11 @@
 	memset(&info, 0, sizeof(info));
 	info.mech = mech->name;
 	info.service = service;
-	info.cert_username = client->proxy == NULL ? NULL :
-		ssl_proxy_get_peer_name(client->proxy);
 	info.flags = client_get_auth_flags(client);
 	info.local_ip = client->local_ip;
 	info.remote_ip = client->ip;
 	info.initial_resp_base64 = initial_resp_base64;
+	info.cert = get_client_cert(client);
 
 	client->auth_request =
 		auth_client_request_new(auth_client, NULL, &info,
Index: login-common/ssl-proxy-openssl.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/login-common/ssl-proxy-openssl.c,v
retrieving revision 1.34
diff -u -r1.34 ssl-proxy-openssl.c
--- login-common/ssl-proxy-openssl.c	15 Jan 2006 13:16:53 -0000	1.34
+++ login-common/ssl-proxy-openssl.c	15 Jan 2006 14:11:17 -0000
@@ -495,24 +495,27 @@
 	return proxy->cert_received && !proxy->cert_broken;
 }
 
-const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy)
+bool ssl_proxy_get_client_cert(struct ssl_proxy *proxy, buffer_t *buffer)
 {
 	X509 *x509;
 	char buf[1024];
 	const char *name;
+	int len, len2;
 
 	if (!ssl_proxy_has_valid_client_cert(proxy))
-		return NULL;
+		return FALSE;
 
 	x509 = SSL_get_peer_certificate(proxy->ssl);
 	if (x509 == NULL)
-		return NULL; /* we should have had it.. */
+		return FALSE; /* we should have had it.. */
 
-	X509_NAME_oneline(X509_get_subject_name(x509), buf, sizeof(buf));
-	name = t_strndup(buf, sizeof(buf));
-	X509_free(x509);
-
-	return *name == '\0' ? NULL : name;
+	len = i2d_X509(x509, NULL);
+	if (len < 0)
+		return FALSE;
+
+	len2 = i2d_X509(x509, buffer_append_space_unsafe(buffer, len));
+	i_assert(len == len2);
+	return TRUE;
 }
 
 void ssl_proxy_free(struct ssl_proxy *proxy)
Index: login-common/ssl-proxy.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/login-common/ssl-proxy.h,v
retrieving revision 1.6
diff -u -r1.6 ssl-proxy.h
--- login-common/ssl-proxy.h	13 Jan 2006 20:26:39 -0000	1.6
+++ login-common/ssl-proxy.h	15 Jan 2006 14:11:17 -0000
@@ -11,7 +11,7 @@
    the given fd must be simply forgotten. */
 int ssl_proxy_new(int fd, struct ip_addr *ip, struct ssl_proxy **proxy_r);
 bool ssl_proxy_has_valid_client_cert(struct ssl_proxy *proxy);
-const char *ssl_proxy_get_peer_name(struct ssl_proxy *proxy);
+bool ssl_proxy_get_client_cert(struct ssl_proxy *proxy, buffer_t *buffer);
 void ssl_proxy_free(struct ssl_proxy *proxy);
 
 void ssl_proxy_init(void);
