More tls_sni support: outbound, logging.
authorPhil Pennock <pdp@exim.org>
Fri, 4 May 2012 15:27:09 +0000 (08:27 -0700)
committerPhil Pennock <pdp@exim.org>
Fri, 4 May 2012 15:27:09 +0000 (08:27 -0700)
tls_sni as SMTP transport option.
Use correct storage pool for copying tls_sni, so survives for life of process.
Add +tls_sni log-selector, for inbound tls_sni.
Update exipick to handle -tls_sni in spool files.

Also reset tls_bits at start of outbound connection (was missing).

16 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
doc/doc-txt/OptionLists.txt
src/src/exipick.src
src/src/functions.h
src/src/globals.c
src/src/local_scan.h
src/src/macros.h
src/src/receive.c
src/src/smtp_in.c
src/src/string.c
src/src/tls-gnu.c
src/src/tls-openssl.c
src/src/transports/smtp.c
src/src/transports/smtp.h

index 32e24ca8086811f1669b75f8f3c2436f835433f5..ea4e040e15d6f8d2b09dbb53e7fdedd003e653fa 100644 (file)
@@ -11899,8 +11899,8 @@ If the variable appears in &%tls_certificate%& then this option and
 a different certificate to be presented (and optionally a different key to be
 used) to the client, based upon the value of the SNI extension.
 
 a different certificate to be presented (and optionally a different key to be
 used) to the client, based upon the value of the SNI extension.
 
-The value will be retained for the lifetime of the message, and not changed
-during outbound SMTP.
+The value will be retained for the lifetime of the message.  During outbound
+SMTP deliveries, it reflects the value of the tls_sni option on the transport.
 
 This is currently only available when using OpenSSL, built with support for
 SNI.
 
 This is currently only available when using OpenSSL, built with support for
 SNI.
@@ -15627,6 +15627,12 @@ receiving incoming messages as a server. If you want to supply certificates for
 use when sending messages as a client, you must set the &%tls_certificate%&
 option in the relevant &(smtp)& transport.
 
 use when sending messages as a client, you must set the &%tls_certificate%&
 option in the relevant &(smtp)& transport.
 
+.new
+If the option contains &$tls_sni$& and Exim is built against OpenSSL, then
+if the OpenSSL build supports TLS extensions and the TLS client sends the
+Server Name Indication extension, then this option and &%tls_privatekey%&
+will be re-expanded.
+.wen
 
 .option tls_crl main string&!! unset
 .cindex "TLS" "server certificate revocation list"
 
 .option tls_crl main string&!! unset
 .cindex "TLS" "server certificate revocation list"
@@ -15659,6 +15665,11 @@ the expansion is forced to fail, or the result is an empty string, the private
 key is assumed to be in the same file as the server's certificates. See chapter
 &<<CHAPTLS>>& for further details.
 
 key is assumed to be in the same file as the server's certificates. See chapter
 &<<CHAPTLS>>& for further details.
 
+.new
+See &%tls_certificate%& discussion of &$tls_sni$& for when this option may be
+re-expanded.
+.wen
+
 
 .option tls_remember_esmtp main boolean false
 .cindex "TLS" "esmtp state; remembering"
 
 .option tls_remember_esmtp main boolean false
 .cindex "TLS" "esmtp state; remembering"
@@ -22371,6 +22382,20 @@ ciphers is a preference order.
 
 
 
 
 
 
+.new
+.option tls_sni smtp string&!! unset
+.cindex "TLS" "Server Name Indication"
+.vindex "&$tls_sni$&"
+If this option is set then it sets the $tls_sni variable and causes any
+TLS session to pass this value as the Server Name Indication extension to
+the remote side, which can be used by the remote side to select an appropriate
+certificate and private key for the session.
+
+OpenSSL only, also requiring a build of OpenSSL that supports TLS extensions.
+.wen
+
+
+
 .option tls_tempfail_tryclear smtp boolean true
 .cindex "4&'xx'& responses" "to STARTTLS"
 When the server host is not in &%hosts_require_tls%&, and there is a problem in
 .option tls_tempfail_tryclear smtp boolean true
 .cindex "4&'xx'& responses" "to STARTTLS"
 When the server host is not in &%hosts_require_tls%&, and there is a problem in
