Hiho Dears,

after investigating my EXIM DMARC (opendmarc EXP) setup and the current docs 
about Exim DMARC in more detail i've found that anything seems to work except 
that the SPF variable(s) - expescially "spf_domain=" are not filled correctly 
within dmarc.c. This leads to bad XML reports too, because of "failed" empty 
SPF fields.

Could someone pls explain how the "spf_domain" vs. spf data within DMARC whould 
work?

Here is an example of a googlemail.com email going through DMARC here:

--- snip ---
2017-05-31 10:40:11 1dFzAp-0007cW-UY DKIM: d=googlemail.com s=20161025 
c=relaxed/relaxed a=rsa-sha256 b=2048 [verification succeeded]
2017-05-31 10:40:11 1dFzAp-0007cW-UY DMARC results: spf_domain= 
dmarc_domain=googlemail.com spf_align=no dkim_align=yes enforcement='Accept'
2017-05-31 10:40:11 1dFzAp-0007cW-UY H=mail-wr0-f195.google.com 
[209.85.128.195] Warning: [DMARC] ACCEPTED: accept googlemail.com
2017-05-31 10:40:11 1dFzAp-0007cW-UY H=mail-wr0-f195.google.com 
[209.85.128.195] Warning: [DMARC] DEBUG: 'accept' for googlemail.com STATUS 
Accept USED_DOMAIN googlemail.com DMARC_HEADER Authentication-Results: 
mail.syndicat.com; dmarc=pass header.from=googlemail.com
--- snap ---

I use EXIM 4.89nb1 on NetBSD

build against:
        - libspf2-1.2.10
        - opendmarc 1.3.1

with:
        LOOKUP_LIBS=-lmysqlclient -lssl -lcrypto -lopendmarc -Wl,-R/usr/pkg/lib 
-L/usr/pkg/lib -lsasl2 -lspf2
        EXPERIMENTAL_SPF=yes
        EXPERIMENTAL_DMARC=yes
        WITH_CONTENT_SCAN=YES
        ...

OpenDMARC is build with SPF support (tried it without too):
        opendmarc: OpenDMARC Filter v1.3.1
        SMFI_VERSION 0x1000001
        libmilter version 1.0.1
        Active code options:
                WITH_SPF

in opendmarc.conf these are commented our / default:

##  SPFIgnoreResults { true | false }
##      default "false"

#SPFSelfValidate true

##  Syslog { true | false }
##      default "false"

I'm not sure if Exim DMARC uses this over i.e. libopendmarc or SPF directly 
from libspf2. 

As described, i do the SPF checks "before" DMARC checks within 


acl_check_rcpt:
...

### SPF native

        warn    set acl_m_spf_record = ${lookup 
dnsdb{txt=$sender_address_domain}{$value}}

        # No record
        warn    !condition      = ${if def:acl_m_spf_record}
                !hosts          = +3rdmxes : +relay_from_hosts
                log_message     = [SPF] no record

        # SPF +all is meaningless
        warn    condition       = ${if match {$acl_m_spf_record}{\\+all}}
                log_message     = [SPF] meaningless +all
                !hosts          = +3rdmxes : +relay_from_hosts

        warn    spf             = fail
                !hosts          = +3rdmxes : +relay_from_hosts : 
+nosa_from_hosts
                log_message     = [SPF] $sender_host_address is not allowed to 
send mail from $sender_address_domain

        # Add a SPF-Received: header to the message
        warn    message         = $spf_received
                !hosts          = +3rdmxes : +relay_from_hosts

        accept  spf             = pass
                log_message     = [SPF] pass
                !hosts          = +3rdmxes : +relay_from_hosts


### DMARC niels
# --- check sender's DMARC policy
        warn    domains        = +local_domains
                hosts          = +3rdmxes : +relay_from_hosts
                log_message    = [DMARC] no check for OUR hosts
                control        = dmarc_disable_verify


        warn    !domains       = +screwed_up_dmarc_records
                #log_message    = [DMARC] check forensics
                control        = dmarc_enable_forensic
###

and then DMARC (as described) in 

acl_check_data:
...

## test
  # --- check sender's DMARC policy
  warn   dmarc_status   = *
         add_header     = $dmarc_ar_header

  deny   dmarc_status   = reject
         message        = Rejected by sender's DMARC policy

  warn   dmarc_status   = quarantine
         set acl_c0     = ${eval:$acl_c0+40}
         set acl_c1     = QDMARC(40) suspicious message according DMARC policy; 
