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 --- Makefile | 8 +++++--- qmail-remote.c | 28 ++++++++++++++++++++++++++-- qmail-rspawn.c | 22 +++++++++++++++++++--- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 70df80d..be8a15e 100644 --- a/Makefile +++ b/Makefile @@ -1509,13 +1509,15 @@ qmail-remote: \ load qmail-remote.o control.o constmap.o timeoutread.o timeoutwrite.o \ timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o ipme.o quote.o \ ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \ -substdio.a error.a str.a fs.a auto_qmail.o base64.o dns.lib socket.lib +substdio.a error.a env.a str.a fs.a auto_qmail.o base64.o \ +dns.lib socket.lib ./load qmail-remote control.o constmap.o timeoutread.o \ timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \ tls.o ssl_timeoutio.o -L/usr/local/ssl/lib -lssl -lcrypto \ ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \ lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \ - str.a fs.a auto_qmail.o base64.o `cat dns.lib` `cat socket.lib` + env.a str.a fs.a auto_qmail.o base64.o \ + `cat dns.lib` `cat socket.lib` qmail-remote.0: \ qmail-remote.8 @@ -1526,7 +1528,7 @@ compile qmail-remote.c sig.h stralloc.h gen_alloc.h substdio.h \ subfd.h substdio.h scan.h case.h error.h auto_qmail.h control.h dns.h \ alloc.h quote.h ip.h ipalloc.h ip.h gen_alloc.h ipme.h ip.h ipalloc.h \ gen_alloc.h gen_allocdefs.h str.h now.h datetime.h exit.h constmap.h \ -tcpto.h readwrite.h timeoutconn.h timeoutread.h timeoutwrite.h +tcpto.h readwrite.h timeoutconn.h timeoutread.h timeoutwrite.h env.h ./compile qmail-remote.c qmail-rspawn: \ 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(); diff --git a/qmail-rspawn.c b/qmail-rspawn.c index 9d838e6..40e5d52 100644 --- a/qmail-rspawn.c +++ b/qmail-rspawn.c @@ -25,6 +25,7 @@ int len; int k; int result; int orr; + int l; if (wait_crashed(wstat)) { substdio_puts(ss,"Zqmail-remote crashed.\n"); return; } @@ -48,8 +49,16 @@ int len; j = k + 1; } + j = 0; + for (k = 0;k < len;++k) + if (!s[k]) + { + if (s[j] != 'l') break; + j = k + 1; + } + orr = result; - switch(s[0]) + switch(s[j]) { case 's': orr = 0; break; case 'h': orr = -1; @@ -62,10 +71,17 @@ int len; case -1: substdio_put(ss,"D",1); break; } - for (k = 1;k < len;) + for (k = l = 1;k < j;++k) + if (!s[k]) + { + substdio_puts(ss,s + l); + l = k + 2; + } + + for (k = j+1;k < len;) if (!s[k++]) { - substdio_puts(ss,s + 1); + substdio_puts(ss,s + j + 1); if (result <= orr) if (k < len) switch(s[k]) -- cgit v1.2.3