GnuTLS: Fix client detection of server reject of client cert under TLS1.3
[exim.git] / src / src / smtp_out.c
index 1209c7fd9c8778ffa4410386209b0bd5e6ff5522..b7a8354797fa5c8b26ab0b60c1823ae839411976 100644 (file)
@@ -191,6 +191,8 @@ switch (tcp_out_fastopen)
        tcp_out_fastopen = TFO_NOT_USED;
        }
     break;
+
+  default: break; /* compiler quietening */
   }
 # endif
 }
@@ -512,34 +514,34 @@ int
 smtp_write_command(void * sx, int mode, const char *format, ...)
 {
 smtp_outblock * outblock = &((smtp_context *)sx)->outblock;
-int count;
 int rc = 0;
-va_list ap;
 
 if (format)
   {
+  gstring gs = { .size = big_buffer_size, .ptr = 0, .s = big_buffer };
+  va_list ap;
+
   va_start(ap, format);
-  if (!string_vformat(big_buffer, big_buffer_size, CS format, ap))
+  if (!string_vformat(&gs, FALSE, CS format, ap))
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing "
       "SMTP");
   va_end(ap);
-  count = Ustrlen(big_buffer);
+  string_from_gstring(&gs);
 
-  if (count > outblock->buffersize)
+  if (gs.ptr > outblock->buffersize)
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing "
       "SMTP");
 
-  if (count > outblock->buffersize - (outblock->ptr - outblock->buffer))
+  if (gs.ptr > outblock->buffersize - (outblock->ptr - outblock->buffer))
     {
     rc = outblock->cmd_count;                 /* flush resets */
     if (!flush_buffer(outblock, SCMD_FLUSH)) return -1;
     }
 
-  Ustrncpy(CS outblock->ptr, big_buffer, count);
-  outblock->ptr += count;
+  Ustrncpy(CS outblock->ptr, gs.s, gs.ptr);
+  outblock->ptr += gs.ptr;
   outblock->cmd_count++;
-  count -= 2;
-  big_buffer[count] = 0;     /* remove \r\n for error message */
+  gs.ptr -= 2; string_from_gstring(&gs); /* remove \r\n for error message */
 
   /* We want to hide the actual data sent in AUTH transactions from reflections
   and logs. While authenticating, a flag is set in the outblock to enable this.
@@ -688,20 +690,22 @@ Returns:    TRUE if a valid, non-error response was received; else FALSE
 /*XXX could move to smtp transport; no other users */
 
 BOOL
-smtp_read_response(void * sx0, uschar *buffer, int size, int okdigit,
+smtp_read_response(void * sx0, uschar * buffer, int size, int okdigit,
    int timeout)
 {
 smtp_context * sx = sx0;
-uschar *ptr = buffer;
-int count = 0;
+uschar * ptr = buffer;
+int count = 0, rc;
 
 errno = 0;  /* Ensure errno starts out zero */
 
 #ifdef EXPERIMENTAL_PIPE_CONNECT
 if (sx->pending_BANNER || sx->pending_EHLO)
-  if (smtp_reap_early_pipe(sx, &count) != OK)
+  if ((rc = smtp_reap_early_pipe(sx, &count)) != OK)
     {
     DEBUG(D_transport) debug_printf("failed reaping pipelined cmd responsess\n");
+    buffer[0] = '\0';
+    if (rc == DEFER) errno = ERRNO_TLSFAILURE;
     return FALSE;
     }
 #endif