Gitweb:
https://git.exim.org/exim.git/commitdiff/30398c0651d976f7ca2713ba9441c117eb37ed1e
Commit: 30398c0651d976f7ca2713ba9441c117eb37ed1e
Parent: 52236390cb37864f3a17bc922ee358138655df44
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Mon Nov 25 16:18:15 2019 +0000
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Sat Nov 30 23:16:24 2019 +0000
Make smtp_flush() work for TLS channel
---
src/src/smtp_in.c | 25 +++++++++++++++----------
src/src/tls-gnu.c | 3 +++
src/src/tls-openssl.c | 17 ++++++++++-------
3 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 301f3c5..b88fde1 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -947,16 +947,13 @@ if (fl.rcpt_in_progress)
/* Now write the string */
+if (
#ifndef DISABLE_TLS
-if (tls_in.active.sock >= 0)
- {
- if (tls_write(NULL, gs.s, gs.ptr, more) < 0)
- smtp_write_error = -1;
- }
-else
+ tls_in.active.sock >= 0 ? (tls_write(NULL, gs.s, gs.ptr, more) < 0) :
#endif
-
-if (fprintf(smtp_out, "%s", gs.s) < 0) smtp_write_error = -1;
+ (fwrite(gs.s, gs.ptr, 1, smtp_out) == 0)
+ )
+ smtp_write_error = -1;
}
@@ -967,8 +964,7 @@ if (fprintf(smtp_out, "%s", gs.s) < 0) smtp_write_error = -1;
/* This function isn't currently used within Exim (it detects errors when it
tries to read the next SMTP input), but is available for use in local_scan().
-For non-TLS connections, it flushes the output and checks for errors. For
-TLS-connections, it checks for a previously-detected TLS write error.
+It flushes the output and checks for errors.
Arguments: none
Returns: 0 for no error; -1 after an error
@@ -978,6 +974,15 @@ int
smtp_fflush(void)
{
if (tls_in.active.sock < 0 && fflush(smtp_out) != 0) smtp_write_error = -1;
+
+if (
+#ifndef DISABLE_TLS
+ tls_in.active.sock >= 0 ? (tls_write(NULL, NULL, 0, FALSE) < 0) :
+#endif
+ (fflush(smtp_out) != 0)
+ )
+ smtp_write_error = -1;
+
return smtp_write_error;
}
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index f3c3835..7b0f2f6 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -3311,6 +3311,9 @@ Arguments:
len number of bytes
more more data expected soon
+Calling with len zero and more unset will flush buffered writes. The buff
+argument can be null for that case.
+
Returns: the number of bytes after a successful write,
-1 after a failed write
*/
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 5ea4d96..7e3cc3f 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -3531,11 +3531,12 @@ Arguments:
Returns: the number of bytes after a successful write,
-1 after a failed write
-Used by both server-side and client-side TLS.
+Used by both server-side and client-side TLS. Calling with len zero and more unset
+will flush buffered writes; buff can be null for this case.
*/
int
-tls_write(void * ct_ctx, const uschar *buff, size_t len, BOOL more)
+tls_write(void * ct_ctx, const uschar * buff, size_t len, BOOL more)
{
size_t olen = len;
int outbytes, error;
@@ -3561,6 +3562,8 @@ a store reset there, so use POOL_PERM. */
if ((more || corked))
{
+ if (!len) buff = US &error; /* dummy just so that string_catn is ok */
+
#ifndef DISABLE_PIPE_CONNECT
int save_pool = store_pool;
store_pool = POOL_PERM;
@@ -3590,16 +3593,16 @@ for (int left = len; left > 0;)
DEBUG(D_tls) debug_printf("outbytes=%d error=%d\n", outbytes, error);
switch (error)
{
+ case SSL_ERROR_NONE: /* the usual case */
+ left -= outbytes;
+ buff += outbytes;
+ break;
+
case SSL_ERROR_SSL:
ERR_error_string_n(ERR_get_error(), ssl_errstring, sizeof(ssl_errstring));
log_write(0, LOG_MAIN, "TLS error (SSL_write): %s", ssl_errstring);
return -1;
- case SSL_ERROR_NONE:
- left -= outbytes;
- buff += outbytes;
- break;
-
case SSL_ERROR_ZERO_RETURN:
log_write(0, LOG_MAIN, "SSL channel closed on write");
return -1;