From 95dfacf282b0a4f0f595b43bdc997ef0e3ed43ed Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 12 Jan 2019 20:47:23 +0000 Subject: [PATCH] Add basic framework for PRDR use with per-user content filters to example config. 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 | 14 +++++++++ src/src/configure.default | 61 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index dc924678d..0fc086d7b 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -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 &<>& 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 diff --git a/src/src/configure.default b/src/src/configure.default index 02a967410..c9b2fc6ef 100644 --- a/src/src/configure.default +++ b/src/src/configure.default @@ -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 -- 2.25.1