Hi all,
Currently exim supports tls_on_connect for incoming connections, but
not for outgoing e-mail. Some mail servers, such as gmail require
tls_on_connect.
The patch attached adds an option "tls_on_connect" of type boolean
to the remote_smtp transport with default false. If the option is
set to true TLS negotiation is started before waiting for the
initial OK reply, and issuing STARTTLS later and retrying in clear
text are both suppressed.
I have tested these changes with debian exim4 4.69-11, and I have
verified that this patch leaves exim in a compilable state.
Can someone please review my patch?
Should I also contribute patches for the documentation?
Is this the right way to contribute patches to exim?
Kind regards,
Arnold Metselaar
Index: src/transports/smtp.c
===================================================================
RCS file: /repo/exim/exim-src/src/transports/smtp.c,v
retrieving revision 1.42
diff -u -p -r1.42 smtp.c
--- src/transports/smtp.c 10 Jun 2009 07:34:05 -0000 1.42
+++ src/transports/smtp.c 22 Aug 2009 10:56:14 -0000
@@ -128,6 +128,8 @@ optionlist smtp_transport_options[] = {
(void *)offsetof(smtp_transport_options_block, tls_certificate) },
{ "tls_crl", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_crl) },
+ { "tls_on_connect", opt_bool,
+ (void *)offsetof(smtp_transport_options_block, tls_on_connect) },
{ "tls_privatekey", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_privatekey) },
{ "tls_require_ciphers", opt_stringptr,
@@ -185,7 +187,8 @@ smtp_transport_options_block smtp_transp
FALSE, /* lmtp_ignore_quota */
TRUE /* retry_include_ip_address */
#ifdef SUPPORT_TLS
- ,NULL, /* tls_certificate */
+ ,FALSE, /* tls_on_connect */
+ NULL, /* tls_certificate */
NULL, /* tls_crl */
NULL, /* tls_privatekey */
NULL, /* tls_require_ciphers */
@@ -931,7 +934,50 @@ if (continue_hostname == NULL)
NULL, DEFER, FALSE);
return DEFER;
}
+
+#ifdef SUPPORT_TLS
+ /* If the remote host expects tls on connect we start tls directly and skip to REDO_EHLO. */
+ if (ob->tls_on_connect)
+ {
+ int rc = tls_client_start(inblock.sock,
+ host,
+ addrlist,
+ NULL, /* No DH param */
+ ob->tls_certificate,
+ ob->tls_privatekey,
+ ob->tls_verify_certificates,
+ ob->tls_crl,
+ ob->tls_require_ciphers,
+ ob->gnutls_require_mac,
+ ob->gnutls_require_kx,
+ ob->gnutls_require_proto,
+ ob->command_timeout);
+ /* TLS negotiation failed; give an error. From outside, this function may
+ be called again to try in clear on a new connection, if the options permit
+ it for this host. */
+
+ if (rc != OK)
+ {
+ save_errno = ERRNO_TLSFAILURE;
+ message = US"failure while setting up TLS session on connect";
+ send_quit = FALSE;
+ goto TLS_FAILED;
+ }
+
+ /* TLS session is set up. */
+
+ for (addr = addrlist; addr != NULL; addr = addr->next)
+ {
+ if (addr->transport_return == PENDING_DEFER)
+ {
+ addr->cipher = tls_cipher;
+ addr->peerdn = tls_peerdn;
+ }
+ }
+ }
+
+#endif
/* Expand the greeting message while waiting for the initial response. (Makes
sense if helo_data contains ${lookup dnsdb ...} stuff). The expansion is
delayed till here so that $sending_interface and $sending_port are set. */
@@ -1031,7 +1077,7 @@ goto SEND_QUIT;
/* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
#ifdef SUPPORT_TLS
- tls_offered = esmtp &&
+ tls_offered = esmtp && !ob->tls_on_connect &&
pcre_exec(regex_STARTTLS, NULL, CS buffer, Ustrlen(buffer), 0,
PCRE_EOPT, NULL, 0) >= 0;
#endif
@@ -1133,7 +1179,7 @@ another process, and so we won't have ex
expand it here. $sending_ip_address and $sending_port are set up right at the
start of the Exim process (in exim.c). */
-if (tls_active >= 0)
+if ( (tls_active >= 0) && (!ob->tls_on_connect) )
{
if (helo_data == NULL)
{
@@ -2758,7 +2804,7 @@ for (cutoff_retry = 0; expired &&
#ifdef SUPPORT_TLS
if (rc == DEFER && first_addr->basic_errno == ERRNO_TLSFAILURE &&
- ob->tls_tempfail_tryclear &&
+ ob->tls_tempfail_tryclear && !ob->tls_on_connect &&
verify_check_this_host(&(ob->hosts_require_tls), NULL, host->name,
host->address, NULL) != OK)
{
Index: src/transports/smtp.h
===================================================================
RCS file: /repo/exim/exim-src/src/transports/smtp.h,v
retrieving revision 1.15
diff -u -p -r1.15 smtp.h
--- src/transports/smtp.h 10 Jun 2009 07:34:05 -0000 1.15
+++ src/transports/smtp.h 22 Aug 2009 10:56:14 -0000
@@ -47,6 +47,7 @@ typedef struct {
BOOL lmtp_ignore_quota;
BOOL retry_include_ip_address;
#ifdef SUPPORT_TLS
+ BOOL tls_on_connect;
uschar *tls_certificate;
uschar *tls_crl;
uschar *tls_privatekey;