[exim] Certified Server Validation (CSV) in Exim.

Etusivu
Poista viesti
Vastaa
Lähettäjä: David Woodhouse
Päiväys:  
Vastaanottaja: exim-users
Aihe: [exim] Certified Server Validation (CSV) in Exim.
This implements CSV (http://mipassoc.org/csv/) in a HELO ACL.
At the moment, the useful part is CSA -- checking which hosts are
authorised to use a given domain name in HELO:

    helo infradead.org
    550 CSV record for infradead.org does not include 205.233.218.70


The accreditation part (DNA) is implemented as a proof of concept but
needs the one-line PTR lookup patch which I just posted, and I can't
actually see any immediate practical use for the information.

# $Id: acl-helo-csv,v 1.1 2004/12/13 17:13:17 dwmw2 Exp $
#
# Exim 4 CSA check. Written 2004 David Woodhouse <dwmw2@???>
#
# This is placed in the public domain. You may copy, modify, distribute
# and use it in any way you see fit.
#
# Ways in which you might want to use it include invoking it directly
# to reject bogus HELO outright, with 'acl_smtp_helo = check_csv' or
# from an existing HELO ACL with 'require acl = check_csv'.
#
# Alternatively, to allow sites which fail the CSA check to still send
# messages to postmaster@, you could set an ACL variable upon CSV failure...
#
# warn !acl = check_csv
#        set acl_c4 = rejectmelater
#
# ... and later test for it in your RCPT ACL:
#
# deny condition = ${if eq{$acl_c4}{rejectmelater} {1}}
#      !local_parts = postmaster
#      message = CSA record for $sender_helo_name does not authorise $sender_host_address
#
# The DNA check is included here as a proof of concept in case anyone 
# actually works out what they want to _do_ with the information. As of
# Exim 4.43, you also need a one-line fix to prevent Exim's dnsdb lookup
# for PTR records from attempting to reverse $sender_helo_name as if it 
# were an IPv4 address and appending '.in-addr.arpa' to it. It stores the
# accreditation service(s) in $acl_c0 and the results in $acl_c1, separated
# by newlines if there is more than one.


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

  # 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}}

  # 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}}


  # Extract good hosts (1 2 x <hostname>)
  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>)
  warn  set acl_m3 = ${sg {${sg {${sg {${sg {$acl_m1} \
                {(?m)^1 ([0-9]+) [0-9]+ (.*)\$} \
                {\N${if eq{$1}{3} {$2}}\N} \
            }} {[\n]+}{:}}} {^:}{}}} {:\$}{} }


  # Extract explicitly denied hosts (1 [01] x <hostname>)
  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]+}{:}}} {^:}{}}} {:\$}{} }



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


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


# require acl = check_dna
accept

###########################################
# DNA checks here as proof of concept.

check_dna:
# Avoid DNA checks for hosts with 'Weight' field of 3.
accept hosts = $acl_m3

# Now look for DNA record, for hosts which may use it for authentication.

  # Look up the reputation service(s) which this host wants us to use for it.
  warn    set acl_c0 = ${lookup dnsdb{ptr=$sender_helo_name}}


accept condition = ${if eq {$acl_c0}{} {1}}

  # Extract the PTR records which start '_vouch._smtp.'
  warn    set acl_c0 = ${sg {${sg{\n$acl_c0} \
                {(?i)(\n_vouch\\._smtp\\.([^\n]*)|\n[^\n]*)} \
                {\N${if !eq{$2}{} {\n$2}}\N}}\
              } {^\n}{}}


# .. and bail if there are none.
accept condition = ${if eq {$acl_c0}{} {1}}

  warn    set acl_c1 = ${sg {${sg{\n$acl_c0} \
               {(?m)^(.*)\$} \
               {\N${lookup dnsdb{txt=$sender_helo_name.$1}}\N} \
            }} {^\n}{}}
  accept





--
dwmw2