[exim-cvs] Make smtp_flush() work for TLS channel

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Make smtp_flush() work for TLS channel
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;