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