Re: [exim] DKIM verification in 4.70 not working

Top Page
Delete this message
Reply to this message
Author: Todd Lyons
Date:  
To: Tom Kistner
CC: exim-users
Subject: Re: [exim] DKIM verification in 4.70 not working
On Thu, Nov 19, 2009 at 12:22 AM, Tom Kistner <tom@???> wrote:
>
> dkim_verify_signers is expanded each time before it is used, at a point
> where header information is available. So you can do several tricks to
> dynamically call the DKIM ACL based on envelope or header addresses.
>
> At the moment, it can be useful to statically call acl_smtp_dkim for "known"
> all-signers additionally, like:
>
> dkim_verify_signers = $dkim_signers:paypal.com:gmail.com


I changed it to more closely match your suggestion:

# Could do a mysql lookup, memcache lookup via perl, etc
KNOWN_DKIM_SIGNERS = paypal.com : gmail.com
dkim_verify_signers = $dkim_signers : KNOWN_DKIM_SIGNERS

I used a MACRO since it turns out that domainlist expansion is not
performed in dkim_verify_signers. At first I tried setting a
domainlist known_dkim_signers. In my ACL, when I did some debugging,
the first time it checked signer "gmail.com" (correct) and then it
checked signer "+known_dkim_signers" (literal, not expanded). So I
switched it to the MACRO and everything works as expected.

> And then in the ACL:
> warn log_message = DKIM: Unsigned message from $sender_address_domain
>     sender_domains = gmail.com:paypal.com
>     dkim_signers = gmail.com:paypal.com
>     dkim_status = none


I changed it to be more like your example, with one logic addition.
However, I'm a bit confused as to the intention of the dkim_signers
line. What is the difference in the operation of the ACL above with
the dkim_signers line commented out? Looking at the spec.txt, it
seems to require that basically the dkim_signers check should be the
same as sender_domains. But logically it seems like the dkim_signers
line should not be used because you're trying to catch an unsigned
message from that known signing domain. Since the email isn't signed,
at least not by that domain, the dkim_signers check _seems_like_ it
should always fail for every pass through that ACL. What logical
mistake am I making here? (Maybe if I think in my head
"dkim_currently_verifying", it would make more sense? Because the
longer I think about it, the more it seems like you're just iterating
through the dkim_verify_signers setting...)

I was suprised to find out that just changing the message From header
doesn't change the $sender_address_domain. $sender_address_domain is
set to mrball.net when the envelope sender is toddatmrball.net and the
From message header is mrballcbatgmail.com (I expected it to
essentially be ${lc:${domain:$h_from:}} aka gmail.com). So the
example above will catch anybody trying to fake the envelope sender
but allow anything in the header From. Thinking about it, that seems
to be one characteristic that makes it mailing list safe if the
mailinglist strips previous signature headers and adds its own. But
that doesn't necessarily seem _good_.

Now my full ACL looks like this. Is there anything obviously wrong
with it? (commented line aside)

acl_check_dkim:
  accept  dkim_status    = none
          sender_domains = KNOWN_DKIM_SIGNERS
          dkim_signers   = KNOWN_DKIM_SIGNERS
          condition      = ${if
match_domain{$sender_address_domain}{$dkim_cur_signer} {yes}{no}}
          log_message    = Possible DKIM Forgery: Unsigned message
from $sender_address_domain
          add_header     = :at_start:X-DKIM: Exim $version_number on
$primary_hostname (no dkim signature for required domain:
$dkim_cur_signer)


  accept  dkim_status    = none
          !sender_domains = KNOWN_DKIM_SIGNERS
          !dkim_signers  = KNOWN_DKIM_SIGNERS
          set acl_m_dkim_hdr = 1
          add_header     = :at_start:X-DKIM: Exim $version_number on
$primary_hostname (no dkim signature for $dkim_cur_signer)


  warn    condition      = ${if eq {$acl_m_dkim_hdr}{1} {no}{yes}}
          set acl_m_dkim_hdr = 1
          add_header     = :at_start:X-DKIM: Exim $version_number on
$primary_hostname


  accept  dkim_status    = pass : invalid
          add_header     = :at_start:Authentication-Results:
$primary_hostname; dkim=$dkim_verify_status;
signing_identity="$dkim_cur_signer"; reason="$dkim_verify_reason"


  deny    dkim_status    = fail
          condition      = ${if eq {$dkim_key_testing}{1} {no}{yes}}
          message        = Rejected: $dkim_verify_reason


accept

> I have tried to create an API that allows for a broad range of policies.
> Unfortunately that can make things quite complicated :)


That level of configurability is very much appreciated! I've been
following DKIM for a while and building/testing/running dkim-milter on
sendmail for a few years now. Murray is very active in the
development and implementation of DKIM. I very much like his milter's
configurability, and I model somewhat my headers after the headers
that the milter generates. Your API gives me even more customizations
than I'm accustomed to. So...Yay!!!

-- 
Regards...      Todd
The best thing about pair programming is that you have the perfect
audience for your genius.  -- Kent Beck