1 From 97c5e07c220b55d1c506a1798c9ce3ae3105adea Mon Sep 17 00:00:00 2001
2 From: Jeremy Harris <jgh146exb@wizmail.org>
3 Date: Thu, 13 Feb 2020 16:45:38 +0000
4 Subject: [PATCH 4/6] GnuTLS: fix hanging callout connections
7 (cherry picked from commit bd95ffc2ba87fbd3c752df17bc8fd9c01586d45a)
9 doc/ChangeLog | 81 ++++---------------------------------------
10 src/tls-gnu.c | 24 +++++++------
11 2 files changed, 20 insertions(+), 85 deletions(-)
15 @@ -67,6 +67,11 @@ JH/41 Bug 2571: Fix SPA authenticator.
16 being used. A malicious client could thus cause an out-of-bounds read and
17 possibly gain authentication. Fix by adding the check.
19 +JH/25 Fix use of concurrent TLS connections under GnuTLS. When a callout was
20 + done during a receiving connection, and both used TLS, global info was
21 + used rather than per-connection info for tracking the state of data
22 + queued for transmission. This could result in a connection hang.
29 @@ -124,10 +124,17 @@ typedef struct exim_gnutls_state {
30 enum peer_verify_requirement verify_requirement;
33 - BOOL peer_cert_verified;
34 - BOOL peer_dane_verified;
35 - BOOL trigger_sni_changes;
36 - BOOL have_set_peerdn;
38 + BOOL peer_cert_verified:1;
39 + BOOL peer_dane_verified:1;
40 + BOOL trigger_sni_changes:1;
41 + BOOL have_set_peerdn:1;
42 + BOOL xfer_eof:1; /*XXX never gets set! */
48 const struct host_item *host; /* NULL if server */
49 gnutls_x509_crt_t peercert;
51 @@ -160,8 +167,6 @@ typedef struct exim_gnutls_state {
55 - BOOL xfer_eof; /*XXX never gets set! */
57 } exim_gnutls_state_st;
59 static const exim_gnutls_state_st exim_gnutls_state_init = {
60 @@ -2790,9 +2795,8 @@ ssize_t outbytes;
62 exim_gnutls_state_st * state = ct_ctx ? ct_ctx : &state_server;
64 -static BOOL corked = FALSE;
66 -if (more && !corked) gnutls_record_cork(state->session);
67 +if (more && !state->corked) gnutls_record_cork(state->session);
70 DEBUG(D_tls) debug_printf("%s(%p, " SIZE_T_FMT "%s)\n", __FUNCTION__,
71 @@ -2833,10 +2837,10 @@ if (len > INT_MAX)
76 +if (more != state->corked)
78 if (!more) (void) gnutls_record_uncork(state->session, 0);
80 + state->corked = more;