From: Wietse Venema Date: Sun, 19 Oct 2014 05:00:00 +0000 (-0500) Subject: postfix-2.12-20141019 X-Git-Tag: v3.0.0-RC1~22 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e4699078cf0c1f93bc232ef6dbcffc12e0e6bef8;p=thirdparty%2Fpostfix.git postfix-2.12-20141019 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 080399cdc..8a0e2084a 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -20666,3 +20666,22 @@ Apologies for any names omitted. with similar code elsewhere. File: master/master_ent.c. Backed out SMTP client TLS fallback due to multiple problems. + +20141018 + + Bugfix (introduced: Postfix 2.3): when a Milter inserted a + header ABOVE Postfix's own Received: header, Postfix would + expose its own Received: header to Milters (violating + protocol) and hide the Milter-inserted header from Milters + (wtf). Files: cleanup/cleanup.h, cleanup/cleanup_message.c, + cleanup/cleanup_state.c, milter/milter.[hc], milter/milter8.c. + + Cleanup: revert the workaround that places headers inserted + with PREPEND actions or policy requests BELOW Postfix's own + Received: message header. File: smtpd/smtpd.c. + +20141019 + + Cleanup: replace dozens and dozens of ad-hoc string constants + with CHARS_SPACE, CHARS_COMMA_SP, and CHARS_BRACE. Files: + 52, too many files to mention here. diff --git a/postfix/README_FILES/TLS_README b/postfix/README_FILES/TLS_README index 67a2e3f8c..adca4c825 100644 --- a/postfix/README_FILES/TLS_README +++ b/postfix/README_FILES/TLS_README @@ -1027,11 +1027,8 @@ default. This is the recommended configuration for early adopters. * The "example.com" destination uses DANE, but if TLSA records are not present or are unusable, mail is deferred. - * The "example.org" destination uses DANE if possible, but uses opportunistic - TLS if no TLSA records are found. The "fallback" attribute (Postfix >= - 2.12) overrides the global main.cf smtp_tls_fallback_level parameter to - employ unauthenticated mandatory encryption if DANE authentication fails, - after logging a warning. + * The "example.org" destination uses DANE if possible, but if no TLSA records + are found opportunistic TLS is used. main.cf: indexed = ${default_database_type}:${config_directory}/ @@ -1055,8 +1052,6 @@ default. This is the recommended configuration for early adopters. tls_policy: example.com dane-only - # Postfix >= 2.12, per-destination smtp_tls_fallback_level override - example.org dane fallback=encrypt master.cf: dane unix - - n - - smtp @@ -1637,9 +1632,7 @@ ddaannee obtained for the remote SMTP server, SSLv2 is automatically disabled (see smtp_tls_mandatory_protocols), and the server certificate must match the TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is - available with Postfix 2.11 and later. The optional "fallback" attribute - provides a per-site override of the main.cf smtp_tls_fallback_level - parameter (Postfix >= 2.12). + available with Postfix 2.11 and later. ddaannee--oonnllyy Mandatory DANE TLS. The TLS policy for the destination is obtained via TLSA records in DNSSEC. If no TLSA records are found, or none are usable, no @@ -1647,9 +1640,7 @@ ddaannee--oonnllyy the remote SMTP server, SSLv2 is automatically disabled (see smtp_tls_mandatory_protocols), and the server certificate must match the TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is - available with Postfix 2.11 and later. The optional "fallback" attribute - provides a per-site override of the main.cf smtp_tls_fallback_level - parameter (Postfix >= 2.12). + available with Postfix 2.11 and later. ffiinnggeerrpprriinntt Certificate fingerprint verification. Available with Postfix 2.5 and later. At this security level, there are no trusted certificate authorities. The @@ -1662,8 +1653,7 @@ ffiinnggeerrpprriinntt combined with a "|" delimiter in a single match attribute, or multiple match attributes can be employed. The ":" character is not used as a delimiter as it occurs between each pair of fingerprint (hexadecimal) - digits. The optional "fallback" attribute provides a per-site override of - the main.cf smtp_tls_fallback_level parameter (Postfix >= 2.12). + digits. vveerriiffyy Mandatory server certificate verification. Mail is delivered only if the TLS handshake succeeds, if the remote SMTP server certificate can be @@ -1674,8 +1664,7 @@ vveerriiffyy "tafile" attribute optionally modifies trust chain verification in the same manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may be specified multiple times to load multiple trust-anchor - files. The optional "fallback" attribute provides a per-site override of - the main.cf smtp_tls_fallback_level parameter (Postfix >= 2.12). + files. sseeccuurree Secure certificate verification. Mail is delivered only if the TLS handshake succeeds, if the remote SMTP server certificate can be validated @@ -1685,9 +1674,7 @@ sseeccuurree "match" attribute is specified). With Postfix >= 2.11 the "tafile" attribute optionally modifies trust chain verification in the same manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may - be specified multiple times to load multiple trust-anchor files. The - optional "fallback" attribute provides a per-site override of the main.cf - smtp_tls_fallback_level parameter (Postfix >= 2.12). + be specified multiple times to load multiple trust-anchor files. Notes: * The "match" attribute is especially useful to verify TLS certificates for @@ -1721,7 +1708,6 @@ Example: smtp_tls_policy_maps = hash:/etc/postfix/tls_policy # Postfix 2.5 and later smtp_tls_fingerprint_digest = md5 - /etc/postfix/tls_policy: example.edu none example.mil may @@ -1737,8 +1723,6 @@ Example: # Postfix 2.6 and later example.info may protocols=!SSLv2 ciphers=medium exclude=3DES - # Postfix 2.12 and later override of smtp_tls_fallback_level - fallback.example secure fallback=encrypt NNoottee:: The "hostname" strategy if listed in a non-default setting of smtp_tls_secure_cert_match or in the "match" attribute in the policy table can diff --git a/postfix/html/TLS_README.html b/postfix/html/TLS_README.html index 286bf394c..2548b9f57 100644 --- a/postfix/html/TLS_README.html +++ b/postfix/html/TLS_README.html @@ -1373,12 +1373,8 @@ for early adopters.

  • The "example.com" destination uses DANE, but if TLSA records are not present or are unusable, mail is deferred.

    -
  • The "example.org" destination uses DANE if possible, but -uses opportunistic TLS if no TLSA records are found. The -"fallback" attribute (Postfix ≥ 2.12) overrides the global -main.cf smtp_tls_fallback_level parameter to employ unauthenticated -mandatory encryption if DANE authentication fails, after logging a -warning.

    +
  • The "example.org" destination uses DANE if possible, but if no TLSA +records are found opportunistic TLS is used.

    @@ -1398,16 +1394,26 @@ warning.

    # default_transport = smtp, but some destinations are special: # transport_maps = ${indexed}transport + +
    +
    +
     transport:
         example.com dane
         example.org dane
    +
    +
    +
    +
     tls_policy:
         example.com dane-only
    -    # Postfix ≥ 2.12, per-destination smtp_tls_fallback_level override
    -    example.org dane fallback=encrypt
    +
    +
    +
    +
     master.cf:
         dane       unix  -       -       n       -       -       smtp
           -o smtp_dns_support_level=dnssec
    @@ -2140,10 +2146,7 @@ href="#client_tls_encrypt">encrypt.  When usable TLSA records
     are obtained for the remote SMTP server, SSLv2 is automatically
     disabled (see smtp_tls_mandatory_protocols), and the server certificate
     must match the TLSA records.  RFC 6698 (DANE) TLS authentication
    -and DNSSEC support is available with Postfix 2.11 and later.  
    -The optional "fallback" attribute provides a per-site override of
    -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12).
    -
    +and DNSSEC support is available with Postfix 2.11 and later.  
     
     
    dane-only
    Mandatory DANE TLS. The TLS policy for the destination is obtained via TLSA records in @@ -2152,10 +2155,7 @@ connection is made to the server. When usable TLSA records are obtained for the remote SMTP server, SSLv2 is automatically disabled (see smtp_tls_mandatory_protocols), and the server certificate must match the TLSA records. RFC 6698 (DANE) TLS authentication and -DNSSEC support is available with Postfix 2.11 and later. -The optional "fallback" attribute provides a per-site override of -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12). -
    +DNSSEC support is available with Postfix 2.11 and later.
    fingerprint
    Certificate fingerprint verification. Available with Postfix 2.5 and @@ -2164,15 +2164,13 @@ authorities. The certificate trust chain, expiration date, ... are not checked. Instead, the optional match attribute, or else the main.cf smtp_tls_fingerprint_cert_match parameter, lists the server certificate fingerprints or public key fingerprints -(Postfix 2.9 and later). The digest algorithm used to calculate -fingerprints is selected by the smtp_tls_fingerprint_digest -parameter. Multiple fingerprints can be combined with a "|" delimiter -in a single match attribute, or multiple match attributes can be -employed. The ":" character is not used as a delimiter as it occurs -between each pair of fingerprint (hexadecimal) digits. -The optional "fallback" attribute provides a per-site override of -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12). -
    +(Postfix 2.9 and later). The +digest algorithm used to calculate fingerprints is selected by the +smtp_tls_fingerprint_digest parameter. Multiple fingerprints can +be combined with a "|" delimiter in a single match attribute, or multiple +match attributes can be employed. The ":" character is not used as a +delimiter as it occurs between each pair of fingerprint (hexadecimal) +digits.
    verify
    Mandatory server certificate verification. Mail is delivered only if the @@ -2183,11 +2181,9 @@ the optional "match" attribute (or the main.cf smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may -be specified multiple times to load multiple trust-anchor files. -The optional "fallback" attribute provides a per-site override of -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12). -
    +"smtp_tls_trust_anchor_file" parameter. The "tafile" attribute +may be specified multiple times to load multiple trust-anchor +files.
    secure
    Secure certificate verification. Mail is delivered only if the TLS handshake succeeds, @@ -2199,10 +2195,7 @@ server certificate name matches the optional "match" attribute (or the attribute optionally modifies trust chain verification in the same manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may be specified multiple times to load multiple trust-anchor -files. -The optional "fallback" attribute provides a per-site override of -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12). -
    +files. @@ -2249,7 +2242,6 @@ Example: smtp_tls_policy_maps = hash:/etc/postfix/tls_policy # Postfix 2.5 and later smtp_tls_fingerprint_digest = md5 - /etc/postfix/tls_policy: example.edu none example.mil may @@ -2264,8 +2256,6 @@ Example: match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1 # Postfix 2.6 and later example.info may protocols=!SSLv2 ciphers=medium exclude=3DES - # Postfix 2.12 and later override of smtp_tls_fallback_level - fallback.example secure fallback=encrypt
    diff --git a/postfix/html/lmtp.8.html b/postfix/html/lmtp.8.html index 2299c5cc5..f07bc31f1 100644 --- a/postfix/html/lmtp.8.html +++ b/postfix/html/lmtp.8.html @@ -552,11 +552,6 @@ SMTP(8) SMTP(8) tlsmgr_service_name (tlsmgr) The name of the tlsmgr(8) service entry in master.cf. - Available in Postfix version 2.12 and later: - - smtp_tls_fallback_level (empty) - Optional fallback levels for authenticated TLS levels. - OBSOLETE STARTTLS CONTROLS The following configuration parameters exist for compatibility with Postfix versions before 2.3. Support for these will be removed in a diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index c40fe6f61..e4e47d80d 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -5027,17 +5027,6 @@ configuration parameter. See there for details.

    This feature is available in Postfix 2.3 and later.

    - - -
    lmtp_tls_fallback_level -(default: empty)
    - -

    The LMTP-specific version of the smtp_tls_fallback_level -configuration parameter. See there for details.

    - -

    This feature is available in Postfix 2.12 and later.

    - -
    lmtp_tls_fingerprint_cert_match @@ -11648,61 +11637,6 @@ key exchange with RSA authentication.

    This feature is available in Postfix 2.3 and later.

    - - -
    smtp_tls_fallback_level -(default: empty)
    - -

    Optional fallback levels for authenticated TLS levels. Specify -a white-space or comma-separated list of -policy_level=fallback_level pairs. The policy_level -must require authentication (one of dane, dane-only, fingerprint, -verify, secure). The fallback_level must be "encrypt" or -"may". When an authenticated connection at some desired policy -level cannot be established, delivery will proceed at the correponding -fallback level if possible. A warning will be logged -indicating the fallback reason.

    - -

    The TLS policy table -can be used to specify a destination-specific fallback strategy via the -"fallback" policy attribute. The value of the "fallback" attribute, if -specified, must be "may", "encrypt" or "none". If not "none", this -specifies the fallback level for the destination in question. If the -attribute value is "none", fallback is suppressed for the destination -even if enabled via a global setting of smtp_tls_fallback_level.

    - -

    Example:

    - -
    -
    -/etc/postfix/main.cf:
    -    # When authentication fails, log a warning and deliver anyway
    -    # over an unauthenticated TLS connection.
    -    #
    -    smtp_tls_fallback_level =
    -        dane=encrypt,
    -        dane-only=encrypt,
    -        fingerprint=encrypt,
    -        verify=encrypt,
    -        secure=encrypt
    -    indexed = ${default_database_type}:${config_directory}/
    -    smtp_tls_policy_maps = ${indexed}tls-policy
    -
    -
    - -
    -
    -/etc/postfix/tls-policy:
    -    # No fallback for example.com
    -    example.com secure fallback=none
    -    # For example.net tolerate cleartext fallback
    -    example.net dane fallback=may
    -
    -
    - -

    This feature is available in Postfix 2.12 and later.

    - -
    smtp_tls_fingerprint_cert_match diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html index 2299c5cc5..f07bc31f1 100644 --- a/postfix/html/smtp.8.html +++ b/postfix/html/smtp.8.html @@ -552,11 +552,6 @@ SMTP(8) SMTP(8) tlsmgr_service_name (tlsmgr) The name of the tlsmgr(8) service entry in master.cf. - Available in Postfix version 2.12 and later: - - smtp_tls_fallback_level (empty) - Optional fallback levels for authenticated TLS levels. - OBSOLETE STARTTLS CONTROLS The following configuration parameters exist for compatibility with Postfix versions before 2.3. Support for these will be removed in a diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index c8b16dfe0..daeebcb9c 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -2970,11 +2970,6 @@ The LMTP-specific version of the smtp_tls_exclude_ciphers configuration parameter. See there for details. .PP This feature is available in Postfix 2.3 and later. -.SH lmtp_tls_fallback_level (default: empty) -The LMTP-specific version of the smtp_tls_fallback_level -configuration parameter. See there for details. -.PP -This feature is available in Postfix 2.12 and later. .SH lmtp_tls_fingerprint_cert_match (default: empty) The LMTP-specific version of the smtp_tls_fingerprint_cert_match configuration parameter. See there for details. @@ -7309,63 +7304,6 @@ and "DES-CBC3-MD5". The last setting disables ciphers that use "EDH" key exchange with RSA authentication. .PP This feature is available in Postfix 2.3 and later. -.SH smtp_tls_fallback_level (default: empty) -Optional fallback levels for authenticated TLS levels. Specify -a white-space or comma-separated list of -\fBpolicy_level\fR=\fBfallback_level\fR pairs. The \fBpolicy_level\fR -must require authentication (one of dane, dane-only, fingerprint, -verify, secure). The \fBfallback_level\fR must be "encrypt" or -"may". When an authenticated connection at some desired policy -level cannot be established, delivery will proceed at the correponding -fallback level if possible. A warning will be logged -indicating the fallback reason. -.PP -The TLS policy table -can be used to specify a destination-specific fallback strategy via the -"fallback" policy attribute. The value of the "fallback" attribute, if -specified, must be "may", "encrypt" or "none". If not "none", this -specifies the fallback level for the destination in question. If the -attribute value is "none", fallback is suppressed for the destination -even if enabled via a global setting of smtp_tls_fallback_level. -.PP -Example: -.sp -.in +4 -.nf -.na -.ft C -/etc/postfix/main.cf: - # When authentication fails, log a warning and deliver anyway - # over an unauthenticated TLS connection. - # - smtp_tls_fallback_level = - dane=encrypt, - dane-only=encrypt, - fingerprint=encrypt, - verify=encrypt, - secure=encrypt - indexed = ${default_database_type}:${config_directory}/ - smtp_tls_policy_maps = ${indexed}tls-policy -.fi -.ad -.ft R -.in -4 -.sp -.in +4 -.nf -.na -.ft C -/etc/postfix/tls-policy: - # No fallback for example.com - example.com secure fallback=none - # For example.net tolerate cleartext fallback - example.net dane fallback=may -.fi -.ad -.ft R -.in -4 -.PP -This feature is available in Postfix 2.12 and later. .SH smtp_tls_fingerprint_cert_match (default: empty) List of acceptable remote SMTP server certificate fingerprints for the "fingerprint" TLS security level (\fBsmtp_tls_security_level\fR = diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8 index 05ff23f2b..c0c3ed2bc 100644 --- a/postfix/man/man8/smtp.8 +++ b/postfix/man/man8/smtp.8 @@ -492,10 +492,6 @@ not an alias and its address records lie in an unsigned zone. RFC 6698 trust-anchor digest support in the Postfix TLS library. .IP "\fBtlsmgr_service_name (tlsmgr)\fR" The name of the \fBtlsmgr\fR(8) service entry in master.cf. -.PP -Available in Postfix version 2.12 and later: -.IP "\fBsmtp_tls_fallback_level (empty)\fR" -Optional fallback levels for authenticated TLS levels. .SH "OBSOLETE STARTTLS CONTROLS" .na .nf diff --git a/postfix/proto/TLS_README.html b/postfix/proto/TLS_README.html index c63ab9e5e..bc492ebd5 100644 --- a/postfix/proto/TLS_README.html +++ b/postfix/proto/TLS_README.html @@ -1373,12 +1373,8 @@ for early adopters.

  • The "example.com" destination uses DANE, but if TLSA records are not present or are unusable, mail is deferred.

    -
  • The "example.org" destination uses DANE if possible, but -uses opportunistic TLS if no TLSA records are found. The -"fallback" attribute (Postfix ≥ 2.12) overrides the global -main.cf smtp_tls_fallback_level parameter to employ unauthenticated -mandatory encryption if DANE authentication fails, after logging a -warning.

    +
  • The "example.org" destination uses DANE if possible, but if no TLSA +records are found opportunistic TLS is used.

    @@ -1398,16 +1394,26 @@ main.cf: # default_transport = smtp, but some destinations are special: # transport_maps = ${indexed}transport + +
    +
    +
     transport:
         example.com dane
         example.org dane
    +
    +
    +
    +
     tls_policy:
         example.com dane-only
    -    # Postfix ≥ 2.12, per-destination smtp_tls_fallback_level override
    -    example.org dane fallback=encrypt
    +
    +
    +
    +
     master.cf:
         dane       unix  -       -       n       -       -       smtp
           -o smtp_dns_support_level=dnssec
    @@ -2140,10 +2146,7 @@ href="#client_tls_encrypt">encrypt.  When usable TLSA records
     are obtained for the remote SMTP server, SSLv2 is automatically
     disabled (see smtp_tls_mandatory_protocols), and the server certificate
     must match the TLSA records.  RFC 6698 (DANE) TLS authentication
    -and DNSSEC support is available with Postfix 2.11 and later.  
    -The optional "fallback" attribute provides a per-site override of
    -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12).
    -
    +and DNSSEC support is available with Postfix 2.11 and later.  
     
     
    dane-only
    Mandatory DANE TLS. The TLS policy for the destination is obtained via TLSA records in @@ -2152,10 +2155,7 @@ connection is made to the server. When usable TLSA records are obtained for the remote SMTP server, SSLv2 is automatically disabled (see smtp_tls_mandatory_protocols), and the server certificate must match the TLSA records. RFC 6698 (DANE) TLS authentication and -DNSSEC support is available with Postfix 2.11 and later. -The optional "fallback" attribute provides a per-site override of -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12). -
    +DNSSEC support is available with Postfix 2.11 and later.
    fingerprint
    Certificate fingerprint verification. Available with Postfix 2.5 and @@ -2164,15 +2164,13 @@ authorities. The certificate trust chain, expiration date, ... are not checked. Instead, the optional match attribute, or else the main.cf smtp_tls_fingerprint_cert_match parameter, lists the server certificate fingerprints or public key fingerprints -(Postfix 2.9 and later). The digest algorithm used to calculate -fingerprints is selected by the smtp_tls_fingerprint_digest -parameter. Multiple fingerprints can be combined with a "|" delimiter -in a single match attribute, or multiple match attributes can be -employed. The ":" character is not used as a delimiter as it occurs -between each pair of fingerprint (hexadecimal) digits. -The optional "fallback" attribute provides a per-site override of -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12). -
    +(Postfix 2.9 and later). The +digest algorithm used to calculate fingerprints is selected by the +smtp_tls_fingerprint_digest parameter. Multiple fingerprints can +be combined with a "|" delimiter in a single match attribute, or multiple +match attributes can be employed. The ":" character is not used as a +delimiter as it occurs between each pair of fingerprint (hexadecimal) +digits.
    verify
    Mandatory server certificate verification. Mail is delivered only if the @@ -2183,11 +2181,9 @@ the optional "match" attribute (or the main.cf smtp_tls_verify_cert_match parameter value when no optional "match" attribute is specified). With Postfix ≥ 2.11 the "tafile" attribute optionally modifies trust chain verification in the same manner as the -"smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may -be specified multiple times to load multiple trust-anchor files. -The optional "fallback" attribute provides a per-site override of -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12). -
    +"smtp_tls_trust_anchor_file" parameter. The "tafile" attribute +may be specified multiple times to load multiple trust-anchor +files.
    secure
    Secure certificate verification. Mail is delivered only if the TLS handshake succeeds, @@ -2199,10 +2195,7 @@ main.cf smtp_tls_secure_cert_match parameter value when no optional attribute optionally modifies trust chain verification in the same manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may be specified multiple times to load multiple trust-anchor -files. -The optional "fallback" attribute provides a per-site override of -the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12). -
    +files. @@ -2249,7 +2242,6 @@ Example: smtp_tls_policy_maps = hash:/etc/postfix/tls_policy # Postfix 2.5 and later smtp_tls_fingerprint_digest = md5 - /etc/postfix/tls_policy: example.edu none example.mil may @@ -2264,8 +2256,6 @@ Example: match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1 # Postfix 2.6 and later example.info may protocols=!SSLv2 ciphers=medium exclude=3DES - # Postfix 2.12 and later override of smtp_tls_fallback_level - fallback.example secure fallback=encrypt
    diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 3d016e68b..d48128065 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -16205,64 +16205,6 @@ mail.

    This feature is available in Postfix 2.12 and later.

    -%PARAM smtp_tls_fallback_level - -

    Optional fallback levels for authenticated TLS levels. Specify -a white-space or comma-separated list of -policy_level=fallback_level pairs. The policy_level -must require authentication (one of dane, dane-only, fingerprint, -verify, secure). The fallback_level must be "encrypt" or -"may". When an authenticated connection at some desired policy -level cannot be established, delivery will proceed at the correponding -fallback level if possible. A warning will be logged -indicating the fallback reason.

    - -

    The TLS policy table -can be used to specify a destination-specific fallback strategy via the -"fallback" policy attribute. The value of the "fallback" attribute, if -specified, must be "may", "encrypt" or "none". If not "none", this -specifies the fallback level for the destination in question. If the -attribute value is "none", fallback is suppressed for the destination -even if enabled via a global setting of smtp_tls_fallback_level.

    - -

    Example:

    - -
    -
    -/etc/postfix/main.cf:
    -    # When authentication fails, log a warning and deliver anyway
    -    # over an unauthenticated TLS connection.
    -    #
    -    smtp_tls_fallback_level =
    -	dane=encrypt,
    -	dane-only=encrypt,
    -	fingerprint=encrypt,
    -	verify=encrypt,
    -	secure=encrypt
    -    indexed = ${default_database_type}:${config_directory}/
    -    smtp_tls_policy_maps = ${indexed}tls-policy
    -
    -
    - -
    -
    -/etc/postfix/tls-policy:
    -    # No fallback for example.com
    -    example.com secure fallback=none
    -    # For example.net tolerate cleartext fallback
    -    example.net dane fallback=may
    -
    -
    - -

    This feature is available in Postfix 2.12 and later.

    - -%PARAM lmtp_tls_fallback_level - -

    The LMTP-specific version of the smtp_tls_fallback_level -configuration parameter. See there for details.

    - -

    This feature is available in Postfix 2.12 and later.

    - %PARAM compatibility_level 0

    A safety net that causes Postfix to run with backwards-compatible diff --git a/postfix/src/cleanup/cleanup.h b/postfix/src/cleanup/cleanup.h index 1891c082d..a18c3cdaa 100644 --- a/postfix/src/cleanup/cleanup.h +++ b/postfix/src/cleanup/cleanup.h @@ -61,6 +61,7 @@ typedef struct CLEANUP_STATE { char *orig_rcpt; /* original recipient address */ char *return_receipt; /* return-receipt address */ char *errors_to; /* errors-to address */ + ARGV *auto_hdrs; /* MTA's own header(s) */ int flags; /* processing options, status flags */ int qmgr_opts; /* qmgr processing options */ int errs; /* any badness experienced */ diff --git a/postfix/src/cleanup/cleanup_init.c b/postfix/src/cleanup/cleanup_init.c index 66d33026e..a117500d2 100644 --- a/postfix/src/cleanup/cleanup_init.c +++ b/postfix/src/cleanup/cleanup_init.c @@ -360,7 +360,7 @@ void cleanup_pre_jail(char *unused_name, char **unused_argv) name_mask(VAR_CANON_CLASSES, rcpt_canon_class_table, var_rcpt_canon_classes); if (*var_masq_domains) - cleanup_masq_domains = argv_split(var_masq_domains, " ,\t\r\n"); + cleanup_masq_domains = argv_split(var_masq_domains, CHARS_COMMA_SP); if (*var_header_checks) cleanup_header_checks = maps_create(VAR_HEADER_CHECKS, var_header_checks, DICT_FLAG_LOCK); diff --git a/postfix/src/cleanup/cleanup_masquerade.c b/postfix/src/cleanup/cleanup_masquerade.c index 9bf9761bf..e81bc188c 100644 --- a/postfix/src/cleanup/cleanup_masquerade.c +++ b/postfix/src/cleanup/cleanup_masquerade.c @@ -207,7 +207,7 @@ int main(int argc, char **argv) var_masq_exceptions = argv[1]; cleanup_masq_exceptions = string_list_init(MATCH_FLAG_RETURN, var_masq_exceptions); - masq_domains = argv_split(argv[2], " ,\t\r\n"); + masq_domains = argv_split(argv[2], CHARS_COMMA_SP); addr = vstring_alloc(1); if (strchr(argv[3], '@') == 0) msg_fatal("address must be in user@domain form"); diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index 7860df213..a233b0220 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -479,6 +479,10 @@ static void cleanup_header_callback(void *context, int header_class, if (hdr_opts && (hdr_opts->flags & HDR_OPT_MIME)) header_class = MIME_HDR_MULTIPART; + /* Update the Received: header count before maybe dropping headers below. */ + if (hdr_opts && hdr_opts->type == HDR_RECEIVED) + state->hop_count += 1; + if ((state->flags & CLEANUP_FLAG_FILTER) && (CHECK(MIME_HDR_PRIMARY, cleanup_header_checks, VAR_HEADER_CHECKS) || CHECK(MIME_HDR_MULTIPART, cleanup_mimehdr_checks, VAR_MIMEHDR_CHECKS) @@ -579,12 +583,16 @@ static void cleanup_header_callback(void *context, int header_class, msg_info("%s: message-id=%s", state->queue_id, hdrval); if (hdr_opts->type == HDR_RESENT_MESSAGE_ID) msg_info("%s: resent-message-id=%s", state->queue_id, hdrval); - if (hdr_opts->type == HDR_RECEIVED) - if (++state->hop_count >= var_hopcount_limit) { + if (hdr_opts->type == HDR_RECEIVED) { + if (state->hop_count >= var_hopcount_limit) { msg_warn("%s: message rejected: hopcount exceeded", state->queue_id); state->errs |= CLEANUP_STAT_HOPS; } + /* Save our Received: header after maybe updating headers above. */ + if (state->hop_count == 1) + argv_add(state->auto_hdrs, vstring_str(header_buf), ARGV_END); + } if (CLEANUP_OUT_OK(state)) { if (hdr_opts->flags & HDR_OPT_RR) state->resent = "Resent-"; @@ -622,6 +630,19 @@ static void cleanup_header_done_callback(void *context) if (CLEANUP_OUT_OK(state) == 0) return; + /* + * Future proofing: the Milter client's header suppression algorithm + * assumes that the MTA prepends its own Received: header. This + * assupmtion may be violated after some source-code update. The + * following check ensures consistency, at least for local submission. + */ + if (state->hop_count < 1) { + msg_warn("%s: message rejected: no Received: header", + state->queue_id); + state->errs |= CLEANUP_STAT_BAD; + return; + } + /* * Add a missing (Resent-)Message-Id: header. The message ID gives the * time in GMT units, plus the local queue ID. diff --git a/postfix/src/cleanup/cleanup_milter.c b/postfix/src/cleanup/cleanup_milter.c index db38c911f..2894fa011 100644 --- a/postfix/src/cleanup/cleanup_milter.c +++ b/postfix/src/cleanup/cleanup_milter.c @@ -2020,7 +2020,7 @@ void cleanup_milter_inspect(CLEANUP_STATE *state, MILTERS *milters) * filter library. */ if ((resp = milter_message(milters, state->handle->stream, - state->data_offset)) != 0) + state->data_offset, state->auto_hdrs)) != 0) cleanup_milter_apply(state, "END-OF-MESSAGE", resp); /* diff --git a/postfix/src/cleanup/cleanup_state.c b/postfix/src/cleanup/cleanup_state.c index 340d32d62..e061921ff 100644 --- a/postfix/src/cleanup/cleanup_state.c +++ b/postfix/src/cleanup/cleanup_state.c @@ -78,6 +78,7 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src) state->orig_rcpt = 0; state->return_receipt = 0; state->errors_to = 0; + state->auto_hdrs = argv_alloc(1); state->flags = 0; state->qmgr_opts = 0; state->errs = 0; @@ -152,6 +153,7 @@ void cleanup_state_free(CLEANUP_STATE *state) myfree(state->return_receipt); if (state->errors_to) myfree(state->errors_to); + argv_free(state->auto_hdrs); if (state->queue_name) myfree(state->queue_name); if (state->queue_id) diff --git a/postfix/src/dns/test_dns_lookup.c b/postfix/src/dns/test_dns_lookup.c index 572f4e37a..8da9033ba 100644 --- a/postfix/src/dns/test_dns_lookup.c +++ b/postfix/src/dns/test_dns_lookup.c @@ -109,7 +109,7 @@ int main(int argc, char **argv) msg_vstream_init(argv[0], VSTREAM_ERR); if (argc != 3) msg_fatal("usage: %s types name", argv[0]); - types_argv = argv_split(argv[1], ", \t\r\n"); + types_argv = argv_split(argv[1], CHARS_COMMA_SP); types = (unsigned *) mymalloc(sizeof(*types) * (types_argv->argc + 1)); for (i = 0; i < types_argv->argc; i++) if ((types[i] = dns_type(types_argv->argv[i])) == 0) diff --git a/postfix/src/global/attr_override.c b/postfix/src/global/attr_override.c index b3454335f..c5bd616d8 100644 --- a/postfix/src/global/attr_override.c +++ b/postfix/src/global/attr_override.c @@ -26,7 +26,7 @@ /* Pointer to input string. The input is modified. /* .IP "delimiters, parens" /* See mystrtok(3) for description. Typical values are -/* ", \\t\\r\\n" and "{}", respectively. +/* CHARS_COMMA_SP and CHARS_BRACE, respectively. /* .PP /* The parens argument is followed by a list of (key, value) /* argument pairs. Each key may appear only once. The list diff --git a/postfix/src/global/dict_ldap.c b/postfix/src/global/dict_ldap.c index 0b7bf8027..0c1182d7b 100644 --- a/postfix/src/global/dict_ldap.c +++ b/postfix/src/global/dict_ldap.c @@ -1683,7 +1683,7 @@ DICT *dict_ldap_open(const char *ldapsource, int open_flags, int dict_flags) url_list = vstring_alloc(32); s = server_host; - while ((h = mystrtok(&s, " \t\n\r,")) != NULL) { + while ((h = mystrtok(&s, CHARS_COMMA_SP)) != NULL) { #if defined(LDAP_API_FEATURE_X_OPENLDAP) /* @@ -1815,14 +1815,14 @@ DICT *dict_ldap_open(const char *ldapsource, int open_flags, int dict_flags) /* Order matters, first the terminal attributes: */ attr = cfg_get_str(dict_ldap->parser, "terminal_result_attribute", "", 0, 0); - dict_ldap->result_attributes = argv_split(attr, " ,\t\r\n"); + dict_ldap->result_attributes = argv_split(attr, CHARS_COMMA_SP); dict_ldap->num_terminal = dict_ldap->result_attributes->argc; myfree(attr); /* Order matters, next the leaf-only attributes: */ attr = cfg_get_str(dict_ldap->parser, "leaf_result_attribute", "", 0, 0); if (*attr) - argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n"); + argv_split_append(dict_ldap->result_attributes, attr, CHARS_COMMA_SP); dict_ldap->num_leaf = dict_ldap->result_attributes->argc - dict_ldap->num_terminal; myfree(attr); @@ -1830,14 +1830,14 @@ DICT *dict_ldap_open(const char *ldapsource, int open_flags, int dict_flags) /* Order matters, next the regular attributes: */ attr = cfg_get_str(dict_ldap->parser, "result_attribute", "maildrop", 0, 0); if (*attr) - argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n"); + argv_split_append(dict_ldap->result_attributes, attr, CHARS_COMMA_SP); dict_ldap->num_attributes = dict_ldap->result_attributes->argc; myfree(attr); /* Order matters, finally the special attributes: */ attr = cfg_get_str(dict_ldap->parser, "special_result_attribute", "", 0, 0); if (*attr) - argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n"); + argv_split_append(dict_ldap->result_attributes, attr, CHARS_COMMA_SP); myfree(attr); /* diff --git a/postfix/src/global/dict_mysql.c b/postfix/src/global/dict_mysql.c index 268f51d33..d5a6254c8 100644 --- a/postfix/src/global/dict_mysql.c +++ b/postfix/src/global/dict_mysql.c @@ -683,7 +683,7 @@ static void mysql_parse_config(DICT_MYSQL *dict_mysql, const char *mysqlcf) hosts = cfg_get_str(p, "hosts", "", 0, 0); - dict_mysql->hosts = argv_split(hosts, " ,\t\r\n"); + dict_mysql->hosts = argv_split(hosts, CHARS_COMMA_SP); if (dict_mysql->hosts->argc == 0) { argv_add(dict_mysql->hosts, "localhost", ARGV_END); argv_terminate(dict_mysql->hosts); diff --git a/postfix/src/global/dict_pgsql.c b/postfix/src/global/dict_pgsql.c index b96a81fe3..efe4957e6 100644 --- a/postfix/src/global/dict_pgsql.c +++ b/postfix/src/global/dict_pgsql.c @@ -735,7 +735,7 @@ static void pgsql_parse_config(DICT_PGSQL *dict_pgsql, const char *pgsqlcf) hosts = cfg_get_str(p, "hosts", "", 0, 0); - dict_pgsql->hosts = argv_split(hosts, " ,\t\r\n"); + dict_pgsql->hosts = argv_split(hosts, CHARS_COMMA_SP); if (dict_pgsql->hosts->argc == 0) { argv_add(dict_pgsql->hosts, "localhost", ARGV_END); argv_terminate(dict_pgsql->hosts); diff --git a/postfix/src/global/mail_conf.c b/postfix/src/global/mail_conf.c index 9ad465e2c..40626bbb7 100644 --- a/postfix/src/global/mail_conf.c +++ b/postfix/src/global/mail_conf.c @@ -133,7 +133,7 @@ static void mail_conf_checkdir(const char *config_dir) if (split_nameval(vstring_str(buf), &name, &value) == 0 && (strcmp(name, VAR_CONFIG_DIRS) == 0 || strcmp(name, VAR_MULTI_CONF_DIRS) == 0)) { - while (found == 0 && (cp = mystrtok(&value, ", \t\r\n")) != 0) + while (found == 0 && (cp = mystrtok(&value, CHARS_COMMA_SP)) != 0) if (strcmp(cp, config_dir) == 0) found = 1; } diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index 415387dd9..18e84abd9 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -898,11 +898,11 @@ void mail_params_init() /* * XXX These should be caught by a proper parameter parsing algorithm. */ - if (var_myorigin[strcspn(var_myorigin, ", \t\r\n")]) + if (var_myorigin[strcspn(var_myorigin, CHARS_COMMA_SP)]) msg_fatal("%s parameter setting must not contain multiple values: %s", VAR_MYORIGIN, var_myorigin); - if (var_relayhost[strcspn(var_relayhost, ", \t\r\n")]) + if (var_relayhost[strcspn(var_relayhost, CHARS_COMMA_SP)]) msg_fatal("%s parameter setting must not contain multiple values: %s", VAR_RELAYHOST, var_relayhost); diff --git a/postfix/src/global/mail_queue.c b/postfix/src/global/mail_queue.c index 95f80490b..6cdfa2482 100644 --- a/postfix/src/global/mail_queue.c +++ b/postfix/src/global/mail_queue.c @@ -171,7 +171,7 @@ const char *mail_queue_dir(VSTRING *buf, const char *queue_name, } if (hash_buf == 0) { hash_buf = vstring_alloc(100); - hash_queue_names = argv_split(var_hash_queue_names, " \t\r\n,"); + hash_queue_names = argv_split(var_hash_queue_names, CHARS_COMMA_SP); } /* diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index ed2e3069c..1cf37dafc 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20141015" +#define MAIL_RELEASE_DATE "20141019" #define MAIL_VERSION_NUMBER "2.12" #ifdef SNAPSHOT diff --git a/postfix/src/global/maps.c b/postfix/src/global/maps.c index b0e0b9b5b..2a46f7c90 100644 --- a/postfix/src/global/maps.c +++ b/postfix/src/global/maps.c @@ -114,8 +114,8 @@ MAPS *maps_create(const char *title, const char *map_names, int dict_flags) const char *myname = "maps_create"; char *temp; char *bufp; - static char sep[] = " \t,\r\n"; - static char parens[] = "{}"; + static char sep[] = CHARS_COMMA_SP; + static char parens[] = CHARS_BRACE; MAPS *maps; char *map_type_name; VSTRING *map_type_name_flags; diff --git a/postfix/src/global/match_service.c b/postfix/src/global/match_service.c index ad029892c..856355edd 100644 --- a/postfix/src/global/match_service.c +++ b/postfix/src/global/match_service.c @@ -98,7 +98,7 @@ static void match_service_compat(ARGV *argv) ARGV *match_service_init(const char *patterns) { - const char *delim = " ,\t\r\n"; + const char *delim = CHARS_COMMA_SP; ARGV *list = argv_alloc(1); char *saved_patterns = mystrdup(patterns); char *bp = saved_patterns; diff --git a/postfix/src/global/pipe_command.c b/postfix/src/global/pipe_command.c index aac532c53..32a32b010 100644 --- a/postfix/src/global/pipe_command.c +++ b/postfix/src/global/pipe_command.c @@ -547,7 +547,7 @@ int pipe_command(VSTREAM *src, DSN_BUF *why,...) execvp(args.argv[0], args.argv); msg_fatal("%s: execvp %s: %m", myname, args.argv[0]); } else if (args.shell && *args.shell) { - argv = argv_split(args.shell, " \t\r\n"); + argv = argv_split(args.shell, CHARS_SPACE); argv_add(argv, args.command, (char *) 0); argv_terminate(argv); execvp(argv->argv[0], argv->argv); diff --git a/postfix/src/global/scache.c b/postfix/src/global/scache.c index 2a242ae0e..802f62f1c 100644 --- a/postfix/src/global/scache.c +++ b/postfix/src/global/scache.c @@ -379,7 +379,7 @@ int main(int unused_argc, char **unused_argv) vstream_fileno(VSTREAM_ERR) = 1; while (get_buffer(buf, VSTREAM_IN, interactive) != VSTREAM_EOF) { - argv = argv_split(STR(buf), " \t\r\n"); + argv = argv_split(STR(buf), CHARS_SPACE); if (argv->argc > 0 && argv->argv[0][0] != '#') { msg_verbose = verbose_level; for (ap = actions; ap->command != 0; ap++) { diff --git a/postfix/src/global/server_acl.c b/postfix/src/global/server_acl.c index d05128dd7..7605e5f59 100644 --- a/postfix/src/global/server_acl.c +++ b/postfix/src/global/server_acl.c @@ -87,8 +87,6 @@ /* Application-specific. */ -#define SERVER_ACL_SEPARATORS ", \t\r\n" - static ADDR_MATCH_LIST *server_acl_mynetworks; static ADDR_MATCH_LIST *server_acl_mynetworks_host; @@ -129,7 +127,7 @@ SERVER_ACL *server_acl_parse(const char *extern_acl, const char *origin) * chroot jail, while access lists are evaluated after entering the * chroot jail. */ - while ((acl = mystrtokq(&bp, SERVER_ACL_SEPARATORS, "{}")) != 0) { + while ((acl = mystrtokq(&bp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) { if (strchr(acl, ':') != 0) { if (strchr(origin, ':') != 0) { msg_warn("table %s: lookup result \"%s\" is not allowed" @@ -196,7 +194,7 @@ int server_acl_eval(const char *client_addr, SERVER_ACL * intern_acl, msg_panic("%s: unexpected dictionary: %s", myname, acl); if ((dict_val = dict_get(dict, client_addr)) != 0) { /* Fake up an ARGV to avoid lots of mallocs and frees. */ - if (dict_val[strcspn(dict_val, ":" SERVER_ACL_SEPARATORS)] == 0) { + if (dict_val[strcspn(dict_val, ":" CHARS_COMMA_SP)] == 0) { ARGV_FAKE_BEGIN(fake_argv, dict_val); ret = server_acl_eval(client_addr, &fake_argv, acl); ARGV_FAKE_END; diff --git a/postfix/src/global/verify_clnt.c b/postfix/src/global/verify_clnt.c index 7468c1f0c..e6de59bcc 100644 --- a/postfix/src/global/verify_clnt.c +++ b/postfix/src/global/verify_clnt.c @@ -221,8 +221,8 @@ static void update(char *query) char *status_text; char *cp = query; - if ((addr = mystrtok(&cp, " \t\r\n")) == 0 - || (status_text = mystrtok(&cp, " \t\r\n")) == 0) { + if ((addr = mystrtok(&cp, CHARS_SPACE)) == 0 + || (status_text = mystrtok(&cp, CHARS_SPACE)) == 0) { msg_warn("bad request format"); return; } @@ -276,7 +276,7 @@ int main(int argc, char **argv) while (vstring_fgets_nonl(buffer, VSTREAM_IN)) { cp = STR(buffer); - if ((command = mystrtok(&cp, " \t\r\n")) == 0) + if ((command = mystrtok(&cp, CHARS_SPACE)) == 0) continue; if (strcmp(command, "query") == 0) query(cp, buffer); diff --git a/postfix/src/local/dotforward.c b/postfix/src/local/dotforward.c index 7b7309e40..3ce2cfca9 100644 --- a/postfix/src/local/dotforward.c +++ b/postfix/src/local/dotforward.c @@ -194,7 +194,7 @@ int deliver_dotforward(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) next = saved_forward_path; lookup_status = -1; - while ((lhs = mystrtok(&next, ", \t\r\n")) != 0) { + while ((lhs = mystrtok(&next, CHARS_COMMA_SP)) != 0) { expand_status = local_expand(path, lhs, &state, &usr_attr, var_fwd_exp_filter); if ((expand_status & (MAC_PARSE_ERROR | MAC_PARSE_UNDEF)) == 0) { diff --git a/postfix/src/master/master_ent.c b/postfix/src/master/master_ent.c index 739cd044e..69cff9f51 100644 --- a/postfix/src/master/master_ent.c +++ b/postfix/src/master/master_ent.c @@ -109,7 +109,7 @@ static int master_line_last; /* config file line number */ static int master_line; /* config file line number */ static ARGV *master_disable; /* disabled service patterns */ -static char master_blanks[] = " \t\r\n";/* field delimiters */ +static char master_blanks[] = CHARS_SPACE;/* field delimiters */ /* fset_master_ent - specify configuration file pathname */ @@ -561,8 +561,9 @@ MASTER_SERV *get_master_ent() argv_add(serv->args, "-s", vstring_str(vstring_sprintf(junk, "%d", serv->listen_fd_count)), (char *) 0); - while ((cp = mystrtokq(&bufp, master_blanks, "{}")) != 0) { - if (*cp == '{' && (err = extpar(&cp, "{}", EXTPAR_FLAG_STRIP)) != 0) + while ((cp = mystrtokq(&bufp, master_blanks, CHARS_BRACE)) != 0) { + if (*cp == CHARS_BRACE[0] + && (err = extpar(&cp, CHARS_BRACE, EXTPAR_FLAG_STRIP)) != 0) fatal_with_context("%s", err); argv_add(serv->args, cp, (char *) 0); } diff --git a/postfix/src/milter/milter.c b/postfix/src/milter/milter.c index 87dad812a..ab63c68fc 100644 --- a/postfix/src/milter/milter.c +++ b/postfix/src/milter/milter.c @@ -85,10 +85,11 @@ /* const char *milter_other_event(milters) /* MILTERS *milters; /* -/* const char *milter_message(milters, qfile, data_offset) +/* const char *milter_message(milters, qfile, data_offset, auto_hdrs) /* MILTERS *milters; /* VSTREAM *qfile; /* off_t data_offset; +/* ARGV *auto_hdrs; /* /* const char *milter_abort(milters) /* MILTERS *milters; @@ -269,7 +270,7 @@ static ARGV *milter_macro_lookup(MILTERS *milters, const char *macro_names) const char *value; const char *name; - while ((name = mystrtok(&cp, ", \t\r\n")) != 0) { + while ((name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) { if (msg_verbose) msg_info("%s: \"%s\"", myname, name); if ((value = milters->mac_lookup(name, milters->mac_context)) != 0) { @@ -483,7 +484,8 @@ const char *milter_other_event(MILTERS *milters) /* milter_message - inspect message content */ -const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset) +const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset, + ARGV *auto_hdrs) { const char *resp; MILTER *m; @@ -497,7 +499,8 @@ const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset) for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) { any_eoh_macros = MILTER_MACRO_EVAL(global_eoh_macros, m, milters, eoh_macros); any_eod_macros = MILTER_MACRO_EVAL(global_eod_macros, m, milters, eod_macros); - resp = m->message(m, fp, data_offset, any_eoh_macros, any_eod_macros); + resp = m->message(m, fp, data_offset, any_eoh_macros, any_eod_macros, + auto_hdrs); if (any_eoh_macros != global_eoh_macros) argv_free(any_eoh_macros); if (any_eod_macros != global_eod_macros) @@ -576,8 +579,8 @@ MILTERS *milter_new(const char *names, MILTER *tail = 0; char *name; MILTER *milter; - const char *sep = ", \t\r\n"; - const char *parens = "{}"; + const char *sep = CHARS_COMMA_SP; + const char *parens = CHARS_BRACE; int my_conn_timeout; int my_cmd_timeout; int my_msg_timeout; @@ -612,7 +615,7 @@ MILTERS *milter_new(const char *names, my_msg_timeout = msg_timeout; my_protocol = protocol; my_def_action = def_action; - if (name[0] == '{') { /* } */ + if (name[0] == parens[0]) { op = name; if ((err = extpar(&op, parens, EXTPAR_FLAG_NONE)) != 0) msg_fatal("milter service syntax error: %s", err); diff --git a/postfix/src/milter/milter.h b/postfix/src/milter/milter.h index 17d163dc4..bf25fccc0 100644 --- a/postfix/src/milter/milter.h +++ b/postfix/src/milter/milter.h @@ -40,7 +40,7 @@ typedef struct MILTER { const char *(*mail_event) (struct MILTER *, const char **, ARGV *); const char *(*rcpt_event) (struct MILTER *, const char **, ARGV *); const char *(*data_event) (struct MILTER *, ARGV *); - const char *(*message) (struct MILTER *, VSTREAM *, off_t, ARGV *, ARGV *); + const char *(*message) (struct MILTER *, VSTREAM *, off_t, ARGV *, ARGV *, ARGV *); const char *(*unknown_event) (struct MILTER *, const char *, ARGV *); const char *(*other_event) (struct MILTER *); void (*abort) (struct MILTER *); @@ -136,7 +136,7 @@ extern const char *milter_helo_event(MILTERS *, const char *, int); extern const char *milter_mail_event(MILTERS *, const char **); extern const char *milter_rcpt_event(MILTERS *, int, const char **); extern const char *milter_data_event(MILTERS *); -extern const char *milter_message(MILTERS *, VSTREAM *, off_t); +extern const char *milter_message(MILTERS *, VSTREAM *, off_t, ARGV *); extern const char *milter_unknown_event(MILTERS *, const char *); extern const char *milter_other_event(MILTERS *); extern void milter_abort(MILTERS *); diff --git a/postfix/src/milter/milter8.c b/postfix/src/milter/milter8.c index 74a50e873..b065f235f 100644 --- a/postfix/src/milter/milter8.c +++ b/postfix/src/milter/milter8.c @@ -1648,7 +1648,7 @@ static void milter8_connect(MILTER8 *milter) * don't want to take the risk that a future version will be more picky. */ cp = saved_version = mystrdup(milter->protocol); - while ((name = mystrtok(&cp, " ,\t\r\n")) != 0) { + while ((name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) { int mask; int vers; @@ -2285,6 +2285,8 @@ typedef struct { MILTER8 *milter; /* milter client */ ARGV *eoh_macros; /* end-of-header macros */ ARGV *eod_macros; /* end-of-body macros */ + ARGV *auto_hdrs; /* auto-generated headers */ + int auto_done; /* good enough for now */ int first_header; /* first header */ int first_body; /* first body line */ const char *resp; /* milter application response */ @@ -2301,6 +2303,8 @@ static void milter8_header(void *ptr, int unused_header_class, MILTER8 *milter = msg_ctx->milter; char *cp; int skip_reply; + char **cpp; + unsigned done; /* * XXX Workaround: mime_state_update() may invoke multiple call-backs @@ -2329,10 +2333,11 @@ static void milter8_header(void *ptr, int unused_header_class, * XXX Sendmail compatibility. It eats the first space (not tab) after the * header label and ":". */ - if (msg_ctx->first_header) { - msg_ctx->first_header = 0; - return; - } + for (cpp = msg_ctx->auto_hdrs->argv, done = 1; *cpp; cpp++, done <<= 1) + if ((msg_ctx->auto_done & done) == 0 && strcmp(*cpp, STR(buf)) == 0) { + msg_ctx->auto_done |= done; + return; + } /* * Sendmail 8 sends multi-line headers as text separated by newline. @@ -2507,7 +2512,8 @@ static void milter8_eob(void *ptr) static const char *milter8_message(MILTER *m, VSTREAM *qfile, off_t data_offset, ARGV *eoh_macros, - ARGV *eod_macros) + ARGV *eod_macros, + ARGV *auto_hdrs) { const char *myname = "milter8_message"; MILTER8 *milter = (MILTER8 *) m; @@ -2541,6 +2547,8 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile, msg_ctx.milter = milter; msg_ctx.eoh_macros = eoh_macros; msg_ctx.eod_macros = eod_macros; + msg_ctx.auto_hdrs = auto_hdrs; + msg_ctx.auto_done = 0; msg_ctx.first_header = 1; msg_ctx.first_body = 1; msg_ctx.resp = 0; diff --git a/postfix/src/oqmgr/qmgr_message.c b/postfix/src/oqmgr/qmgr_message.c index 33cfad725..6112e0585 100644 --- a/postfix/src/oqmgr/qmgr_message.c +++ b/postfix/src/oqmgr/qmgr_message.c @@ -1101,7 +1101,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) */ if (*var_defer_xports && (message->qflags & QMGR_FLUSH_DFXP) == 0) { if (defer_xport_argv == 0) - defer_xport_argv = argv_split(var_defer_xports, " \t\r\n,"); + defer_xport_argv = argv_split(var_defer_xports, CHARS_COMMA_SP); for (cpp = defer_xport_argv->argv; *cpp; cpp++) if (strcmp(*cpp, STR(reply.transport)) == 0) break; diff --git a/postfix/src/postconf/postconf_dbms.c b/postfix/src/postconf/postconf_dbms.c index 97405194e..2d1ab5c76 100644 --- a/postfix/src/postconf/postconf_dbms.c +++ b/postfix/src/postconf/postconf_dbms.c @@ -162,7 +162,7 @@ static void pcf_register_dbms_helper(char *str_value, * Naive parsing. We don't really know if this substring specifies a * database or some other text. */ - while ((db_type = mystrtokq(&str_value, " ,\t\r\n", "{}")) != 0) { + while ((db_type = mystrtokq(&str_value, CHARS_COMMA_SP, CHARS_BRACE)) != 0) { /* * Skip over "proxy:" maptypes, to emulate the proxymap(8) server's @@ -180,8 +180,8 @@ static void pcf_register_dbms_helper(char *str_value, * local or global namespace. */ if (prefix != 0 && *prefix != '/' && *prefix != '.') { - if (*prefix == '{') { /* } */ - if ((err = extpar(&prefix, "{}", EXTPAR_FLAG_NONE)) != 0) { + if (*prefix == CHARS_BRACE[0]) { + if ((err = extpar(&prefix, CHARS_BRACE, EXTPAR_FLAG_NONE)) != 0) { /* XXX Encapsulate this in pcf_warn() function. */ if (local_scope) msg_warn("%s:%s: %s", diff --git a/postfix/src/postconf/postconf_edit.c b/postfix/src/postconf/postconf_edit.c index 4781c46f4..7a9208733 100644 --- a/postfix/src/postconf/postconf_edit.c +++ b/postfix/src/postconf/postconf_edit.c @@ -234,7 +234,7 @@ void pcf_edit_main(int mode, int argc, char **argv) } /* Copy or replace start of logical line. */ else { - vstring_strncpy(key, cp, strcspn(cp, " \t\r\n=")); + vstring_strncpy(key, cp, strcspn(cp, CHARS_SPACE "=")); cvalue = (struct cvalue *) htable_find(table, STR(key)); if ((interesting = !!cvalue) != 0) { if (cvalue->found++ == 1) diff --git a/postfix/src/postconf/postconf_master.c b/postfix/src/postconf/postconf_master.c index a745df20c..7f9a5c1b5 100644 --- a/postfix/src/postconf/postconf_master.c +++ b/postfix/src/postconf/postconf_master.c @@ -261,16 +261,16 @@ static void pcf_normalize_daemon_args(ARGV *argv) argv_insert_one(argv, field + 1, arg + 2); arg[2] = 0; /* XXX argv_replace_one() */ field += 1; - extract_field = (argv->argv[field][0] == '{'); + extract_field = (argv->argv[field][0] == CHARS_BRACE[0]); } else if (argv->argv[field + 1] != 0) { /* Already in "-o" "name=value" form. */ field += 1; - extract_field = (argv->argv[field][0] == '{'); + extract_field = (argv->argv[field][0] == CHARS_BRACE[0]); } else extract_field = 0; /* Extract text inside {}, optionally convert to name=value. */ if (extract_field) { - pcf_extract_field(argv, field, "{}"); + pcf_extract_field(argv, field, CHARS_BRACE); if (argv->argv[field - 1][1] == 'o') pcf_normalize_nameval(argv, field); } @@ -278,8 +278,8 @@ static void pcf_normalize_daemon_args(ARGV *argv) /* Normalize non-option arguments. */ for ( /* void */ ; argv->argv[field] != 0; field++) /* Extract text inside {}. */ - if (argv->argv[field][0] == '{') /* } */ - pcf_extract_field(argv, field, "{}"); + if (argv->argv[field][0] == CHARS_BRACE[0]) + pcf_extract_field(argv, field, CHARS_BRACE); } /* pcf_fix_fatal - fix multiline text before release */ @@ -370,7 +370,7 @@ const char *pcf_parse_master_entry(PCF_MASTER_ENT *masterp, const char *buf) * * XXX Do per-field sanity checks. */ - argv = argv_splitq(buf, PCF_MASTER_BLANKS, "{}"); + argv = argv_splitq(buf, PCF_MASTER_BLANKS, CHARS_BRACE); if (argv->argc < PCF_MASTER_MIN_FIELDS) { argv_free(argv); /* Coverity 201311 */ return ("bad field count"); @@ -829,7 +829,7 @@ void pcf_edit_master_field(PCF_MASTER_ENT *masterp, int field, */ if (field == PCF_MASTER_FLD_CMD) { argv_truncate(masterp->argv, PCF_MASTER_FLD_CMD); - argv_splitq_append(masterp->argv, new_value, PCF_MASTER_BLANKS, "{}"); + argv_splitq_append(masterp->argv, new_value, PCF_MASTER_BLANKS, CHARS_BRACE); pcf_normalize_daemon_args(masterp->argv); } diff --git a/postfix/src/postconf/postconf_user.c b/postfix/src/postconf/postconf_user.c index 639f2efd3..a55074fc0 100644 --- a/postfix/src/postconf/postconf_user.c +++ b/postfix/src/postconf/postconf_user.c @@ -237,7 +237,7 @@ static void pcf_scan_user_parameter_namespace(const char *dict_name, */ if ((class_list = pcf_lookup_eval(dict_name, VAR_REST_CLASSES)) != 0) { cp = saved_class_list = mystrdup(class_list); - while ((param_name = mystrtok(&cp, ", \t\r\n")) != 0) { + while ((param_name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) { if (local_scope == 0 && htable_locate(pcf_rest_class_table, param_name) == 0) htable_enter(pcf_rest_class_table, param_name, ""); diff --git a/postfix/src/postfix/postfix.c b/postfix/src/postfix/postfix.c index 6f676d5aa..2d8a1abe1 100644 --- a/postfix/src/postfix/postfix.c +++ b/postfix/src/postfix/postfix.c @@ -559,7 +559,7 @@ int main(int argc, char **argv) * Run the management script. */ if (force_single_instance - || argv_split(var_multi_conf_dirs, "\t\r\n, ")->argc == 0) { + || argv_split(var_multi_conf_dirs, CHARS_COMMA_SP)->argc == 0) { script = concatenate(var_daemon_dir, "/postfix-script", (char *) 0); if (optind < 1) msg_panic("bad optind value"); @@ -575,7 +575,7 @@ int main(int argc, char **argv) if (*var_multi_wrapper == 0) msg_fatal("multi-instance support is requested, but %s is empty", VAR_MULTI_WRAPPER); - my_argv = argv_split(var_multi_wrapper, " \t\r\n"); + my_argv = argv_split(var_multi_wrapper, CHARS_SPACE); do { argv_add(my_argv, argv[optind], (char *) 0); } while (argv[optind++] != 0); diff --git a/postfix/src/postmap/postmap.c b/postfix/src/postmap/postmap.c index 85301cc7f..adcae3207 100644 --- a/postfix/src/postmap/postmap.c +++ b/postfix/src/postmap/postmap.c @@ -406,7 +406,7 @@ static void postmap(char *map_type, char *path_name, int postmap_flags, * trailing whitespace from key and value. */ key = STR(line_buffer); - value = key + strcspn(key, " \t\r\n"); + value = key + strcspn(key, CHARS_SPACE); if (*value) *value++ = 0; while (ISSPACE(*value)) diff --git a/postfix/src/postmulti/postmulti.c b/postfix/src/postmulti/postmulti.c index 3c24d33c0..6c80314c9 100644 --- a/postfix/src/postmulti/postmulti.c +++ b/postfix/src/postmulti/postmulti.c @@ -863,7 +863,7 @@ static void load_all_instances(void) * only comma characters. Count the actual number of elements, before we * decide that the list is empty. */ - secondary_names = argv_split(var_multi_conf_dirs, "\t\n\r, "); + secondary_names = argv_split(var_multi_conf_dirs, CHARS_COMMA_SP); /* * First, the primary instance. This is synthesized out of thin air. @@ -1469,7 +1469,7 @@ static int word_in_list(char *cmdlist, const char *cmd) char *elem; cp = saved = mystrdup(cmdlist); - while ((elem = mystrtok(&cp, "\t\n\r, ")) != 0 && strcmp(elem, cmd) != 0) + while ((elem = mystrtok(&cp, CHARS_COMMA_SP)) != 0 && strcmp(elem, cmd) != 0) /* void */ ; myfree(saved); return (elem != 0); diff --git a/postfix/src/postscreen/postscreen_dnsbl.c b/postfix/src/postscreen/postscreen_dnsbl.c index 9d379e740..3e3b9eb09 100644 --- a/postfix/src/postscreen/postscreen_dnsbl.c +++ b/postfix/src/postscreen/postscreen_dnsbl.c @@ -531,7 +531,7 @@ int psc_dnsbl_request(const char *client_addr, void psc_dnsbl_init(void) { const char *myname = "psc_dnsbl_init"; - ARGV *dnsbl_site = argv_split(var_psc_dnsbl_sites, ", \t\r\n"); + ARGV *dnsbl_site = argv_split(var_psc_dnsbl_sites, CHARS_COMMA_SP); char **cpp; /* diff --git a/postfix/src/postsuper/postsuper.c b/postfix/src/postsuper/postsuper.c index 9dabb5dc4..0e821367d 100644 --- a/postfix/src/postsuper/postsuper.c +++ b/postfix/src/postsuper/postsuper.c @@ -726,7 +726,7 @@ static int fix_queue_id(const char *actual_path, const char *actual_queue, static void super(const char **queues, int action) { - ARGV *hash_queue_names = argv_split(var_hash_queue_names, " \t\r\n,"); + ARGV *hash_queue_names = argv_split(var_hash_queue_names, CHARS_COMMA_SP); VSTRING *actual_path = vstring_alloc(10); VSTRING *wanted_path = vstring_alloc(10); struct stat st; diff --git a/postfix/src/proxymap/proxymap.c b/postfix/src/proxymap/proxymap.c index ec745e094..6f792481d 100644 --- a/postfix/src/proxymap/proxymap.c +++ b/postfix/src/proxymap/proxymap.c @@ -650,8 +650,8 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags) static void post_jail_init(char *service_name, char **unused_argv) { - const char *sep = ", \t\r\n"; - const char *parens = "{}"; + const char *sep = CHARS_COMMA_SP; + const char *parens = CHARS_BRACE; char *saved_filter; char *bp; char *type_name; diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index f2c69a699..54af411df 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -1160,7 +1160,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) */ if (*var_defer_xports && (message->qflags & QMGR_FLUSH_DFXP) == 0) { if (defer_xport_argv == 0) - defer_xport_argv = argv_split(var_defer_xports, " \t\r\n,"); + defer_xport_argv = argv_split(var_defer_xports, CHARS_COMMA_SP); for (cpp = defer_xport_argv->argv; *cpp; cpp++) if (strcmp(*cpp, STR(reply.transport)) == 0) break; diff --git a/postfix/src/sendmail/sendmail.c b/postfix/src/sendmail/sendmail.c index d68a294d1..b510513de 100644 --- a/postfix/src/sendmail/sendmail.c +++ b/postfix/src/sendmail/sendmail.c @@ -1395,7 +1395,7 @@ int main(int argc, char **argv) argv_add(ext_argv, "postalias", (char *) 0); for (n = 0; n < msg_verbose; n++) argv_add(ext_argv, "-v", (char *) 0); - argv_split_append(ext_argv, var_alias_db_map, ", \t\r\n"); + argv_split_append(ext_argv, var_alias_db_map, CHARS_COMMA_SP); argv_terminate(ext_argv); mail_run_replace(var_command_dir, ext_argv->argv); /* NOTREACHED */ diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c index 1d4a6bbf4..8522205c7 100644 --- a/postfix/src/smtp/smtp_connect.c +++ b/postfix/src/smtp/smtp_connect.c @@ -781,7 +781,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop, non_fallback_sites = sites->argc; /* When we are lmtp(8) var_fallback_relay is null */ if (smtp_mode) - argv_split_append(sites, var_fallback_relay, ", \t\r\n"); + argv_split_append(sites, var_fallback_relay, CHARS_COMMA_SP); /* * Don't give up after a hard host lookup error until we have tried the diff --git a/postfix/src/smtp/smtp_sasl_auth_cache.c b/postfix/src/smtp/smtp_sasl_auth_cache.c index 520f8b6e5..29ad938cb 100644 --- a/postfix/src/smtp/smtp_sasl_auth_cache.c +++ b/postfix/src/smtp/smtp_sasl_auth_cache.c @@ -114,7 +114,7 @@ SMTP_SASL_AUTH_CACHE *smtp_sasl_auth_cache_init(const char *map, int ttl) /* * Sanity checks. */ -#define HAS_MULTIPLE_VALUES(s) ((s)[strcspn((s), ", \t\r\n")] != 0) +#define HAS_MULTIPLE_VALUES(s) ((s)[strcspn((s), CHARS_COMMA_SP)] != 0) if (*map == 0) msg_panic("%s: empty SASL authentication cache name", myname); diff --git a/postfix/src/smtp/smtp_tls_policy.c b/postfix/src/smtp/smtp_tls_policy.c index f58113e57..6ae7ade9e 100644 --- a/postfix/src/smtp/smtp_tls_policy.c +++ b/postfix/src/smtp/smtp_tls_policy.c @@ -242,7 +242,7 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level, } saved_policy = policy = mystrdup(lookup); - if ((tok = mystrtok(&policy, "\t\n\r ,")) == 0) { + if ((tok = mystrtok(&policy, CHARS_COMMA_SP)) == 0) { msg_warn("%s: invalid empty policy", WHERE); INVALID_RETURN(tls->why, site_level); } @@ -257,7 +257,7 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level, * Warn about ignored attributes when TLS is disabled. */ if (*site_level < TLS_LEV_MAY) { - while ((tok = mystrtok(&policy, "\t\n\r ,")) != 0) + while ((tok = mystrtok(&policy, CHARS_COMMA_SP)) != 0) msg_warn("%s: ignoring attribute \"%s\" with TLS disabled", WHERE, tok); FREE_RETURN; @@ -267,7 +267,7 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level, * Errors in attributes may have security consequences, don't ignore * errors that can degrade security. */ - while ((tok = mystrtok(&policy, "\t\n\r ,")) != 0) { + while ((tok = mystrtok(&policy, CHARS_COMMA_SP)) != 0) { if ((err = split_nameval(tok, &name, &val)) != 0) { msg_warn("%s: malformed attribute/value pair \"%s\": %s", WHERE, tok, err); @@ -397,7 +397,7 @@ static int load_tas(TLS_DANE *dane, const char *files) char *file; do { - if ((file = mystrtok(&buf, "\t\n\r ,")) != 0) + if ((file = mystrtok(&buf, CHARS_COMMA_SP)) != 0) ret = tls_dane_load_trustfile(dane, file); } while (file && ret); @@ -565,7 +565,7 @@ static void *policy_create(const char *unused_key, void *context) tls->dane = tls_dane_alloc(); if (!TLS_DANE_HASEE(tls->dane)) { tls_dane_add_ee_digests(tls->dane, var_smtp_tls_fpt_dgst, - var_smtp_tls_fpt_cmatch, "\t\n\r, "); + var_smtp_tls_fpt_cmatch, CHARS_COMMA_SP); if (!TLS_DANE_HASEE(tls->dane)) { msg_warn("nexthop domain %s: configured at fingerprint " "security level, but with no fingerprints to match.", @@ -581,7 +581,7 @@ static void *policy_create(const char *unused_key, void *context) tls->matchargv = argv_split(tls->level == TLS_LEV_VERIFY ? var_smtp_tls_vfy_cmatch : var_smtp_tls_sec_cmatch, - "\t\n\r, :"); + CHARS_COMMA_SP ":"); if (*var_smtp_tls_tafile) { if (tls->dane == 0) tls->dane = tls_dane_alloc(); diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 6932d4997..b2ce8da14 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -3114,6 +3114,13 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) rec_fputs(state->cleanup, REC_TYPE_MESG, ""); } + /* + * PREPEND message headers above our own Received: header. + */ + if (state->prepend) + for (cpp = state->prepend->argv; *cpp; cpp++) + out_fprintf(out_stream, REC_TYPE_NORM, "%s", *cpp); + /* * Suppress our own Received: header in the unlikely case that we are an * intermediate proxy. @@ -3204,17 +3211,6 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) #endif } - /* - * PREPEND message headers below our own Received: header. According - * https://www.milter.org/developers/api/smfi_insheader, Milters see only - * headers that have been sent by the SMTP client and those header - * modifications by earlier filters. Based on this we allow Milters to - * see headers added by access map or by policy service. - */ - if (state->prepend) - for (cpp = state->prepend->argv; *cpp; cpp++) - out_fprintf(out_stream, REC_TYPE_NORM, "%s", *cpp); - smtpd_chat_reply(state, "354 End data with ."); state->where = SMTPD_AFTER_DATA; diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index 41db10327..cfe6d014b 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -252,8 +252,6 @@ #include "smtpd_resolve.h" #include "smtpd_expand.h" -#define RESTRICTION_SEPARATORS ", \t\r\n" - /* * Eject seat in case of parsing problems. */ @@ -510,8 +508,8 @@ static void policy_client_register(const char *name) char *saved_name = 0; const char *policy_name = 0; char *cp; - const char *sep = ", \t\r\n"; - const char *parens = "{}"; + const char *sep = CHARS_COMMA_SP; + const char *parens = CHARS_BRACE; char *err; if (policy_clnt_table == 0) @@ -538,7 +536,7 @@ static void policy_client_register(const char *name) link_override_table_to_variable(int_table, smtpd_policy_try_limit); link_override_table_to_variable(str_table, smtpd_policy_def_action); - if (*name == '{') { /* } */ + if (*name == parens[0]) { cp = saved_name = mystrdup(name); if ((err = extpar(&cp, parens, EXTPAR_FLAG_NONE)) != 0) msg_fatal("policy service syntax error: %s", cp); @@ -601,7 +599,7 @@ static ARGV *smtpd_check_parse(int flags, const char *checks) #define SMTPD_CHECK_PARSE_MAPS (1<<1) #define SMTPD_CHECK_PARSE_ALL (~0) - while ((name = mystrtokq(&bp, RESTRICTION_SEPARATORS, "{}")) != 0) { + while ((name = mystrtokq(&bp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) { argv_add(argv, name, (char *) 0); if ((flags & SMTPD_CHECK_PARSE_POLICY) && last && strcasecmp(last, CHECK_POLICY_SERVICE) == 0) @@ -807,7 +805,7 @@ void smtpd_check_init(void) smtpd_rest_classes = htable_create(1); if (*var_rest_classes) { cp = saved_classes = mystrdup(var_rest_classes); - while ((name = mystrtok(&cp, RESTRICTION_SEPARATORS)) != 0) { + while ((name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) { if ((value = mail_conf_lookup_eval(name)) == 0 || *value == 0) msg_fatal("restriction class `%s' needs a definition", name); /* XXX This store operation should not be case-sensitive. */ @@ -2590,7 +2588,7 @@ static int check_table_result(SMTPD_STATE *state, const char *table, */ #define ADDROF(x) ((char *) &(x)) - restrictions = argv_splitq(value, RESTRICTION_SEPARATORS, "{}"); + restrictions = argv_splitq(value, CHARS_COMMA_SP, CHARS_BRACE); memcpy(ADDROF(savebuf), ADDROF(smtpd_check_buf), sizeof(savebuf)); status = setjmp(smtpd_check_buf); if (status != 0) { @@ -3699,7 +3697,7 @@ static int reject_maps_rbl(SMTPD_STATE *state) "use \"%s domain-name\" instead", REJECT_MAPS_RBL, var_mail_name, REJECT_RBL_CLIENT); } - while ((rbl_domain = mystrtok(&bp, RESTRICTION_SEPARATORS)) != 0) { + while ((rbl_domain = mystrtok(&bp, CHARS_COMMA_SP)) != 0) { result = reject_rbl_addr(state, rbl_domain, state->addr, SMTPD_NAME_CLIENT); if (result != SMTPD_CHECK_DUNNO) @@ -3740,7 +3738,7 @@ static int reject_auth_sender_login_mismatch(SMTPD_STATE *state, const char *sen if ((owners = check_mail_addr_find(state, sender, smtpd_sender_login_maps, STR(reply->recipient), (char **) 0)) != 0) { cp = saved_owners = mystrdup(owners); - while ((name = mystrtok(&cp, RESTRICTION_SEPARATORS)) != 0) { + while ((name = mystrtok(&cp, CHARS_COMMA_SP)) != 0) { if (strcasecmp(state->sasl_username, name) == 0) { found = 1; break; @@ -5653,7 +5651,7 @@ static void rest_class(char *class) if (smtpd_rest_classes == 0) smtpd_rest_classes = htable_create(1); - if ((name = mystrtok(&cp, RESTRICTION_SEPARATORS)) == 0) + if ((name = mystrtok(&cp, CHARS_COMMA_SP)) == 0) msg_panic("rest_class: null class name"); if ((entry = htable_locate(smtpd_rest_classes, name)) != 0) argv_free((ARGV *) entry->value); @@ -5843,7 +5841,7 @@ int main(int argc, char **argv) vstream_printf("exit %d\n", system(bp + 1)); continue; } - args = argv_split(bp, " \t\r\n"); + args = argv_split(bp, CHARS_SPACE); /* * Recognize the command. diff --git a/postfix/src/smtpstone/smtp-sink.c b/postfix/src/smtpstone/smtp-sink.c index 120cef10a..68dd84039 100644 --- a/postfix/src/smtpstone/smtp-sink.c +++ b/postfix/src/smtpstone/smtp-sink.c @@ -1005,7 +1005,7 @@ static void set_cmds_flags(const char *cmds, int flags) char *cmd; saved_cmds = cp = mystrdup(cmds); - while ((cmd = mystrtok(&cp, " \t\r\n,")) != 0) + while ((cmd = mystrtok(&cp, CHARS_COMMA_SP)) != 0) set_cmd_flags(cmd, flags); myfree(saved_cmds); } diff --git a/postfix/src/tls/tls_dane.c b/postfix/src/tls/tls_dane.c index 9013bc50f..6195e04bd 100644 --- a/postfix/src/tls/tls_dane.c +++ b/postfix/src/tls/tls_dane.c @@ -473,7 +473,7 @@ static void dane_init(void) VAR_TLS_DANE_AGILITY, var_tls_dane_agility); } else if (add_digest(fullmtype, 0)) { save = cp = mystrdup(var_tls_dane_digests); - while ((tok = mystrtok(&cp, "\t\n\r ,")) != 0) { + while ((tok = mystrtok(&cp, CHARS_COMMA_SP)) != 0) { if ((d = add_digest(tok, ++digest_pref)) == 0) { signalg = 0; signmd = 0; diff --git a/postfix/src/tls/tls_mgr.c b/postfix/src/tls/tls_mgr.c index 702aeee7c..1ac9b50b9 100644 --- a/postfix/src/tls/tls_mgr.c +++ b/postfix/src/tls/tls_mgr.c @@ -411,7 +411,7 @@ int main(int unused_ac, char **av) msg_fatal("chdir %s: %m", var_queue_dir); while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) { - argv = argv_split(STR(inbuf), " \t\r\n"); + argv = argv_split(STR(inbuf), CHARS_SPACE); if (argv->argc == 0) { argv_free(argv); continue; diff --git a/postfix/src/tls/tls_misc.c b/postfix/src/tls/tls_misc.c index 1791dce22..b6d5f4fdd 100644 --- a/postfix/src/tls/tls_misc.c +++ b/postfix/src/tls/tls_misc.c @@ -580,7 +580,7 @@ int tls_protocol_mask(const char *plist) } while (0) save = cp = mystrdup(plist); - while ((tok = mystrtok(&cp, "\t\n\r ,:")) != 0) { + while ((tok = mystrtok(&cp, CHARS_COMMA_SP ":")) != 0) { if (*tok == '!') exclude |= code = name_code(protocol_table, NAME_CODE_FLAG_NONE, ++tok); @@ -718,7 +718,7 @@ const char *tls_set_ciphers(TLS_APPL_STATE *app_ctx, const char *context, /* * Apply locally-specified exclusions. */ -#define CIPHER_SEP "\t\n\r ,:" +#define CIPHER_SEP CHARS_COMMA_SP ":" if (exclusions != 0) { cp = save = mystrdup(exclusions); while ((tok = mystrtok(&cp, CIPHER_SEP)) != 0) { diff --git a/postfix/src/util/dict_pipe.c b/postfix/src/util/dict_pipe.c index 135c66d50..e15ff5e01 100644 --- a/postfix/src/util/dict_pipe.c +++ b/postfix/src/util/dict_pipe.c @@ -138,7 +138,7 @@ DICT *dict_pipe_open(const char *name, int open_flags, int dict_flags) /* * Split the table name into its constituent parts. */ - if ((len = balpar(name, "{}")) == 0 || name[len] != 0 + if ((len = balpar(name, CHARS_BRACE)) == 0 || name[len] != 0 || *(saved_name = mystrndup(name + 1, len - 2)) == 0) DICT_PIPE_RETURN(dict_surrogate(DICT_TYPE_PIPE, name, open_flags, dict_flags, @@ -152,7 +152,7 @@ DICT *dict_pipe_open(const char *name, int open_flags, int dict_flags) * level. The first table determines the pattern-matching flags. */ DICT_OWNER_AGGREGATE_INIT(aggr_owner); - argv = argv_splitq(saved_name, ", \t\r\n", "{}"); + argv = argv_splitq(saved_name, CHARS_COMMA_SP, CHARS_BRACE); for (cpp = argv->argv; (dict_type_name = *cpp) != 0; cpp++) { if (msg_verbose) msg_info("%s: %s", myname, dict_type_name); diff --git a/postfix/src/util/dict_random.c b/postfix/src/util/dict_random.c index 0ee4a8365..4497fe1c3 100644 --- a/postfix/src/util/dict_random.c +++ b/postfix/src/util/dict_random.c @@ -104,7 +104,7 @@ DICT *dict_random_open(const char *name, int open_flags, int dict_flags) /* * Split the name name into its constituent parts. */ - if ((len = balpar(name, "{}")) == 0 || name[len] != 0 + if ((len = balpar(name, CHARS_BRACE)) == 0 || name[len] != 0 || *(saved_name = mystrndup(name + 1, len - 2)) == 0) DICT_RANDOM_RETURN(dict_surrogate(DICT_TYPE_RANDOM, name, open_flags, dict_flags, @@ -121,7 +121,7 @@ DICT *dict_random_open(const char *name, int open_flags, int dict_flags) dict_random->dict.lookup = dict_random_lookup; dict_random->dict.close = dict_random_close; dict_random->dict.flags = dict_flags | DICT_FLAG_PATTERN; - dict_random->replies = argv_splitq(saved_name, ", \t\r\n", "{}"); + dict_random->replies = argv_splitq(saved_name, CHARS_COMMA_SP, CHARS_BRACE); dict_random->dict.owner.status = DICT_OWNER_TRUSTED; dict_random->dict.owner.uid = 0; diff --git a/postfix/src/util/dict_thash.c b/postfix/src/util/dict_thash.c index 1bee77d30..93a4f4472 100644 --- a/postfix/src/util/dict_thash.c +++ b/postfix/src/util/dict_thash.c @@ -199,7 +199,7 @@ DICT *dict_thash_open(const char *path, int open_flags, int dict_flags) * trailing whitespace from key and value. */ key = STR(line_buffer); - value = key + strcspn(key, " \t\r\n"); + value = key + strcspn(key, CHARS_SPACE); if (*value) *value++ = 0; while (ISSPACE(*value)) diff --git a/postfix/src/util/dict_union.c b/postfix/src/util/dict_union.c index ef709ed43..b2a5feec8 100644 --- a/postfix/src/util/dict_union.c +++ b/postfix/src/util/dict_union.c @@ -145,7 +145,7 @@ DICT *dict_union_open(const char *name, int open_flags, int dict_flags) /* * Split the table name into its constituent parts. */ - if ((len = balpar(name, "{}")) == 0 || name[len] != 0 + if ((len = balpar(name, CHARS_BRACE)) == 0 || name[len] != 0 || *(saved_name = mystrndup(name + 1, len - 2)) == 0) DICT_UNION_RETURN(dict_surrogate(DICT_TYPE_UNION, name, open_flags, dict_flags, @@ -159,7 +159,7 @@ DICT *dict_union_open(const char *name, int open_flags, int dict_flags) * level. The first table determines the pattern-matching flags. */ DICT_OWNER_AGGREGATE_INIT(aggr_owner); - argv = argv_splitq(saved_name, ", \t\r\n", "{}"); + argv = argv_splitq(saved_name, CHARS_COMMA_SP, CHARS_BRACE); for (cpp = argv->argv; (dict_type_name = *cpp) != 0; cpp++) { if (msg_verbose) msg_info("%s: %s", myname, dict_type_name); diff --git a/postfix/src/util/mac_expand.c b/postfix/src/util/mac_expand.c index d7e6c1101..2b081b810 100644 --- a/postfix/src/util/mac_expand.c +++ b/postfix/src/util/mac_expand.c @@ -208,7 +208,7 @@ static const NAME_CODE mac_exp_op_table[] = /* * The whitespace separator set. */ -#define MAC_EXP_WHITESPACE " \t\r\n" +#define MAC_EXP_WHITESPACE CHARS_SPACE /* mac_exp_eval - evaluate binary expression */ @@ -628,8 +628,8 @@ int main(int unused_argc, char **unused_argv) if (VSTRING_LEN(buf) == 0) break; cp = vstring_str(buf); - name = mystrtok(&cp, " \t\r\n="); - value = mystrtok(&cp, " \t\r\n="); + name = mystrtok(&cp, CHARS_SPACE "="); + value = mystrtok(&cp, CHARS_SPACE "="); htable_enter(table, name, value ? mystrdup(value) : 0); } diff --git a/postfix/src/util/match_list.c b/postfix/src/util/match_list.c index cfd93e655..306a5ed9c 100644 --- a/postfix/src/util/match_list.c +++ b/postfix/src/util/match_list.c @@ -99,7 +99,7 @@ static ARGV *match_list_parse(ARGV *list, char *string, int init_match) const char *myname = "match_list_parse"; VSTRING *buf = vstring_alloc(10); VSTREAM *fp; - const char *delim = " ,\t\r\n"; + const char *delim = CHARS_COMMA_SP; char *bp = string; char *start; char *item; @@ -114,7 +114,7 @@ static ARGV *match_list_parse(ARGV *list, char *string, int init_match) * /filename contents are expanded in-line. To support !/filename we * prepend the negation operator to each item from the file. */ - while ((start = mystrtokq(&bp, delim, "{}")) != 0) { + while ((start = mystrtokq(&bp, delim, CHARS_BRACE)) != 0) { if (*start == '#') { msg_warn("%s: comment at end of line is not supported: %s %s", myname, start, bp); diff --git a/postfix/src/util/mystrtok.c b/postfix/src/util/mystrtok.c index 0056f836a..91e3c472e 100644 --- a/postfix/src/util/mystrtok.c +++ b/postfix/src/util/mystrtok.c @@ -127,11 +127,11 @@ int main(void) while (vstring_fgets(vp, VSTREAM_IN) && VSTRING_LEN(vp) > 0) { start = vstring_str(vp); - if (strchr(start, '{') == 0) { - while ((str = mystrtok(&start, " \t\r\n")) != 0) + if (strchr(start, CHARS_BRACE[0]) == 0) { + while ((str = mystrtok(&start, CHARS_SPACE)) != 0) vstream_printf(">%s<\n", str); } else { - while ((str = mystrtokq(&start, " \t\r\n", "{}")) != 0) + while ((str = mystrtokq(&start, CHARS_SPACE, CHARS_BRACE)) != 0) vstream_printf(">%s<\n", str); } vstream_fflush(VSTREAM_OUT); diff --git a/postfix/src/util/spawn_command.c b/postfix/src/util/spawn_command.c index a45258224..2cfb3b272 100644 --- a/postfix/src/util/spawn_command.c +++ b/postfix/src/util/spawn_command.c @@ -276,7 +276,7 @@ WAIT_STATUS_T spawn_command(int key,...) execvp(args.argv[0], args.argv); msg_fatal("%s: execvp %s: %m", myname, args.argv[0]); } else if (args.shell && *args.shell) { - argv = argv_split(args.shell, " \t\r\n"); + argv = argv_split(args.shell, CHARS_SPACE); argv_add(argv, args.command, (char *) 0); argv_terminate(argv); execvp(argv->argv[0], argv->argv); diff --git a/postfix/src/util/stringops.h b/postfix/src/util/stringops.h index 43b97fcb5..3d9b60fa6 100644 --- a/postfix/src/util/stringops.h +++ b/postfix/src/util/stringops.h @@ -51,13 +51,6 @@ extern char *extpar(char **, const char *, int); #define EXTPAR_FLAG_STRIP (1<<0) /* "{ text }" -> "text" */ #define EXTPAR_FLAG_EXTRACT (1<<1) /* hint from caller's caller */ - /* - * Character sets for parsing. - */ -#define CHARS_COMMA_SP ", \t\r\n" /* list separator */ -#define CHARS_SPACE " \t\r\n" /* word separator */ -#define CHARS_BRACE "{}" /* grouping */ - /* LICENSE /* .ad /* .fi diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index 5c37ac3fd..bfd6f0549 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -1717,6 +1717,13 @@ typedef int pid_t; #define TOLOWER(c) (ISUPPER(c) ? tolower((unsigned char)(c)) : (c)) #define TOUPPER(c) (ISLOWER(c) ? toupper((unsigned char)(c)) : (c)) + /* + * Character sets for parsing. + */ +#define CHARS_COMMA_SP ", \t\r\n" /* list separator */ +#define CHARS_SPACE " \t\r\n" /* word separator */ +#define CHARS_BRACE "{}" /* grouping */ + /* * Scaffolding. I don't want to lose messages while the program is under * development. diff --git a/postfix/src/util/vstream_popen.c b/postfix/src/util/vstream_popen.c index aace6c82c..7c54ec14a 100644 --- a/postfix/src/util/vstream_popen.c +++ b/postfix/src/util/vstream_popen.c @@ -255,7 +255,7 @@ VSTREAM *vstream_popen(int flags,...) execvp(args.argv[0], args.argv); msg_fatal("%s: execvp %s: %m", myname, args.argv[0]); } else if (args.shell && *args.shell) { - argv = argv_split(args.shell, " \t\r\n"); + argv = argv_split(args.shell, CHARS_SPACE); argv_add(argv, args.command, (char *) 0); argv_terminate(argv); execvp(argv->argv[0], argv->argv);