TLS: PIPELINING under OpenSSL
authorJeremy Harris <jgh146exb@wizmail.org>
Fri, 19 May 2017 21:55:25 +0000 (22:55 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Fri, 19 May 2017 21:55:25 +0000 (22:55 +0100)
doc/doc-txt/ChangeLog
src/src/tls-openssl.c
src/src/transport.c
test/confs/2107

index 12c1ff3..6ba9a3e 100644 (file)
@@ -76,7 +76,7 @@ JH/11 Bug 2104: Fix continued use of a transport connection with TLS.  In the
 JH/12 Fix check on SMTP command input synchronisation.  Previously there were
       false-negatives in the check that the sender had not preempted a response
       or prompt from Exim (running as a server), due to that code's lack of
-      awareness of the SMTP input buferring.
+      awareness of the SMTP input buffering.
 
 PP/04 Add commandline_checks_require_admin option.
       Exim drops privileges sanely, various checks such as -be aren't a
@@ -86,11 +86,11 @@ PP/04 Add commandline_checks_require_admin option.
       AND make fixes to the calling application, such as using `--` to stop
       processing options.
 
-JH/13 Do pipelining under TLS, with GnuTLS.  Previously, although safe, no
-      advantage was taken.  Now take care to pack both (client) MAIL,RCPT,DATA,
-      and (server) responses to those, into a single TLS record each way (this
-      usually means a single packet).  As a side issue, we can now detect
-      over-eager senders in non-pipelined mode.
+JH/13 Do pipelining under TLS.  Previously, although safe, no advantage was
+      taken.  Now take care to pack both (client) MAIL,RCPT,DATA, and (server)
+      responses to those, into a single TLS record each way (this usually means
+      a single packet).  As a side issue, smtp_enforce_sync now works on TLS
+      connections.
 
 
 Exim version 4.89
index 7f41c10..c09d9bd 100644 (file)
@@ -2483,8 +2483,7 @@ if (n > 0)
 BOOL
 tls_could_read(void)
 {
-/* XXX no actual inquiry into library; only our buffer */
-return ssl_xfer_buffer_lwm < ssl_xfer_buffer_hwm;
+return ssl_xfer_buffer_lwm < ssl_xfer_buffer_hwm || SSL_pending(server_ssl) > 0;
 }
 
 
@@ -2551,13 +2550,30 @@ Used by both server-side and client-side TLS.
 int
 tls_write(BOOL is_server, const uschar *buff, size_t len, BOOL more)
 {
-int outbytes;
-int error;
-int left = len;
+int outbytes, error, left;
 SSL *ssl = is_server ? server_ssl : client_ssl;
+static uschar * corked = NULL;
+static int c_size = 0, c_len = 0;
+
+DEBUG(D_tls) debug_printf("%s(%p, %d%s)\n", __FUNCTION__,
+  buff, left, 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. */
+
+if (is_server && (more || corked))
+  {
+  corked = string_catn(corked, &c_size, &c_len, buff, len);
+  if (more)
+    return len;
+  buff = CUS corked;
+  len = c_len;
+  corked = NULL; c_size = c_len = 0;
+  }
 
-DEBUG(D_tls) debug_printf("%s(%p, %d)\n", __FUNCTION__, buff, left);
-while (left > 0)
+for (left = len; left > 0;)
   {
   DEBUG(D_tls) debug_printf("SSL_write(SSL, %p, %d)\n", buff, left);
   outbytes = SSL_write(ssl, CS buff, left);
index 04b67f9..20d0b8a 100644 (file)
@@ -969,9 +969,11 @@ if (!(tctx->options & topt_no_headers))
 
   if (tctx->options & topt_add_delivery_date)
     {
-    uschar buffer[100];
-    int n = sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full));
-    if (!write_chunk(tctx, buffer, n)) goto bad;
+    uschar * s = tod_stamp(tod_full);
+
+    if (  !write_chunk(tctx, US"Delivery-date: ", 15)
+       || !write_chunk(tctx, s, Ustrlen(s))
+       || !write_chunk(tctx, US"\n", 1)) goto bad;
     }
 
   /* Then the message's headers. Don't write any that are flagged as "old";
index 9487445..6793673 100644 (file)
@@ -16,6 +16,7 @@ queue_only
 queue_run_in_order
 
 tls_advertise_hosts = *
+tls_require_ciphers = AES256-SHA
 
 # Set certificate only if server