@@ -33155,6 +33180,7 @@ selection marked by asterisks:
 &` tls_certificate_verified   `&  certificate verification status
 &`*tls_cipher                 `&  TLS cipher suite on <= and => lines
 &` tls_peerdn                 `&  TLS peer DN on <= and => lines
 &` tls_certificate_verified   `&  certificate verification status
 &`*tls_cipher                 `&  TLS cipher suite on <= and => lines
 &` tls_peerdn                 `&  TLS peer DN on <= and => lines
+&` tls_sni                    `&  TLS SNI on <= lines
 &` unknown_in_list            `&  DNS lookup failed in list match
 
 &` all                        `&  all of the above
 &` unknown_in_list            `&  DNS lookup failed in list match
 
 &` all                        `&  all of the above
@@ -33450,6 +33476,12 @@ connection, the cipher suite used is added to the log line, preceded by X=.
 connection, and a certificate is supplied by the remote host, the peer DN is
 added to the log line, preceded by DN=.
 .next
 connection, and a certificate is supplied by the remote host, the peer DN is
 added to the log line, preceded by DN=.
 .next
+.cindex "log" "TLS SNI"
+.cindex "TLS" "logging SNI"
+&%tls_sni%&: When a message is received over an encrypted connection, and
+the remote host provided the Server Name Indication extension, the SNI is
+added to the log line, preceded by SNI=.
+.next
 .cindex "log" "DNS failure in list"
 &%unknown_in_list%&: This setting causes a log entry to be written when the
 result of a list match is failure because a DNS lookup failed.
 .cindex "log" "DNS failure in list"
 &%unknown_in_list%&: This setting causes a log entry to be written when the
 result of a list match is failure because a DNS lookup failed.
index 4ad79c28e274ea97f8fea730ff1bbb5facac6a1d..55cde6dcffa16fcb1a69e6fcdc808af61302265d 100644 (file)
@@ -75,6 +75,8 @@ PP/16 Removed "dont_insert_empty_fragments" fron "openssl_options".
 
 PP/17 OpenSSL: new expansion var $tls_sni, which if used in tls_certificate
       lets Exim select keys and certificates based upon TLS SNI from client.
 
 PP/17 OpenSSL: new expansion var $tls_sni, which if used in tls_certificate
       lets Exim select keys and certificates based upon TLS SNI from client.
+      Also option tls_sni on SMTP Transports.  Also clear $tls_bits correctly
+      before an outbound SMTP session.  New log_selector, +tls_sni.
 
 
 Exim version 4.77
 
 
 Exim version 4.77
index b788b45dc47f029bb903dc8825ef113ad7f1dd10..2872d241f0f74857095d85ba1b521e3c4e44142e 100644 (file)
@@ -47,6 +47,13 @@ Version 4.78
     sends the TLS Server Name Indication extension, to permit choosing a
     different certificate; tls_privatekey will also be re-expanded.  You must
     still set these options to expand to valid files when $tls_sni is not set.
     sends the TLS Server Name Indication extension, to permit choosing a
     different certificate; tls_privatekey will also be re-expanded.  You must
     still set these options to expand to valid files when $tls_sni is not set.
+
+    The SMTP Transport has gained the option tls_sni, which will set a hostname
+    for outbound TLS sessions, and set $tls_sni too.
+
+    A new log_selector, +tls_sni, has been added, to log received SNI values
+    for Exim as a server.
+
     Currently OpenSSL only.
 
 
     Currently OpenSSL only.
 
 
