From: Jeremy Harris Date: Sun, 22 Sep 2019 14:43:37 +0000 (+0100) Subject: DMARC: promote the support from Experimental to mainline X-Git-Url: https://git.exim.org/users/jgh/exim.git/commitdiff_plain/1a2e76e1676bf405a464a233950a95012533c227?ds=sidebyside;hp=3164b94cfab879ab758d3bb16e5b8b923638ab19 DMARC: promote the support from Experimental to mainline --- diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 00ff91d85..c2adc9ea6 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -12079,6 +12079,15 @@ contain the trailing slash. If &$config_file$& does not contain a slash, .vindex "&$config_file$&" The name of the main configuration file Exim is using. +.new +.vitem &$dmarc_domain_policy$& &&& + &$dmarc_status$& &&& + &$dmarc_status_text$& &&& + &$dmarc_used_domains$& +Results of DMARC verification. +For details see section &<>&. +.wen + .vitem &$dkim_verify_status$& Results of DKIM verification. For details see section &<>&. @@ -39752,11 +39761,11 @@ There is no dot-stuffing (and no dot-termination). . //////////////////////////////////////////////////////////////////////////// . //////////////////////////////////////////////////////////////////////////// -.chapter "DKIM and SPF" "CHAPdkim" &&& - "DKIM and SPF Support" -.cindex "DKIM" +.chapter "DKIM, SPF and DMARC" "CHAPdkim" &&& + "DKIM, SPF and DMARC Support" .section "DKIM (DomainKeys Identified Mail)" SECDKIM +.cindex "DKIM" DKIM is a mechanism by which messages sent by some entity can be provably linked to a domain which that entity controls. It permits reputation to @@ -40446,6 +40455,240 @@ The lookup will return the same result strings as can appear in + +.new +.section DMARC SECDMARC +.cindex DMARC verification + +DMARC combines feedback from SPF, DKIM, and header From: in order +to attempt to provide better indicators of the authenticity of an +email. This document does not explain the fundamentals; you +should read and understand how it works by visiting the website at +&url(http://www.dmarc.org/). + +If Exim is built with DMARC support, +the libopendmarc library is used. + +For building Exim yourself, obtain the library from +&url(http://sourceforge.net/projects/opendmarc/) +to obtain a copy, or find it in your favorite rpm package +repository. You will need to attend to the local/Makefile feature +SUPPORT_DMARC and the associated LDFLAGS addition. +This description assumes +that headers will be in /usr/local/include, and that the libraries +are in /usr/local/lib. + +. subsection + +There are three main-configuration options: +.cindex DMARC "configuration options" + +The &%dmarc_tld_file%& option +.oindex &%dmarc_tld_file%& +defines the location of a text file of valid +top level domains the opendmarc library uses +during domain parsing. Maintained by Mozilla, +the most current version can be downloaded +from a link at &url(http://publicsuffix.org/list/). +See also util/renew-opendmarc-tlds.sh script. +The default for the option is currently +/etc/exim/opendmarc.tlds + +The &%dmarc_history_file%& option, if set +.oindex &%dmarc_history_file%& +defines the location of a file to log results +of dmarc verification on inbound emails. The +contents are importable by the opendmarc tools +which will manage the data, send out DMARC +reports, and expire the data. Make sure the +directory of this file is writable by the user +exim runs as. +The default is unset. + +The &%dmarc_forensic_sender%& option +.oindex &%dmarc_forensic_sender%& +defines an alternate email address to use when sending a +forensic report detailing alignment failures +if a sender domain's dmarc record specifies it +and you have configured Exim to send them. +If set, this is expanded and used for the +From: header line; the address is extracted +from it and used for the envelope from. +If not set (the default), the From: header is expanded from +the dsn_from option, and <> is used for the +envelope from. + +. I wish we had subsections... + +.cindex DMARC controls +By default, the DMARC processing will run for any remote, +non-authenticated user. It makes sense to only verify DMARC +status of messages coming from remote, untrusted sources. You can +use standard conditions such as hosts, senders, etc, to decide that +DMARC verification should *not* be performed for them and disable +DMARC with a control setting: +.code + control = dmarc_disable_verify +.endd +A DMARC record can also specify a "forensic address", which gives +exim an email address to submit reports about failed alignment. +Exim does not do this by default because in certain conditions it +results in unintended information leakage (what lists a user might +be subscribed to, etc). You must configure exim to submit forensic +reports to the owner of the domain. If the DMARC record contains a +forensic address and you specify the control statement below, then +exim will send these forensic emails. It's also advised that you +configure a dmarc_forensic_sender because the default sender address +construction might be inadequate. +.code + control = dmarc_enable_forensic +.endd +(AGAIN: You can choose not to send these forensic reports by simply +not putting the dmarc_enable_forensic control line at any point in +your exim config. If you don't tell it to send them, it will not +send them.) + +There are no options to either control. Both must appear before +the DATA acl. + +. subsection + +DMARC checks cam be run on incoming SMTP messages by using the +"dmarc_status" ACL condition in the DATA ACL. You are required to +call the "spf" condition first in the ACLs, then the "dmarc_status" +condition. Putting this condition in the ACLs is required in order +for a DMARC check to actually occur. All of the variables are set +up before the DATA ACL, but there is no actual DMARC check that +occurs until a "dmarc_status" condition is encountered in the ACLs. + +The dmarc_status condition takes a list of strings on its +right-hand side. These strings describe recommended action based +on the DMARC check. To understand what the policy recommendations +mean, refer to the DMARC website above. Valid strings are: +.display +&'accept '& The DMARC check passed and the library recommends accepting the email. +&'reject '& The DMARC check failed and the library recommends rejecting the email. +&'quarantine '& The DMARC check failed and the library recommends keeping it for further inspection. +&'none '& The DMARC check passed and the library recommends no specific action, neutral. +&'norecord '& No policy section in the DMARC record for this sender domain. +&'nofrom '& Unable to determine the domain of the sender. +&'temperror '& Library error or dns error. +&'off '& The DMARC check was disabled for this email. +.endd +You can prefix each string with an exclamation mark to invert its +meaning, for example "!accept" will match all results but +"accept". The string list is evaluated left-to-right in a +short-circuit fashion. When a string matches the outcome of the +DMARC check, the condition succeeds. If none of the listed +strings matches the outcome of the DMARC check, the condition +fails. + +Of course, you can also use any other lookup method that Exim +supports, including LDAP, Postgres, MySQL, etc, as long as the +result is a list of colon-separated strings. + +Performing the check sets up information used by the +&%authresults%& expansion item. + +Several expansion variables are set before the DATA ACL is +processed, and you can use them in this ACL. The following +expansion variables are available: + +&$dmarc_status$& +.vindex &$dmarc_status$& +.cindex DMARC result +is a one word status indicating what the DMARC library +thinks of the email. It is a combination of the results of +DMARC record lookup and the SPF/DKIM/DMARC processing results +(if a DMARC record was found). The actual policy declared +in the DMARC record is in a separate expansion variable. + +&$dmarc_status_text$& +.vindex &$dmarc_status_text$& +is a slightly longer, human readable status. + +&$dmarc_used_domain$& +.vindex &$dmarc_used_domain$& +is the domain which DMARC used to look up the DMARC policy record. + +&$dmarc_domain_policy$& +.vindex &$dmarc_domain_policy$& +is the policy declared in the DMARC record. Valid values +are "none", "reject" and "quarantine". It is blank when there +is any error, including no DMARC record. + +. subsection + +By default, Exim's DMARC configuration is intended to be +non-intrusive and conservative. To facilitate this, Exim will not +create any type of logging files without explicit configuration by +you, the admin. Nor will Exim send out any emails/reports about +DMARC issues without explicit configuration by you, the admin (other +than typical bounce messages that may come about due to ACL +processing or failure delivery issues). + +In order to log statistics suitable to be imported by the opendmarc +tools, you need to: +.ilist +Configure the global setting dmarc_history_file +.next +Configure cron jobs to call the appropriate opendmarc history +import scripts and truncating the dmarc_history_file +.endlist + +In order to send forensic reports, you need to: +.ilist +Configure the global setting dmarc_forensic_sender +.next +Configure, somewhere before the DATA ACL, the control option to +enable sending DMARC forensic reports +.endlist + +. subsection + +Example usage: +.code +(RCPT ACL) + warn domains = +local_domains + hosts = +local_hosts + control = dmarc_disable_verify + + warn !domains = +screwed_up_dmarc_records + control = dmarc_enable_forensic + + warn condition = (lookup if destined to mailing list) + set acl_m_mailing_list = 1 + +(DATA ACL) + warn dmarc_status = accept : none : off + !authenticated = * + log_message = DMARC DEBUG: $dmarc_status $dmarc_used_domain + + warn dmarc_status = !accept + !authenticated = * + log_message = DMARC DEBUG: '$dmarc_status' for $dmarc_used_domain + + warn dmarc_status = quarantine + !authenticated = * + set $acl_m_quarantine = 1 + # Do something in a transport with this flag variable + + deny condition = ${if eq{$dmarc_domain_policy}{reject}} + condition = ${if eq{$acl_m_mailing_list}{1}} + message = Messages from $dmarc_used_domain break mailing lists + + deny dmarc_status = reject + !authenticated = * + message = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT + + warn add_header = :at_start:${authresults {$primary_hostname}} +.endd + +.wen + + + + . //////////////////////////////////////////////////////////////////////////// . //////////////////////////////////////////////////////////////////////////// diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 22a38981b..293ff201a 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -183,6 +183,8 @@ JH/38 Bug 1395: Teach the DNS negative-cache about TTL value from the SOA in HS/05 Handle trailing backslash gracefully. (CVE-2019-15846) +JH/39 Promote DMARC support to mainline. + Exim version 4.92 ----------------- diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt index abc09ece1..1618e4279 100644 --- a/doc/doc-txt/OptionLists.txt +++ b/doc/doc-txt/OptionLists.txt @@ -182,9 +182,9 @@ directory_transport string* unset redirect disable_ipv6 boolean false main 4.61 disable_logging boolean false routers 4.11 false transports 4.11 -dmarc_forensic_sender string unset main 4.82 if experimental_dmarc -dmarc_history_file string unset main 4.82 if experimental_dmarc -dmarc_tld_file string unset main 4.82 if experimental_dmarc +dmarc_forensic_sender string unset main 4.82 if experimental_dmarc, 4.93 mainline +dmarc_history_file string unset main 4.82 if experimental_dmarc, 4.93 mainline +dmarc_tld_file string unset main 4.82 if experimental_dmarc, 4.93 mainline dns_again_means_nonexist domain list unset main 1.89 dns_check_names_pattern string + main 2.11 dns_cname_loops integer 0 main 4.92 Set to 9 for older behaviour diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt index f748f6146..2b77d2647 100644 --- a/doc/doc-txt/experimental-spec.txt +++ b/doc/doc-txt/experimental-spec.txt @@ -390,239 +390,6 @@ Use a reasonable IP. eg. one the sending cluster actually uses. -DMARC Support --------------------------------------------------------------- - -DMARC combines feedback from SPF, DKIM, and header From: in order -to attempt to provide better indicators of the authenticity of an -email. This document does not explain the fundamentals, you -should read and understand how it works by visiting the website at -http://www.dmarc.org/. - -DMARC support is added via the libopendmarc library. Visit: - - http://sourceforge.net/projects/opendmarc/ - -to obtain a copy, or find it in your favorite rpm package -repository. If building from source, this description assumes -that headers will be in /usr/local/include, and that the libraries -are in /usr/local/lib. - -1. To compile Exim with DMARC support, you must first enable SPF. -Please read the Local/Makefile comments on enabling the SUPPORT_SPF -feature. You must also have DKIM support, so you cannot set the -DISABLE_DKIM feature. Once both of those conditions have been met -you can enable DMARC in Local/Makefile: - -EXPERIMENTAL_DMARC=yes -LDFLAGS += -lopendmarc -# CFLAGS += -I/usr/local/include -# LDFLAGS += -L/usr/local/lib - -The first line sets the feature to include the correct code, and -the second line says to link the libopendmarc libraries into the -exim binary. The commented out lines should be uncommented if you -built opendmarc from source and installed in the default location. -Adjust the paths if you installed them elsewhere, but you do not -need to uncomment them if an rpm (or you) installed them in the -package controlled locations (/usr/include and /usr/lib). - - -2. Use the following global options to configure DMARC: - -Required: -dmarc_tld_file Defines the location of a text file of valid - top level domains the opendmarc library uses - during domain parsing. Maintained by Mozilla, - the most current version can be downloaded - from a link at http://publicsuffix.org/list/. - See also util/renew-opendmarc-tlds.sh script. - The default for the option is currently - /etc/exim/opendmarc.tlds - -Optional: -dmarc_history_file Defines the location of a file to log results - of dmarc verification on inbound emails. The - contents are importable by the opendmarc tools - which will manage the data, send out DMARC - reports, and expire the data. Make sure the - directory of this file is writable by the user - exim runs as. - -dmarc_forensic_sender Alternate email address to use when sending a - forensic report detailing alignment failures - if a sender domain's dmarc record specifies it - and you have configured Exim to send them. - - If set, this is expanded and used for the - From: header line; the address is extracted - from it and used for the envelope from. - If not set, the From: header is expanded from - the dsn_from option, and <> is used for the - envelope from. - - Default: unset. - - -3. By default, the DMARC processing will run for any remote, -non-authenticated user. It makes sense to only verify DMARC -status of messages coming from remote, untrusted sources. You can -use standard conditions such as hosts, senders, etc, to decide that -DMARC verification should *not* be performed for them and disable -DMARC with a control setting: - - control = dmarc_disable_verify - -A DMARC record can also specify a "forensic address", which gives -exim an email address to submit reports about failed alignment. -Exim does not do this by default because in certain conditions it -results in unintended information leakage (what lists a user might -be subscribed to, etc). You must configure exim to submit forensic -reports to the owner of the domain. If the DMARC record contains a -forensic address and you specify the control statement below, then -exim will send these forensic emails. It's also advised that you -configure a dmarc_forensic_sender because the default sender address -construction might be inadequate. - - control = dmarc_enable_forensic - -(AGAIN: You can choose not to send these forensic reports by simply -not putting the dmarc_enable_forensic control line at any point in -your exim config. If you don't tell it to send them, it will not -send them.) - -There are no options to either control. Both must appear before -the DATA acl. - - -4. You can now run DMARC checks in incoming SMTP by using the -"dmarc_status" ACL condition in the DATA ACL. You are required to -call the spf condition first in the ACLs, then the "dmarc_status" -condition. Putting this condition in the ACLs is required in order -for a DMARC check to actually occur. All of the variables are set -up before the DATA ACL, but there is no actual DMARC check that -occurs until a "dmarc_status" condition is encountered in the ACLs. - -The dmarc_status condition takes a list of strings on its -right-hand side. These strings describe recommended action based -on the DMARC check. To understand what the policy recommendations -mean, refer to the DMARC website above. Valid strings are: - - o accept The DMARC check passed and the library recommends - accepting the email. - o reject The DMARC check failed and the library recommends - rejecting the email. - o quarantine The DMARC check failed and the library recommends - keeping it for further inspection. - o none The DMARC check passed and the library recommends - no specific action, neutral. - o norecord No policy section in the DMARC record for this - sender domain. - o nofrom Unable to determine the domain of the sender. - o temperror Library error or dns error. - o off The DMARC check was disabled for this email. - -You can prefix each string with an exclamation mark to invert its -meaning, for example "!accept" will match all results but -"accept". The string list is evaluated left-to-right in a -short-circuit fashion. When a string matches the outcome of the -DMARC check, the condition succeeds. If none of the listed -strings matches the outcome of the DMARC check, the condition -fails. - -Of course, you can also use any other lookup method that Exim -supports, including LDAP, Postgres, MySQL, etc, as long as the -result is a list of colon-separated strings. - -Performing the check sets up information used by the -${authresults } expansion item. - -Several expansion variables are set before the DATA ACL is -processed, and you can use them in this ACL. The following -expansion variables are available: - - o $dmarc_status - This is a one word status indicating what the DMARC library - thinks of the email. It is a combination of the results of - DMARC record lookup and the SPF/DKIM/DMARC processing results - (if a DMARC record was found). The actual policy declared - in the DMARC record is in a separate expansion variable. - - o $dmarc_status_text - This is a slightly longer, human readable status. - - o $dmarc_used_domain - This is the domain which DMARC used to look up the DMARC - policy record. - - o $dmarc_domain_policy - This is the policy declared in the DMARC record. Valid values - are "none", "reject" and "quarantine". It is blank when there - is any error, including no DMARC record. - -A now-redundant variable $dmarc_ar_header has now been withdrawn. -Use the ${authresults } expansion instead. - - -5. How to enable DMARC advanced operation: -By default, Exim's DMARC configuration is intended to be -non-intrusive and conservative. To facilitate this, Exim will not -create any type of logging files without explicit configuration by -you, the admin. Nor will Exim send out any emails/reports about -DMARC issues without explicit configuration by you, the admin (other -than typical bounce messages that may come about due to ACL -processing or failure delivery issues). - -In order to log statistics suitable to be imported by the opendmarc -tools, you need to: -a. Configure the global setting dmarc_history_file. -b. Configure cron jobs to call the appropriate opendmarc history - import scripts and truncating the dmarc_history_file. - -In order to send forensic reports, you need to: -a. Configure the global setting dmarc_forensic_sender. -b. Configure, somewhere before the DATA ACL, the control option to - enable sending DMARC forensic reports. - - -6. Example usage: -(RCPT ACL) - warn domains = +local_domains - hosts = +local_hosts - control = dmarc_disable_verify - - warn !domains = +screwed_up_dmarc_records - control = dmarc_enable_forensic - - warn condition = (lookup if destined to mailing list) - set acl_m_mailing_list = 1 - -(DATA ACL) - warn dmarc_status = accept : none : off - !authenticated = * - log_message = DMARC DEBUG: $dmarc_status $dmarc_used_domain - - warn dmarc_status = !accept - !authenticated = * - log_message = DMARC DEBUG: '$dmarc_status' for $dmarc_used_domain - - warn dmarc_status = quarantine - !authenticated = * - set $acl_m_quarantine = 1 - # Do something in a transport with this flag variable - - deny condition = ${if eq{$dmarc_domain_policy}{reject}} - condition = ${if eq{$acl_m_mailing_list}{1}} - message = Messages from $dmarc_used_domain break mailing lists - - deny dmarc_status = reject - !authenticated = * - message = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT - - warn add_header = :at_start:${authresults {$primary_hostname}} - - - DSN extra information --------------------- If compiled with EXPERIMENTAL_DSN_INFO extra information will be added diff --git a/src/src/EDITME b/src/src/EDITME index 37e43ac39..965f058bb 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -589,7 +589,7 @@ DISABLE_MAL_MKS=yes # Uncomment the following line to add DMARC checking capability, implemented # using libopendmarc libraries. You must have SPF and DKIM support enabled also. -# EXPERIMENTAL_DMARC=yes +# SUPPORT_DMARC=yes # CFLAGS += -I/usr/local/include # LDFLAGS += -lopendmarc # Uncomment the following if you need to change the default. You can diff --git a/src/src/acl.c b/src/src/acl.c index 5f0a7864b..8e34513d0 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -70,7 +70,7 @@ enum { ACLC_ACL, ACLC_DKIM_SIGNER, ACLC_DKIM_STATUS, #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC ACLC_DMARC_STATUS, #endif ACLC_DNSLISTS, @@ -192,7 +192,7 @@ static condition_def conditions[] = { [ACLC_DKIM_SIGNER] = { US"dkim_signers", TRUE, FALSE, (unsigned int) ~ACL_BIT_DKIM }, [ACLC_DKIM_STATUS] = { US"dkim_status", TRUE, FALSE, (unsigned int) ~ACL_BIT_DKIM }, #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC [ACLC_DMARC_STATUS] = { US"dmarc_status", TRUE, FALSE, (unsigned int) ~ACL_BIT_DATA }, #endif @@ -346,7 +346,7 @@ enum { #ifndef DISABLE_DKIM CONTROL_DKIM_VERIFY, #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC CONTROL_DMARC_VERIFY, CONTROL_DMARC_FORENSIC, #endif @@ -417,7 +417,7 @@ static control_def controls_list[] = { }, #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC [CONTROL_DMARC_VERIFY] = { US"dmarc_disable_verify", FALSE, ACL_BIT_DATA | ACL_BIT_NOTSMTP | ACL_BIT_NOTSMTP_START @@ -3029,18 +3029,18 @@ for (; cb; cb = cb->next) break; #endif - #ifndef DISABLE_DKIM +#ifndef DISABLE_DKIM case CONTROL_DKIM_VERIFY: f.dkim_disable_verify = TRUE; - #ifdef EXPERIMENTAL_DMARC +# ifdef SUPPORT_DMARC /* Since DKIM was blocked, skip DMARC too */ f.dmarc_disable_verify = TRUE; f.dmarc_enable_forensic = FALSE; - #endif +# endif break; - #endif +#endif - #ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC case CONTROL_DMARC_VERIFY: f.dmarc_disable_verify = TRUE; break; @@ -3048,7 +3048,7 @@ for (; cb; cb = cb->next) case CONTROL_DMARC_FORENSIC: f.dmarc_enable_forensic = TRUE; break; - #endif +#endif case CONTROL_DSCP: if (*p == '/') @@ -3442,7 +3442,7 @@ for (; cb; cb = cb->next) break; #endif - #ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC case ACLC_DMARC_STATUS: if (!f.dmarc_has_been_checked) dmarc_process(); @@ -3452,7 +3452,7 @@ for (; cb; cb = cb->next) rc = match_isinlist(dmarc_exim_expand_query(DMARC_VERIFY_STATUS), &arg,0,NULL,NULL,MCL_STRING,TRUE,NULL); break; - #endif +#endif case ACLC_DNSLISTS: rc = verify_check_dnsbl(where, &arg, log_msgptr); diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index 17239bb85..b94b36866 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -143,6 +143,8 @@ Do not put spaces between # and the 'define'. #define SUPPORT_CRYPTEQ #define SUPPORT_DANE +#define SUPPORT_DMARC +#define DMARC_TLD_FILE "/etc/exim/opendmarc.tlds" #define SUPPORT_I18N #define SUPPORT_I18N_2008 #define SUPPORT_MAILDIR @@ -199,8 +201,6 @@ Do not put spaces between # and the 'define'. #define EXPERIMENTAL_BRIGHTMAIL #define EXPERIMENTAL_DCC #define EXPERIMENTAL_DSN_INFO -#define EXPERIMENTAL_DMARC -#define DMARC_TLD_FILE "/etc/exim/opendmarc.tlds" #define EXPERIMENTAL_LMDB #define EXPERIMENTAL_QUEUEFILE #define EXPERIMENTAL_SRS diff --git a/src/src/dmarc.c b/src/src/dmarc.c index 0644563d0..2e43f846d 100644 --- a/src/src/dmarc.c +++ b/src/src/dmarc.c @@ -1,7 +1,7 @@ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Experimental DMARC support. +/* DMARC support. Copyright (c) Todd Lyons 2012 - 2014 Copyright (c) The Exim Maintainers 2019 License: GPL */ @@ -12,7 +12,7 @@ /* Code for calling dmarc checks via libopendmarc. Called from acl.c. */ #include "exim.h" -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC # if !defined SUPPORT_SPF # error SPF must also be enabled for DMARC # elif defined DISABLE_DKIM @@ -635,6 +635,6 @@ return g; } # endif /* SUPPORT_SPF */ -#endif /* EXPERIMENTAL_DMARC */ +#endif /* SUPPORT_DMARC */ /* vi: aw ai sw=2 */ diff --git a/src/src/dmarc.h b/src/src/dmarc.h index 3a3bc6d13..c94d939cc 100644 --- a/src/src/dmarc.h +++ b/src/src/dmarc.h @@ -9,7 +9,7 @@ /* Portions Copyright (c) 2012, 2013, The Trusted Domain Project; All rights reserved, licensed for use per LICENSE.opendmarc. */ -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC # include "opendmarc/dmarc.h" # ifdef SUPPORT_SPF @@ -58,4 +58,4 @@ static int dmarc_write_history_file(); #define ARES_RESULT_UNKNOWN 11 #define ARES_RESULT_DISCARD 12 -#endif /* EXPERIMENTAL_DMARC */ +#endif /* SUPPORT_DMARC */ diff --git a/src/src/exim.c b/src/src/exim.c index f163b1249..388743f8d 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -916,6 +916,9 @@ fprintf(fp, "Support for:"); #ifdef SUPPORT_SPF fprintf(fp, " SPF"); #endif +#ifdef SUPPORT_DMARC + fprintf(fp, " DMARC"); +#endif #ifdef TCP_FASTOPEN deliver_init(); if (f.tcp_fastopen_ok) fprintf(fp, " TCP_Fast_Open"); @@ -938,9 +941,6 @@ fprintf(fp, "Support for:"); #ifdef EXPERIMENTAL_DCC fprintf(fp, " Experimental_DCC"); #endif -#ifdef EXPERIMENTAL_DMARC - fprintf(fp, " Experimental_DMARC"); -#endif #ifdef EXPERIMENTAL_DSN_INFO fprintf(fp, " Experimental_DSN_info"); #endif diff --git a/src/src/exim.h b/src/src/exim.h index 263c00321..2cc2621c4 100644 --- a/src/src/exim.h +++ b/src/src/exim.h @@ -499,7 +499,7 @@ config.h, mytypes.h, and store.h, so we don't need to mention them explicitly. #ifndef DISABLE_DKIM # include "dkim.h" #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC # include "dmarc.h" # include #endif diff --git a/src/src/expand.c b/src/src/expand.c index f38d7a492..d2ccddc73 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -530,7 +530,7 @@ static var_entry var_table[] = { { "dkim_verify_reason", vtype_stringptr, &dkim_verify_reason }, { "dkim_verify_status", vtype_stringptr, &dkim_verify_status }, #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC { "dmarc_domain_policy", vtype_stringptr, &dmarc_domain_policy }, { "dmarc_status", vtype_stringptr, &dmarc_status }, { "dmarc_status_text", vtype_stringptr, &dmarc_status_text }, @@ -4390,7 +4390,7 @@ while (*s != 0) #ifndef DISABLE_DKIM yield = authres_dkim(yield); #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC yield = authres_dmarc(yield); #endif #ifdef EXPERIMENTAL_ARC diff --git a/src/src/functions.h b/src/src/functions.h index 4a44096ea..0cd0a0d18 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -124,7 +124,7 @@ extern gstring *authres_arc(gstring *); #ifndef DISABLE_DKIM extern gstring *authres_dkim(gstring *); #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC extern gstring *authres_dmarc(gstring *); #endif extern gstring *authres_smtpauth(gstring *); diff --git a/src/src/globals.c b/src/src/globals.c index 61a9c9796..ad6b38ec5 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -239,7 +239,7 @@ struct global_flags f = #ifndef DISABLE_DKIM .dkim_disable_verify = FALSE, #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC .dmarc_has_been_checked = FALSE, .dmarc_disable_verify = FALSE, .dmarc_enable_forensic = FALSE, @@ -838,7 +838,7 @@ uschar *dkim_verify_signers = US"$dkim_signers"; uschar *dkim_verify_status = NULL; uschar *dkim_verify_reason = NULL; #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC uschar *dmarc_domain_policy = NULL; uschar *dmarc_forensic_sender = NULL; uschar *dmarc_history_file = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index 4ab43ca65..533def981 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -199,7 +199,7 @@ extern struct global_flags { #ifndef DISABLE_DKIM BOOL dkim_disable_verify :1; /* Set via ACL control statement. When set, DKIM verification is disabled for the current message */ #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC BOOL dmarc_has_been_checked :1; /* Global variable to check if test has been called yet */ BOOL dmarc_disable_verify :1; /* Set via ACL control statement. When set, DMARC verification is disabled for the current message */ BOOL dmarc_enable_forensic :1; /* Set via ACL control statement. When set, DMARC forensic reports are enabled for the current message */ @@ -511,7 +511,7 @@ extern uschar *dkim_verify_signers; /* Colon-separated list of domains for ea extern uschar *dkim_verify_status; /* result for this signature */ extern uschar *dkim_verify_reason; /* result for this signature */ #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC extern uschar *dmarc_domain_policy; /* Expansion for declared policy of used domain */ extern uschar *dmarc_forensic_sender; /* Set sender address for forensic reports */ extern uschar *dmarc_history_file; /* Expansion variable, file to store dmarc results */ diff --git a/src/src/macro_predef.c b/src/src/macro_predef.c index fce981996..e96fef938 100644 --- a/src/src/macro_predef.c +++ b/src/src/macro_predef.c @@ -146,6 +146,9 @@ due to conflicts with other common macros. */ #ifndef DISABLE_DKIM builtin_macro_create(US"_HAVE_DKIM"); #endif +#ifdef SUPPORT_DMARC + builtin_macro_create(US"_HAVE_DMARC"); +#endif #ifndef DISABLE_DNSSEC builtin_macro_create(US"_HAVE_DNSSEC"); #endif @@ -194,9 +197,6 @@ due to conflicts with other common macros. */ #ifdef EXPERIMENTAL_DCC builtin_macro_create(US"_HAVE_DCC"); #endif -#ifdef EXPERIMENTAL_DMARC - builtin_macro_create(US"_HAVE_DMARC"); -#endif #ifdef EXPERIMENTAL_DSN_INFO builtin_macro_create(US"_HAVE_DSN_INFO"); #endif diff --git a/src/src/macros.h b/src/src/macros.h index a94a71f7e..e36c09c47 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -238,7 +238,7 @@ enum { ERRMESS_TOOMANYRECIP, /* Too many recipients */ ERRMESS_LOCAL_SCAN, /* Rejected by local scan */ ERRMESS_LOCAL_ACL /* Rejected by non-SMTP ACL */ -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC ,ERRMESS_DMARC_FORENSIC /* DMARC Forensic Report */ #endif }; diff --git a/src/src/moan.c b/src/src/moan.c index fea3683ba..f6cda37f2 100644 --- a/src/src/moan.c +++ b/src/src/moan.c @@ -73,7 +73,7 @@ int size_limit = bounce_return_size_limit; FILE * fp; int pid; -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC uschar * s, * s2; /* For DMARC if there is a specific sender set, expand the variable for the @@ -111,7 +111,7 @@ fp = fdopen(fd, "wb"); if (errors_reply_to) fprintf(fp, "Reply-To: %s\n", errors_reply_to); fprintf(fp, "Auto-Submitted: auto-replied\n"); -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC if (s) fprintf(fp, "From: %s\n", s); else @@ -228,7 +228,7 @@ switch(ident) fprintf(fp, "\n"); break; -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC case ERRMESS_DMARC_FORENSIC: bounce_return_message = TRUE; bounce_return_body = FALSE; @@ -339,7 +339,7 @@ if (bounce_return_message) fputs(CS buf, fp); } } -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC /* Overkill, but use exact test in case future code gets inserted */ else if (bounce_return_body && message_file == NULL) { diff --git a/src/src/readconf.c b/src/src/readconf.c index 16f4a8abe..2f78cd746 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -122,7 +122,7 @@ static optionlist optionlist_config[] = { { "dkim_verify_minimal", opt_bool, &dkim_verify_minimal }, { "dkim_verify_signers", opt_stringptr, &dkim_verify_signers }, #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC { "dmarc_forensic_sender", opt_stringptr, &dmarc_forensic_sender }, { "dmarc_history_file", opt_stringptr, &dmarc_history_file }, { "dmarc_tld_file", opt_stringptr, &dmarc_tld_file }, diff --git a/src/src/receive.c b/src/src/receive.c index ada3ca519..31e3f7cbb 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -14,9 +14,9 @@ extern int dcc_ok; #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC # include "dmarc.h" -#endif /* EXPERIMENTAL_DMARC */ +#endif /************************************************* * Local static variables * @@ -1703,9 +1703,9 @@ header_line *msgid_header = NULL; header_line *received_header; BOOL msgid_header_newly_created = FALSE; -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC int dmarc_up = 0; -#endif /* EXPERIMENTAL_DMARC */ +#endif /* Variables for use when building the Received: header. */ @@ -1767,9 +1767,8 @@ if (smtp_input && !smtp_batched_input && !f.dkim_disable_verify) dkim_exim_verify_init(chunking_state <= CHUNKING_OFFERED); #endif -#ifdef EXPERIMENTAL_DMARC -/* initialize libopendmarc */ -dmarc_up = dmarc_init(); +#ifdef SUPPORT_DMARC +dmarc_up = dmarc_init(); /* initialize libopendmarc */ #endif /* Remember the time of reception. Exim uses time+pid for uniqueness of message @@ -3499,9 +3498,9 @@ else goto TIDYUP; #endif /* WITH_CONTENT_SCAN */ -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC dmarc_up = dmarc_store_data(from_header); -#endif /* EXPERIMENTAL_DMARC */ +#endif #ifndef DISABLE_PRDR if (prdr_requested && recipients_count > 1 && acl_smtp_data_prdr) diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 257c33de1..671798641 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2075,7 +2075,7 @@ dkim_collect_input = 0; dkim_verify_overall = dkim_verify_status = dkim_verify_reason = NULL; dkim_key_length = 0; #endif -#ifdef EXPERIMENTAL_DMARC +#ifdef SUPPORT_DMARC f.dmarc_has_been_checked = f.dmarc_disable_verify = f.dmarc_enable_forensic = FALSE; dmarc_domain_policy = dmarc_status = dmarc_status_text = dmarc_used_domain = NULL; diff --git a/test/scripts/4650-DMARC/REQUIRES b/test/scripts/4650-DMARC/REQUIRES index bb17aff6c..fe9e7b342 100644 --- a/test/scripts/4650-DMARC/REQUIRES +++ b/test/scripts/4650-DMARC/REQUIRES @@ -1 +1 @@ -support Experimental_DMARC +support DMARC