Add basic framework for PRDR use with per-user content filters to example config.
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 12 Jan 2019 20:47:23 +0000 (20:47 +0000)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Sun, 27 Jan 2019 19:50:27 +0000 (20:50 +0100)
Mostly commented-out and with dummy lookups since we do not know what sorts
of filtering may be employed.

(cherry picked from commit b220576b3ba5396af6b3e0f45739f269079f8fc5)

doc/doc-docbook/spec.xfpt
src/src/configure.default

index dc92467..0fc086d 100644 (file)
@@ -6257,6 +6257,9 @@ remote_smtp:
   dnssec_request_domains = *
   hosts_try_dane = *
 .endif
+.ifdef _HAVE_PRDR
+  hosts_try_prdr = *
+.endif
 .endd
 This transport is used for delivering messages over SMTP connections.
 The list of remote hosts comes from the router.
@@ -6265,6 +6268,11 @@ with over-long lines.  The built-in macro _HAVE_DANE guards configuration
 to try to use DNSSEC for all queries and to use DANE for delivery;
 see section &<<SECDANE>>& for more details.
 
+The &%hosts_try_prdr%& option enables an efficiency SMTP option.  It is
+negotiated between client and server and not expected to cause problems
+but can be disabled if needed.  The built-in macro _HAVE_PRDR guards the
+use of the &%hosts_try_prdr%& configuration option.
+
 The other remote transport is used when delivering to a specific smarthost
 with whom there must be some kind of existing relationship, instead of the
 usual federated system.
@@ -6299,6 +6307,9 @@ smarthost_smtp:
   tls_require_ciphers = SECURE192:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1
 .endif
 .endif
+.ifdef _HAVE_PRDR
+  hosts_try_prdr = *
+.endif
 .endd
 After the same &%message_size_limit%& hack, we then specify that this Transport
 can handle messages to multiple domains in one run.  The assumption here is
@@ -6318,6 +6329,9 @@ ROUTER_SMARTHOST macro, because that is unaffected by CNAMEs present in DNS.
 You want to specify the hostname which you'll expect to validate for, and that
 should not be subject to insecure tampering via DNS results.
 
+For the &%hosts_try_prdr%& option see the previous transport.
+
+All other options are defaulted.
 .code
 local_delivery:
   driver = appendfile
index 02a9674..c9b2fc6 100644 (file)
@@ -119,8 +119,11 @@ hostlist   relay_from_hosts = localhost
 # manual for details. The lists above are used in the access control lists for
 # checking incoming messages. The names of these ACLs are defined here:
 
-acl_smtp_rcpt = acl_check_rcpt
-acl_smtp_data = acl_check_data
+acl_smtp_rcpt =         acl_check_rcpt
+.ifdef _HAVE_PRDR
+acl_smtp_data_prdr =    acl_check_prdr
+.endif
+acl_smtp_data =         acl_check_data
 
 # You should not change those settings until you understand how ACLs work.
 
@@ -263,7 +266,9 @@ dns_dnssec_ok = 1
 # may request to use it.  For multi-recipient mails we then can
 # reject or accept per-user after the message is received.
 #
+.ifdef _HAVE_PRDR
 prdr_enable = true
+.endif
 
 
 # By default, Exim expects all envelope addresses to be fully qualified, that
@@ -516,12 +521,45 @@ acl_check_rcpt:
   # require verify = csa
   #############################################################################
 
+  #############################################################################
+  # If doing per-user content filtering then recipients with filters different
+  # to the first recipient must be deferred unless the sender talks PRDR.
+  #
+  # defer  !condition     = $prdr_requested
+  #        condition      = ${if > {0}{$receipients_count}}
+  #        condition      = ${if !eq {$acl_m_content_filter} \
+  #                                  {${lookup PER_RCPT_CONTENT_FILTER}}}
+  # warn   !condition     = $prdr_requested
+  #        condition      = ${if > {0}{$receipients_count}}
+  #        set acl_m_content_filter = ${lookup PER_RCPT_CONTENT_FILTER}
+  #############################################################################
+
   # At this point, the address has passed all the checks that have been
   # configured, so we accept it unconditionally.
 
   accept
 
 
+# This ACL is used once per recipient, for multi-recipient messages, if
+# we advertised PRDR.  It can be used to perform receipient-dependent
+# header- and body- based filtering and rejections.
+# We set a variable to record that PRDR was active used, so that checking
+# in the data ACL can be skipped.
+
+.ifdef _HAVE_PRDR
+acl_check_prdr:
+  warn  set acl_m_did_prdr = y
+.endif
+
+  #############################################################################
+  # do lookup on filtering, with $local_part@$domain, deny on filter match
+  #
+  # deny      set acl_m_content_filter = ${lookup PER_RCPT_CONTENT_FILTER}
+  #           condition    = ...
+  #############################################################################
+
+  accept
+
 # This ACL is used after the contents of a message have been received. This
 # is the ACL in which you can test a message's headers or body, and in
 # particular, this is where you can invoke external virus or spam scanners.
@@ -561,6 +599,19 @@ acl_check_data:
   #                      X-Spam_bar: $spam_bar\n\
   #                      X-Spam_report: $spam_report
 
+  #############################################################################
+  # No more tests if PRDR was actively used.
+  # accept   condition  = ${if def:acl_m_did_prdr}
+  #
+  # To get here, all message recipients must have identical per-user
+  # content filtering (enforced by RCPT ACL).  Do lookup for filter
+  # and deny on match.
+  #
+  # deny      set acl_m_content_filter = ${lookup PER_RCPT_CONTENT_FILTER}
+  #           condition    = ...
+  #############################################################################
+
+
   # Accept the message.
 
   accept
@@ -757,6 +808,9 @@ remote_smtp:
   dnssec_request_domains = *
   hosts_try_dane = *
 .endif
+.ifdef _HAVE_PRDR
+  hosts_try_prdr = *
+.endif
 
 
 # This transport is used for delivering messages to a smarthost, if the
@@ -795,6 +849,9 @@ smarthost_smtp:
   tls_require_ciphers = SECURE192:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1
 .endif
 .endif
+.ifdef _HAVE_PRDR
+  hosts_try_prdr = *
+.endif
 
 
 # This transport is used for local delivery to user mailboxes in traditional