GnuTLS: Do not free the cached creds on transport connection close. Bug 2886
authorJeremy Harris <jgh146exb@wizmail.org>
Thu, 19 May 2022 13:23:02 +0000 (14:23 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Thu, 19 May 2022 13:23:02 +0000 (14:23 +0100)
doc/doc-txt/ChangeLog
src/src/tls-gnu.c
test/confs/2011 [new file with mode: 0644]
test/log/2011 [new file with mode: 0644]
test/rejectlog/2011 [new file with mode: 0644]
test/scripts/2000-GnuTLS/2011 [new file with mode: 0644]

index ac5354c73bf52d2e170623a09638d336ffc6d95d..389968a9033f691bb9d7c3736a51cbfcb10f7bda 100644 (file)
@@ -136,6 +136,10 @@ JH/30 Fix string_copyn() for limit greater than actual string length.
       overlapping memcpy for newly allocated destination soon after a
       source string shorter than the limit.  Found/investigated  by KM.
 
+JH/31 Bug 2886: GnuTLS: Do not free the cached creds on transport connection
+      close; it may be needed for a subsequent connection.  This caused a
+      SEGV on primary-MX defer.  Found/investigated by Gedalya & Andreas.
+
 
 Exim version 4.95
 -----------------
index 875862cc1aa992668b9088908317e32a2313be50..30c8d40c0f10cdb4e93d7bfa87a8c66fccce49c7 100644 (file)
@@ -1600,6 +1600,9 @@ return lifetime;
 /* Preload whatever creds are static, onto a transport.  The client can then
 just copy the pointer as it starts up. */
 
+/*XXX this is not called for a cmdline send. But one needing to use >1 conn would benefit,
+and there seems little downside. */
+
 static void
 tls_client_creds_init(transport_instance * t, BOOL watch)
 {
@@ -3084,8 +3087,6 @@ if (rc != GNUTLS_E_SUCCESS)
 #endif
     (void) gnutls_alert_send_appropriate(state->session, rc);
     gnutls_deinit(state->session);
-    gnutls_certificate_free_credentials(state->lib_state.x509_cred);
-    state->lib_state = null_tls_preload;
     millisleep(500);
     shutdown(state->fd_out, SHUT_WR);
     for (int i = 1024; fgetc(smtp_in) != EOF && i > 0; ) i--;  /* drain skt */
@@ -3778,9 +3779,6 @@ if (!ct_ctx)      /* server */
   }
 
 gnutls_deinit(state->session);
-gnutls_certificate_free_credentials(state->lib_state.x509_cred);
-state->lib_state = null_tls_preload;
-
 tlsp->active.sock = -1;
 tlsp->active.tls_ctx = NULL;
 /* Leave bits, peercert, cipher, peerdn, certificate_verified set, for logging */
diff --git a/test/confs/2011 b/test/confs/2011
new file mode 100644 (file)
index 0000000..eac8ccd
--- /dev/null
@@ -0,0 +1,72 @@
+# Exim test configuration 2011
+
+SERVER=
+
+keep_environment = PATH:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+add_environment = SSLKEYLOGFILE=DIR/spool/sslkeys
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+
+.ifdef SERVER
+log_file_path = DIR/spool/log/SERVER%slog
+.else
+log_file_path = DIR/spool/log/%slog
+.endif
+
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+dns_cname_loops = 9
+chunking_advertise_hosts = *
+
+.ifdef _HAVE_PIPE_CONNECT
+pipelining_connect_advertise_hosts = :
+.endif
+.ifdef _HAVE_DMARC
+dmarc_tld_file =
+.endif
+.ifdef _EXP_LIMITS
+limits_advertise_hosts = !*
+.endif
+
+primary_hostname = test.ex
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = check_rcpt
+
+log_selector = +received_recipients +dkim_verbose
+queue_only
+queue_run_in_order
+
+# ----- ACL -----
+begin acl
+
+check_rcpt:
+  defer        hosts = HOSTIPV4
+  accept
+
+# ----- Routers -----
+
+begin routers
+
+d0:
+  driver =     manualroute
+  route_list = *       "HOSTIPV4::PORT_D : 127.0.0.1::PORT_D"
+  self =       send
+  transport =  gsmtp
+
+# ----- Transports -----
+
+begin transports
+
+gsmtp:
+  driver =                     smtp
+  allow_localhost
+  tls_verify_certificates =    system
+  hosts_require_tls =          *
+
+begin retry
+* * F,5d,10s
+
+# End
diff --git a/test/log/2011 b/test/log/2011
new file mode 100644 (file)
index 0000000..f0fad26
--- /dev/null
@@ -0,0 +1,13 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for fred@test.net
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmaX-0005vi-00 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: SMTP error from remote mail server after RCPT TO:<fred@test.net>: 451 Temporary local problem - please try later
+1999-03-02 09:44:33 10HmaX-0005vi-00 => fred@test.net R=d0 T=gsmtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no K C="250- 3nn byte chunk, total 3nn\\n250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp
+
+******** SERVER ********
+1999-03-02 09:44:33 Warning: No server certificate defined; will use a selfsigned one.
+ Suggested action: either install a certificate or change tls_advertise_hosts option
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 H=the.local.host.name (test.ex) [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no F=<CALLER@test.ex> temporarily rejected RCPT <fred@test.net>
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@test.ex H=localhost (test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no K S=sss id=E10HmaX-0005vi-00@test.ex for fred@test.net
diff --git a/test/rejectlog/2011 b/test/rejectlog/2011
new file mode 100644 (file)
index 0000000..b8ae22a
--- /dev/null
@@ -0,0 +1,3 @@
+
+******** SERVER ********
+1999-03-02 09:44:33 H=the.local.host.name (test.ex) [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no F=<CALLER@test.ex> temporarily rejected RCPT <fred@test.net>
diff --git a/test/scripts/2000-GnuTLS/2011 b/test/scripts/2000-GnuTLS/2011
new file mode 100644 (file)
index 0000000..c5504c3
--- /dev/null
@@ -0,0 +1,20 @@
+# Cached CA bundle re-use
+#
+# Preload a message into spool
+exim -odq fred@test.net
+Subject: test
+
+this is a test
+
+****
+#
+# Server to work against
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# Send message from spool
+exim -q
+****
+#
+killdaemon
+no_msglog_check