Import Debian changes 4.92-8+deb10u3
[hcoop/debian/exim4.git] / debian / patches / 75_09-OpenSSL-Fix-aggregation-of-messages.patch
diff --git a/debian/patches/75_09-OpenSSL-Fix-aggregation-of-messages.patch b/debian/patches/75_09-OpenSSL-Fix-aggregation-of-messages.patch
new file mode 100644 (file)
index 0000000..b82891d
--- /dev/null
@@ -0,0 +1,127 @@
+From 332ebeaf8139b2b75f475880fc14b63c7c45c706 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Tue, 19 Mar 2019 15:33:31 +0000
+Subject: [PATCH 5/5] OpenSSL: Fix aggregation of messages.
+
+Broken-by: a5ffa9b475
+(cherry picked from commit c09dbcfb71f4b9a42cbfd8a20e0be6bfa1b12488)
+---
+ doc/ChangeLog |  5 +++
+ src/tls-openssl.c | 24 ++++++++++----
+ test/confs/2152       | 76 +++++++++++++++++++++++++++++++++++++++++++
+ test/log/2152         |  9 +++++
+ 4 files changed, 108 insertions(+), 6 deletions(-)
+ create mode 100644 test/confs/2152
+ create mode 100644 test/log/2152
+
+diff --git a/doc/ChangeLog b/doc/ChangeLog
+index 3c0ffbf0..3d63725f 100644
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -26,10 +26,15 @@ JH/08 Add hardening against SRV & TLSA lookups the hit CNAMEs (a nonvalid
+       crash could result.
+ JH/09 Logging: Fix initial listening-on line for multiple ports for an IP when
+       the OS reports them interleaved with other addresses.
++JH/10 OpenSSL: Fix aggregation of messages.  Previously, when PIPELINING was
++      used both for input and for a verify callout, both encrypted, SMTP
++      responses being sent by the server could be lost.  This resulted in
++      dropped connections and sometimes bounces generated by a peer sending
++      to this system.
+ Exim version 4.92
+ -----------------
+diff --git a/src/tls-openssl.c b/src/tls-openssl.c
+index 8f4cf4d8..cc0ead02 100644
+--- a/src/tls-openssl.c
++++ b/src/tls-openssl.c
+@@ -272,10 +272,11 @@ Server:
+ */
+ typedef struct {
+   SSL_CTX *   ctx;
+   SSL *               ssl;
++  gstring *   corked;
+ } exim_openssl_client_tls_ctx;
+ static SSL_CTX *server_ctx = NULL;
+ static SSL     *server_ssl = NULL;
+@@ -2471,10 +2472,11 @@ BOOL require_ocsp = FALSE;
+ #endif
+ rc = store_pool;
+ store_pool = POOL_PERM;
+ exim_client_ctx = store_get(sizeof(exim_openssl_client_tls_ctx));
++exim_client_ctx->corked = NULL;
+ store_pool = rc;
+ #ifdef SUPPORT_DANE
+ tlsp->tlsa_usage = 0;
+ #endif
+@@ -2906,22 +2908,29 @@ Used by both server-side and client-side TLS.
+ int
+ tls_write(void * ct_ctx, const uschar *buff, size_t len, BOOL more)
+ {
+ int outbytes, error, left;
+-SSL * ssl = ct_ctx ? ((exim_openssl_client_tls_ctx *)ct_ctx)->ssl : server_ssl;
+-static gstring * corked = NULL;
++SSL * ssl = ct_ctx
++  ? ((exim_openssl_client_tls_ctx *)ct_ctx)->ssl : server_ssl;
++static gstring * server_corked = NULL;
++gstring ** corkedp = ct_ctx
++  ? &((exim_openssl_client_tls_ctx *)ct_ctx)->corked : &server_corked;
++gstring * corked = *corkedp;
+ DEBUG(D_tls) debug_printf("%s(%p, %lu%s)\n", __FUNCTION__,
+   buff, (unsigned long)len, more ? ", more" : "");
+ /* Lacking a CORK or MSG_MORE facility (such as GnuTLS has) we copy data when
+ "more" is notified.  This hack is only ok if small amounts are involved AND only
+ one stream does it, in one context (i.e. no store reset).  Currently it is used
+-for the responses to the received SMTP MAIL , RCPT, DATA sequence, only. */
+-/*XXX + if PIPE_COMMAND, banner & ehlo-resp for smmtp-on-connect. Suspect there's
+-a store reset there. */
++for the responses to the received SMTP MAIL , RCPT, DATA sequence, only.
++We support callouts done by the server process by using a separate client
++context for the stashed information. */
++/* + if PIPE_COMMAND, banner & ehlo-resp for smmtp-on-connect. Suspect there's
++a store reset there, so use POOL_PERM. */
++/* + if CHUNKING, cmds EHLO,MAIL,RCPT(s),BDAT */
+ if (!ct_ctx && (more || corked))
+   {
+ #ifdef EXPERIMENTAL_PIPE_CONNECT
+   int save_pool = store_pool;
+@@ -2933,14 +2942,17 @@ if (!ct_ctx && (more || corked))
+ #ifdef EXPERIMENTAL_PIPE_CONNECT
+   store_pool = save_pool;
+ #endif
+   if (more)
++    {
++    *corkedp = corked;
+     return len;
++    }
+   buff = CUS corked->s;
+   len = corked->ptr;
+-  corked = NULL;
++  *corkedp = NULL;
+   }
+ for (left = len; left > 0;)
+   {
+   DEBUG(D_tls) debug_printf("SSL_write(%p, %p, %d)\n", ssl, buff, left);
+diff --git a/test/confs/2152 b/test/confs/2152
+new file mode 100644
+index 00000000..f783192b
+diff --git a/test/log/2152 b/test/log/2152
+new file mode 100644
+index 00000000..720200be
+-- 
+2.20.1
+