TLS: Session resumption, under the EXPERIMENTAL_TLS_RESUME build option.
[exim.git] / src / src / transports / smtp.c
index 3558fa65c7c73ddf5d8e61abe33ad73bc1a5df91..f76b4f730cd0ba5de83cdd529880cd83ea3f4557 100644 (file)
@@ -183,6 +183,10 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, tls_privatekey) },
   { "tls_require_ciphers",  opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, tls_require_ciphers) },
+# ifdef EXPERIMENTAL_TLS_RESUME
+  { "tls_resumption_hosts", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, tls_resumption_hosts) },
+# endif
   { "tls_sni",              opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, tls_sni) },
   { "tls_tempfail_tryclear", opt_bool,
@@ -293,6 +297,9 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   .tls_verify_certificates =   US"system",
   .tls_dh_min_bits =           EXIM_CLIENT_DH_DEFAULT_MIN_BITS,
   .tls_tempfail_tryclear =     TRUE,
+# ifdef EXPERIMENTAL_TLS_RESUME
+  .tls_resumption_hosts =      NULL,
+# endif
   .tls_verify_hosts =          NULL,
   .tls_try_verify_hosts =      US"*",
   .tls_verify_cert_hostnames = US"*",
@@ -825,7 +832,7 @@ write_ehlo_cache_entry(const smtp_context * sx)
 {
 open_db dbblock, * dbm_file;
 
-if ((dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE)))
+if ((dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE, TRUE)))
   {
   uschar * ehlo_resp_key = ehlo_cache_key(sx);
   dbdata_ehlo_resp er = { .data = sx->ehlo_resp };
@@ -845,7 +852,7 @@ invalidate_ehlo_cache_entry(smtp_context * sx)
 open_db dbblock, * dbm_file;
 
 if (  sx->early_pipe_active
-   && (dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE)))
+   && (dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE, TRUE)))
   {
   uschar * ehlo_resp_key = ehlo_cache_key(sx);
   dbfn_delete(dbm_file, ehlo_resp_key);
@@ -859,7 +866,7 @@ read_ehlo_cache_entry(smtp_context * sx)
 open_db dbblock;
 open_db * dbm_file;
 
-if (!(dbm_file = dbfn_open(US"misc", O_RDONLY, &dbblock, FALSE)))
+if (!(dbm_file = dbfn_open(US"misc", O_RDONLY, &dbblock, FALSE, TRUE)))
   { DEBUG(D_transport) debug_printf("ehlo-cache: no misc DB\n"); }
 else
   {
@@ -872,7 +879,7 @@ else
     {
     DEBUG(D_transport) debug_printf("ehlo-resp record too old\n");
     dbfn_close(dbm_file);
-    if ((dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE)))
+    if ((dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE, TRUE)))
       dbfn_delete(dbm_file, ehlo_resp_key);
     }
   else
@@ -1073,9 +1080,9 @@ sync_responses(smtp_context * sx, int count, int pending_DATA)
 address_item * addr = sx->sync_addr;
 smtp_transport_options_block * ob = sx->conn_args.ob;
 int yield = 0;
-int rc;
 
 #ifdef EXPERIMENTAL_PIPE_CONNECT
+int rc;
 if ((rc = smtp_reap_early_pipe(sx, &count)) != OK)
   return rc == FAIL ? -4 : -5;
 #endif
@@ -1427,8 +1434,6 @@ if (  sx->esmtp
   if (  require_auth == OK
      || verify_check_given_host(CUSS &ob->hosts_try_auth, host) == OK)
     {
-    auth_instance * au;
-
     DEBUG(D_transport) debug_printf("scanning authentication mechanisms\n");
     fail_reason = US"no common mechanisms were found";
 
@@ -1441,6 +1446,7 @@ if (  sx->esmtp
       client function.  We are limited to supporting up to 16 authenticator
       public-names by the number of bits in a short. */
 
+      auth_instance * au;
       uschar bitnum;
       int rc;
 
@@ -2017,6 +2023,9 @@ tls_out.peerdn = NULL;
 tls_out.sni = NULL;
 #endif
 tls_out.ocsp = OCSP_NOT_REQ;
+#ifdef EXPERIMENTAL_TLS_RESUME
+tls_out.resumption = 0;
+#endif
 
 /* Flip the legacy TLS-related variables over to the outbound set in case
 they're used in the context of the transport.  Don't bother resetting
@@ -2496,7 +2505,9 @@ if (  smtp_peer_options & OPTION_TLS
       /* 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. */
-GNUTLS_CONN_FAILED:
+#ifdef USE_GNUTLS
+  GNUTLS_CONN_FAILED:
+#endif
       DEBUG(D_tls) debug_printf("TLS session fail: %s\n", tls_errstr);
 
 # ifdef SUPPORT_DANE