[dovecot-cvs] dovecot/src/login-common client-common.h, 1.4, 1.5 main.c, 1.15, 1.16 ssl-proxy-openssl.c, 1.22, 1.23 ssl-proxy.h, 1.2, 1.3

cras at procontrol.fi cras at procontrol.fi
Mon May 17 04:32:19 EEST 2004


Update of /home/cvs/dovecot/src/login-common
In directory talvi:/tmp/cvs-serv3177/src/login-common

Modified Files:
	client-common.h main.c ssl-proxy-openssl.c ssl-proxy.h 
Log Message:
Added ssl_require_client_cert auth-specific setting. Hide
ssl_verify_client_cert from default config file as it's automatically set if
needed and there's not much point in forcing it.



Index: client-common.h
===================================================================
RCS file: /home/cvs/dovecot/src/login-common/client-common.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- client-common.h	22 Aug 2003 02:42:13 -0000	1.4
+++ client-common.h	17 May 2004 01:32:17 -0000	1.5
@@ -6,6 +6,7 @@
 
 struct client {
 	struct ip_addr ip;
+	struct ssl_proxy *proxy;
 
 	int fd;
 	struct io *io;

Index: main.c
===================================================================
RCS file: /home/cvs/dovecot/src/login-common/main.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- main.c	10 May 2004 16:05:10 -0000	1.15
+++ main.c	17 May 2004 01:32:17 -0000	1.16
@@ -95,6 +95,8 @@
 static void login_accept_ssl(void *context __attr_unused__)
 {
 	struct ip_addr ip;
+	struct client *client;
+	struct ssl_proxy *proxy;
 	int fd, fd_ssl;
 
 	fd = net_accept(LOGIN_SSL_LISTEN_FD, &ip, NULL);
@@ -107,11 +109,13 @@
 	if (process_per_connection)
 		main_close_listen();
 
-	fd_ssl = ssl_proxy_new(fd, &ip);
+	fd_ssl = ssl_proxy_new(fd, &ip, &proxy);
 	if (fd_ssl == -1)
 		net_disconnect(fd);
-	else
-		(void)client_create(fd_ssl, &ip, TRUE);
+	else {
+		client = client_create(fd_ssl, &ip, TRUE);
+		client->proxy = proxy;
+	}
 }
 
 static void auth_connect_notify(struct auth_client *client __attr_unused__,
@@ -213,6 +217,8 @@
 {
 	const char *name, *group_name;
 	struct ip_addr ip;
+	struct ssl_proxy *proxy = NULL;
+	struct client *client;
 	int i, fd = -1, master_fd = -1;
 
 	is_inetd = getenv("DOVECOT_MASTER") == NULL;
@@ -258,7 +264,7 @@
 		fd = 1;
 		for (i = 1; i < argc; i++) {
 			if (strcmp(argv[i], "--ssl") == 0) {
-				fd = ssl_proxy_new(fd, &ip);
+				fd = ssl_proxy_new(fd, &ip, &proxy);
 				if (fd == -1)
 					i_fatal("SSL initialization failed");
 			} else if (strncmp(argv[i], "--group=", 8) != 0)
@@ -269,8 +275,10 @@
 		closing_down = TRUE;
 	}
 
-	if (fd != -1)
-		(void)client_create(fd, &ip, TRUE);
+	if (fd != -1) {
+		client = client_create(fd, &ip, TRUE);
+		client->proxy = proxy;
+	}
 
 	io_loop_run(ioloop);
 	main_deinit();

Index: ssl-proxy-openssl.c
===================================================================
RCS file: /home/cvs/dovecot/src/login-common/ssl-proxy-openssl.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- ssl-proxy-openssl.c	10 May 2004 20:05:30 -0000	1.22
+++ ssl-proxy-openssl.c	17 May 2004 01:32:17 -0000	1.23
@@ -41,8 +41,11 @@
 
 	unsigned int handshaked:1;
 	unsigned int destroyed:1;
+	unsigned int cert_received:1;
+	unsigned int cert_broken:1;
 };
 
+static int extdata_index;
 static SSL_CTX *ssl_ctx;
 static struct hash_table *ssl_proxies;
 
@@ -308,12 +311,14 @@
 	ssl_proxy_unref(proxy);
 }
 
-int ssl_proxy_new(int fd, struct ip_addr *ip)
+int ssl_proxy_new(int fd, struct ip_addr *ip, struct ssl_proxy **proxy_r)
 {
 	struct ssl_proxy *proxy;
 	SSL *ssl;
 	int sfd[2];
 
+	*proxy_r = NULL;
+
 	if (!ssl_initialized)
 		return -1;
 
@@ -340,26 +345,32 @@
 	net_set_nonblock(fd, TRUE);
 
 	proxy = i_new(struct ssl_proxy, 1);
-	proxy->refcount = 1;
+	proxy->refcount = 2;
 	proxy->ssl = ssl;
 	proxy->fd_ssl = fd;
 	proxy->fd_plain = sfd[0];
 	proxy->ip = *ip;
+        SSL_set_ex_data(ssl, extdata_index, proxy);
 
 	hash_insert(ssl_proxies, proxy, proxy);
 
-	proxy->refcount++;
 	ssl_handshake(proxy);
-	if (!ssl_proxy_unref(proxy)) {
-		/* handshake failed. return the disconnected socket anyway
-		   so the caller doesn't try to use the old closed fd */
-		return sfd[1];
-	}
-
         main_ref();
+
+	*proxy_r = proxy;
 	return sfd[1];
 }
 
+int ssl_proxy_has_valid_client_cert(struct ssl_proxy *proxy)
+{
+	return proxy->cert_received && !proxy->cert_broken;
+}
+
+void ssl_proxy_free(struct ssl_proxy *proxy)
+{
+	ssl_proxy_unref(proxy);
+}
+
 static int ssl_proxy_unref(struct ssl_proxy *proxy)
 {
 	if (--proxy->refcount > 0)
@@ -401,6 +412,22 @@
 	return RSA_generate_key(keylength, RSA_F4, NULL, NULL);
 }
 
+static int ssl_verify_client_cert(int preverify_ok, X509_STORE_CTX *ctx)
+{
+	SSL *ssl;
+        struct ssl_proxy *proxy;
+
+	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 (!preverify_ok)
+		proxy->cert_broken = TRUE;
+
+	return 1;
+}
+
 void ssl_proxy_init(void)
 {
 	const char *cafile, *certfile, *keyfile, *paramfile, *cipher_list;
@@ -419,6 +446,8 @@
 	SSL_library_init();
 	SSL_load_error_strings();
 
+	extdata_index = SSL_get_ex_new_index(0, "dovecot", NULL, NULL, NULL);
+
 	if ((ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
 		i_fatal("SSL_CTX_new() failed");
 
@@ -455,8 +484,8 @@
 
 	if (getenv("SSL_VERIFY_CLIENT_CERT") != NULL) {
 		SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER |
-				   SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
-				   SSL_VERIFY_CLIENT_ONCE, NULL);
+				   SSL_VERIFY_CLIENT_ONCE,
+				   ssl_verify_client_cert);
 	}
 
 	/* PRNG initialization might want to use /dev/urandom, make sure it

Index: ssl-proxy.h
===================================================================
RCS file: /home/cvs/dovecot/src/login-common/ssl-proxy.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ssl-proxy.h	23 Feb 2003 19:44:47 -0000	1.2
+++ ssl-proxy.h	17 May 2004 01:32:17 -0000	1.3
@@ -2,13 +2,16 @@
 #define __SSL_PROXY_H
 
 struct ip_addr;
+struct ssl_proxy;
 
 extern int ssl_initialized;
 
 /* establish SSL connection with the given fd, returns a new fd which you
    must use from now on, or -1 if error occured. Unless -1 is returned,
    the given fd must be simply forgotten. */
-int ssl_proxy_new(int fd, struct ip_addr *ip);
+int ssl_proxy_new(int fd, struct ip_addr *ip, struct ssl_proxy **proxy_r);
+int ssl_proxy_has_valid_client_cert(struct ssl_proxy *proxy);
+void ssl_proxy_free(struct ssl_proxy *proxy);
 
 void ssl_proxy_init(void);
 void ssl_proxy_deinit(void);



More information about the dovecot-cvs mailing list