[Exim] Exim behaviour on 4xx response to STARTTLS.

Top Page
Delete this message
Reply to this message
Author: David Woodhouse
Date:  
To: exim-users
Subject: [Exim] Exim behaviour on 4xx response to STARTTLS.
There are MTAs out there which when configured to use TLS but the keys are
missing, will advertise STARTTLS capability but always respond to a
STARTTLS request with a 4xx temporary failure.

Those MTAs observed to do this include some versions of Sendmail and Exim 3.

Exim, upon receiving a 4xx response to STARTTLS, will disconnect from the
offending server and try others, or defer the mail delivery if no
alternatives are available.

If Exim receives a 5xx permanent failure response, or if the server
responds agreeably but something goes wrong with the TLS setup, Exim
will go ahead and deliver in the clear as if TLS capability had not been
advertised -- unless explicitly configured not to send cleartext to the host
in question.

I believe that Exim should do the same upon receiving a 4xx temporary
failure, rather than deferring the delivery. In this situation I've seen
Exim hold on to mail messages until they bounced, rather than just giving up
on TLS and delivering them in the clear.

OTOH, it has been argued that Exim _should_ disconnect from the offending
server and try other hosts, as sending with TLS to a working server is
preferable to sending without TLS.

I maintain that in the case where _all_ the available servers are doing the
same thing, sending the mail at all is preferable to waiting for the servers
to get un-misconfigured. That failure mode is IMHO far worse than the
'problem' of failing to use TLS when we might possibly have managed to do
so opportunistically. If I want to make sure TLS is used, that's what
the hosts_require_tls option is for.

Nonetheless, because the argument comes from someone I'm inclined to
respect, I'll grant that perhaps it should be a configurable option.

The patch below probably¹ implements a 'tls_tempfail_fallback' option. If
set, which is the default, it will cause Exim to continue with a session
and deliver mail in cleartext if STARTTLS fails with a 4xx error, just as
it would on a 5xx error. Obviously if the host in question is in
hosts_require_tls then the delivery is deferred.

If the value of this option is false then the current behaviour, which
annoyed me so much by causing my outgoing mail to certain domains to bounce
gratuitously, remains.

Comments?

--- exim-4.04/src/transports/smtp.c~    Thu Apr 18 09:08:35 2002
+++ exim-4.04/src/transports/smtp.c    Tue Apr 23 22:50:35 2002
@@ -93,7 +93,9 @@
   { "tls_require_ciphers",   opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, tls_require_ciphers) },
   { "tls_verify_certificates", opt_stringptr,
-      (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) }
+      (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) },
+  { "tls_tempfail_fallback", opt_bool,
+      (void *)offsetof(smtp_transport_options_block, tls_tempfail_fallback) }
   #endif
 };


@@ -139,7 +141,8 @@
  ,NULL,                /* tls_certificate */
   NULL,                /* tls_privatekey */
   NULL,                /* tls_require_ciphers */
-  NULL                 /* tls_verify_certificates */
+  NULL,                /* tls_verify_certificates */
+  TRUE                 /* tls_tempfail_fallback */
   #endif
 };


@@ -838,15 +841,17 @@
if (!smtp_write_command(&outblock, FALSE, "STARTTLS\r\n")) goto SEND_FAILED;

/* If there is an I/O error, or if there is a temporary failure of
- the STARTTLS command, transmission of this message is deferred. If there is
- an outright rejection of STARTTLS, we proceed to try to send the message in
+ the STARTTLS command and the tls_tempfail_fallback option is not set,
+ transmission of this message is deferred. If there is an outright
+ rejection of STARTTLS, we proceed to try to send the message in
clear, unless the host is in hosts_require_tls (tested below). */

   if (!smtp_read_response(&inblock, buffer2, sizeof(buffer2), '2',
       ob->command_timeout))
     {
     Ustrncpy(buffer, buffer2, sizeof(buffer));
-    if (errno != 0 || buffer2[0] == 0 || buffer2[0] == '4')
+    if (errno != 0 || buffer2[0] == 0 ||
+    (buffer2[0] == '4' && !ob->tls_tempfail_fallback))
       goto RESPONSE_FAILED;
     }


--- exim-4.04/src/transports/smtp.h~    Thu Apr 18 09:08:35 2002
+++ exim-4.04/src/transports/smtp.h    Tue Apr 23 22:37:10 2002
@@ -42,6 +42,7 @@
   uschar *tls_privatekey;
   uschar *tls_require_ciphers;
   uschar *tls_verify_certificates;
+  BOOL  tls_tempfail_fallback;
   #endif
 } smtp_transport_options_block;





--
dwmw2

¹ It builds. It's untested and I hadn't looked at Exim source for about 5
years beforehand. YMMV :)