Fix bug with aborted server TLS connection, under GnuTLS
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 23 Oct 2016 13:09:55 +0000 (14:09 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 23 Oct 2016 13:09:55 +0000 (14:09 +0100)
Longstanding, but exposed by 60d10ce

doc/doc-txt/ChangeLog
src/src/daemon.c
src/src/tls-gnu.c

index 1267d75dcc2f6b559c7a3e47b04e468a4abd49d9..1fdfc126e1ec3f6ceafa4eb77cdf07dc54f9f988 100644 (file)
@@ -120,6 +120,12 @@ PP/01 Changed default Diffie-Hellman parameters to be Exim-specific, created
 PP/02 Unbreak build via pkg-config with new hash support when crypto headers
       are not in the system include path.
 
 PP/02 Unbreak build via pkg-config with new hash support when crypto headers
       are not in the system include path.
 
+JH/31 Fix longstanding bug with aborted TLS server connection handling.  Under
+      GnuTLS, when a sennsion startup failed (eg because the client disconnected)
+      Exim did stdio operations after fclose.  This was exposed by a recent
+      change which nulled out the file handle after the fclose.
+      
+
 
 Exim version 4.87
 -----------------
 
 Exim version 4.87
 -----------------
index 60275c02d9a958889988a0f3ad2ab779621473c0..dc49eeb85a32770ce98282c7c1539f844c5220cc 100644 (file)
@@ -385,10 +385,10 @@ if (pid == 0)
   likely what it depends on.) */
 
   smtp_active_hostname = primary_hostname;
   likely what it depends on.) */
 
   smtp_active_hostname = primary_hostname;
-  if (raw_active_hostname != NULL)
+  if (raw_active_hostname)
     {
     {
-    uschar *nah = expand_string(raw_active_hostname);
-    if (nah == NULL)
+    uschar * nah = expand_string(raw_active_hostname);
+    if (!nah)
       {
       if (!expand_string_forcedfail)
         {
       {
       if (!expand_string_forcedfail)
         {
@@ -402,7 +402,7 @@ if (pid == 0)
         _exit(EXIT_FAILURE);
         }
       }
         _exit(EXIT_FAILURE);
         }
       }
-    else if (nah[0] != 0) smtp_active_hostname = nah;
+    else if (*nah) smtp_active_hostname = nah;
     }
 
   /* Initialize the queueing flags */
     }
 
   /* Initialize the queueing flags */
@@ -518,11 +518,15 @@ if (pid == 0)
       }
     else
       {
       }
     else
       {
-      int i;
-      uschar * buf[128];
-      mac_smtp_fflush();
-      /* drain socket, for clean TCP FINs */
-      for(i = 16; read(fileno(smtp_in), buf, sizeof(buf)) > 0 && i > 0; ) i--;
+      if (smtp_out)
+       {
+       int i;
+       uschar buf[128];
+
+       mac_smtp_fflush();
+       /* drain socket, for clean TCP FINs */
+       for(i = 16; read(fileno(smtp_in), buf, sizeof(buf)) > 0 && i > 0; ) i--;
+       }
       search_tidyup();
       smtp_log_no_mail();                 /* Log no mail if configured */
 
       search_tidyup();
       smtp_log_no_mail();                 /* Log no mail if configured */
 
index 7ddd7a7248c6b4b447ebe7412853a3456c32323e..9afaa8feae6f250506e5308b58749324d5638a72 100644 (file)
@@ -1827,13 +1827,17 @@ if (rc != GNUTLS_E_SUCCESS)
   until the server times out. */
 
   if (sigalrm_seen)
   until the server times out. */
 
   if (sigalrm_seen)
+    {
     tls_error(US"gnutls_handshake", "timed out", NULL);
     tls_error(US"gnutls_handshake", "timed out", NULL);
+    gnutls_db_remove_session(state->session);
+    }
   else
     {
     tls_error(US"gnutls_handshake", gnutls_strerror(rc), NULL);
     (void) gnutls_alert_send_appropriate(state->session, rc);
   else
     {
     tls_error(US"gnutls_handshake", gnutls_strerror(rc), NULL);
     (void) gnutls_alert_send_appropriate(state->session, rc);
+    gnutls_deinit(state->session);
     millisleep(500);
     millisleep(500);
-    shutdown(state->fd_in, SHUT_WR);
+    shutdown(state->fd_out, SHUT_WR);
     for (rc = 1024; fgetc(smtp_in) != EOF && rc > 0; ) rc--;   /* drain skt */
     (void)fclose(smtp_out);
     (void)fclose(smtp_in);
     for (rc = 1024; fgetc(smtp_in) != EOF && rc > 0; ) rc--;   /* drain skt */
     (void)fclose(smtp_out);
     (void)fclose(smtp_in);