index b10f3f1aaa98f09c5648c490652af443e11adad4..52a24b1984584045bc5964ba0bf7cc88c1e55c4c 100644 (file)
@@ -554,6 +554,7 @@ tls_privatekey                       string*         unset         main
 tls_remember_emstp                   boolean         false         main              4.21
 tls_require_ciphers                  string*         unset         smtp              4.00 replaces tls_verify_ciphers
                                      string*         unset         main              4.33
 tls_remember_emstp                   boolean         false         main              4.21
 tls_require_ciphers                  string*         unset         smtp              4.00 replaces tls_verify_ciphers
                                      string*         unset         main              4.33
+tls_sni                              string*         unset         main              4.78
 tls_tempfail_tryclear                boolean         true          smtp              4.05
 tls_try_verify_hosts                 host list       unset         main              4.00
 tls_verify_certificates              string*         unset         main              3.20
 tls_tempfail_tryclear                boolean         true          smtp              4.05
 tls_try_verify_hosts                 host list       unset         main              4.00
 tls_verify_certificates              string*         unset         main              3.20
index 811092dc142bde6b904c00f8f8383ba60576e6ec..ed3b6615436ed6df7bfccd0780abe9b24190a6e1 100644 (file)
@@ -955,6 +955,8 @@ sub _parse_header {
         $self->{_vars}{tls_cipher} = $arg;
       } elsif ($tag eq '-tls_peerdn') {
         $self->{_vars}{tls_peerdn} = $arg;
         $self->{_vars}{tls_cipher} = $arg;
       } elsif ($tag eq '-tls_peerdn') {
         $self->{_vars}{tls_peerdn} = $arg;
+      } elsif ($tag eq '-tls_sni') {
+        $self->{_vars}{tls_sni} = $arg;
       } elsif ($tag eq '-host_address') {
         $self->{_vars}{sender_host_port} = $self->_get_host_and_port(\$arg);
         $self->{_vars}{sender_host_address} = $arg;
       } elsif ($tag eq '-host_address') {
         $self->{_vars}{sender_host_port} = $self->_get_host_and_port(\$arg);
         $self->{_vars}{sender_host_address} = $arg;
@@ -1793,6 +1795,10 @@ The cipher suite that was negotiated for encrypted SMTP connections.
 
 The value of the Distinguished Name of the certificate if Exim is configured to request one
 
 
 The value of the Distinguished Name of the certificate if Exim is configured to request one
 
+=item S . $tls_sni
+
+The value of the Server Name Indication TLS extension sent by a client, if one was sent.
+
 =item N + $warning_count
 
 The number of delay warnings which have been sent for this message.
 =item N + $warning_count
 
 The number of delay warnings which have been sent for this message.
index f1af42ee589a5449000616a37baf9dc211516c80..220235235db63757b2bc4fba1e06e90df5e33a0c 100644 (file)
@@ -23,7 +23,7 @@ extern uschar *init_perl(uschar *);
 #ifdef SUPPORT_TLS
 extern int     tls_client_start(int, host_item *, address_item *, uschar *,
                  uschar *, uschar *, uschar *, uschar *, uschar *, uschar *,
 #ifdef SUPPORT_TLS
 extern int     tls_client_start(int, host_item *, address_item *, uschar *,
                  uschar *, uschar *, uschar *, uschar *, uschar *, uschar *,
-                 uschar *, uschar *, int);
+                 uschar *, uschar *, uschar *, int);
 extern void    tls_close(BOOL);
 extern int     tls_feof(void);
 extern int     tls_ferror(void);
 extern void    tls_close(BOOL);
 extern int     tls_feof(void);
 extern int     tls_ferror(void);
index 7985cd3f066007ba2102e525ddd43ac0cee3a678..f11c7c2dbacfac87bd72041f8b813da306fd123c 100644 (file)
@@ -697,7 +697,7 @@ uschar *log_file_path          = US LOG_FILE_PATH
 /* Those log options with L_xxx identifiers have values less than 0x800000 and
 are the ones that get put into log_write_selector. They can be used in calls to
 log_write() to test for the bit. The options with LX_xxx identifiers have
 /* Those log options with L_xxx identifiers have values less than 0x800000 and
 are the ones that get put into log_write_selector. They can be used in calls to
 log_write() to test for the bit. The options with LX_xxx identifiers have
-values greater than 0x80000000 and are put int log_extra_selector (without the
+values greater than 0x80000000 and are put into log_extra_selector (without the
 top bit). They are never used in calls to log_write(), but are tested
 independently. This separation became necessary when the number of log
 selectors was getting close to filling a 32-bit word. */
 top bit). They are never used in calls to log_write(), but are tested
 independently. This separation became necessary when the number of log
 selectors was getting close to filling a 32-bit word. */
