[exim-cvs] OpenSSL: Fix aggregation of messages.

Inizio della pagina
Delete this message
Reply to this message
Autore: Exim Git Commits Mailing List
Data:  
To: exim-cvs
Oggetto: [exim-cvs] OpenSSL: Fix aggregation of messages.
Gitweb: https://git.exim.org/exim.git/commitdiff/c09dbcfb71f4b9a42cbfd8a20e0be6bfa1b12488
Commit:     c09dbcfb71f4b9a42cbfd8a20e0be6bfa1b12488
Parent:     254f38d1c5ada5e4df0bccb385dc466549620c71
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Tue Mar 19 15:33:31 2019 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Tue Mar 19 15:33:31 2019 +0000


    OpenSSL: Fix aggregation of messages.


    Broken-by: a5ffa9b475
---
 doc/doc-txt/ChangeLog |  5 ++++
 src/src/tls-openssl.c | 19 ++++++++++---
 test/confs/2152       | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++
 test/log/2152         |  9 ++++++
 4 files changed, 105 insertions(+), 4 deletions(-)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 7a0a9c6..2085a3b 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -42,6 +42,11 @@ JH/08 Add hardening against SRV & TLSA lookups the hit CNAMEs (a nonvalid
 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/src/tls-openssl.c b/src/src/tls-openssl.c
index d37c789..5a5e146 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -289,6 +289,7 @@ Server:
 typedef struct {
   SSL_CTX *    ctx;
   SSL *        ssl;
+  gstring *    corked;
 } exim_openssl_client_tls_ctx;


static SSL_CTX *server_ctx = NULL;
@@ -2523,6 +2524,7 @@ BOOL require_ocsp = FALSE;
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
@@ -2979,8 +2981,12 @@ tls_write(void * ct_ctx, const uschar *buff, size_t len, BOOL more)
{
size_t olen = len;
int outbytes, error;
-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" : "");
@@ -2988,7 +2994,9 @@ DEBUG(D_tls) debug_printf("%s(%p, %lu%s)\n", __FUNCTION__,
/* 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. */
+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 */
@@ -3007,10 +3015,13 @@ if ((more || corked))
#endif

   if (more)
+    {
+    *corkedp = corked;
     return len;
+    }
   buff = CUS corked->s;
   len = corked->ptr;
-  corked = NULL;
+  *corkedp = NULL;
   }


 for (int left = len; left > 0;)
diff --git a/test/confs/2152 b/test/confs/2152
new file mode 100644
index 0000000..f783192
--- /dev/null
+++ b/test/confs/2152
@@ -0,0 +1,76 @@
+# Exim test configuration 2152
+
+SERVER=
+
+.include DIR/aux-var/tls_conf_prefix
+
+primary_hostname = myhost.test.ex
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = chk_r
+
+#log_selector =  +tls_peerdn
+
+queue_only
+queue_run_in_order
+
+tls_advertise_hosts = *
+
+tls_certificate = DIR/aux-fixed/cert1
+tls_privatekey =  DIR/aux-fixed/cert1
+
+
+# ----- ACL -----
+
+begin acl
+
+chk_r:
+  accept    condition =    ${if = {$received_port}{PORT_D2}}
+  accept    verify =    recipient/callout
+
+# ----- Routers -----
+
+begin routers
+
+client:
+  driver = accept
+  condition = ${if !eq {SERVER}{server}}
+  transport = send_to_server
+
+srvr_v:
+  driver = accept
+  verify_only
+  transport = send_to_server_v
+
+
+# ----- Transports -----
+
+begin transports
+
+send_to_server:
+  driver =    smtp
+  allow_localhost
+  hosts =    127.0.0.1
+  port =    PORT_D
+  tls_verify_certificates = DIR/aux-fixed/cert1
+  tls_verify_cert_hostnames = :
+
+send_to_server_v:
+  driver =    smtp
+  allow_localhost
+  hosts =    127.0.0.1
+  port =    PORT_D2
+  tls_verify_certificates = DIR/aux-fixed/cert1
+  tls_verify_cert_hostnames = :
+
+
+# ----- Retry -----
+
+
+begin retry
+
+* * F,5d,10s
+
+
+# End
diff --git a/test/log/2152 b/test/log/2152
new file mode 100644
index 0000000..6796211
--- /dev/null
+++ b/test/log/2152
@@ -0,0 +1,9 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@??? U=CALLER P=local S=sss
+1999-03-02 09:44:33 Start queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmaX-0005vi-00 => a@??? R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes C="250 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 -qf
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D port PORT_D2
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@??? H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaX-0005vi-00@???