ietf-clear
[Top] [All Lists]

[ietf-clear] CSV implementation for Exim 4.

2004-12-12 17:19:54
David Woodhouse <dwmw2(_at_)infradead(_dot_)org> wrote:

OK, new version. We're also a bit more picky about the text we find in
the hostname part of a SRV record and about stray colons. 

   I'm still trying to learn exim-speak, so somebody may need to help me...

I've included an attempt at DNA too, although it doesn't actually work
because Exim assumes you're using an IP address if you ask for a PTR
record to be looked up. In any case, I don't quite understand what I'd
do with the information which I get from the hosts _own_ nominated
reputation service. We should surely be using our own trusted services
for that?

   Yes, absolutely. The PTR records are mainly for use by other reputation
services to find accreditations which are useful.


check_csa:

   I understand this to be intended to be called as an ACL at HELO time
during the SMTP session.

# Don't force everyone to include localhost in their CSA record, 
# just so that connections to the local MTA work properly.
accept hosts = localhost

   Based on further considerations of Dave Crocker's comments, I'd
recommend that localhost result in an "unknown" response.

   (Earlier, we had discussed considering localhost to be implied in
any IP list returned by the SRV query. I still don't see any harm in
that, but I do see the potential for confusion. In any case, localhost
should be handled as its own case, not run through CSV testing.)

# Find CSA record.
warn  set acl_m1 = ${lookup dnsdb{srv=_client._smtp.$sender_helo_name}}

# If there's no CSA record, accept the HELO name.
accept condition = ${if eq {$acl_m1}{} {1}}

   CSV needs two separate conditions where processing continues:

1) the "unknown" case, where all anti-spam tests will be run;
2) the "authenticated and authorized" case, where those are bypassed.

   My understanding of Exim is that there are three returns from an ACL:

- accept, which sends a 2xx;
- deny, which sends a 5xx;
- defer, which sends a 4xx;

   Thus, "accept" is correct for both the cases above.

   (I'm not sure how this code saves the A+A information, though...

# Check the CSA record. Each SRV record should match {^1 [0123] [0-9]+ 
<hostname>}
# or we treat it as no record at all. The uncommented <hostname> regex is 
taken from
# the Exim default dns_check_names_pattern; the commented version below is the
# UTF-8 version of same. Switch them over if you use the 'allow_utf8_domains' 
option
# to allow Exim to use raw UTF-8 in DNS. 
  accept condition = ${if !match{\n$acl_m1} {(?i)^(\n1 [0123] [0-9]+ \
      (?>(?(2)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+\
#     
(?>(?(2)\.|())[_a-z0-9\xc0-\xff](?>[-_a-z0-9\x80-\xff]*[_a-z0-9\x80-\xbf])?)+\
      )*\$} {1}}

   I trust David has gotten these expressions right.

  # Extract good hosts (1 2 x <hostname>)

   My understanding is that "warn" in Exim causes a header to be added
and/or information to be logged. Alas, I can't read the following well
enough to guess what that header or log message might be.

  warn        set acl_m2 = ${sg {${sg {${sg {${sg {$acl_m1} \
                              {(?m)^1 ([0-9]+) [0-9]+ (.*)\$} \
                              {\N${if eq{$1}{2} {$2}}\N} \
                      }} {[\n]+}{:}}} {^:}{}}} {:\$}{} }

  # Extract hosts which are authorised, but not to be used for authentication
  # (1 3 x <hostname>)

   This is wrong. For weight==3, the list (if any) of IP addresses returned
by the SRV query MUST be ignored.

  warn  set acl_m3 = ${sg {${sg {${sg {${sg {$acl_m1} \
                              {(?m)^1 ([0-9]+) [0-9]+ (.*)\$} \
                              {\N${if eq{$1}{3} {$2}}\N} \
                      }} {[\n]+}{:}}} {^:}{}}} {:\$}{} }

   This case should probably return the "unknown" CSV response.

  # Extract explicitly denied hosts (1 [01] x <hostname>)

   Likewise, for weight==1 the list of IP addresses MUST be ignored. It's
the _name_ which is not authorized.

  warn  set acl_m4 = ${sg {${sg {${sg {${sg {$acl_m1} \
                              {(?m)^1 ([0-9]+) [0-9]+ (.*)\$} \
                              {\N${if or {{eq{$1}{0}} {eq{$1}{1}}} {$2}}\N} \
                      }} {[\n]+}{:}}} {^:}{}}} {:\$}{} }



   This weight==1 case should return a 5xx error (that the name is not
authorized).

  deny        hosts = $acl_m4
      message = CSA record for $sender_helo_name explicitly forbids 
$sender_host_address

   We're coming to the case where weight==2, but the IP address does not
match any in the list. (I'm not sure what code here tests that.)

  deny        message = CSA record for $sender_helo_name does not include 
$sender_host_address
      !hosts = $acl_m2
      !hosts = $acl_m3

<snip the DNA part>

--
John Leslie <john(_at_)jlc(_dot_)net>