$acl_c1

## test


For me it seems, in dmarc.c spf_domain is set not correctly (however?)., but 
seems relatively "hard wired" there Any idea, what could be wrong here?
https://github.com/Exim/exim/blob/master/src/src/dmarc.c
--- snip ---
  /* Use the envelope sender domain for this part of DMARC */
  spf_sender_domain = expand_string(US"$sender_address_domain");
  if (!spf_response)
    {
    /* No spf data means null envelope sender so generate a domain name
     * from the sender_helo_name  */
    if (!spf_sender_domain)
      {
      spf_sender_domain = sender_helo_name;
      log_write(0, LOG_MAIN, "DMARC using synthesized SPF sender domain = %s\n",
                             spf_sender_domain);
      DEBUG(D_receive)
        debug_printf("DMARC using synthesized SPF sender domain = %s\n",
          spf_sender_domain);
      }
    dmarc_spf_result = DMARC_POLICY_SPF_OUTCOME_NONE;
    dmarc_spf_ares_result = ARES_RESULT_UNKNOWN;
    origin = DMARC_POLICY_SPF_ORIGIN_HELO;
    spf_human_readable = US"";
    }
  else
    {
    sr = spf_response->result;
    dmarc_spf_result = sr == SPF_RESULT_NEUTRAL  ? 
DMARC_POLICY_SPF_OUTCOME_NONE :
                       sr == SPF_RESULT_PASS     ? 
DMARC_POLICY_SPF_OUTCOME_PASS :
                       sr == SPF_RESULT_FAIL     ? 
DMARC_POLICY_SPF_OUTCOME_FAIL :
                       sr == SPF_RESULT_SOFTFAIL ? 
DMARC_POLICY_SPF_OUTCOME_TMPFAIL :
                       DMARC_POLICY_SPF_OUTCOME_NONE;
    dmarc_spf_ares_result = sr == SPF_RESULT_NEUTRAL   ? ARES_RESULT_NEUTRAL :
                            sr == SPF_RESULT_PASS      ? ARES_RESULT_PASS :
                            sr == SPF_RESULT_FAIL      ? ARES_RESULT_FAIL :
                            sr == SPF_RESULT_SOFTFAIL  ? ARES_RESULT_SOFTFAIL :
                            sr == SPF_RESULT_NONE      ? ARES_RESULT_NONE :
                            sr == SPF_RESULT_TEMPERROR ? ARES_RESULT_TEMPERROR :
                            sr == SPF_RESULT_PERMERROR ? ARES_RESULT_PERMERROR :
                            ARES_RESULT_UNKNOWN;
    origin = DMARC_POLICY_SPF_ORIGIN_MAILFROM;
    spf_human_readable = (uschar *)spf_response->header_comment;
    DEBUG(D_receive)
      debug_printf("DMARC using SPF sender domain = %s\n", spf_sender_domain);
    }
  if (strcmp( CCS spf_sender_domain, "") == 0)
dmarc_abort = TRUE;
--- snap ---

...and here the "spf_sender_domain" is used for rendering of "spf_sender":
--- snip ---
    {
    log_write(0, LOG_MAIN, "DMARC results: spf_domain=%s dmarc_domain=%s "
                           "spf_align=%s dkim_align=%s enforcement='%s'",
                           spf_sender_domain, dmarc_used_domain,
                           (sa==DMARC_POLICY_SPF_ALIGNMENT_PASS) ?"yes":"no",
                           (da==DMARC_POLICY_DKIM_ALIGNMENT_PASS)?"yes":"no",
                           dmarc_status_text);
    history_file_status = dmarc_write_history_file();
    /* Now get the forensic reporting addresses, if any */
    ruf = opendmarc_policy_fetch_ruf(dmarc_pctx, NULL, 0, 1);
    dmarc_send_forensic_report(ruf);
    }
}
--- snap ---

many thanks in advance for any help or hint!

best regards,




Niels.
-- 
 ---
 Niels Dettenbach
 Syndicat IT & Internet
 http://www.syndicat.com
 PGP: https://syndicat.com/pub_key.asc
 ---
 





-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Reply via email to