File netqmail-1.06-tls-fixes.patch of Package netqmail

Fix for netqmail-1.06 with Fred Vermeulen's tls patch.

Actually, this is more than just a fix - it modifies the patch to request
an optional client certificate already on the initial ssl handshake, instead
of trying to renegotiate later. With openssl-1.0.x, requesting client certs
when renegotiating didn't seem to work anymore.

This has the additional advantage that clients using certificates will always
be treated as RELAYCLIENTs.

(C) 2012 Peter Conrad <conrad@quisquis.de>

This file is licensed under the terms of the
GNU General Public License Version 2. A copy of these terms should be
enclosed as "gpl-2.0.txt" in the package containing this file.

--- netqmail-1.06/qmail-smtpd.c	2012-10-11 13:14:34.000000000 +0200
+++ netqmail-1.06.sslfix/qmail-smtpd.c	2012-10-11 13:17:28.000000000 +0200
@@ -559,26 +559,11 @@
   {
   case 1:
     if (constmap_init(&mapclients, clients.s, clients.len, 0)) {
-      /* if CLIENTCA contains all the standard root certificates, a
-       * 0.9.6b client might fail with SSL_R_EXCESSIVE_MESSAGE_SIZE;
-       * it is probably due to 0.9.6b supporting only 8k key exchange
-       * data while the 0.9.6c release increases that limit to 100k */
-      STACK_OF(X509_NAME) *sk = SSL_load_client_CA_file(CLIENTCA);
-      if (sk) {
-        SSL_set_client_CA_list(ssl, sk);
-        SSL_set_verify(ssl, SSL_VERIFY_PEER, verify_cb);
-        break;
-      }
-      constmap_free(&mapclients);
+      break;
     }
   case 0: alloc_free(clients.s); return 0;
   case -1: die_control();
   }
-
-  if (ssl_timeoutrehandshake(timeout, ssl_rfd, ssl_wfd, ssl) <= 0) {
-    const char *err = ssl_error_str();
-    tls_out("rehandshake failed", err); die_read();
-  }
 
   do { /* one iteration */
     X509 *peercert;
@@ -633,6 +618,7 @@
   X509_STORE *store;
   X509_LOOKUP *lookup;
   int session_id_context = 1; /* anything will do */
+  STACK_OF(X509_NAME) *sk;
 
   SSL_library_init();
 
@@ -647,6 +633,15 @@
     { SSL_CTX_free(ctx); tls_err("missing certificate"); return; }
   SSL_CTX_load_verify_locations(ctx, CLIENTCA, NULL);
 
+  sk = SSL_load_client_CA_file(CLIENTCA);
+  /* if CLIENTCA contains all the standard root certificates, a
+   * 0.9.6b client might fail with SSL_R_EXCESSIVE_MESSAGE_SIZE;
+   * it is probably due to 0.9.6b supporting only 8k key exchange
+   * data while the 0.9.6c release increases that limit to 100k */
+  if (sk) {
+    SSL_CTX_set_client_CA_list(ctx, sk);
+  }
+
   /* crl checking */
   store = SSL_CTX_get_cert_store(ctx);
   if ((lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) &&
@@ -657,7 +652,7 @@
   SSL_CTX_set_ecdh_auto(ctx,1);
 #endif
 
-  SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
+  SSL_CTX_set_verify(ctx, sk ? SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE : SSL_VERIFY_NONE, verify_cb);
 
   /* a new SSL object, with the rest added to it directly to avoid copying */
   myssl = SSL_new(ctx);
--- netqmail-1.06/qmail-smtpd.c	2012-10-16 12:03:39.000000000 +0200
+++ netqmail-1.06.new/qmail-smtpd.c	2012-10-16 12:12:51.000000000 +0200
@@ -244,21 +244,18 @@
   return 0;
 }
 
-int addrallowed()
+static int addrallowed()
 {
   int r;
   r = rcpthosts(addr.s,str_len(addr.s));
   if (r == -1) die_control();
-#ifdef TLS
-  if (r == 0) if (tls_verify()) r = -2;
-#endif
   return r;
 }
 
 
 int seenmail = 0;
 int flagbarf; /* defined if seenmail */
-int allowed;
+static int allowed;
 stralloc mailfrom = {0};
 stralloc rcptto = {0};
 
@@ -534,7 +531,7 @@
 # define CLIENTCRL "control/clientcrl.pem"
 # define SERVERCERT "control/servercert.pem"
 
-int tls_verify()
+static int tls_verify()
 {
   stralloc clients = {0};
   struct constmap mapclients;
@@ -699,6 +685,8 @@
   if (!stralloc_0(&proto)) die_nomem();
   protocol = proto.s;
 
+  tls_verify(); /* set relayclient if client certifiate is acceptable */
+
   /* have to discard the pre-STARTTLS HELO/EHLO argument, if any */
   dohelo(remotehost);
 }
--- netqmail-1.06/qmail-smtpd.c	2012-10-16 12:13:50.000000000 +0200
+++ netqmail-1.06.new/qmail-smtpd.c	2012-10-16 12:15:13.000000000 +0200
@@ -39,7 +39,6 @@
 #include "ssl_timeoutio.h"
 
 void tls_init();
-int tls_verify();
 void tls_nogateway();
 int ssl_rfd = -1, ssl_wfd = -1; /* SSL_get_Xfd() are broken */
 #endif
openSUSE Build Service is sponsored by