Hello

I've updated my backend client certificates patch to work with 2.3.14.
Attached and at https://bugzilla.andrew.cmu.edu/show_bug.cgi?id=3133

I doing so, I added a few checks in the new MITM attack detection code
because the client segfaults if the server initially gives an empty mech
list (ie it wants the client to STARTTLS before offering EXTERNAL).

Also, I set mupdate_protocol.tls_cmd.auto_capa because the client needs
to re-parse the banner after STARTTLS to pick up EXTERNAL when using a
client cert.  I think this is harmless, and I know it's useless without
https://bugzilla.andrew.cmu.edu/show_bug.cgi?id=3119


Cheers


Duncan

-- 
Duncan Gibb - Technical Director
Sirius Corporation plc - control through freedom
http://www.siriusit.co.uk/ || t: +44 870 608 0063
Debian Cyrus Team - https://alioth.debian.org/projects/pkg-cyrus-imapd/
diff -Nrub cyrus-imapd-2.3.14/imap/backend.c cyrus-imapd-2.3.14_clientcerts/imap/backend.c
--- cyrus-imapd-2.3.14/imap/backend.c	2009-02-04 16:42:02.000000000 +0000
+++ cyrus-imapd-2.3.14_clientcerts/imap/backend.c	2009-04-25 15:51:27.000000000 +0100
@@ -134,7 +134,8 @@
     return ret;
 }
 
-static int do_starttls(struct backend *s, struct tls_cmd_t *tls_cmd)
+static int do_starttls(struct backend *s, struct tls_cmd_t *tls_cmd,
+			char *c_cert_file, char *c_key_file)
 {
 #ifndef HAVE_SSL
     return -1;
@@ -154,7 +155,7 @@
 	strncmp(buf, tls_cmd->ok, strlen(tls_cmd->ok)))
 	return -1;
 
-    r = tls_init_clientengine(5, "", "");
+    r = tls_init_clientengine(5, c_cert_file, c_key_file);
     if (r == -1) return -1;
 
     /* SASL and openssl have different ideas about whether ssf is signed */
@@ -190,6 +191,8 @@
     int local_cb = 0;
     char buf[2048], optstr[128], *p;
     const char *mech_conf, *pass;
+    char *c_cert_file = NULL;
+    char *c_key_file = NULL;
 
     if (!cb) {
 	local_cb = 1;
@@ -244,6 +247,26 @@
 	mech_conf = config_getstring(IMAPOPT_FORCE_SASL_CLIENT_MECH);
     }
 
