git: d5f03fef61f8 - main - mail/exim: port TLS patches from upstream (+)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 31 Mar 2022 20:01:42 UTC
The branch main has been updated by fluffy: URL: https://cgit.FreeBSD.org/ports/commit/?id=d5f03fef61f8dd05ac7308ad148e2a98e598fdcc commit d5f03fef61f8dd05ac7308ad148e2a98e598fdcc Author: Dima Panov <fluffy@FreeBSD.org> AuthorDate: 2022-03-31 19:57:25 +0000 Commit: Dima Panov <fluffy@FreeBSD.org> CommitDate: 2022-03-31 19:57:25 +0000 mail/exim: port TLS patches from upstream (+) This fixes hang in TLS transport after 4xx or 5xx bug (see https://bugs.exim.org/show_bug.cgi?id=2864) PR: 262594 Tested by: Kurt Jaeger, David Siebörger --- mail/exim/Makefile | 7 +- mail/exim/files/tls/patch-tls1 | 43 ++++++++++ mail/exim/files/tls/patch-tls2 | 174 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+), 1 deletion(-) diff --git a/mail/exim/Makefile b/mail/exim/Makefile index 614fd1f88b0a..d6c7c6ffc8b1 100644 --- a/mail/exim/Makefile +++ b/mail/exim/Makefile @@ -2,7 +2,7 @@ PORTNAME= exim PORTVERSION?= ${EXIM_VERSION} -PORTREVISION?= 3 +PORTREVISION?= 4 CATEGORIES= mail MASTER_SITES= EXIM:exim MASTER_SITE_SUBDIR= /exim4/:exim \ @@ -77,6 +77,11 @@ EXTRA_PATCHES= \ ${DEBIAN_PATCHES_PREFIX}_50-Fix-include_directory-in-redirect-routers.-Bug-2715.patch:-p1 \ ${DEBIAN_PATCHES_PREFIX}_55-Specific-check-for-null-pointer.patch:-p1 +TLS_PATCHES_PREFIX= ${FILESDIR}/tls/ +EXTRA_PATCHES+= \ + ${TLS_PATCHES_PREFIX}patch-tls1:-p1 \ + ${TLS_PATCHES_PREFIX}patch-tls2:-p1 + .include <bsd.port.options.mk> # OCSP is supported for openssl only diff --git a/mail/exim/files/tls/patch-tls1 b/mail/exim/files/tls/patch-tls1 new file mode 100644 index 000000000000..d76d5589b2bb --- /dev/null +++ b/mail/exim/files/tls/patch-tls1 @@ -0,0 +1,43 @@ +From fc624b8cb4c3312d7450dfa86adfa3fe8dd9cbeb Mon Sep 17 00:00:00 2001 +From: Jeremy Harris <jgh146exb@wizmail.org> +Date: Tue, 11 Jan 2022 14:50:09 +0000 +Subject: [PATCH] Ensure server tls close alert not delayed + +--- + src/src/tls-gnu.c | 5 +++++ + src/src/tls-openssl.c | 3 +++ + 2 files changed, 8 insertions(+) + +diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c +index 53635ac..3adadb8 100644 +--- a/src/tls-gnu.c ++++ b/src/tls-gnu.c +@@ -3731,6 +3731,11 @@ if (do_shutdown) + + tls_write(ct_ctx, NULL, 0, FALSE); /* flush write buffer */ + ++#ifdef EXIM_TCP_CORK ++ if (do_shutdown > 1) ++ (void) setsockopt(tlsp->active.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &off, sizeof(off)); ++#endif ++ + ALARM(2); + gnutls_bye(state->session, do_shutdown > 1 ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); + ALARM_CLR(0); +diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c +index 5130455..576f62b 100644 +--- a/src/tls-openssl.c ++++ b/src/tls-openssl.c +@@ -4516,6 +4516,9 @@ if (do_shutdown) + if ( (rc = SSL_shutdown(*sslp)) == 0 /* send "close notify" alert */ + && do_shutdown > 1) + { ++#ifdef EXIM_TCP_CORK ++ (void) setsockopt(*fdp, IPPROTO_TCP, EXIM_TCP_CORK, US &off, sizeof(off)); ++#endif + ALARM(2); + rc = SSL_shutdown(*sslp); /* wait for response */ + ALARM_CLR(0); +-- +1.9.1 + diff --git a/mail/exim/files/tls/patch-tls2 b/mail/exim/files/tls/patch-tls2 new file mode 100644 index 000000000000..e88c127fd374 --- /dev/null +++ b/mail/exim/files/tls/patch-tls2 @@ -0,0 +1,174 @@ +From 2ead369f8435918f3f15408b9394e580bcaf0910 Mon Sep 17 00:00:00 2001 +From: Jeremy Harris <jgh146exb@wizmail.org> +Date: Thu, 10 Mar 2022 15:23:26 +0000 +Subject: [PATCH] OpenSSL: track shutdown calls. Bug 2864 + +--- + doc/doc-txt/ChangeLog | 5 +++++ + src/src/macros.h | 7 ++++--- + src/src/tls-gnu.c | 10 +++++++--- + src/src/tls-openssl.c | 13 ++++++++----- + src/src/transports/smtp.c | 19 +++++++++++++------ + 5 files changed, 37 insertions(+), 17 deletions(-) + +diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog +index 5ba587b..1c799b6 100644 +--- a/doc/ChangeLog ++++ b/doc/ChangeLog +@@ -95,6 +95,11 @@ JH/21 Remove the "allow_insecure_tainted_data" main config option and the + JH/22 Fix static address-list lookups to properly return the matched item. + Previously only the domain part was returned. + ++JH/23 Bug 2864: FreeBSD: fix transport hang after 4xx/5xx response. Previously ++ the call into OpenSSL to send a TLS Close was being repeated; this ++ resulted in the library waiting for the peer's Close. If that was never ++ sent we waited forever. Fix by tracking send calls. ++ + + Exim version 4.95 + ----------------- +diff --git a/src/src/macros.h b/src/src/macros.h +index 92f2cc0..659a70f 100644 +--- a/src/macros.h ++++ b/src/macros.h +@@ -1051,9 +1051,10 @@ enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE }; + + + /* Options on tls_close */ +-#define TLS_NO_SHUTDOWN 0 +-#define TLS_SHUTDOWN_NOWAIT 1 +-#define TLS_SHUTDOWN_WAIT 2 ++#define TLS_NO_SHUTDOWN 0 /* Just forget the context */ ++#define TLS_SHUTDOWN_NOWAIT 1 /* Send alert; do not wait */ ++#define TLS_SHUTDOWN_WAIT 2 /* Send alert & wait for peer's alert */ ++#define TLS_SHUTDOWN_WONLY 3 /* only wait for peer's alert */ + + + #ifdef COMPILE_UTILITY +diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c +index 1215f85..6227823 100644 +--- a/src/tls-gnu.c ++++ b/src/tls-gnu.c +@@ -3744,17 +3744,21 @@ if (!tlsp || tlsp->active.sock < 0) return; /* TLS was not active */ + if (do_shutdown) + { + DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS%s\n", +- do_shutdown > 1 ? " (with response-wait)" : ""); ++ do_shutdown > TLS_SHUTDOWN_NOWAIT ? " (with response-wait)" : ""); + + tls_write(ct_ctx, NULL, 0, FALSE); /* flush write buffer */ + + #ifdef EXIM_TCP_CORK +- if (do_shutdown > 1) ++ if (do_shutdown == TLS_SHUTDOWN_WAIT) + (void) setsockopt(tlsp->active.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &off, sizeof(off)); + #endif + ++ /* The library seems to have no way to only wait for a peer's ++ shutdown, so handle the same as TLS_SHUTDOWN_WAIT */ ++ + ALARM(2); +- gnutls_bye(state->session, do_shutdown > 1 ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); ++ gnutls_bye(state->session, ++ do_shutdown > TLS_SHUTDOWN_NOWAIT ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); + ALARM_CLR(0); + } + +diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c +index d5c5778..7bf62f5 100644 +--- a/src/tls-openssl.c ++++ b/src/tls-openssl.c +@@ -4519,22 +4519,25 @@ int * fdp = o_ctx ? &tls_out.active.sock : &tls_in.active.sock; + + if (*fdp < 0) return; /* TLS was not active */ + +-if (do_shutdown) ++if (do_shutdown > TLS_NO_SHUTDOWN) + { + int rc; + DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS%s\n", +- do_shutdown > 1 ? " (with response-wait)" : ""); ++ do_shutdown > TLS_SHUTDOWN_NOWAIT ? " (with response-wait)" : ""); + + tls_write(ct_ctx, NULL, 0, FALSE); /* flush write buffer */ + +- if ( (rc = SSL_shutdown(*sslp)) == 0 /* send "close notify" alert */ +- && do_shutdown > 1) ++ if ( ( do_shutdown >= TLS_SHUTDOWN_WONLY ++ || (rc = SSL_shutdown(*sslp)) == 0 /* send "close notify" alert */ ++ ) ++ && do_shutdown > TLS_SHUTDOWN_NOWAIT ++ ) + { + #ifdef EXIM_TCP_CORK + (void) setsockopt(*fdp, IPPROTO_TCP, EXIM_TCP_CORK, US &off, sizeof(off)); + #endif + ALARM(2); +- rc = SSL_shutdown(*sslp); /* wait for response */ ++ rc = SSL_shutdown(*sslp); /* wait for response */ + ALARM_CLR(0); + } + +diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c +index e2c2680..524f186 100644 +--- a/src/transports/smtp.c ++++ b/src/transports/smtp.c +@@ -4085,7 +4085,7 @@ else + sx->send_quit = FALSE; /* avoid sending it later */ + + #ifndef DISABLE_TLS +- if (sx->cctx.tls_ctx) /* need to send TLS Close Notify */ ++ if (sx->cctx.tls_ctx && sx->send_tlsclose) /* need to send TLS Close Notify */ + { + # ifdef EXIM_TCP_CORK /* Use _CORK to get Close Notify in FIN segment */ + (void) setsockopt(sx->cctx.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on)); +@@ -4429,7 +4429,8 @@ if (!sx->ok) + # ifndef DISABLE_TLS + if (sx->cctx.tls_ctx) + { +- tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WAIT); ++ tls_close(sx->cctx.tls_ctx, ++ sx->send_tlsclose ? TLS_SHUTDOWN_WAIT : TLS_SHUTDOWN_WONLY); + sx->cctx.tls_ctx = NULL; + } + # endif +@@ -4640,7 +4641,8 @@ if (sx->completed_addr && sx->ok && sx->send_quit) + a new EHLO. If we don't get a good response, we don't attempt to pass + the socket on. */ + +- tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WAIT); ++ tls_close(sx->cctx.tls_ctx, ++ sx->send_tlsclose ? TLS_SHUTDOWN_WAIT : TLS_SHUTDOWN_WONLY); + sx->send_tlsclose = FALSE; + sx->cctx.tls_ctx = NULL; + tls_out.active.sock = -1; +@@ -4742,7 +4744,7 @@ if (sx->send_quit) + { /* Use _MORE to get QUIT in FIN segment */ + (void)smtp_write_command(sx, SCMD_MORE, "QUIT\r\n"); + #ifndef DISABLE_TLS +- if (sx->cctx.tls_ctx) ++ if (sx->cctx.tls_ctx && sx->send_tlsclose) + { + # ifdef EXIM_TCP_CORK /* Use _CORK to get TLS Close Notify in FIN segment */ + (void) setsockopt(sx->cctx.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on)); +@@ -4797,10 +4799,15 @@ if (sx->send_quit || tcw_done && !tcw) + while (!sigalrm_seen && n > 0); + ALARM_CLR(0); + ++ if (sx->send_tlsclose) ++ { + # ifdef EXIM_TCP_CORK +- (void) setsockopt(sx->cctx.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on)); ++ (void) setsockopt(sx->cctx.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on)); + # endif +- tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WAIT); ++ tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WAIT); ++ } ++ else ++ tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WONLY); + sx->cctx.tls_ctx = NULL; + } + #endif +-- +1.9.1 +