@@ -746,6 +746,7 @@ bit_table log_options[]        = {
   { US"tls_certificate_verified",     LX_tls_certificate_verified },
   { US"tls_cipher",                   LX_tls_cipher },
   { US"tls_peerdn",                   LX_tls_peerdn },
   { US"tls_certificate_verified",     LX_tls_certificate_verified },
   { US"tls_cipher",                   LX_tls_cipher },
   { US"tls_peerdn",                   LX_tls_peerdn },
+  { US"tls_sni",                      LX_tls_sni },
   { US"unknown_in_list",              LX_unknown_in_list }
 };
 
   { US"unknown_in_list",              LX_unknown_in_list }
 };
 
index 25b194407ad04a967cc49fe98f0ef7fd55917506..aedfc9f92f5c06bdd4ee734e252e102b95ae6805 100644 (file)
@@ -186,7 +186,7 @@ extern uschar *rfc2047_decode(uschar *, BOOL, uschar *, int, int *, uschar **);
 extern int     smtp_fflush(void);
 extern void    smtp_printf(const char *, ...) PRINTF_FUNCTION(1,2);
 extern void    smtp_vprintf(const char *, va_list);
 extern int     smtp_fflush(void);
 extern void    smtp_printf(const char *, ...) PRINTF_FUNCTION(1,2);
 extern void    smtp_vprintf(const char *, va_list);
-extern uschar *string_copy(uschar *);
+extern uschar *string_copy(const uschar *);
 extern uschar *string_copyn(uschar *, int);
 extern uschar *string_sprintf(const char *, ...) PRINTF_FUNCTION(1,2);
 
 extern uschar *string_copyn(uschar *, int);
 extern uschar *string_sprintf(const char *, ...) PRINTF_FUNCTION(1,2);
 
index c1c4cc33f703faeedaf500d5268f86daf336443c..9b41226e51470feb47b2095b09604d49fcf19415 100644 (file)
@@ -407,7 +407,8 @@ set all the bits in a multi-word selector. */
 #define LX_tls_certificate_verified    0x80100000
 #define LX_tls_cipher                  0x80200000
 #define LX_tls_peerdn                  0x80400000
 #define LX_tls_certificate_verified    0x80100000
 #define LX_tls_cipher                  0x80200000
 #define LX_tls_peerdn                  0x80400000
-#define LX_unknown_in_list             0x80800000
+#define LX_tls_sni                     0x80800000
+#define LX_unknown_in_list             0x81000000
 
 #define L_default     (L_connection_reject        | \
                        L_delay_delivery           | \
 
 #define L_default     (L_connection_reject        | \
                        L_delay_delivery           | \