+#ifdef HAVE_SSL
+    strlcpy(optstr, s->hostname, sizeof(optstr));
+    p = strchr(optstr, '.');
+    if (p) *p = '\0';
+    strlcat(optstr, "_tls_client_cert_file", sizeof(optstr));
+    c_cert_file = config_getoverflowstring(optstr, NULL);
+    if(!c_cert_file) {
+	c_cert_file = config_getstring(IMAPOPT_TLS_CLIENT_CERT_FILE);
+    }
+
+    strlcpy(optstr, s->hostname, sizeof(optstr));
+    p = strchr(optstr, '.');
+    if (p) *p = '\0';
+    strlcat(optstr, "_tls_client_key_file", sizeof(optstr));
+    c_key_file = config_getoverflowstring(optstr, NULL);
+    if(!c_key_file) {
+	c_key_file = config_getstring(IMAPOPT_TLS_CLIENT_KEY_FILE);
+    }
+#endif
+
     do {
 	/* If we have a mech_conf, use it */
 	if (mech_conf) {
@@ -264,7 +287,7 @@
 
 	/* If we don't have a usable mech, do TLS and try again */
     } while (r == SASL_NOMECH && CAPA(s, CAPA_STARTTLS) &&
-	     do_starttls(s, &prot->tls_cmd) != -1 &&
+	     do_starttls(s, &prot->tls_cmd, c_cert_file, c_key_file) != -1 &&
 	     (*mechlist = ask_capability(s->out, s->in, prot,
 					 &s->capability,
 					 prot->tls_cmd.auto_capa)));
@@ -426,7 +449,7 @@
     if ((server[0] != '/') ||
 	(strcmp(prot->sasl_service, "lmtp") &&
 	 strcmp(prot->sasl_service, "csync"))) {
-	char *mlist = xstrdup(mechlist); /* backend_auth is destructive */
+	char *mlist = ( mechlist ? xstrdup(mechlist) : NULL ); /* backend_auth is destructive */
 
 	if ((r = backend_authenticate(ret, prot, &mlist, userid,
 				      cb, auth_status))) {
@@ -467,7 +490,7 @@
 
 		new_mechlist = ask_capability(ret->out, ret->in, prot,
 					      &ret->capability, auto_capa);
-		if (new_mechlist && strcmp(new_mechlist, mechlist)) {
+		if (new_mechlist && mechlist && strcmp(new_mechlist, mechlist)) {
 		    syslog(LOG_ERR, "possible MITM attack:"
 			   "list of available SASL mechanisms changed");
 		    if (!ret_backend) free(ret);
@@ -475,7 +498,7 @@
 		    ret = NULL;
 		}
 
-		free(new_mechlist);
+		if (new_mechlist) free(new_mechlist);
 	    }
 	}
 
diff -Nrub cyrus-imapd-2.3.14/imap/mupdate-client.c cyrus-imapd-2.3.14_clientcerts/imap/mupdate-client.c
--- cyrus-imapd-2.3.14/imap/mupdate-client.c	2008-10-08 16:47:08.000000000 +0100
+++ cyrus-imapd-2.3.14_clientcerts/imap/mupdate-client.c	2009-04-25 15:51:27.000000000 +0100
@@ -90,7 +90,7 @@
     { { "* AUTH ", CAPA_AUTH },
       { "* STARTTLS", CAPA_STARTTLS },
       { NULL, 0 } } },
-  { "S01 STARTTLS", "S01 OK", "S01 NO", 0 },
+  { "S01 STARTTLS", "S01 OK", "S01 NO", 1 },
   { "A01 AUTHENTICATE", INT_MAX, 1, "A01 OK", "A01 NO", "", "*", NULL, 0 },
   { "N01 NOOP", NULL, "N01 OK" },
   { "Q01 LOGOUT", NULL, "Q01 " }
diff -Nrub cyrus-imapd-2.3.14/imap/tls.c cyrus-imapd-2.3.14_clientcerts/imap/tls.c
--- cyrus-imapd-2.3.14/imap/tls.c	2008-11-14 22:24:38.000000000 +0000
+++ cyrus-imapd-2.3.14_clientcerts/imap/tls.c	2009-04-25 15:51:27.000000000 +0100
@@ -1214,11 +1214,11 @@
 	syslog(LOG_NOTICE,"TLS client engine: cannot load CA data");	
     }
 
-    if (strlen(var_tls_cert_file) == 0)
+    if (var_tls_cert_file && (strlen(var_tls_cert_file) == 0))
 	c_cert_file = NULL;
     else
 	c_cert_file = var_tls_cert_file;
-    if (strlen(var_tls_key_file) == 0)
+    if (var_tls_key_file && (strlen(var_tls_key_file) == 0))
 	c_key_file = NULL;
     else
 	c_key_file = var_tls_key_file;
diff -Nrub cyrus-imapd-2.3.14/lib/imapoptions cyrus-imapd-2.3.14_clientcerts/lib/imapoptions
--- cyrus-imapd-2.3.14/lib/imapoptions	2009-03-06 03:52:55.000000000 +0000
+++ cyrus-imapd-2.3.14_clientcerts/lib/imapoptions	2009-04-25 15:51:27.000000000 +0100
@@ -1083,6 +1083,14 @@
 /* The list of SSL/TLS ciphers to allow.  The format of the string is
    described in ciphers(1). */
 
+{ "tls_client_cert_file", NULL, STRING }
+/* File containing the client certificate to send to remote servers
+   when making an SSL/TLS connection. */
+
+{ "tls_client_key_file", NULL, STRING }
+/* File containing the private key belonging to the client
+   certificate used when making an SSL/TLS connection. */
+
 { "tls_key_file", NULL, STRING }
 /* File containing the private key belonging to the server
    certificate.  A value of "disabled" will disable SSL/TLS. */

Reply via email to