Compiler quietening and testcase consistency
[exim.git] / src / src / transports / smtp.c
index 938844799f731d50016a4ff504e6f362f02db208..fd894862072f0dd0512a958e919b67189bdbce93 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2013 */
+/* Copyright (c) University of Cambridge 1995 - 2014 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 #include "../exim.h"
@@ -55,6 +55,10 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, dns_qualify_single) },
   { "dns_search_parents",   opt_bool,
       (void *)offsetof(smtp_transport_options_block, dns_search_parents) },
+  { "dnssec_request_domains", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dnssec_request_domains) },
+  { "dnssec_require_domains", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dnssec_require_domains) },
   { "dscp",                 opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, dscp) },
   { "fallback_hosts",       opt_stringptr,
@@ -98,6 +102,10 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, hosts_override) },
   { "hosts_randomize",      opt_bool,
       (void *)offsetof(smtp_transport_options_block, hosts_randomize) },
+#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_OCSP)
+  { "hosts_request_ocsp",   opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, hosts_request_ocsp) },
+#endif
   { "hosts_require_auth",   opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, hosts_require_auth) },
 #ifdef SUPPORT_TLS
@@ -192,6 +200,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   NULL,                /* hosts_try_prdr */
 #endif
 #ifdef EXPERIMENTAL_OCSP
+  US"*",               /* hosts_request_ocsp */
   NULL,                /* hosts_require_ocsp */
 #endif
   NULL,                /* hosts_require_tls */
@@ -213,6 +222,8 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   FALSE,               /* gethostbyname */
   TRUE,                /* dns_qualify_single */
   FALSE,               /* dns_search_parents */
+  NULL,                /* dnssec_request_domains */
+  NULL,                /* dnssec_require_domains */
   TRUE,                /* delay_after_cutoff */
   FALSE,               /* hosts_override */
   FALSE,               /* hosts_randomize */
@@ -625,7 +636,7 @@ tpda_defer_errstr = addr->message
     ? string_sprintf("%s: %s", addr->message, strerror(addr->basic_errno))
     : string_copy(addr->message)
   : addr->basic_errno > 0
-    ? string_copy(strerror(addr->basic_errno))
+    ? string_copy(US strerror(addr->basic_errno))
     : NULL;
 
 DEBUG(D_transport)
@@ -1213,25 +1224,27 @@ outblock.authenticating = FALSE;
 
 /* Reset the parameters of a TLS session. */
 
-tls_in.bits = 0;
-tls_in.cipher = NULL;  /* for back-compatible behaviour */
-tls_in.peerdn = NULL;
-#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
-tls_in.sni = NULL;
-#endif
-
 tls_out.bits = 0;
 tls_out.cipher = NULL; /* the one we may use for this transport */
+tls_out.ourcert = NULL;
+tls_out.peercert = NULL;
 tls_out.peerdn = NULL;
 #if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
 tls_out.sni = NULL;
 #endif
+tls_out.ocsp = OCSP_NOT_REQ;
+
+/* 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
+afterward as we're in a subprocess. */
+
+tls_modify_variables(&tls_out);
 
 #ifndef SUPPORT_TLS
 if (smtps)
   {
-    set_errno(addrlist, 0, US"TLS support not available", DEFER, FALSE);
-    return ERROR;
+  set_errno(addrlist, 0, US"TLS support not available", DEFER, FALSE);
+  return ERROR;
   }
 #endif
 
@@ -1439,22 +1452,7 @@ if (tls_offered && !suppress_tls &&
   else
   TLS_NEGOTIATE:
     {
-    int rc = tls_client_start(inblock.sock,
-      host,
-      addrlist,
-      ob->tls_certificate,
-      ob->tls_privatekey,
-      ob->tls_sni,
-      ob->tls_verify_certificates,
-      ob->tls_crl,
-      ob->tls_require_ciphers,
-#ifdef EXPERIMENTAL_OCSP
-      ob->hosts_require_ocsp,
-#endif
-      ob->tls_dh_min_bits,
-      ob->command_timeout,
-      ob->tls_verify_hosts,
-      ob->tls_try_verify_hosts);
+    int rc = tls_client_start(inblock.sock, host, addrlist, ob);
 
     /* 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
@@ -1475,7 +1473,10 @@ if (tls_offered && !suppress_tls &&
       if (addr->transport_return == PENDING_DEFER)
         {
         addr->cipher = tls_out.cipher;
+        addr->ourcert = tls_out.ourcert;
+        addr->peercert = tls_out.peercert;
         addr->peerdn = tls_out.peerdn;
+       addr->ocsp = tls_out.ocsp;
         }
       }
     }
@@ -2412,8 +2413,6 @@ tls_close(FALSE, TRUE);
 #endif
 
 /* Close the socket, and return the appropriate value, first setting
-continue_transport and continue_hostname NULL to prevent any other addresses
-that may include the host from trying to re-use a continuation socket. This
 works because the NULL setting is passed back to the calling process, and
 remote_max_parallel is forced to 1 when delivering over an existing connection,
 
@@ -2514,7 +2513,10 @@ for (addr = addrlist; addr != NULL; addr = addr->next)
   addr->message = NULL;
   #ifdef SUPPORT_TLS
   addr->cipher = NULL;
+  addr->ourcert = NULL;
+  addr->peercert = NULL;
   addr->peerdn = NULL;
+  addr->ocsp = OCSP_NOT_REQ;
   #endif
   }
 return first_addr;
@@ -2817,6 +2819,7 @@ for (cutoff_retry = 0; expired &&
         rc = host_find_byname(host, NULL, flags, &canonical_name, TRUE);
       else
         rc = host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
+         ob->dnssec_request_domains, ob->dnssec_require_domains,
           &canonical_name, NULL);
 
       /* Update the host (and any additional blocks, resulting from
@@ -3429,4 +3432,6 @@ DEBUG(D_transport) debug_printf("Leaving %s transport\n", tblock->name);
 return TRUE;   /* Each address has its status */
 }
 
+/* vi: aw ai sw=2
+*/
 /* End of transport/smtp.c */