index 71052657cdc83e26af7b9bb94b755527498b9cb7..aaaf64ce6f1e9f797462af60bddfc9c5d3fbff68 100644 (file)
@@ -3488,6 +3488,11 @@ if ((log_extra_selector & LX_tls_certificate_verified) != 0 &&
 if ((log_extra_selector & LX_tls_peerdn) != 0 && tls_peerdn != NULL)
   s = string_append(s, &size, &sptr, 3, US" DN=\"",
     string_printing(tls_peerdn), US"\"");
 if ((log_extra_selector & LX_tls_peerdn) != 0 && tls_peerdn != NULL)
   s = string_append(s, &size, &sptr, 3, US" DN=\"",
     string_printing(tls_peerdn), US"\"");
+#ifndef USE_GNUTLS
+if ((log_extra_selector & LX_tls_sni) != 0 && tls_sni != NULL)
+  s = string_append(s, &size, &sptr, 3, US" SNI=\"",
+    string_printing(tls_sni), US"\"");
+#endif
 #endif
 
 if (sender_host_authenticated != NULL)
 #endif
 
 if (sender_host_authenticated != NULL)
index 23bc5315e8f22978a6809c46bdd113d8af0cc0d8..d1c10f00fb5b81f3a8ddb9f26390d25425245684 100644 (file)
@@ -841,6 +841,11 @@ if ((log_extra_selector & LX_tls_certificate_verified) != 0 &&
 if ((log_extra_selector & LX_tls_peerdn) != 0 && tls_peerdn != NULL)
   s = string_append(s, &size, &ptr, 3, US" DN=\"",
     string_printing(tls_peerdn), US"\"");
 if ((log_extra_selector & LX_tls_peerdn) != 0 && tls_peerdn != NULL)
   s = string_append(s, &size, &ptr, 3, US" DN=\"",
     string_printing(tls_peerdn), US"\"");
+#ifndef USE_GNUTLS
+if ((log_extra_selector & LX_tls_sni) != 0 && tls_sni != NULL)
+  s = string_append(s, &size, &ptr, 3, US" SNI=\"",
+    string_printing(tls_sni), US"\"");
+#endif
 #endif
 
 sep = (smtp_connection_had[SMTP_HBUFF_SIZE-1] != SCH_NONE)?
 #endif
 
 sep = (smtp_connection_had[SMTP_HBUFF_SIZE-1] != SCH_NONE)?
index 0a321ee1f761b998449fa3a7a455148f879cac8f..3fea7c048393e4006d2cf1b8adc2414438f46dc6 100644 (file)
@@ -415,7 +415,7 @@ Returns:  copy of string in new store
 */
 
 uschar *
 */
 
 uschar *
-string_copy(uschar *s)
+string_copy(const uschar *s)
 {
 int len = Ustrlen(s) + 1;
 uschar *ss = store_get(len);
 {
 int len = Ustrlen(s) + 1;
 uschar *ss = store_get(len);
index 2f952e47b3aeef121f294ae8e6d521f46fa57841..7e87dded0e0859f93dc6196ac047bb31e470fa91 100644 (file)
@@ -1055,6 +1055,7 @@ Arguments:
   dhparam           DH parameter file
   certificate       certificate file
   privatekey        private key file
   dhparam           DH parameter file
   certificate       certificate file
   privatekey        private key file
+  sni               TLS SNI to send to remote host
   verify_certs      file for certificate verify
   verify_crl        CRL for verify
   require_ciphers   list of allowed ciphers or NULL
   verify_certs      file for certificate verify
   verify_crl        CRL for verify
   require_ciphers   list of allowed ciphers or NULL
@@ -1069,8 +1070,9 @@ Returns:            OK/DEFER/FAIL (because using common functions),
 
 int
 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
 
 int
 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
-  uschar *certificate, uschar *privatekey, uschar *verify_certs,
-  uschar *verify_crl, uschar *require_ciphers, uschar *require_mac,
+  uschar *certificate, uschar *privatekey, uschar *sni ARG_UNUSED,
+  uschar *verify_certs, uschar *verify_crl,
+  uschar *require_ciphers, uschar *require_mac,
   uschar *require_kx, uschar *require_proto, int timeout)
 {
 const gnutls_datum *server_certs;
   uschar *require_kx, uschar *require_proto, int timeout)
 {
 const gnutls_datum *server_certs;
index 8cc2457e5b6cbe88d6486db9d12813c51ad5b1b6..e609670ee73e57d0ebb311dfdf98178e9d222e75 100644 (file)
@@ -385,15 +385,18 @@ tls_servername_cb(SSL *s, int *ad ARG_UNUSED, void *arg)
 const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
 const tls_ext_ctx_cb *cbinfo = (tls_ext_ctx_cb *) arg;
 int rc;
 const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
 const tls_ext_ctx_cb *cbinfo = (tls_ext_ctx_cb *) arg;
 int rc;
+int old_pool = store_pool;
 
 if (!servername)
   return SSL_TLSEXT_ERR_OK;
 
 
 if (!servername)
   return SSL_TLSEXT_ERR_OK;
 
-DEBUG(D_tls) debug_printf("TLS SNI: %s%s\n", servername,
+DEBUG(D_tls) debug_printf("Received TLS SNI \"%s\"%s\n", servername,
     reexpand_tls_files_for_sni ? "" : " (unused for certificate selection)");
 
 /* Make the extension value available for expansion */
     reexpand_tls_files_for_sni ? "" : " (unused for certificate selection)");
 
 /* Make the extension value available for expansion */
-tls_sni = servername;
+store_pool = POOL_PERM;
+tls_sni = string_copy(US servername);
+store_pool = old_pool;
 
 if (!reexpand_tls_files_for_sni)
   return SSL_TLSEXT_ERR_OK;
 
 if (!reexpand_tls_files_for_sni)
   return SSL_TLSEXT_ERR_OK;
@@ -550,10 +553,13 @@ if (rc != OK) return rc;
 
 /* If we need to handle SNI, do so */
 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
 
 /* If we need to handle SNI, do so */
 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
-/* We always do this, so that $tls_sni is available even if not used in
-tls_certificate */
-SSL_CTX_set_tlsext_servername_callback(ctx, tls_servername_cb);
-SSL_CTX_set_tlsext_servername_arg(ctx, cbinfo);
+if (host == NULL)
+  {
+  /* We always do this, so that $tls_sni is available even if not used in
+  tls_certificate */
+  SSL_CTX_set_tlsext_servername_callback(ctx, tls_servername_cb);
+  SSL_CTX_set_tlsext_servername_arg(ctx, cbinfo);
+  }
 #endif
 
 /* Set up the RSA callback */
 #endif
 
 /* Set up the RSA callback */
@@ -944,6 +950,7 @@ Argument:
   dhparam          DH parameter file
   certificate      certificate file
   privatekey       private key file
   dhparam          DH parameter file
   certificate      certificate file
   privatekey       private key file
+  sni              TLS SNI to send to remote host
   verify_certs     file for certificate verify
   crl              file containing CRL
   require_ciphers  list of allowed ciphers
   verify_certs     file for certificate verify
   crl              file containing CRL
   require_ciphers  list of allowed ciphers
@@ -961,7 +968,8 @@ Returns:           OK on success
 
 int
 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
 
 int
 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
-  uschar *certificate, uschar *privatekey, uschar *verify_certs, uschar *crl,
+  uschar *certificate, uschar *privatekey, uschar *sni,
+  uschar *verify_certs, uschar *crl,
   uschar *require_ciphers, uschar *require_mac, uschar *require_kx,
   uschar *require_proto, int timeout)
 {
   uschar *require_ciphers, uschar *require_mac, uschar *require_kx,
   uschar *require_proto, int timeout)
 {
@@ -1000,6 +1008,19 @@ SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
 SSL_set_fd(ssl, fd);
 SSL_set_connect_state(ssl);
 
 SSL_set_fd(ssl, fd);
 SSL_set_connect_state(ssl);
 
+if (sni)
+  {
+  if (!expand_check(sni, US"tls_sni", &tls_sni))
+    return FAIL;
+  if (!Ustrlen(tls_sni))
+    tls_sni = NULL;
+  else
+    {
+    DEBUG(D_tls) debug_printf("Setting TLS SNI \"%s\"\n", tls_sni);
+    SSL_set_tlsext_host_name(ssl, tls_sni);
+    }
+  }
+
 /* There doesn't seem to be a built-in timeout on connection. */
 
 DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
 /* There doesn't seem to be a built-in timeout on connection. */
 
 DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
@@ -1078,8 +1099,10 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
     SSL_free(ssl);
     ssl = NULL;
     tls_active = -1;
     SSL_free(ssl);
     ssl = NULL;
     tls_active = -1;
+    tls_bits = 0;
     tls_cipher = NULL;
     tls_peerdn = NULL;
     tls_cipher = NULL;
     tls_peerdn = NULL;
+    tls_sni = NULL;
 
     return smtp_getc();
     }
 
     return smtp_getc();
     }
index c571d874c4a1d4fa83d038c77984c7136981fd9d..b1fedd2d4a9d1ccc9f626addf56a9ad65f19adf3 100644 (file)
@@ -128,8 +128,10 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, tls_crl) },
   { "tls_privatekey",       opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, tls_privatekey) },
       (void *)offsetof(smtp_transport_options_block, tls_crl) },
   { "tls_privatekey",       opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, tls_privatekey) },
