diff --git a/postfix/HISTORY b/postfix/HISTORY
index 277752d35..e30ce59cc 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -28918,4 +28918,19 @@ Apologies for any names omitted.
Debug logging: cleanup/cleanup_api.c. tls/tlsrpt_wrapper.c.
proto/TLSRPT_README.html.
- Postfix 3.10 code freeze.
+20250204
+
+ Feature: with "smtpd_hide_client_session = yes", the Postfix
+ SMTP server generates a Received: header without client
+ session info (EHLO, hostname, IP address, TLS session
+ details, SASL login details, SMTP protocol details). Files:
+ conf/master.cf, mantools/postlink, proto/postconf.proto,
+ global/mail_params.h, smtpd/smtpd.c.
+
+20250205
+
+ Documentation: updated TLSRPT_README, added postfix-tlspol
+ policy plugin, deprecated the policy_ttl attribute. File:
+ proto/TLSRPT_README.html.
+
+ Postfix 3.10 code freeze.
diff --git a/postfix/README_FILES/TLSRPT_README b/postfix/README_FILES/TLSRPT_README
index 94f011ebe..fe26e3b04 100644
--- a/postfix/README_FILES/TLSRPT_README
+++ b/postfix/README_FILES/TLSRPT_README
@@ -48,11 +48,12 @@ are collected and processed into daily summary reports.
TLSRPT report generator produces daily summary reports.
The TLSRPT client library, and the infrastructure to collect, fetch, and report
-TLSRPT information are maintained by sys4 at https://github.com/sys4/libtlsrpt
-and https://github.com/sys4/tlsrpt-reporter, respectively.
+TLSRPT information, are implemented and maintained by sys4 at https://
+github.com/sys4/libtlsrpt and https://github.com/sys4/tlsrpt-reporter,
+respectively.
-The Postfix implementation supports both DANE (Postfix built-in) and MTA-STS
-(through an smtp_tls_policy_maps plug-in).
+The Postfix implementation supports domains with DANE (Postfix built-in) and
+MTA-STS (through an smtp_tls_policy_maps plug-in).
The Postfix smtp(8) client process implements the SMTP client engine. With
"smtp_tls_connection_reuse = no", the smtp(8) client process also implements
@@ -228,19 +229,25 @@ Options:
MMTTAA--SSTTSS SSuuppppoorrtt vviiaa ssmmttpp__ttllss__ppoolliiccyy__mmaappss
Postfix supports MTA-STS though an smtp_tls_policy_maps policy plugin, which
-replies with a TLS security level and optional matching requirements. Postfix
-3.10 and later optionally also accept the name=value attributes described
-below. Specify { name = value } when a value may contain whitespace.
+replies with a TLS security level and name=value attributes with certificate
+matching requirements. Postfix 3.10 and later accept additional name=value
+attributes that are needed for TLSRPT.
- Note 1: Postfix 3.10 and later will accept these attributes in an MTA-STS
- response even if TLSRPT support is disabled (at build time or run time).
- With TLSRPT support turned off, Postfix will use the ttl and policy_failure
- attributes, and will ignore the attributes that are used only for TLSRPT.
+Examples of smtp_tls_policy_maps plugins with MTA-STS support are:
- Note 2: It is an error to specify these attributes for a non-STS policy.
+ * postfix-tlspol, supports domains with DANE (using Postfix built-in DANE),
+ and domains with MTA-STS.
-The examples in the table apply to the MTA-STS policy example given in RFC 8461
-Section 3.2:
+ * postfix-mta-sts-resolver, supports domains with MTA-STS.
+
+Both plugins can generate the additional name=value attributes that Postfix
+needs for TLSRPT support (as of February 2025). This is enabled by setting a
+tlsrpt boolean in a plugin configuration file. This setting is safe with
+Postfix 3.10 and later, even if Postfix TLSRPT support is disabled (at build
+time or at run time).
+
+The examples in the text below apply to this MTA-STS policy example given in
+RFC 8461 Section 3.2:
version: STSv1
mode: enforce
@@ -249,7 +256,9 @@ Section 3.2:
mx: backupmx.example.com
max_age: 604800
-A policy response may contain line breaks.
+The list of supported attributes is given below. Instead of name=value, specify
+{ name = value } when a value may contain whitespace. A policy response may
+contain line breaks.
* policy_type=type
@@ -259,45 +268,49 @@ A policy response may contain line breaks.
The domain that the MTA-STS policy applies to.
- * policy_ttl=time
-
- How long (in seconds) a Postfix SMTP client process will cache the MTA-STS
- plugin response.
+ Example: policy_domain=example.com
* { policy_string = value }
Specify one policy_string instance for each MTA-STS policy feature,
enclosed inside "{" and "}" to protect whitespace in attribute values.
- Example:
+ Example: { policy_string = version: STSv1 } { policy_string = mode: enforce
+ } ...
- { policy_string = version: STSv1 } { policy_string = mode: enforce }
- ...
-
- This form ignores whitespace after the opening "{", around the "=", and
- before the closing "}".
+ The above form ignores whitespace after the opening "{", around the "=",
+ and before the closing "}".
* mx_host_pattern=pattern
Specify one mx_host_pattern instance for each "mx:" feature in the MTA-STS
policy.
- Example:
-
- mx_host_pattern=mail.example.com mx_host_pattern=*.example.net ...
+ Example: mx_host_pattern=mail.example.com mx_host_pattern=*.example.net ...
* policy_failure=type
If specified, forces MTA-STS policy enforcement to fail with the indicated
error, even if a server certificate would satisfy conventional PKI
- constraints.
+ constraints. Valid errors are sts-policy-fetch-error, sts-policy-invalid,
+ sts-webpki-invalid, or the less informative validation-failure.
- Valid errors are sts-policy-fetch-error, sts-policy-invalid, sts-webpki-
- invalid, or the less informative validation-failure.
+ Example: policy_failure=sts-webpki-invalid
- Example:
+ * policy_ttl=time
- policy_failure=sts-webpki-invalid
+ This attribute is deprecated. The time value is not used, and support for
+ this attribute will eventually be removed from the code.
+
+Notes:
+
+ * Postfix 3.10 and later will accept these additional attributes in an MTA-
+ STS response even if TLSRPT support is disabled (at build time or at run
+ time). With TLSRPT support turned off, Postfix may still use the
+ policy_failure attribute, and will ignore the attributes that are used only
+ for TLSRPT.
+
+ * It is an error to specify these attributes for a non-STS policy.
LLiimmiittaattiioonnss
@@ -314,7 +327,7 @@ SMTP protocol engine. It just is not how Postfix works internally.
CCrreeddiittss
- * The TLSRPT client library and report generator are implemented and
- maintained by sys4.
+ * The TLSRPT client library, and the infrastructure to collect, fetch, and
+ report TLSRPT information, are implemented and maintained by sys4.
* Wietse Venema implemented the integration with Postfix.
diff --git a/postfix/conf/master.cf b/postfix/conf/master.cf
index dc038d0d1..5abe06cbd 100644
--- a/postfix/conf/master.cf
+++ b/postfix/conf/master.cf
@@ -23,6 +23,7 @@ smtp inet n - n - - smtpd
# -o smtpd_sasl_auth_enable=yes
# -o smtpd_tls_auth_only=yes
# -o local_header_rewrite_clients=static:all
+# -o smtpd_hide_client_session=yes
# -o smtpd_reject_unlisted_recipient=no
# Instead of specifying complex smtpd_ The TLSRPT client library, and the infrastructure to collect,
-fetch, and report TLSRPT information are maintained by sys4 at
-https://github.com/sys4/libtlsrpt and
+fetch, and report TLSRPT information, are implemented and maintained
+by sys4 at https://github.com/sys4/libtlsrpt and
https://github.com/sys4/tlsrpt-reporter, respectively. The Postfix implementation supports both DANE (Postfix built-in)
-and MTA-STS (through an smtp_tls_policy_maps plug-in). The Postfix implementation supports domains with DANE (Postfix
+built-in) and MTA-STS (through an smtp_tls_policy_maps plug-in).
+ The Postfix smtp(8) client process implements the SMTP client
engine. With "smtp_tls_connection_reuse = no", the smtp(8) client
@@ -215,7 +216,7 @@ queue, but it will also log a visible record to the mail logfile.
Below are a few examples of logging from a Postfix SMTP client
or tlsproxy daemon: Notes: Postfix logs and reports the TLSRPT status only for TLS
handshakes on a new SMTP connection. There is no TLS handshake, and
@@ -332,25 +333,33 @@ generator's sender address): Postfix supports MTA-STS though an smtp_tls_policy_maps policy
-plugin, which replies with a TLS security level and optional matching
-requirements. Postfix 3.10 and later optionally also accept the
-name=value attributes described below. Specify { name = value
-} when a value may contain whitespace.
+
TLSRPT: status=success, domain=example.com, receiving_mx=mail.example.com[ipaddr]
@@ -229,7 +230,7 @@ TLSRPT: status=failure, domain=example.net, receiving_mx=mail.example.net[ipaddr
+
++Examples of smtp_tls_policy_maps plugins with MTA-STS support +are:
-Note 1: Postfix 3.10 and later will accept these attributes in -an MTA-STS response even if TLSRPT support is disabled (at build -time or run time). With TLSRPT support turned off, Postfix -will use the ttl and policy_failure attributes, -and will ignore the attributes that are used only for TLSRPT.
+-
Note 2: It is an error to specify these attributes for a non-STS -policy.
++postfix-tlspol, supports domains with DANE (using Postfix +built-in DANE), and domains with MTA-STS.
-
+postfix-mta-sts-resolver, supports domains with MTA-STS.
-The examples in the table apply to the MTA-STS policy example + + +
Both plugins can generate the additional name=value attributes +that Postfix needs for TLSRPT support (as of February 2025). This +is enabled by setting a tlsrpt boolean in a plugin +configuration file. This setting is safe with Postfix 3.10 and +later, even if Postfix TLSRPT support is disabled (at build time +or at run time).
+ +The examples in the text below apply to this MTA-STS policy example given in RFC 8461 Section 3.2:
@@ -366,72 +375,77 @@ max_age: 604800 -A policy response may contain line breaks.
+The list of supported attributes is given below. Instead of +name=value, specify { name = value } when a value +may contain whitespace. A policy response may contain line breaks. +
policy_type=type +
policy_type=type
Specify sts or no-policy-found.
policy_domain=name
-The domain that the MTA-STS policy applies to.
The domain that the MTA-STS policy applies to.
-policy_ttl=time
-How long (in seconds) a Postfix SMTP client process will cache -the MTA-STS plugin response.
Example: policy_domain=example.com
+ +{ policy_string = value }
Specify one policy_string instance for each MTA-STS policy feature, enclosed inside "{" and "}" to protect whitespace -in attribute values.
+in attribute values.-
Example:
+Example: { policy_string = version: STSv1 } { policy_string += mode: enforce } ...
--- --{ policy_string = version: STSv1 } { policy_string = mode: enforce } ... --
This form ignores whitespace after the opening "{", around the "=", -and before the closing "}".
The above form ignores whitespace after the opening "{", around +the "=", and before the closing "}".
mx_host_pattern=pattern
Specify one mx_host_pattern instance for each "mx:" feature in the MTA-STS policy.
-Example:
- ----mx_host_pattern=mail.example.com mx_host_pattern=*.example.net ... --
Example: mx_host_pattern=mail.example.com +mx_host_pattern=*.example.net ...
policy_failure=type
If specified, forces MTA-STS policy enforcement to fail with the indicated error, even if a server certificate would satisfy -conventional PKI constraints.
+conventional PKI constraints. Valid errors are sts-policy-fetch-error, +sts-policy-invalid, sts-webpki-invalid, or the less +informative validation-failure. -Valid errors are sts-policy-fetch-error, sts-policy-invalid, -sts-webpki-invalid, or the less informative -validation-failure.
+Example: policy_failure=sts-webpki-invalid
Example:
+policy_ttl=time
----policy_failure=sts-webpki-invalid --
This attribute is deprecated. The time value is not used, +and support for this attribute will eventually be removed from the +code.
+ + + +Notes:
+ +Postfix 3.10 and later will accept these additional +attributes in an MTA-STS response even if TLSRPT support is disabled +(at build time or at run time). With TLSRPT support turned off, +Postfix may still use the policy_failure +attribute, and will ignore the attributes that are used only for +TLSRPT.
+ +It is an error to specify these attributes for a non-STS +policy.
Do not include SMTP client session information in the Postfix +SMTP server's Received: message header.
+ +The default setting, "smtpd_hide_client_session = no", +must be used for the port 25 MTA service. It provides information +that is required by RFC 5321.
+ +The setting "smtpd_hide_client_session = yes" may be used +for the port 587 and 465 MUA services. This hides the SMTP client +hostname and IP address, TLS session details, SASL login details, +and SMTP protocol details.
+ +Depending on the number of recipients, a redacted Received: +header has one of the following forms:
+ +++ ++Received: by mail.example.com (Postfix) id postfix-queue-id + for <user@example.com>; Day, dd Mon yyyy hh:mm:ss tz-offset (zone) ++
+Received: by mail.example.com (Postfix) id postfix-queue-id + Day, dd Mon yyyy hh:mm:ss tz-offset (zone) +
The redacted form hides that a message was received with SMTP, +and therefore it does not need to provide the information required by +RFC 5321. The form does still meet RFC 5322 requirements.
+ +This feature is available in Postfix ≥ 3.10.
+ +The TLSRPT client library, and the infrastructure to collect, -fetch, and report TLSRPT information are maintained by sys4 at -https://github.com/sys4/libtlsrpt and +fetch, and report TLSRPT information, are implemented and maintained +by sys4 at https://github.com/sys4/libtlsrpt and https://github.com/sys4/tlsrpt-reporter, respectively.
-The Postfix implementation supports both DANE (Postfix built-in) -and MTA-STS (through an smtp_tls_policy_maps plug-in).
+The Postfix implementation supports domains with DANE (Postfix +built-in) and MTA-STS (through an smtp_tls_policy_maps plug-in). +
The Postfix smtp(8) client process implements the SMTP client engine. With "smtp_tls_connection_reuse = no", the smtp(8) client @@ -215,7 +216,7 @@ queue, but it will also log a visible record to the mail logfile.
Below are a few examples of logging from a Postfix SMTP client or tlsproxy daemon:
-+-TLSRPT: status=success, domain=example.com, receiving_mx=mail.example.com[ipaddr] @@ -229,7 +230,7 @@ TLSRPT: status=failure, domain=example.net, receiving_mx=mail.example.net[ipaddrNotes:
-+
+ +
Postfix logs and reports the TLSRPT status only for TLS handshakes on a new SMTP connection. There is no TLS handshake, and @@ -332,25 +333,33 @@ generator's sender address):
Postfix supports MTA-STS though an smtp_tls_policy_maps policy -plugin, which replies with a TLS security level and optional matching -requirements. Postfix 3.10 and later optionally also accept the -name=value attributes described below. Specify { name = value -} when a value may contain whitespace.
+plugin, which replies with a TLS security level and name=value +attributes with certificate matching requirements. Postfix 3.10 and +later accept additional name=value attributes that are needed for +TLSRPT. -++Examples of smtp_tls_policy_maps plugins with MTA-STS support +are:
-Note 1: Postfix 3.10 and later will accept these attributes in -an MTA-STS response even if TLSRPT support is disabled (at build -time or run time). With TLSRPT support turned off, Postfix -will use the ttl and policy_failure attributes, -and will ignore the attributes that are used only for TLSRPT.
+-
Note 2: It is an error to specify these attributes for a non-STS -policy.
++postfix-tlspol, supports domains with DANE (using Postfix +built-in DANE), and domains with MTA-STS.
-+postfix-mta-sts-resolver, supports domains with MTA-STS.
-The examples in the table apply to the MTA-STS policy example +
Both plugins can generate the additional name=value attributes +that Postfix needs for TLSRPT support (as of February 2025). This +is enabled by setting a tlsrpt boolean in a plugin +configuration file. This setting is safe with Postfix 3.10 and +later, even if Postfix TLSRPT support is disabled (at build time +or at run time).
+ +The examples in the text below apply to this MTA-STS policy example given in RFC 8461 Section 3.2:
@@ -366,72 +375,77 @@ max_age: 604800A policy response may contain line breaks.
+The list of supported attributes is given below. Instead of +name=value, specify { name = value } when a value +may contain whitespace. A policy response may contain line breaks. +
-
+ +policy_type=type +
policy_type=type
Specify sts or no-policy-found.
- +
policy_domain=name
-The domain that the MTA-STS policy applies to.
The domain that the MTA-STS policy applies to.
-- +
policy_ttl=time
-How long (in seconds) a Postfix SMTP client process will cache -the MTA-STS plugin response.
Example: policy_domain=example.com
+ +- +
{ policy_string = value }
Specify one policy_string instance for each MTA-STS policy feature, enclosed inside "{" and "}" to protect whitespace -in attribute values.
+in attribute values.-
Example:
+Example: { policy_string = version: STSv1 } { policy_string += mode: enforce } ...
--- --{ policy_string = version: STSv1 } { policy_string = mode: enforce } ... --This form ignores whitespace after the opening "{", around the "=", -and before the closing "}".
The above form ignores whitespace after the opening "{", around +the "=", and before the closing "}".
- +
mx_host_pattern=pattern
Specify one mx_host_pattern instance for each "mx:" feature in the MTA-STS policy.
-Example:
- ----mx_host_pattern=mail.example.com mx_host_pattern=*.example.net ... --Example: mx_host_pattern=mail.example.com +mx_host_pattern=*.example.net ...
- -
policy_failure=type
If specified, forces MTA-STS policy enforcement to fail with the indicated error, even if a server certificate would satisfy -conventional PKI constraints.
+conventional PKI constraints. Valid errors are sts-policy-fetch-error, +sts-policy-invalid, sts-webpki-invalid, or the less +informative validation-failure. -Valid errors are sts-policy-fetch-error, sts-policy-invalid, -sts-webpki-invalid, or the less informative -validation-failure.
+Example: policy_failure=sts-webpki-invalid
Example:
+- +
policy_ttl=time
----policy_failure=sts-webpki-invalid --This attribute is deprecated. The time value is not used, +and support for this attribute will eventually be removed from the +code.
+ +Notes:
+ ++ +
@@ -453,8 +467,9 @@ engine. It just is not how Postfix works internally.Postfix 3.10 and later will accept these additional +attributes in an MTA-STS response even if TLSRPT support is disabled +(at build time or at run time). With TLSRPT support turned off, +Postfix may still use the policy_failure +attribute, and will ignore the attributes that are used only for +TLSRPT.
+ +It is an error to specify these attributes for a non-STS +policy.
-
- The TLSRPT client library and report generator are implemented -and maintained by sys4.
+- The TLSRPT client library, and the infrastructure to collect, +fetch, and report TLSRPT information, are implemented and maintained +by sys4.
- Wietse Venema implemented the integration with Postfix.
diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index abb606368..25eef4da9 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -19486,3 +19486,40 @@ will add that header to a delivery status notification for that message.This feature is available in Postfix ≥ 3.10.
+ +%PARAM smtpd_hide_client_session no + +Do not include SMTP client session information in the Postfix +SMTP server's Received: message header.
+ ++ +
+ +The default setting, "smtpd_hide_client_session = no", +must be used for the port 25 MTA service. It provides information +that is required by RFC 5321.
+ +The setting "smtpd_hide_client_session = yes" may be used +for the port 587 and 465 MUA services. This hides the SMTP client +hostname and IP address, TLS session details, SASL login details, +and SMTP protocol details.
+ +Depending on the number of recipients, a redacted Received: +header has one of the following forms:
+ +++ ++Received: by mail.example.com (Postfix) id postfix-queue-id + for <user@example.com>; Day, dd Mon yyyy hh:mm:ss tz-offset (zone) ++
+Received: by mail.example.com (Postfix) id postfix-queue-id + Day, dd Mon yyyy hh:mm:ss tz-offset (zone) +The redacted form hides that a message was received with SMTP, +and therefore it does not need to provide the information required by +RFC 5321. The form does still meet RFC 5322 requirements.
+ +This feature is available in Postfix ≥ 3.10.
diff --git a/postfix/proto/stop b/postfix/proto/stop index c1a080d87..a8b5522a5 100644 --- a/postfix/proto/stop +++ b/postfix/proto/stop @@ -1664,3 +1664,4 @@ REQUIRETLS RequireTLS requiretls sendopts +tz diff --git a/postfix/proto/stop.double-history b/postfix/proto/stop.double-history index 15d98a3c3..870135f2b 100644 --- a/postfix/proto/stop.double-history +++ b/postfix/proto/stop.double-history @@ -160,3 +160,7 @@ proto proto socketmap_table smtp smtp_proto c smtpd smtpd c verify verify c operations Files cleanup cleanup h cleanup cleanup_message c proto postconf proto pipe pipe c + bounce bounce c bounce bounce_notify_util c cleanup cleanup c + cleanup cleanup_message c smtp smtp c smtp smtp_connect c + Documentation edited for clarity Files pipe pipe c + global mail_params h smtpd smtpd c diff --git a/postfix/proto/stop.spell-history b/postfix/proto/stop.spell-history index 74e0858b7..d358e3614 100644 --- a/postfix/proto/stop.spell-history +++ b/postfix/proto/stop.spell-history @@ -99,3 +99,4 @@ CLOSEFROM Roessner bitflags Schulze +tlspol diff --git a/postfix/proto/stop.spell-proto-html b/postfix/proto/stop.spell-proto-html index 1a487be5f..b5bd4adf3 100644 --- a/postfix/proto/stop.spell-proto-html +++ b/postfix/proto/stop.spell-proto-html @@ -397,3 +397,6 @@ dtd marc LP collectd +Snawoot +Zuplu +tlspol diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 8b54490f5..aa2f294bf 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -4502,6 +4502,13 @@ extern char *var_full_name_encoding_charset; #define DEF_SOCKMAP_MAX_REPLY 100000 /* reply size limit */ extern int var_sockmap_max_reply; + /* + * Client privacy. + */ +#define VAR_SMTPD_HIDE_CLIENT_SESSION "smtpd_hide_client_session" +#define DEF_SMTPD_HIDE_CLIENT_SESSION "no" +extern int var_smtpd_hide_client_session; + /* LICENSE /* .ad /* .fi diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 825bcae3d..27e83993c 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 "20250202" +#define MAIL_RELEASE_DATE "20250205" #define MAIL_VERSION_NUMBER "3.10" #ifdef SNAPSHOT diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 962b361c7..9c11b18ca 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -1174,6 +1174,11 @@ /* .IP "\fBsmtpd_reject_footer_maps (empty)\fR" /* Lookup tables, indexed by the complete Postfix SMTP server 4xx or /* 5xx response, with reject footer templates. +/* .PP +/* Available in Postfix 3.10 and later: +/* .IP "\fBsmtpd_hide_client_session (no)\fR" +/* Do not include SMTP client session information in the Postfix +/* SMTP server's Received: message header. /* SEE ALSO /* anvil(8), connection/rate limiting /* cleanup(8), message canonicalization @@ -1558,6 +1563,7 @@ char *var_smtpd_forbid_bare_lf_excl; int var_smtpd_forbid_bare_lf_code; static int bare_lf_mask; static NAMADR_LIST *bare_lf_excl; +bool var_smtpd_hide_client_session; /* * Silly little macros. @@ -3434,10 +3440,13 @@ static void common_pre_message_handling(SMTPD_STATE *state, { SMTPD_PROXY *proxy = state->proxy; char **cpp; - const char *rfc3848_sess; - const char *rfc3848_auth; + const char *rfc3848_sess = ""; + const char *rfc3848_auth = ""; + const char *with_verb = " with "; const char *with_protocol = (state->flags & SMTPD_FLAG_SMTPUTF8) ? "UTF8SMTP" : state->protocol; + const char *id_verb = state->cleanup ? " id " : ""; + const char *id_value = state->cleanup ? state->queue_id : ""; #ifdef USE_TLS VSTRING *peer_CN; @@ -3483,152 +3492,153 @@ static void common_pre_message_handling(SMTPD_STATE *state, * intermediate proxy. */ if (!proxy || state->xforward.flags == 0) { - out_fprintf(out_stream, REC_TYPE_NORM, - "Received: from %s (%s [%s])", - state->helo_name ? state->helo_name : state->name, - state->name, state->rfc_addr); + if (!var_smtpd_hide_client_session) { + out_fprintf(out_stream, REC_TYPE_NORM, + "Received: from %s (%s [%s])", + state->helo_name ? state->helo_name : state->name, + state->name, state->rfc_addr); #define VSTRING_STRDUP(s) vstring_strcpy(vstring_alloc(strlen(s) + 1), (s)) #ifdef USE_TLS - if (var_smtpd_tls_received_header && state->tls_context) { - int cont = 0; + if (var_smtpd_tls_received_header && state->tls_context) { + int cont = 0; - vstring_sprintf(state->buffer, - "\t(using %s with cipher %s (%d/%d bits)", - state->tls_context->protocol, - state->tls_context->cipher_name, - state->tls_context->cipher_usebits, - state->tls_context->cipher_algbits); - if (state->tls_context->kex_name && *state->tls_context->kex_name) { - out_record(out_stream, REC_TYPE_NORM, STR(state->buffer), - LEN(state->buffer)); - vstring_sprintf(state->buffer, "\t key-exchange %s", - state->tls_context->kex_name); - if (state->tls_context->kex_curve - && *state->tls_context->kex_curve) - vstring_sprintf_append(state->buffer, " (%s)", - state->tls_context->kex_curve); - else if (state->tls_context->kex_bits > 0) - vstring_sprintf_append(state->buffer, " (%d bits)", - state->tls_context->kex_bits); - cont = 1; - } - if (state->tls_context->srvr_sig_name - && *state->tls_context->srvr_sig_name) { - if (cont) { - vstring_sprintf_append(state->buffer, " server-signature %s", - state->tls_context->srvr_sig_name); - } else { + vstring_sprintf(state->buffer, + "\t(using %s with cipher %s (%d/%d bits)", + state->tls_context->protocol, + state->tls_context->cipher_name, + state->tls_context->cipher_usebits, + state->tls_context->cipher_algbits); + if (state->tls_context->kex_name && *state->tls_context->kex_name) { out_record(out_stream, REC_TYPE_NORM, STR(state->buffer), LEN(state->buffer)); - vstring_sprintf(state->buffer, "\t server-signature %s", - state->tls_context->srvr_sig_name); + vstring_sprintf(state->buffer, "\t key-exchange %s", + state->tls_context->kex_name); + if (state->tls_context->kex_curve + && *state->tls_context->kex_curve) + vstring_sprintf_append(state->buffer, " (%s)", + state->tls_context->kex_curve); + else if (state->tls_context->kex_bits > 0) + vstring_sprintf_append(state->buffer, " (%d bits)", + state->tls_context->kex_bits); + cont = 1; } - if (state->tls_context->srvr_sig_curve - && *state->tls_context->srvr_sig_curve) - vstring_sprintf_append(state->buffer, " (%s%s)", + if (state->tls_context->srvr_sig_name + && *state->tls_context->srvr_sig_name) { + if (cont) { + vstring_sprintf_append(state->buffer, " server-signature %s", + state->tls_context->srvr_sig_name); + } else { + out_record(out_stream, REC_TYPE_NORM, STR(state->buffer), + LEN(state->buffer)); + vstring_sprintf(state->buffer, "\t server-signature %s", + state->tls_context->srvr_sig_name); + } + if (state->tls_context->srvr_sig_curve + && *state->tls_context->srvr_sig_curve) + vstring_sprintf_append(state->buffer, " (%s%s)", state->tls_context->srvr_sig_curve, - state->tls_context->stoc_rpk ? - " raw public key" : ""); - else if (state->tls_context->srvr_sig_bits > 0) - vstring_sprintf_append(state->buffer, " (%d bit%s)", - state->tls_context->srvr_sig_bits, - state->tls_context->stoc_rpk ? - " raw public key" : "s"); - if (state->tls_context->srvr_sig_dgst - && *state->tls_context->srvr_sig_dgst) - vstring_sprintf_append(state->buffer, " server-digest %s", + state->tls_context->stoc_rpk ? + " raw public key" : ""); + else if (state->tls_context->srvr_sig_bits > 0) + vstring_sprintf_append(state->buffer, " (%d bit%s)", + state->tls_context->srvr_sig_bits, + state->tls_context->stoc_rpk ? + " raw public key" : "s"); + if (state->tls_context->srvr_sig_dgst + && *state->tls_context->srvr_sig_dgst) + vstring_sprintf_append(state->buffer, " server-digest %s", state->tls_context->srvr_sig_dgst); - } - if (state->tls_context->clnt_sig_name - && *state->tls_context->clnt_sig_name) { - out_record(out_stream, REC_TYPE_NORM, STR(state->buffer), - LEN(state->buffer)); - vstring_sprintf(state->buffer, "\t client-signature %s", - state->tls_context->clnt_sig_name); - if (state->tls_context->clnt_sig_curve - && *state->tls_context->clnt_sig_curve) - vstring_sprintf_append(state->buffer, " (%s%s)", + } + if (state->tls_context->clnt_sig_name + && *state->tls_context->clnt_sig_name) { + out_record(out_stream, REC_TYPE_NORM, STR(state->buffer), + LEN(state->buffer)); + vstring_sprintf(state->buffer, "\t client-signature %s", + state->tls_context->clnt_sig_name); + if (state->tls_context->clnt_sig_curve + && *state->tls_context->clnt_sig_curve) + vstring_sprintf_append(state->buffer, " (%s%s)", state->tls_context->clnt_sig_curve, - state->tls_context->ctos_rpk ? - " raw public key" : ""); - else if (state->tls_context->clnt_sig_bits > 0) - vstring_sprintf_append(state->buffer, " (%d bit%s)", - state->tls_context->clnt_sig_bits, - state->tls_context->ctos_rpk ? - " raw public key" : "s"); - if (state->tls_context->clnt_sig_dgst - && *state->tls_context->clnt_sig_dgst) - vstring_sprintf_append(state->buffer, " client-digest %s", + state->tls_context->ctos_rpk ? + " raw public key" : ""); + else if (state->tls_context->clnt_sig_bits > 0) + vstring_sprintf_append(state->buffer, " (%d bit%s)", + state->tls_context->clnt_sig_bits, + state->tls_context->ctos_rpk ? + " raw public key" : "s"); + if (state->tls_context->clnt_sig_dgst + && *state->tls_context->clnt_sig_dgst) + vstring_sprintf_append(state->buffer, " client-digest %s", state->tls_context->clnt_sig_dgst); - } - out_fprintf(out_stream, REC_TYPE_NORM, "%s)", STR(state->buffer)); - if (TLS_CERT_IS_PRESENT(state->tls_context)) { - peer_CN = VSTRING_STRDUP(state->tls_context->peer_CN); - comment_sanitize(peer_CN); - issuer_CN = VSTRING_STRDUP(state->tls_context->issuer_CN ? + } + out_fprintf(out_stream, REC_TYPE_NORM, "%s)", STR(state->buffer)); + if (TLS_CERT_IS_PRESENT(state->tls_context)) { + peer_CN = VSTRING_STRDUP(state->tls_context->peer_CN); + comment_sanitize(peer_CN); + issuer_CN = VSTRING_STRDUP(state->tls_context->issuer_CN ? state->tls_context->issuer_CN : ""); - comment_sanitize(issuer_CN); - out_fprintf(out_stream, REC_TYPE_NORM, - "\t(Client CN \"%s\", Issuer \"%s\" (%s))", - STR(peer_CN), STR(issuer_CN), - TLS_CERT_IS_TRUSTED(state->tls_context) ? - "verified OK" : "not verified"); - vstring_free(issuer_CN); - vstring_free(peer_CN); - } else if (TLS_RPK_IS_PRESENT(state->tls_context)) { - out_fprintf(out_stream, REC_TYPE_NORM, - "\t(Client RPK %s digest %s)", - var_smtpd_tls_fpt_dgst, - state->tls_context->peer_pkey_fprint); - } else if (var_smtpd_tls_ask_ccert) - out_fprintf(out_stream, REC_TYPE_NORM, - "\t(Client did not present a certificate)"); - else - out_fprintf(out_stream, REC_TYPE_NORM, - "\t(No client certificate requested)"); - } - /* RFC 3848 is defined for ESMTP only. */ - if (state->tls_context != 0 - && strcmp(state->protocol, MAIL_PROTO_ESMTP) == 0) - rfc3848_sess = "S"; - else + comment_sanitize(issuer_CN); + out_fprintf(out_stream, REC_TYPE_NORM, + "\t(Client CN \"%s\", Issuer \"%s\" (%s))", + STR(peer_CN), STR(issuer_CN), + TLS_CERT_IS_TRUSTED(state->tls_context) ? + "verified OK" : "not verified"); + vstring_free(issuer_CN); + vstring_free(peer_CN); + } else if (TLS_RPK_IS_PRESENT(state->tls_context)) { + out_fprintf(out_stream, REC_TYPE_NORM, + "\t(Client RPK %s digest %s)", + var_smtpd_tls_fpt_dgst, + state->tls_context->peer_pkey_fprint); + } else if (var_smtpd_tls_ask_ccert) + out_fprintf(out_stream, REC_TYPE_NORM, + "\t(Client did not present a certificate)"); + else + out_fprintf(out_stream, REC_TYPE_NORM, + "\t(No client certificate requested)"); + } + /* RFC 3848 is defined for ESMTP only. */ + if (state->tls_context != 0 + && strcmp(state->protocol, MAIL_PROTO_ESMTP) == 0) + rfc3848_sess = "S"; #endif - rfc3848_sess = ""; #ifdef USE_SASL_AUTH - if (var_smtpd_sasl_auth_hdr && state->sasl_username) { - username = VSTRING_STRDUP(state->sasl_username); - comment_sanitize(username); - out_fprintf(out_stream, REC_TYPE_NORM, - "\t(Authenticated sender: %s)", STR(username)); - vstring_free(username); - } - /* RFC 3848 is defined for ESMTP only. */ - if (state->sasl_username - && strcmp(state->protocol, MAIL_PROTO_ESMTP) == 0) - rfc3848_auth = "A"; - else + if (var_smtpd_sasl_auth_hdr && state->sasl_username) { + username = VSTRING_STRDUP(state->sasl_username); + comment_sanitize(username); + out_fprintf(out_stream, REC_TYPE_NORM, + "\t(Authenticated sender: %s)", STR(username)); + vstring_free(username); + } + /* RFC 3848 is defined for ESMTP only. */ + if (state->sasl_username + && strcmp(state->protocol, MAIL_PROTO_ESMTP) == 0) + rfc3848_auth = "A"; #endif - rfc3848_auth = ""; + } else { + with_verb = ""; + with_protocol = ""; + } if (state->rcpt_count == 1 && state->recipient) { out_fprintf(out_stream, REC_TYPE_NORM, - state->cleanup ? "\tby %s (%s) with %s%s%s id %s" : - "\tby %s (%s) with %s%s%s", + "%sby %s (%s)%s%s%s%s%s%s", + var_smtpd_hide_client_session ? "Received: " : "\t", var_myhostname, var_mail_name, - with_protocol, rfc3848_sess, - rfc3848_auth, state->queue_id); + with_verb, with_protocol, rfc3848_sess, + rfc3848_auth, id_verb, id_value); quote_822_local(state->buffer, state->recipient); out_fprintf(out_stream, REC_TYPE_NORM, "\tfor <%s>; %s", STR(state->buffer), mail_date(state->arrival_time.tv_sec)); } else { out_fprintf(out_stream, REC_TYPE_NORM, - state->cleanup ? "\tby %s (%s) with %s%s%s id %s;" : - "\tby %s (%s) with %s%s%s;", + "%sby %s (%s)%s%s%s%s%s%s;", + var_smtpd_hide_client_session ? "Received: " : "\t", var_myhostname, var_mail_name, - with_protocol, rfc3848_sess, - rfc3848_auth, state->queue_id); + with_verb, with_protocol, rfc3848_sess, + rfc3848_auth, id_verb, id_value); out_fprintf(out_stream, REC_TYPE_NORM, "\t%s", mail_date(state->arrival_time.tv_sec)); } @@ -6790,6 +6800,7 @@ int main(int argc, char **argv) static const CONFIG_NBOOL_TABLE nbool_table[] = { VAR_RELAY_BEFORE_RCPT_CHECKS, DEF_RELAY_BEFORE_RCPT_CHECKS, &var_relay_before_rcpt_checks, VAR_SMTPD_REQ_DEADLINE, DEF_SMTPD_REQ_DEADLINE, &var_smtpd_req_deadline, + VAR_SMTPD_HIDE_CLIENT_SESSION, DEF_SMTPD_HIDE_CLIENT_SESSION, &var_smtpd_hide_client_session, 0, }; static const CONFIG_STR_TABLE str_table[] = {