From c76a0244565136c708d945f3ef1d4e14c7d3e1f8 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 30 Jun 2015 14:00:01 +0200 Subject: opportunistic TLS When the TLS handshake fails, retry delivery with TLS disabled --- qmail-remote.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'qmail-remote.c') diff --git a/qmail-remote.c b/qmail-remote.c index b865b4d..b5b93d5 100644 --- a/qmail-remote.c +++ b/qmail-remote.c @@ -31,6 +31,7 @@ #include "timeoutread.h" #include "timeoutwrite.h" #include "base64.h" +#include "env.h" #define HUGESMTPTEXT 5000 @@ -65,6 +66,7 @@ struct ip_address partner; int tls_init(); const char *ssl_err_str = 0; +char **myargv; #endif void out(s) char *s; { if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); } @@ -400,6 +402,7 @@ int tls_init() return 0; } alloc_free(tmp.s); + if (env_get("NOTLS")) return 0; } } @@ -476,8 +479,25 @@ int tls_init() } ssl = myssl; - if (ssl_timeoutconn(timeout, smtpfd, smtpfd, ssl) <= 0) - tls_quit("ZTLS connect failed", ssl_error_str()); + if (ssl_timeoutconn(timeout, smtpfd, smtpfd, ssl) <= 0) { + if (servercert) + tls_quit("ZTLS connect failed", ssl_error_str()); + else { + /* shouldn't talk to the client unless in an appropriate state */ + int state = ssl ? ssl->state : SSL_ST_BEFORE; + if (state & SSL_ST_OK || (!smtps && state & SSL_ST_BEFORE)) + substdio_putsflush(&smtpto,"QUIT\r\n"); + + out("lTLS connect failed: "); + out(ssl_error_str()); + out("; retrying without TLS\n"); + zero(); + substdio_flush(subfdoutsmall); + + env_put("NOTLS=1"); + execvp(*myargv, myargv); + } + } if (servercert) { X509 *peercert; @@ -847,6 +867,10 @@ char **argv; char **recips; unsigned long prefme; char *relayhost; + +#ifdef TLS + myargv = argv; +#endif sig_pipeignore(); if (argc < 4) perm_usage(); -- cgit v1.2.3