DMARC: send forensic reports for reject & quarantine results, and "none" policy....
authorTony Meyer <tony@spamexperts.com>
Sun, 14 Aug 2016 15:09:02 +0000 (16:09 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 14 Aug 2016 15:09:02 +0000 (16:09 +0100)
doc/doc-txt/ChangeLog
src/src/dmarc.c
src/src/dmarc.h

index 7304c9c..d2d2cff 100644 (file)
@@ -76,6 +76,9 @@ JH/19 Bug 1850: support Radius libraries that return REJECT_RC.
 JH/20 Bug 1872: Ensure that acl_smtp_notquit is run when the connection drops
       after the data-go-ahead and data-ack.  Patch from Jason Betts.
 
+JH/21 Bug 1846: Send DMARC forensic reports for reject and quaratine results,
+      even for a "none" policy.  Patch from Tony Meyer.
+
 
 Exim version 4.87
 -----------------
index 373691d..2fdc9ed 100644 (file)
@@ -150,6 +150,63 @@ int dmarc_store_data(header_line *hdr) {
 }
 
 
+static void
+dmarc_send_forensic_report(u_char **ruf)
+{
+int   c;
+uschar *recipient, *save_sender;
+BOOL  send_status = FALSE;
+error_block *eblock = NULL;
+FILE *message_file = NULL;
+
+/* Earlier ACL does not have *required* control=dmarc_enable_forensic */
+if (!dmarc_enable_forensic)
+  return;
+
+if (  dmarc_policy == DMARC_POLICY_REJECT     && action == DMARC_RESULT_REJECT
+   || dmarc_policy == DMARC_POLICY_QUARANTINE && action == DMARC_RESULT_QUARANTINE
+   || dmarc_policy == DMARC_POLICY_NONE       && action == DMARC_RESULT_REJECT
+   || dmarc_policy == DMARC_POLICY_NONE       && action == DMARC_RESULT_QUARANTINE
+   )
+  if (ruf)
+    {
+    eblock = add_to_eblock(eblock, US"Sender Domain", dmarc_used_domain);
+    eblock = add_to_eblock(eblock, US"Sender IP Address", sender_host_address);
+    eblock = add_to_eblock(eblock, US"Received Date", tod_stamp(tod_full));
+    eblock = add_to_eblock(eblock, US"SPF Alignment",
+                          (sa==DMARC_POLICY_SPF_ALIGNMENT_PASS) ?US"yes":US"no");
+    eblock = add_to_eblock(eblock, US"DKIM Alignment",
+                          (da==DMARC_POLICY_DKIM_ALIGNMENT_PASS)?US"yes":US"no");
+    eblock = add_to_eblock(eblock, US"DMARC Results", dmarc_status_text);
+    /* Set a sane default envelope sender */
+    dsn_from = dmarc_forensic_sender ? dmarc_forensic_sender :
+              dsn_from ? dsn_from :
+              string_sprintf("do-not-reply@%s",primary_hostname);
+    for (c = 0; ruf[c]; c++)
+      {
+      recipient = string_copylc(ruf[c]);
+      if (Ustrncmp(recipient, "mailto:",7))
+       continue;
+      /* Move to first character past the colon */
+      recipient += 7;
+      DEBUG(D_receive)
+       debug_printf("DMARC forensic report to %s%s\n", recipient,
+            (host_checking || running_in_test_harness) ? " (not really)" : "");
+      if (host_checking || running_in_test_harness)
+       continue;
+
+      save_sender = sender_address;
+      sender_address = recipient;
+      send_status = moan_to_sender(ERRMESS_DMARC_FORENSIC, eblock,
+                                  header_list, message_file, FALSE);
+      sender_address = save_sender;
+      if (!send_status)
+       log_write(0, LOG_MAIN|LOG_PANIC,
+         "failure to send DMARC forensic report to %s", recipient);
+      }
+    }
+}
+
 /* dmarc_process adds the envelope sender address to the existing
    context (if any), retrieves the result, sets up expansion
    strings and evaluates the condition outcome. */
@@ -518,60 +575,6 @@ else
 return DMARC_HIST_OK;
 }
 
-void
-dmarc_send_forensic_report(u_char **ruf)
-{
-int   c;
-uschar *recipient, *save_sender;
-BOOL  send_status = FALSE;
-error_block *eblock = NULL;
-FILE *message_file = NULL;
-
-/* Earlier ACL does not have *required* control=dmarc_enable_forensic */
-if (!dmarc_enable_forensic)
-  return;
-
-if ((dmarc_policy == DMARC_POLICY_REJECT     && action == DMARC_RESULT_REJECT) ||
-    (dmarc_policy == DMARC_POLICY_QUARANTINE && action == DMARC_RESULT_QUARANTINE) )
-  if (ruf)
-    {
-    eblock = add_to_eblock(eblock, US"Sender Domain", dmarc_used_domain);
-    eblock = add_to_eblock(eblock, US"Sender IP Address", sender_host_address);
-    eblock = add_to_eblock(eblock, US"Received Date", tod_stamp(tod_full));
-    eblock = add_to_eblock(eblock, US"SPF Alignment",
-                          (sa==DMARC_POLICY_SPF_ALIGNMENT_PASS) ?US"yes":US"no");
-    eblock = add_to_eblock(eblock, US"DKIM Alignment",
-                          (da==DMARC_POLICY_DKIM_ALIGNMENT_PASS)?US"yes":US"no");
-    eblock = add_to_eblock(eblock, US"DMARC Results", dmarc_status_text);
-    /* Set a sane default envelope sender */
-    dsn_from = dmarc_forensic_sender ? dmarc_forensic_sender :
-              dsn_from ? dsn_from :
-              string_sprintf("do-not-reply@%s",primary_hostname);
-    for (c = 0; ruf[c]; c++)
-      {
-      recipient = string_copylc(ruf[c]);
-      if (Ustrncmp(recipient, "mailto:",7))
-       continue;
-      /* Move to first character past the colon */
-      recipient += 7;
-      DEBUG(D_receive)
-       debug_printf("DMARC forensic report to %s%s\n", recipient,
-            (host_checking || running_in_test_harness) ? " (not really)" : "");
-      if (host_checking || running_in_test_harness)
-       continue;
-
-      save_sender = sender_address;
-      sender_address = recipient;
-      send_status = moan_to_sender(ERRMESS_DMARC_FORENSIC, eblock,
-                                  header_list, message_file, FALSE);
-      sender_address = save_sender;
-      if (!send_status)
-       log_write(0, LOG_MAIN|LOG_PANIC,
-         "failure to send DMARC forensic report to %s", recipient);
-      }
-    }
-}
-
 uschar *
 dmarc_exim_expand_query(int what)
 {
index 63d451c..78e2a5b 100644 (file)
@@ -24,7 +24,6 @@ uschar *dmarc_exim_expand_query(int);
 uschar *dmarc_exim_expand_defaults(int);
 uschar *dmarc_auth_results_header(header_line *,uschar *);
 int dmarc_write_history_file();
-void dmarc_send_forensic_report(u_char **);
 
 #define DMARC_AR_HEADER        US"Authentication-Results:"
 #define DMARC_VERIFY_STATUS    1