summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2017-05-19 22:55:25 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2017-05-19 22:55:25 +0100
commita5ffa9b475a426bc73366db01f7cc92a3811bc3a (patch)
treebbbbcf0a06f9c15f090adf4a4b3a4bc03dd21d30
parent16b33efd9367c4f0a2560b2facd50797fd17a2b6 (diff)
TLS: PIPELINING under OpenSSL
-rw-r--r--doc/doc-txt/ChangeLog12
-rw-r--r--src/src/tls-openssl.c30
-rw-r--r--src/src/transport.c8
-rw-r--r--test/confs/21071
4 files changed, 35 insertions, 16 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 12c1ff35b..6ba9a3e5e 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -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
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 7f41c106e..c09d9bdf6 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -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);
diff --git a/src/src/transport.c b/src/src/transport.c
index 04b67f9e9..20d0b8a52 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -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";
diff --git a/test/confs/2107 b/test/confs/2107
index 9487445cc..679367315 100644
--- a/test/confs/2107
+++ b/test/confs/2107
@@ -16,6 +16,7 @@ queue_only
queue_run_in_order
tls_advertise_hosts = *
+tls_require_ciphers = AES256-SHA
# Set certificate only if server