From 1e5ccd7c52be79d1de45691a0bb46cbb1a686bf0 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 14 Jun 2015 13:51:55 +0100 Subject: [PATCH] Delay ACL header edits until transport time. Don't use the `add_header' ACL control any more. Instead, just accumulate the desired header additions and removals in variables, and apply them at transport time. This way, the headers we see in the message are the unmodified ones, as the message was originally given to us. We can therefore apply header /removals/ (which aren't allowed in ACLs, so have to be delayed to routing/transport time) coherently, without the risk of clobbering the headers we've added ourselves. --- base.m4 | 21 +++++++++++++++++++-- defs.m4 | 7 +++++++ exchange.m4 | 4 ++-- spam.m4 | 8 ++++---- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/base.m4 b/base.m4 index 506c4e0..39e302b 100644 --- a/base.m4 +++ b/base.m4 @@ -160,11 +160,11 @@ mail: warn condition = $acl_c_helo_warning !condition = ${if eq{$acl_c_mode}{submission}} !hosts = +allnets - add_header = :after_received:X-CONF_header_token-Warning: \ + ADD_HEADER(<:X-CONF_header_token-Warning: \ BADHELO \ Client's HELO doesn't match its IP address.\n\t\ helo-name=$sender_helo_name \ - address=$sender_host_address + address=$sender_host_address:>) ## Always allow the empty sender, so that we can receive bounces. accept senders = : @@ -382,6 +382,16 @@ m4_define(<:USER_DELIVERY:>, envelope_to_add = true return_path_add = true:>) +m4_define(<:APPLY_HEADER_CHANGES:>, + <:headers_add = m4_ifelse(<:$1:>, <::>, + <:$acl_m_hdradd:>, + <:${if def:acl_m_hdradd{$acl_m_hdradd\n}}\ + $1:>) + headers_remove = m4_ifelse(<:$2:>, <::>, + <:$acl_m_hdrrm:>, + <:${if def:acl_m_hdrrm{$acl_m_hdrrm:}}\ + $2:>):>) + SECTION(transports)m4_dnl ## A standard transport for remote delivery. By default, try to do TLS, and ## don't worry too much if it's not very secure: the alternative is sending @@ -391,12 +401,14 @@ SECTION(transports)m4_dnl ## it into the transport name. This is very unpleasant, of course. smtp: driver = smtp + APPLY_HEADER_CHANGES tls_require_ciphers = CONF_acceptable_ciphers tls_dh_min_bits = 1020 tls_tempfail_tryclear = true m4_define(<:SMTP_TRANS_DHBITS:>, <:driver = smtp + APPLY_HEADER_CHANGES hosts_try_auth = * hosts_require_tls = DOMKV(tls-peer-ca, {*}{}) hosts_require_auth = \ @@ -423,6 +435,7 @@ smtp_dhbits_2048: ## authentication. smtp_local: driver = smtp + APPLY_HEADER_CHANGES hosts_require_tls = * tls_certificate = CONF_sysconf_dir/client.certlist tls_privatekey = CONF_sysconf_dir/client.key @@ -437,6 +450,7 @@ smtp_local: ## A standard transport for local delivery. deliver: driver = appendfile + APPLY_HEADER_CHANGES file = /var/mail/$local_part group = mail mode = 0600 @@ -446,17 +460,20 @@ deliver: ## Transports for user filters. mailbox: driver = appendfile + APPLY_HEADER_CHANGES initgroups = true USER_DELIVERY maildir: driver = appendfile + APPLY_HEADER_CHANGES maildir_format = true initgroups = true USER_DELIVERY pipe: driver = pipe + APPLY_HEADER_CHANGES path = ${if and {{def:home} {exists{$home/bin}}} {$home/bin:} {}}\ /usr/local/bin:/usr/local/sbin:\ /usr/bin:/usr/sbin:/bin:/sbin diff --git a/defs.m4 b/defs.m4 index 8ece5d4..370c2d3 100644 --- a/defs.m4 +++ b/defs.m4 @@ -112,6 +112,13 @@ m4_ifdef(<:_done:$1/$2:>, <::>, <:m4_dnl m4_ifdef(<:_head:$1/$2:>, <:<:##:> m4_indir(<:_head:$1/$2:>) :>)m4_define(<:_done:$1/$2:>):>):>):>) +## ADD_HEADER(hdrs) +## +## An ACL action to add the given HDRS, which are a `\n'-terminated list of +## new header lines. +m4_define(<:ADD_HEADER:>, <:m4_dnl + set acl_m_hdradd = ${if def:acl_m_hdradd{$acl_m_hdradd}{}}$1\n:>) + ## RENAME_HEADERS_ADD(list) ## ## Return a newline-separated list of message header additions of the form diff --git a/exchange.m4 b/exchange.m4 index 1dc58f0..9f8324a 100644 --- a/exchange.m4 +++ b/exchange.m4 @@ -52,12 +52,12 @@ mail_client_addr: {${if match_domain {$sender_address_domain} \ {+public} \ {+allnets}{! +allnets}}})} - add_header = :after_received:X-CONF_header_token-Warning: \ + ADD_HEADER(<:X-CONF_header_token-Warning: \ RCLNTLSNDR \ Apparently local sender, but received from remote \ server.\n\t\ sender=$sender_address \ - host=$sender_host_address + host=$sender_host_address:>) ## OK. accept diff --git a/spam.m4 b/spam.m4 index bae1686..a1134e5 100644 --- a/spam.m4 +++ b/spam.m4 @@ -205,13 +205,13 @@ data_spam: set acl_m_spam_tests = ${sg{$acl_m_spam_tests}{!(.)}{\$1}} ## Insert the headers. - add_header = X-CONF_header_token-SpamAssassin-Score: \ + ADD_HEADER(<:X-CONF_header_token-SpamAssassin-Score: \ $spam_score/$acl_m_spam_limit_presentation \ - ($spam_bar) - add_header = X-CONF_header_token-SpamAssassin-Status: \ + ($spam_bar):>) + ADD_HEADER(<:X-CONF_header_token-SpamAssassin-Status: \ score=$spam_score, \ limit=$acl_m_spam_limit_presentation, \n\t\ - tests=$acl_m_spam_tests + tests=$acl_m_spam_tests:>) ## We're good. accept -- 2.11.0