| 1 | From 332ebeaf8139b2b75f475880fc14b63c7c45c706 Mon Sep 17 00:00:00 2001 |
| 2 | From: Jeremy Harris <jgh146exb@wizmail.org> |
| 3 | Date: Tue, 19 Mar 2019 15:33:31 +0000 |
| 4 | Subject: [PATCH 5/5] OpenSSL: Fix aggregation of messages. |
| 5 | |
| 6 | Broken-by: a5ffa9b475 |
| 7 | (cherry picked from commit c09dbcfb71f4b9a42cbfd8a20e0be6bfa1b12488) |
| 8 | --- |
| 9 | doc/ChangeLog | 5 +++ |
| 10 | src/tls-openssl.c | 24 ++++++++++---- |
| 11 | test/confs/2152 | 76 +++++++++++++++++++++++++++++++++++++++++++ |
| 12 | test/log/2152 | 9 +++++ |
| 13 | 4 files changed, 108 insertions(+), 6 deletions(-) |
| 14 | create mode 100644 test/confs/2152 |
| 15 | create mode 100644 test/log/2152 |
| 16 | |
| 17 | diff --git a/doc/ChangeLog b/doc/ChangeLog |
| 18 | index 3c0ffbf0..3d63725f 100644 |
| 19 | --- a/doc/ChangeLog |
| 20 | +++ b/doc/ChangeLog |
| 21 | @@ -26,10 +26,15 @@ JH/08 Add hardening against SRV & TLSA lookups the hit CNAMEs (a nonvalid |
| 22 | crash could result. |
| 23 | |
| 24 | JH/09 Logging: Fix initial listening-on line for multiple ports for an IP when |
| 25 | the OS reports them interleaved with other addresses. |
| 26 | |
| 27 | +JH/10 OpenSSL: Fix aggregation of messages. Previously, when PIPELINING was |
| 28 | + used both for input and for a verify callout, both encrypted, SMTP |
| 29 | + responses being sent by the server could be lost. This resulted in |
| 30 | + dropped connections and sometimes bounces generated by a peer sending |
| 31 | + to this system. |
| 32 | |
| 33 | |
| 34 | Exim version 4.92 |
| 35 | ----------------- |
| 36 | |
| 37 | diff --git a/src/tls-openssl.c b/src/tls-openssl.c |
| 38 | index 8f4cf4d8..cc0ead02 100644 |
| 39 | --- a/src/tls-openssl.c |
| 40 | +++ b/src/tls-openssl.c |
| 41 | @@ -272,10 +272,11 @@ Server: |
| 42 | */ |
| 43 | |
| 44 | typedef struct { |
| 45 | SSL_CTX * ctx; |
| 46 | SSL * ssl; |
| 47 | + gstring * corked; |
| 48 | } exim_openssl_client_tls_ctx; |
| 49 | |
| 50 | static SSL_CTX *server_ctx = NULL; |
| 51 | static SSL *server_ssl = NULL; |
| 52 | |
| 53 | @@ -2471,10 +2472,11 @@ BOOL require_ocsp = FALSE; |
| 54 | #endif |
| 55 | |
| 56 | rc = store_pool; |
| 57 | store_pool = POOL_PERM; |
| 58 | exim_client_ctx = store_get(sizeof(exim_openssl_client_tls_ctx)); |
| 59 | +exim_client_ctx->corked = NULL; |
| 60 | store_pool = rc; |
| 61 | |
| 62 | #ifdef SUPPORT_DANE |
| 63 | tlsp->tlsa_usage = 0; |
| 64 | #endif |
| 65 | @@ -2906,22 +2908,29 @@ Used by both server-side and client-side TLS. |
| 66 | |
| 67 | int |
| 68 | tls_write(void * ct_ctx, const uschar *buff, size_t len, BOOL more) |
| 69 | { |
| 70 | int outbytes, error, left; |
| 71 | -SSL * ssl = ct_ctx ? ((exim_openssl_client_tls_ctx *)ct_ctx)->ssl : server_ssl; |
| 72 | -static gstring * corked = NULL; |
| 73 | +SSL * ssl = ct_ctx |
| 74 | + ? ((exim_openssl_client_tls_ctx *)ct_ctx)->ssl : server_ssl; |
| 75 | +static gstring * server_corked = NULL; |
| 76 | +gstring ** corkedp = ct_ctx |
| 77 | + ? &((exim_openssl_client_tls_ctx *)ct_ctx)->corked : &server_corked; |
| 78 | +gstring * corked = *corkedp; |
| 79 | |
| 80 | DEBUG(D_tls) debug_printf("%s(%p, %lu%s)\n", __FUNCTION__, |
| 81 | buff, (unsigned long)len, more ? ", more" : ""); |
| 82 | |
| 83 | /* Lacking a CORK or MSG_MORE facility (such as GnuTLS has) we copy data when |
| 84 | "more" is notified. This hack is only ok if small amounts are involved AND only |
| 85 | one stream does it, in one context (i.e. no store reset). Currently it is used |
| 86 | -for the responses to the received SMTP MAIL , RCPT, DATA sequence, only. */ |
| 87 | -/*XXX + if PIPE_COMMAND, banner & ehlo-resp for smmtp-on-connect. Suspect there's |
| 88 | -a store reset there. */ |
| 89 | +for the responses to the received SMTP MAIL , RCPT, DATA sequence, only. |
| 90 | +We support callouts done by the server process by using a separate client |
| 91 | +context for the stashed information. */ |
| 92 | +/* + if PIPE_COMMAND, banner & ehlo-resp for smmtp-on-connect. Suspect there's |
| 93 | +a store reset there, so use POOL_PERM. */ |
| 94 | +/* + if CHUNKING, cmds EHLO,MAIL,RCPT(s),BDAT */ |
| 95 | |
| 96 | if (!ct_ctx && (more || corked)) |
| 97 | { |
| 98 | #ifdef EXPERIMENTAL_PIPE_CONNECT |
| 99 | int save_pool = store_pool; |
| 100 | @@ -2933,14 +2942,17 @@ if (!ct_ctx && (more || corked)) |
| 101 | #ifdef EXPERIMENTAL_PIPE_CONNECT |
| 102 | store_pool = save_pool; |
| 103 | #endif |
| 104 | |
| 105 | if (more) |
| 106 | + { |
| 107 | + *corkedp = corked; |
| 108 | return len; |
| 109 | + } |
| 110 | buff = CUS corked->s; |
| 111 | len = corked->ptr; |
| 112 | - corked = NULL; |
| 113 | + *corkedp = NULL; |
| 114 | } |
| 115 | |
| 116 | for (left = len; left > 0;) |
| 117 | { |
| 118 | DEBUG(D_tls) debug_printf("SSL_write(%p, %p, %d)\n", ssl, buff, left); |
| 119 | diff --git a/test/confs/2152 b/test/confs/2152 |
| 120 | new file mode 100644 |
| 121 | index 00000000..f783192b |
| 122 | diff --git a/test/log/2152 b/test/log/2152 |
| 123 | new file mode 100644 |
| 124 | index 00000000..720200be |
| 125 | -- |
| 126 | 2.20.1 |
| 127 | |