chiark / gitweb /
Delay ACL header edits until transport time.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 14 Jun 2015 12:51:55 +0000 (13:51 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 14 Jun 2015 12:51:55 +0000 (13:51 +0100)
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
defs.m4
exchange.m4
spam.m4

diff --git a/base.m4 b/base.m4
index 506c4e0f216438d67dbb444d394b47131feb7ee7..39e302bf07f7f587e3969ac32555716754acf6e3 100644 (file)
--- 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 8ece5d493254d2ba3880ab32cd6fa43270dbc97a..370c2d31a11a76c081db311a7b7e0567f93e7a5d 100644 (file)
--- 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
index 1dc58f013342f51f06cdc0a2723369b2c516f308..9f8324a6c9f74bd862f788e308c2d76f4d70a273 100644 (file)
@@ -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 bae1686903611d9649437ab41d6477c5a30689ed..a1134e58c6f4baf1aefb3cd12d90a94bfcea00e7 100644 (file)
--- 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