-  { "tls_require_ciphers",   opt_stringptr,
+  { "tls_require_ciphers",  opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, tls_require_ciphers) },
       (void *)offsetof(smtp_transport_options_block, tls_require_ciphers) },
+  { "tls_sni",              opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, tls_sni) },
   { "tls_tempfail_tryclear", opt_bool,
       (void *)offsetof(smtp_transport_options_block, tls_tempfail_tryclear) },
   { "tls_verify_certificates", opt_stringptr,
   { "tls_tempfail_tryclear", opt_bool,
       (void *)offsetof(smtp_transport_options_block, tls_tempfail_tryclear) },
   { "tls_verify_certificates", opt_stringptr,
@@ -191,7 +193,8 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   NULL,                /* gnutls_require_mac */
   NULL,                /* gnutls_require_proto */
   NULL,                /* tls_verify_certificates */
   NULL,                /* gnutls_require_mac */
   NULL,                /* gnutls_require_proto */
   NULL,                /* tls_verify_certificates */
-  TRUE                 /* tls_tempfail_tryclear */
+  TRUE,                /* tls_tempfail_tryclear */
+  NULL                 /* tls_sni */
 #endif
 #ifndef DISABLE_DKIM
  ,NULL,                /* dkim_canon */
 #endif
 #ifndef DISABLE_DKIM
  ,NULL,                /* dkim_canon */
@@ -889,8 +892,10 @@ outblock.authenticating = FALSE;
 
 /* Reset the parameters of a TLS session. */
 
 
 /* Reset the parameters of a TLS session. */
 
+tls_bits = 0;
 tls_cipher = NULL;
 tls_peerdn = NULL;
 tls_cipher = NULL;
 tls_peerdn = NULL;
+tls_sni = NULL;
 
 /* If an authenticated_sender override has been specified for this transport
 instance, expand it. If the expansion is forced to fail, and there was already
 
 /* If an authenticated_sender override has been specified for this transport
 instance, expand it. If the expansion is forced to fail, and there was already
@@ -1122,6 +1127,7 @@ if (tls_offered && !suppress_tls &&
       NULL,                    /* No DH param */
       ob->tls_certificate,
       ob->tls_privatekey,
       NULL,                    /* No DH param */
       ob->tls_certificate,
       ob->tls_privatekey,
+      ob->tls_sni,
       ob->tls_verify_certificates,
       ob->tls_crl,
       ob->tls_require_ciphers,
       ob->tls_verify_certificates,
       ob->tls_crl,
       ob->tls_require_ciphers,
index a2ea4ff0a2488aa270f25eeff95b2c814993e4c0..605be4800297927c629c03a322134fb37344146e 100644 (file)
@@ -54,6 +54,7 @@ typedef struct {
   uschar *gnutls_require_proto;
   uschar *tls_verify_certificates;
   BOOL    tls_tempfail_tryclear;
   uschar *gnutls_require_proto;
   uschar *tls_verify_certificates;
   BOOL    tls_tempfail_tryclear;
+  uschar *tls_sni;
   #endif
   #ifndef DISABLE_DKIM
   uschar *dkim_domain;
   #endif
   #ifndef DISABLE_DKIM
   uschar *dkim_domain;