From: Tony Meyer Date: Sun, 14 Aug 2016 15:09:02 +0000 (+0100) Subject: DMARC: send forensic reports for reject & quarantine results, and "none" policy.... X-Git-Tag: exim-4_88_RC1~33 X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=commitdiff_plain;h=72a201e2d5a734ace1637d571d40dd058161891f DMARC: send forensic reports for reject & quarantine results, and "none" policy. Bug 1846 --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 7304c9c04..d2d2cffa7 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -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 ----------------- diff --git a/src/src/dmarc.c b/src/src/dmarc.c index 373691df4..2fdc9eda3 100644 --- a/src/src/dmarc.c +++ b/src/src/dmarc.c @@ -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) { diff --git a/src/src/dmarc.h b/src/src/dmarc.h index 63d451c5d..78e2a5b7b 100644 --- a/src/src/dmarc.h +++ b/src/src/dmarc.h @@ -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