DANE: smtp transport option dane_require_tls_ciphers
[exim.git] / src / src / transports / smtp.c
index d3af04cc8ffa8820aa17381a68227096c9fa4b23..bd1e20d7fc3a35667af2e79d9a71a71fc09ac1a2 100644 (file)
@@ -24,6 +24,10 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, address_retry_include_sender) },
   { "allow_localhost",      opt_bool,
       (void *)offsetof(smtp_transport_options_block, allow_localhost) },
+#ifdef EXPERIMENTAL_ARC
+  { "arc_sign", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, arc_sign) },
+#endif
   { "authenticated_sender", opt_stringptr,
       (void *)offsetof(smtp_transport_options_block, authenticated_sender) },
   { "authenticated_sender_force", opt_bool,
@@ -34,6 +38,10 @@ optionlist smtp_transport_options[] = {
       (void *)offsetof(smtp_transport_options_block, connect_timeout) },
   { "connection_max_messages", opt_int | opt_public,
       (void *)offsetof(transport_instance, connection_max_messages) },
+# ifdef SUPPORT_DANE
+  { "dane_require_tls_ciphers", opt_stringptr,
+      (void *)offsetof(smtp_transport_options_block, dane_require_tls_ciphers) },
+# endif
   { "data_timeout",         opt_time,
       (void *)offsetof(smtp_transport_options_block, data_timeout) },
   { "delay_after_cutoff", opt_bool,
@@ -209,7 +217,6 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   .fallback_hosts =            NULL,
   .hostlist =                  NULL,
   .fallback_hostlist =         NULL,
-  .authenticated_sender =      NULL,
   .helo_data =                 US"$primary_hostname",
   .interface =                 NULL,
   .port =                      NULL,
@@ -222,6 +229,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
 #ifdef SUPPORT_DANE
   .hosts_try_dane =            NULL,
   .hosts_require_dane =                NULL,
+  .dane_require_tls_ciphers =  NULL,
 #endif
   .hosts_try_fastopen =                NULL,
 #ifndef DISABLE_PRDR
@@ -287,7 +295,15 @@ smtp_transport_options_block smtp_transport_option_defaults = {
     .dkim_sign_headers =       NULL,
     .dkim_strict =             NULL,
     .dkim_hash =               US"sha256",
-    .dot_stuffed =             FALSE},
+    .dot_stuffed =             FALSE,
+    .force_bodyhash =          FALSE,
+# ifdef EXPERIMENTAL_ARC
+    .arc_signspec =            NULL,
+# endif
+    },
+# ifdef EXPERIMENTAL_ARC
+  .arc_sign =                  NULL,
+# endif
 #endif
 };
 
@@ -1607,6 +1623,9 @@ if (!continue_hostname)
                                  string_sprintf("DANE error: tlsa lookup %s",
                                    rc == DEFER ? "DEFER" : "FAIL"),
                                  rc, FALSE);
+                               (void) event_raise(sx->tblock->event_action,
+                                 US"dane:fail", sx->dane_required
+                                   ?  US"dane-required" : US"dnssec-invalid");
                                return rc;
          }
       }
@@ -1615,6 +1634,8 @@ if (!continue_hostname)
       set_errno_nohost(sx->addrlist, ERRNO_DNSDEFER,
        string_sprintf("DANE error: %s lookup not DNSSEC", sx->host->name),
        FAIL, FALSE);
+      (void) event_raise(sx->tblock->event_action,
+       US"dane:fail", US"dane-required");
       return FAIL;
       }
     }
@@ -1948,9 +1969,14 @@ if (  smtp_peer_options & OPTION_TLS
     if (rc != OK)
       {
 # ifdef SUPPORT_DANE
-      if (sx->dane) log_write(0, LOG_MAIN,
+      if (sx->dane)
+        {
+       log_write(0, LOG_MAIN,
          "DANE attempt failed; TLS connection to %s [%s]: %s",
          sx->host->name, sx->host->address, errstr);
+       (void) event_raise(sx->tblock->event_action,
+         US"dane:fail", US"validation-failure");       /* could do with better detail */
+       }
 # endif
 
       errno = ERRNO_TLSFAILURE;
@@ -2044,6 +2070,13 @@ else if (  sx->smtps
   message = string_sprintf("a TLS session is required, but %s",
     smtp_peer_options & OPTION_TLS
     ? "an attempt to start TLS failed" : "the server did not offer TLS support");
+# ifdef SUPPORT_DANE
+  if (sx->dane)
+    (void) event_raise(sx->tblock->event_action, US"dane:fail",
+      smtp_peer_options & OPTION_TLS
+      ? US"validation-failure"         /* could do with better detail */
+      : US"starttls-not-supported");
+# endif
   goto TLS_FAILED;
   }
 #endif /*SUPPORT_TLS*/
@@ -2965,6 +2998,24 @@ else
   transport_count = 0;
 
 #ifndef DISABLE_DKIM
+  dkim_exim_sign_init();
+# ifdef EXPERIMENTAL_ARC
+    {
+    uschar * s = sx.ob->arc_sign;
+    if (s)
+      {
+      if (!(sx.ob->dkim.arc_signspec = expand_string(s)))
+       {
+       message = US"failed to expand arc_sign";
+       sx.ok = FALSE;
+       goto SEND_FAILED;
+       }
+      /* Ask dkim code to hash the body for ARC */
+      (void) arc_ams_setup_sign_bodyhash();
+      sx.ob->dkim.force_bodyhash = TRUE;
+      }
+    }
+# endif
   sx.ok = dkim_transport_write_message(&tctx, &sx.ob->dkim, CUSS &message);
 #else
   sx.ok = transport_write_message(&tctx, 0);
@@ -3178,8 +3229,11 @@ else
 #ifndef DISABLE_PRDR
       if (sx.prdr_active)
         {
+       const uschar * overall_message;
+
        /* PRDR - get the final, overall response.  For any non-success
        upgrade all the address statuses. */
+
         sx.ok = smtp_read_response(&sx.inblock, sx.buffer, sizeof(sx.buffer), '2',
           sx.ob->final_timeout);
         if (!sx.ok)
@@ -3195,7 +3249,14 @@ else
          goto RESPONSE_FAILED;
          }
 
-       /* Update the journal, or setup retry. */
+       /* Append the overall response to the individual PRDR response for logging
+       and update the journal, or setup retry. */
+
+       overall_message = string_printing(sx.buffer);
+        for (addr = addrlist; addr != sx.first_addr; addr = addr->next)
+         if (addr->transport_return == OK)
+           addr->message = string_sprintf("%s\\n%s", addr->message, overall_message);
+
         for (addr = addrlist; addr != sx.first_addr; addr = addr->next)
          if (addr->transport_return == OK)
            {