From: Wietse Venema
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.
+
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
+
+
++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.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
This feature is available in Postfix 2.3 and later.
- - -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.
- -This feature is available in Postfix 2.3 and later.
- - -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.
- -
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
+
+
++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.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
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