2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-22 09:57:34 +00:00

postfix-3.10-20250129-nonprod

This commit is contained in:
Wietse Z Venema 2025-01-29 00:00:00 -05:00 committed by Viktor Dukhovni
parent 137e70673b
commit 6e36f53630
29 changed files with 508 additions and 60 deletions

View File

@ -28959,20 +28959,29 @@ Apologies for any names omitted.
Completed: simplified cleanup_envelope_test implementation.
TODO:
20250127
Add a log-only mode for REQUIRETLS, so that one can find out
how much would break. Maybe make it a map, so that different
sites can have different enforcement levels.
Cleanup: broken non-TLS builds because of a missing #ifdef
USE_TLS/#endif around a new function get_effective_tls_level().
File: smtp/smtp_connect.c.
If we support log-only REQUIRETLS, then don't panic ("can't
happen") when the code reaches a point that can't be reached
when REQUIRETLS is actually enforced.
Cleanup: a few remaining pre-ANSI C function definitions
in the lowest-level Postfix code. Files: util/binhash.c,
util/close_on_exec.c, util/non_blocking.c, util/ring.c.
20250129
Completed: smtp_enforce_requiretls list of next-hop domains
(or UNIX-domain pathnames) that are ready for REQUIRETLS
enforcement. This may help with gradual adoption.
TODO
Encapsulate the sendopts-to-cleanup-flags mapping.
How do we make it work with multi-instance SMTP-based content
filters? How is this different from the single-instance case?
filters? How is this different from the single-instance
case?
What REQUIRETLS expectations can we enforce when delivering
over a UNIX-domain channel? The SMTP/LMTP client currently

View File

@ -765,6 +765,13 @@ SMTP(8) SMTP(8)
Enable support for the ESMTP verb "REQUIRETLS", defined in <a href="https://tools.ietf.org/html/rfc8689">RFC</a>
<a href="https://tools.ietf.org/html/rfc8689">8689</a>.
<b><a href="postconf.5.html#smtp_enforce_requiretls">smtp_enforce_requiretls</a> (empty)</b>
An optional list of next-hop destinations that the Postfix
SMTP/LMTP client will enforce REQUIRETLS for, when a message was
received with the REQUIRETLS option: the next-hop server must
offer a matching TLS server certificate, and the server must
announce REQUIRETLS support).
<b><a name="obsolete_tls_controls">OBSOLETE TLS CONTROLS</a></b>
The following configuration parameters exist for compatibility with
Postfix versions before 2.3. Support for these will be removed in a

View File

@ -5041,6 +5041,17 @@ configuration parameter. See there for details. </p>
<p> This feature is available in Postfix 2.11 and later. </p>
</DD>
<DT><b><a name="lmtp_enforce_requiretls">lmtp_enforce_requiretls</a>
(default: empty)</b></DT><DD>
<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_enforce_requiretls">smtp_enforce_requiretls</a>
configuration parameter. See there for details. </p>
<p> This feature is available in Postfix &ge; 3.10. </p>
</DD>
<DT><b><a name="lmtp_enforce_tls">lmtp_enforce_tls</a>
@ -10585,7 +10596,16 @@ the <a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> pa
satisfies requirements. Otherwise, Postfix returns the message as
undeliverable. </p>
<p> Note: REQUIRETLS overrides "TLS-Required: no". </p>
<p> Notes: </p>
<ul>
<li> <p> REQUIRETLS enforcement is controlled with <a href="postconf.5.html#smtp_enforce_requiretls">smtp_enforce_requiretls</a>
or <a href="postconf.5.html#lmtp_enforce_requiretls">lmtp_enforce_requiretls</a>. </p>
<li> <p> REQUIRETLS overrides "TLS-Required: no". </p>
</ul>
<p> This feature is available in Postfix &ge; 3.10. </p>
@ -11921,6 +11941,86 @@ RES_USE_DNSSEC and RES_USE_EDNS0 resolver options. </p>
<p> This feature is available in Postfix 2.11 and later. </p>
</DD>
<DT><b><a name="smtp_enforce_requiretls">smtp_enforce_requiretls</a>
(default: empty)</b></DT><DD>
<p> An optional list of next-hop destinations that the Postfix
SMTP/LMTP client will enforce REQUIRETLS for, when a message was
received with the REQUIRETLS option: the next-hop server must offer
a matching TLS server certificate, and the server must announce
REQUIRETLS support). Such a message will be returned to the sender
if some REQUIRETLS requirement cannot be satisfied. These "hard"
REQUIRETLS failures are logged as "REQUIRETLS failure". </p>
<p> Other messages that were received with the REQUIRETLS option
will be delivered with REQUIRETLS if possible. If not, a message
will be delivered as if it was received without the REQUIRETLS
option. This allows a mail sending site to discover when REQUIRETLS
can be enforced, without disrupting email deliveries. These "soft"
REQUIRETLS failures are logged with "REQUIRETLS Debug". </p>
<p> On a perimeter MTA, it can make sense to turn off REQUIRETLS
enforcement, or even to turn off REQUIRETLS support, when delivering
a message to an internal destination. The internal servers may not
support REQUIRETLS, and their connections may be secured with means
other than DANE, STS, and the like. </p>
<p> The supported syntax differs with SMTP and LMTP: </p>
<ul>
<li> <p> With SMTP, specify a list of next-hop domain names (without
the ":port" or ":service" suffix), "/file/name" patterns or
"<a href="DATABASE_README.html">type:table</a>" lookup tables, separated by commas and/or whitespace.
Continue long lines by starting the next line with whitespace. A
"/file/name" pattern is replaced by its contents; a "<a href="DATABASE_README.html">type:table</a>"
lookup table is matched when a domain appears as lookup key. Specify
"!pattern" to exclude a domain from the list. </p>
<li> <p> With LMTP, specify list of domain names (without the "inet":
prefix, or ":port" or ":service" suffix), and/or UNIX-domain socket
"/path/name" (without the "unix:" prefix), separated by commas
and/or whitespace. Continue long lines by starting the next line
with whitespace. Specify "!pattern" to exclude a pattern from the
list. </p>
</ul>
<p> By default, specify the form ".domain" to match any name ending
in ".domain". This behavior is controlled by the presence or absence
of "<a href="postconf.5.html#smtp_enforce_requiretls">smtp_enforce_requiretls</a>" or "<a href="postconf.5.html#lmtp_enforce_requiretls">lmtp_enforce_requiretls</a>" in the
<a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a> parameter value (by default they
are absent). </p>
<p>
SMTP Examples:
</p>
<pre>
# Enforce REQUIRETLS for SMTP with selected next-hop domains.
<a href="postconf.5.html#smtp_enforce_requiretls">smtp_enforce_requiretls</a> = example.com, foo.example
<br>
# Enforce REQUIRETLS for SMTP with all but a few next-hop domains.
<a href="postconf.5.html#smtp_enforce_requiretls">smtp_enforce_requiretls</a> = !foo.example, <a href="DATABASE_README.html#types">static</a>:all
</pre>
<p>
LMTP examples:
</p>
<pre>
# Don't enforce REQUIRETLS
<a href="postconf.5.html#lmtp_enforce_requiretls">lmtp_enforce_requiretls</a> =
<br>
# Enforce REQUIRETLS for specific destinations.
<a href="postconf.5.html#lmtp_enforce_requiretls">lmtp_enforce_requiretls</a> = /path/to/socket, message-store.example
</pre>
<p> This feature is available in Postfix &ge; 3.10. </p>
</DD>
<DT><b><a name="smtp_enforce_tls">smtp_enforce_tls</a>

View File

@ -765,6 +765,13 @@ SMTP(8) SMTP(8)
Enable support for the ESMTP verb "REQUIRETLS", defined in <a href="https://tools.ietf.org/html/rfc8689">RFC</a>
<a href="https://tools.ietf.org/html/rfc8689">8689</a>.
<b><a href="postconf.5.html#smtp_enforce_requiretls">smtp_enforce_requiretls</a> (empty)</b>
An optional list of next-hop destinations that the Postfix
SMTP/LMTP client will enforce REQUIRETLS for, when a message was
received with the REQUIRETLS option: the next-hop server must
offer a matching TLS server certificate, and the server must
announce REQUIRETLS support).
<b><a name="obsolete_tls_controls">OBSOLETE TLS CONTROLS</a></b>
The following configuration parameters exist for compatibility with
Postfix versions before 2.3. Support for these will be removed in a

View File

@ -3136,6 +3136,11 @@ The LMTP\-specific version of the smtp_dns_support_level
configuration parameter. See there for details.
.PP
This feature is available in Postfix 2.11 and later.
.SH lmtp_enforce_requiretls (default: empty)
The LMTP\-specific version of the smtp_enforce_requiretls
configuration parameter. See there for details.
.PP
This feature is available in Postfix >= 3.10.
.SH lmtp_enforce_tls (default: no)
The LMTP\-specific version of the smtp_enforce_tls configuration
parameter. See there for details.
@ -6591,7 +6596,13 @@ the smtp_mx_address_limit parameter, until it finds a server that
satisfies requirements. Otherwise, Postfix returns the message as
undeliverable.
.PP
Note: REQUIRETLS overrides "TLS\-Required: no".
Notes:
.IP \(bu
REQUIRETLS enforcement is controlled with smtp_enforce_requiretls
or lmtp_enforce_requiretls.
.IP \(bu
REQUIRETLS overrides "TLS\-Required: no".
.br
.PP
This feature is available in Postfix >= 3.10.
.SH reset_owner_alias (default: no)
@ -7528,6 +7539,77 @@ reasonably\-modern DNS \fBresolver\fR(3) library that implements the
RES_USE_DNSSEC and RES_USE_EDNS0 resolver options.
.PP
This feature is available in Postfix 2.11 and later.
.SH smtp_enforce_requiretls (default: empty)
An optional list of next\-hop destinations that the Postfix
SMTP/LMTP client will enforce REQUIRETLS for, when a message was
received with the REQUIRETLS option: the next\-hop server must offer
a matching TLS server certificate, and the server must announce
REQUIRETLS support). Such a message will be returned to the sender
if some REQUIRETLS requirement cannot be satisfied. These "hard"
REQUIRETLS failures are logged as "REQUIRETLS failure".
.PP
Other messages that were received with the REQUIRETLS option
will be delivered with REQUIRETLS if possible. If not, a message
will be delivered as if it was received without the REQUIRETLS
option. This allows a mail sending site to discover when REQUIRETLS
can be enforced, without disrupting email deliveries. These "soft"
REQUIRETLS failures are logged with "REQUIRETLS Debug".
.PP
On a perimeter MTA, it can make sense to turn off REQUIRETLS
enforcement, or even to turn off REQUIRETLS support, when delivering
a message to an internal destination. The internal servers may not
support REQUIRETLS, and their connections may be secured with means
other than DANE, STS, and the like.
.PP
The supported syntax differs with SMTP and LMTP:
.IP \(bu
With SMTP, specify a list of next\-hop domain names (without
the ":port" or ":service" suffix), "/file/name" patterns or
"type:table" lookup tables, separated by commas and/or whitespace.
Continue long lines by starting the next line with whitespace. A
"/file/name" pattern is replaced by its contents; a "type:table"
lookup table is matched when a domain appears as lookup key. Specify
"!pattern" to exclude a domain from the list.
.IP \(bu
With LMTP, specify list of domain names (without the "inet":
prefix, or ":port" or ":service" suffix), and/or UNIX\-domain socket
"/path/name" (without the "unix:" prefix), separated by commas
and/or whitespace. Continue long lines by starting the next line
with whitespace. Specify "!pattern" to exclude a pattern from the
list.
.br
.PP
By default, specify the form ".domain" to match any name ending
in ".domain". This behavior is controlled by the presence or absence
of "smtp_enforce_requiretls" or "lmtp_enforce_requiretls" in the
parent_domain_matches_subdomains parameter value (by default they
are absent).
.PP
SMTP Examples:
.PP
.nf
.na
# Enforce REQUIRETLS for SMTP with selected next\-hop domains.
smtp_enforce_requiretls = example.com, foo.example
.br
# Enforce REQUIRETLS for SMTP with all but a few next\-hop domains.
smtp_enforce_requiretls = !foo.example, static:all
.fi
.ad
.PP
LMTP examples:
.PP
.nf
.na
# Don't enforce REQUIRETLS
lmtp_enforce_requiretls =
.br
# Enforce REQUIRETLS for specific destinations.
lmtp_enforce_requiretls = /path/to/socket, message\-store.example
.fi
.ad
.PP
This feature is available in Postfix >= 3.10.
.SH smtp_enforce_tls (default: no)
Enforcement mode: require that remote SMTP servers use TLS
encryption, and never send mail in the clear. This also requires

View File

@ -687,6 +687,12 @@ information to report).
.IP "\fBrequiretls_enable (yes)\fR"
Enable support for the ESMTP verb "REQUIRETLS", defined in RFC
8689.
.IP "\fBsmtp_enforce_requiretls (empty)\fR"
An optional list of next\-hop destinations that the Postfix
SMTP/LMTP client will enforce REQUIRETLS for, when a message was
received with the REQUIRETLS option: the next\-hop server must offer
a matching TLS server certificate, and the server must announce
REQUIRETLS support).
.SH "OBSOLETE TLS CONTROLS"
.na
.nf

View File

@ -1188,6 +1188,8 @@ while (<>) {
s;\btls_required_enable\b;<a href="postconf.5.html#tls_required_enable">$&</a>;g;
s;\brequiretls_enable\b;<a href="postconf.5.html#requiretls_enable">$&</a>;g;
s;\bsmtp_enforce_requiretls\b;<a href="postconf.5.html#smtp_enforce_requiretls">$&</a>;g;
s;\blmtp_enforce_requiretls\b;<a href="postconf.5.html#lmtp_enforce_requiretls">$&</a>;g;
s;\bfull_name_encoding_charset\b;<a href="postconf.5.html#full_name_encoding_charset">$&</a>;g;

View File

@ -19501,6 +19501,98 @@ the smtp_mx_address_limit parameter, until it finds a server that
satisfies requirements. Otherwise, Postfix returns the message as
undeliverable. </p>
<p> Note: REQUIRETLS overrides "TLS-Required: no". </p>
<p> Notes: </p>
<ul>
<li> <p> REQUIRETLS enforcement is controlled with smtp_enforce_requiretls
or lmtp_enforce_requiretls. </p>
<li> <p> REQUIRETLS overrides "TLS-Required: no". </p>
</ul>
<p> This feature is available in Postfix &ge; 3.10. </p>
%PARAM smtp_enforce_requiretls empty
<p> An optional list of next-hop destinations that the Postfix
SMTP/LMTP client will enforce REQUIRETLS for, when a message was
received with the REQUIRETLS option: the next-hop server must offer
a matching TLS server certificate, and the server must announce
REQUIRETLS support). Such a message will be returned to the sender
if some REQUIRETLS requirement cannot be satisfied. These "hard"
REQUIRETLS failures are logged as "REQUIRETLS failure". </p>
<p> Other messages that were received with the REQUIRETLS option
will be delivered with REQUIRETLS if possible. If not, a message
will be delivered as if it was received without the REQUIRETLS
option. This allows a mail sending site to discover when REQUIRETLS
can be enforced, without disrupting email deliveries. These "soft"
REQUIRETLS failures are logged with "REQUIRETLS Debug". </p>
<p> On a perimeter MTA, it can make sense to turn off REQUIRETLS
enforcement, or even to turn off REQUIRETLS support, when delivering
a message to an internal destination. The internal servers may not
support REQUIRETLS, and their connections may be secured with means
other than DANE, STS, and the like. </p>
<p> The supported syntax differs with SMTP and LMTP: </p>
<ul>
<li> <p> With SMTP, specify a list of next-hop domain names (without
the ":port" or ":service" suffix), "/file/name" patterns or
"type:table" lookup tables, separated by commas and/or whitespace.
Continue long lines by starting the next line with whitespace. A
"/file/name" pattern is replaced by its contents; a "type:table"
lookup table is matched when a domain appears as lookup key. Specify
"!pattern" to exclude a domain from the list. </p>
<li> <p> With LMTP, specify list of domain names (without the "inet":
prefix, or ":port" or ":service" suffix), and/or UNIX-domain socket
"/path/name" (without the "unix:" prefix), separated by commas
and/or whitespace. Continue long lines by starting the next line
with whitespace. Specify "!pattern" to exclude a pattern from the
list. </p>
</ul>
<p> By default, specify the form ".domain" to match any name ending
in ".domain". This behavior is controlled by the presence or absence
of "smtp_enforce_requiretls" or "lmtp_enforce_requiretls" in the
parent_domain_matches_subdomains parameter value (by default they
are absent). </p>
<p>
SMTP Examples:
</p>
<pre>
# Enforce REQUIRETLS for SMTP with selected next-hop domains.
smtp_enforce_requiretls = example.com, foo.example
<br>
# Enforce REQUIRETLS for SMTP with all but a few next-hop domains.
smtp_enforce_requiretls = !foo.example, static:all
</pre>
<p>
LMTP examples:
</p>
<pre>
# Don't enforce REQUIRETLS
lmtp_enforce_requiretls =
<br>
# Enforce REQUIRETLS for specific destinations.
lmtp_enforce_requiretls = /path/to/socket, message-store.example
</pre>
<p> This feature is available in Postfix &ge; 3.10. </p>
%PARAM lmtp_enforce_requiretls empty
<p> The LMTP-specific version of the smtp_enforce_requiretls
configuration parameter. See there for details. </p>
<p> This feature is available in Postfix &ge; 3.10. </p>

View File

@ -1858,3 +1858,4 @@ TINYCDB
getdata
XXXSENDOPTS
xtra
NODICT

View File

@ -42,6 +42,10 @@
/* Request that addr_match_list_match() logs a warning and
/* returns zero with list->error set to a non-zero dictionary
/* error code, instead of raising a fatal error.
/* .IP MATCH_FLAG_NOFILE
/* Disable special handling for /file/name.
/* .IP MATCH_FLAG_NODICT
/* Disable special handling for type:name.
/* .PP
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The last argument is a list of patterns, or the absolute
@ -67,6 +71,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* porcupine.org
/*--*/
/* System library. */

View File

@ -45,6 +45,10 @@
/* Request that domain_list_match() logs a warning and returns
/* zero, with list->error set to a non-zero dictionary error
/* code, instead of raising a fatal error.
/* .IP MATCH_FLAG_NOFILE
/* Disable special handling for /file/name.
/* .IP MATCH_FLAG_NODICT
/* Disable special handling for type:name.
/* .PP
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The last argument is a list of domain patterns, or the name of
@ -69,6 +73,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* porcupine.org
/*--*/
/* System library. */

View File

@ -4387,6 +4387,13 @@ extern int var_requiretls_enable;
#define DEF_TLSREQUIRED_ENABLE "yes"
extern int var_tls_required_enable;
#define VAR_SMTP_ENFORCE_REQUIRETLS "smtp_enforce_requiretls"
#define DEF_SMTP_ENFORCE_REQUIRETLS ""
extern char *var_smtp_enforce_requiretls;
#define VAR_LMTP_ENFORCE_REQUIRETLS "lmtp_enforce_requiretls"
#define DEF_LMTP_ENFORCE_REQUIRETLS ""
/*
* Workaround for future incompatibility. Our implementation of RFC 2308
* negative reply caching relies on the promise that res_query() and

View File

@ -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 "20250126"
#define MAIL_RELEASE_DATE "20250129"
#define MAIL_VERSION_NUMBER "3.10"
#ifdef SNAPSHOT

View File

@ -51,6 +51,10 @@
/* Request that namadr_list_match() logs a warning and returns
/* zero with list->error set to a non-zero dictionary error
/* code, instead of raising a fatal error.
/* .IP MATCH_FLAG_NOFILE
/* Disable special handling for /file/name.
/* .IP MATCH_FLAG_NODICT
/* Disable special handling for type:name.
/* .PP
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The last argument is a list of patterns, or the absolute
@ -75,6 +79,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* porcupine.org
/*--*/
/* System library. */

View File

@ -39,6 +39,10 @@
/* Request that string_list_match() logs a warning and returns
/* zero with list->error set to a non-zero dictionary error
/* code, instead of raising a fatal error.
/* .IP MATCH_FLAG_NOFILE
/* Disable special handling for /file/name.
/* .IP MATCH_FLAG_NODICT
/* Disable special handling for type:name.
/* .PP
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The last argument specifies a list of string patterns.
@ -61,6 +65,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* porcupine.org
/*--*/
/* System library. */

View File

@ -84,6 +84,7 @@ smtp.o: ../../include/deliver_request.h
smtp.o: ../../include/delivered_hdr.h
smtp.o: ../../include/dict.h
smtp.o: ../../include/dns.h
smtp.o: ../../include/domain_list.h
smtp.o: ../../include/dsn.h
smtp.o: ../../include/dsn_buf.h
smtp.o: ../../include/ext_prop.h
@ -134,6 +135,7 @@ smtp_addr.o: ../../include/check_arg.h
smtp_addr.o: ../../include/deliver_request.h
smtp_addr.o: ../../include/dict.h
smtp_addr.o: ../../include/dns.h
smtp_addr.o: ../../include/domain_list.h
smtp_addr.o: ../../include/dsn.h
smtp_addr.o: ../../include/dsn_buf.h
smtp_addr.o: ../../include/header_body_checks.h
@ -178,6 +180,7 @@ smtp_chat.o: ../../include/cleanup_user.h
smtp_chat.o: ../../include/deliver_request.h
smtp_chat.o: ../../include/dict.h
smtp_chat.o: ../../include/dns.h
smtp_chat.o: ../../include/domain_list.h
smtp_chat.o: ../../include/dsn.h
smtp_chat.o: ../../include/dsn_buf.h
smtp_chat.o: ../../include/dsn_util.h
@ -229,6 +232,7 @@ smtp_connect.o: ../../include/deliver_pass.h
smtp_connect.o: ../../include/deliver_request.h
smtp_connect.o: ../../include/dict.h
smtp_connect.o: ../../include/dns.h
smtp_connect.o: ../../include/domain_list.h
smtp_connect.o: ../../include/dsn.h
smtp_connect.o: ../../include/dsn_buf.h
smtp_connect.o: ../../include/header_body_checks.h
@ -284,6 +288,7 @@ smtp_key.o: ../../include/check_arg.h
smtp_key.o: ../../include/deliver_request.h
smtp_key.o: ../../include/dict.h
smtp_key.o: ../../include/dns.h
smtp_key.o: ../../include/domain_list.h
smtp_key.o: ../../include/dsn.h
smtp_key.o: ../../include/dsn_buf.h
smtp_key.o: ../../include/header_body_checks.h
@ -321,6 +326,7 @@ smtp_map11.o: ../../include/check_arg.h
smtp_map11.o: ../../include/deliver_request.h
smtp_map11.o: ../../include/dict.h
smtp_map11.o: ../../include/dns.h
smtp_map11.o: ../../include/domain_list.h
smtp_map11.o: ../../include/dsn.h
smtp_map11.o: ../../include/dsn_buf.h
smtp_map11.o: ../../include/header_body_checks.h
@ -361,6 +367,7 @@ smtp_misc.o: ../../include/check_arg.h
smtp_misc.o: ../../include/deliver_request.h
smtp_misc.o: ../../include/dict.h
smtp_misc.o: ../../include/dns.h
smtp_misc.o: ../../include/domain_list.h
smtp_misc.o: ../../include/dsn.h
smtp_misc.o: ../../include/dsn_buf.h
smtp_misc.o: ../../include/ext_prop.h
@ -404,6 +411,7 @@ smtp_proto.o: ../../include/defer.h
smtp_proto.o: ../../include/deliver_request.h
smtp_proto.o: ../../include/dict.h
smtp_proto.o: ../../include/dns.h
smtp_proto.o: ../../include/domain_list.h
smtp_proto.o: ../../include/dsn.h
smtp_proto.o: ../../include/dsn_buf.h
smtp_proto.o: ../../include/dsn_mask.h
@ -470,6 +478,7 @@ smtp_rcpt.o: ../../include/deliver_completed.h
smtp_rcpt.o: ../../include/deliver_request.h
smtp_rcpt.o: ../../include/dict.h
smtp_rcpt.o: ../../include/dns.h
smtp_rcpt.o: ../../include/domain_list.h
smtp_rcpt.o: ../../include/dsn.h
smtp_rcpt.o: ../../include/dsn_buf.h
smtp_rcpt.o: ../../include/dsn_mask.h
@ -510,6 +519,7 @@ smtp_reuse.o: ../../include/check_arg.h
smtp_reuse.o: ../../include/deliver_request.h
smtp_reuse.o: ../../include/dict.h
smtp_reuse.o: ../../include/dns.h
smtp_reuse.o: ../../include/domain_list.h
smtp_reuse.o: ../../include/dsn.h
smtp_reuse.o: ../../include/dsn_buf.h
smtp_reuse.o: ../../include/header_body_checks.h
@ -551,6 +561,7 @@ smtp_sasl_auth_cache.o: ../../include/deliver_request.h
smtp_sasl_auth_cache.o: ../../include/dict.h
smtp_sasl_auth_cache.o: ../../include/dict_proxy.h
smtp_sasl_auth_cache.o: ../../include/dns.h
smtp_sasl_auth_cache.o: ../../include/domain_list.h
smtp_sasl_auth_cache.o: ../../include/dsn.h
smtp_sasl_auth_cache.o: ../../include/dsn_buf.h
smtp_sasl_auth_cache.o: ../../include/dsn_util.h
@ -591,6 +602,7 @@ smtp_sasl_glue.o: ../../include/check_arg.h
smtp_sasl_glue.o: ../../include/deliver_request.h
smtp_sasl_glue.o: ../../include/dict.h
smtp_sasl_glue.o: ../../include/dns.h
smtp_sasl_glue.o: ../../include/domain_list.h
smtp_sasl_glue.o: ../../include/dsn.h
smtp_sasl_glue.o: ../../include/dsn_buf.h
smtp_sasl_glue.o: ../../include/header_body_checks.h
@ -636,6 +648,7 @@ smtp_sasl_proto.o: ../../include/check_arg.h
smtp_sasl_proto.o: ../../include/deliver_request.h
smtp_sasl_proto.o: ../../include/dict.h
smtp_sasl_proto.o: ../../include/dns.h
smtp_sasl_proto.o: ../../include/domain_list.h
smtp_sasl_proto.o: ../../include/dsn.h
smtp_sasl_proto.o: ../../include/dsn_buf.h
smtp_sasl_proto.o: ../../include/header_body_checks.h
@ -677,6 +690,7 @@ smtp_session.o: ../../include/debug_peer.h
smtp_session.o: ../../include/deliver_request.h
smtp_session.o: ../../include/dict.h
smtp_session.o: ../../include/dns.h
smtp_session.o: ../../include/domain_list.h
smtp_session.o: ../../include/dsn.h
smtp_session.o: ../../include/dsn_buf.h
smtp_session.o: ../../include/header_body_checks.h
@ -717,6 +731,7 @@ smtp_state.o: ../../include/debug_peer.h
smtp_state.o: ../../include/deliver_request.h
smtp_state.o: ../../include/dict.h
smtp_state.o: ../../include/dns.h
smtp_state.o: ../../include/domain_list.h
smtp_state.o: ../../include/dsn.h
smtp_state.o: ../../include/dsn_buf.h
smtp_state.o: ../../include/header_body_checks.h
@ -757,6 +772,7 @@ smtp_tls_policy.o: ../../include/ctable.h
smtp_tls_policy.o: ../../include/deliver_request.h
smtp_tls_policy.o: ../../include/dict.h
smtp_tls_policy.o: ../../include/dns.h
smtp_tls_policy.o: ../../include/domain_list.h
smtp_tls_policy.o: ../../include/dsn.h
smtp_tls_policy.o: ../../include/dsn_buf.h
smtp_tls_policy.o: ../../include/header_body_checks.h
@ -799,6 +815,7 @@ smtp_tlsrpt.o: ../../include/check_arg.h
smtp_tlsrpt.o: ../../include/deliver_request.h
smtp_tlsrpt.o: ../../include/dict.h
smtp_tlsrpt.o: ../../include/dns.h
smtp_tlsrpt.o: ../../include/domain_list.h
smtp_tlsrpt.o: ../../include/dsn.h
smtp_tlsrpt.o: ../../include/dsn_buf.h
smtp_tlsrpt.o: ../../include/header_body_checks.h
@ -843,6 +860,7 @@ smtp_trouble.o: ../../include/deliver_completed.h
smtp_trouble.o: ../../include/deliver_request.h
smtp_trouble.o: ../../include/dict.h
smtp_trouble.o: ../../include/dns.h
smtp_trouble.o: ../../include/domain_list.h
smtp_trouble.o: ../../include/dsn.h
smtp_trouble.o: ../../include/dsn_buf.h
smtp_trouble.o: ../../include/header_body_checks.h
@ -884,6 +902,7 @@ smtp_unalias.o: ../../include/check_arg.h
smtp_unalias.o: ../../include/deliver_request.h
smtp_unalias.o: ../../include/dict.h
smtp_unalias.o: ../../include/dns.h
smtp_unalias.o: ../../include/domain_list.h
smtp_unalias.o: ../../include/dsn.h
smtp_unalias.o: ../../include/dsn_buf.h
smtp_unalias.o: ../../include/header_body_checks.h

View File

@ -68,6 +68,7 @@
VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
VAR_USE_SRV_LOOKUP, DEF_USE_SRV_LOOKUP, &var_use_srv_lookup, 0, 0,
VAR_LMTP_TLSRPT_SOCKNAME, DEF_LMTP_TLSRPT_SOCKNAME, &var_smtp_tlsrpt_sockname, 0, 0,
VAR_LMTP_ENFORCE_REQUIRETLS, DEF_LMTP_ENFORCE_REQUIRETLS, &var_smtp_enforce_requiretls, 0, 0,
0,
};
static const CONFIG_TIME_TABLE lmtp_time_table[] = {

View File

@ -653,6 +653,12 @@
/* .IP "\fBrequiretls_enable (yes)\fR"
/* Enable support for the ESMTP verb "REQUIRETLS", defined in RFC
/* 8689.
/* .IP "\fBsmtp_enforce_requiretls (empty)\fR"
/* An optional list of next-hop destinations that the Postfix
/* SMTP/LMTP client will enforce REQUIRETLS for, when a message was
/* received with the REQUIRETLS option: the next-hop server must offer
/* a matching TLS server certificate, and the server must announce
/* REQUIRETLS support).
/* OBSOLETE TLS CONTROLS
/* .ad
/* .fi
@ -1020,6 +1026,8 @@
#include <maps.h>
#include <ext_prop.h>
#include <hfrom_format.h>
#include <domain_list.h>
#include <match_parent_style.h>
/* DNS library. */
@ -1164,6 +1172,7 @@ bool var_allow_srv_fallback;
bool var_smtp_tlsrpt_enable;
char *var_smtp_tlsrpt_sockname;
bool var_smtp_tlsrpt_skip_reused_hs;
char *var_smtp_enforce_requiretls;
/* Special handling of 535 AUTH errors. */
char *var_smtp_sasl_auth_cache_name;
@ -1191,6 +1200,7 @@ HBC_CHECKS *smtp_body_checks; /* limited body checks */
SMTP_CLI_ATTR smtp_cli_attr; /* parsed command-line */
int smtp_hfrom_format; /* postmaster notifications */
STRING_LIST *smtp_use_srv_lookup;
DOMAIN_LIST *smtp_enforce_requiretls;
#ifdef USE_TLS
@ -1692,6 +1702,23 @@ static void pre_init(char *unused_name, char **unused_argv)
if (*var_smtp_dns_re_filter)
dns_rr_filter_compile(VAR_LMTP_SMTP(DNS_RE_FILTER),
var_smtp_dns_re_filter);
/*
* REQUIRETLS enforcement uses a match list. No MATCH_FLAG_RETURN after
* table lookup error, because fail-open is not a good option. We would
* have to defer all delivery requests anyway. Disable magic syntax for
* LMTP, because the syntax would interfere with UNIX-domain socket
* pathnames.
*/
if (var_requiretls_enable && *var_smtp_enforce_requiretls) {
int flags = smtp_mode ? 0 : (MATCH_FLAG_NOFILE | MATCH_FLAG_NODICT);
const char *param_name = VAR_LMTP_SMTP(ENFORCE_REQUIRETLS);
smtp_enforce_requiretls =
string_list_init(param_name,
match_parent_style(param_name) | flags,
var_smtp_enforce_requiretls);
}
}
/* pre_accept - see if tables have changed */

View File

@ -32,6 +32,7 @@
#include <tok822.h>
#include <dsn_buf.h>
#include <header_body_checks.h>
#include <domain_list.h>
/*
* Postfix TLS library.
@ -200,6 +201,7 @@ typedef struct SMTP_STATE {
#ifdef USE_TLSRPT
struct TLSRPT_WRAPPER *tlsrpt;
#endif
int enforce_requiretls; /* from smtp_enforce_requiretls */
#endif
/*
@ -359,6 +361,7 @@ extern STRING_LIST *smtp_use_srv_lookup;/* services with SRV record lookup */
extern TLS_APPL_STATE *smtp_tls_ctx; /* client-side TLS engine */
extern int smtp_tls_insecure_mx_policy; /* DANE post insecure MX? */
extern DOMAIN_LIST *smtp_enforce_requiretls; /* parsed list */
#endif

View File

@ -106,6 +106,7 @@
#include <mail_addr.h>
#include <valid_hostname.h>
#include <sendopts.h>
#include <domain_list.h>
/* DNS library. */
@ -521,13 +522,24 @@ static int smtp_get_effective_tls_level(DSN_BUF *why, SMTP_STATE *state)
else if (var_requiretls_enable
&& (state->request->sendopts & SOPT_REQUIRETLS_ESMTP)) {
if (TLS_MUST_MATCH(tls->level) == 0) {
dsb_simple(why, "5.7.10", "Sender requires a TLS server "
"certificate match, but the configured %s TLS "
"security level '%s' does not support that. "
"The last attempted server was %s",
var_mail_name, str_tls_level(tls->level),
STR(iter->host));
return (0);
if (state->enforce_requiretls) {
dsb_simple(why, "5.7.10", "REQUIRETLS Failure: Sender "
"requires a TLS server certificate match, "
"but the configured %s TLS security level '%s' "
"does not support that. The last attempted "
"server was %s",
var_mail_name, str_tls_level(tls->level),
STR(iter->host));
return (0);
} else {
msg_info("REQUIRETLS Debug: Sender requires a TLS server "
"certificate match, but the configured %s TLS "
"security level '%s' does not support that. "
"The last attempted server was %s",
var_mail_name, str_tls_level(tls->level),
STR(iter->host));
return (0);
}
}
}
@ -576,6 +588,18 @@ static void smtp_connect_local(SMTP_STATE *state, const char *path)
if (state->misc_flags & SMTP_MISC_FLAG_CONN_CACHE_MASK)
SET_SCACHE_REQUEST_NEXTHOP(state, path);
/*
* REQUIRETLS enforcement is based on the UNIX-domain pathname, without
* the "unix:" prefix.
*/
#ifdef USE_TLS
state->enforce_requiretls =
(var_requiretls_enable
&& smtp_enforce_requiretls
&& (state->request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0
&& domain_list_match(smtp_enforce_requiretls, path));
#endif
/*
* Here we ensure that the iter->addr member refers to a copy of the
* UNIX-domain pathname, so that smtp_save_session() will cache the
@ -980,6 +1004,18 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
state->tlsrpt = 0;
#endif /* USE_TLSRPT */
/*
* REQUIRETLS enforcement is based on the next-hop domain name
* without the service or port.
*/
#ifdef USE_TLS
state->enforce_requiretls =
(var_requiretls_enable
&& smtp_enforce_requiretls
&& (state->request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0
&& domain_list_match(smtp_enforce_requiretls, domain));
#endif
/*
* Resolve an SMTP or LMTP server. Skip MX or SRV lookups when a
* quoted domain is specified or when DNS lookups are disabled.

View File

@ -69,6 +69,7 @@
VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
VAR_USE_SRV_LOOKUP, DEF_USE_SRV_LOOKUP, &var_use_srv_lookup, 0, 0,
VAR_SMTP_TLSRPT_SOCKNAME, DEF_SMTP_TLSRPT_SOCKNAME, &var_smtp_tlsrpt_sockname, 0, 0,
VAR_SMTP_ENFORCE_REQUIRETLS, DEF_SMTP_ENFORCE_REQUIRETLS, &var_smtp_enforce_requiretls, 0, 0,
0,
};
static const CONFIG_TIME_TABLE smtp_time_table[] = {

View File

@ -693,15 +693,24 @@ int smtp_helo(SMTP_STATE *state)
if (var_requiretls_enable
&& (request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0
&& (state->misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) != 0
&& (session->features & SMTP_FEATURE_REQUIRETLS) == 0)
return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
DSN_BY_LOCAL_MTA,
SMTP_RESP_FAKE(&fake, "5.7.30"),
"Sender requested delivery wth "
"REQUIRETLS, but no mail server was "
"found with REQUIRETLS support. The "
"last attempted server was %s",
session->namaddr));
&& (session->features & SMTP_FEATURE_REQUIRETLS) == 0) {
if (state->enforce_requiretls) {
return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
DSN_BY_LOCAL_MTA,
SMTP_RESP_FAKE(&fake, "5.7.30"),
"REQUIRETLS Failure: Sender requested "
"delivery wth REQUIRETLS, but no mail "
"server was found with REQUIRETLS "
"support. The last attempted server "
"was %s", session->namaddr));
} else {
msg_info("REQUIRETLS Debug: Sender requested delivery wth "
"REQUIRETLS, but no mail server was found with "
"REQUIRETLS support. The last attempted server was "
"%s", session->namaddr);
}
}
#endif
/*
@ -1221,14 +1230,22 @@ static int smtp_start_tls(SMTP_STATE *state)
*/
if (var_requiretls_enable
&& (state->request->sendopts & SOPT_REQUIRETLS_ESMTP)) {
return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
DSN_BY_LOCAL_MTA,
SMTP_RESP_FAKE(&fake, "5.7.10"),
"Sender requires a TLS server "
"certificate match, but no matching "
"mail server was found. The last "
"attempted server was %s",
session->namaddr));
if (state->enforce_requiretls) {
return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
DSN_BY_LOCAL_MTA,
SMTP_RESP_FAKE(&fake, "5.7.10"),
"REQUIRETLS Failure: Sender "
"requested a TLS server "
"certificate match, but no "
"match was found. The last "
"attempted server was %s",
session->namaddr));
} else {
msg_info("REQUIRETLS Debug: Sender requested a TLS "
"server certificate match, but no match was "
"found. The last attempted server was %s",
session->namaddr);
}
}
return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
SMTP_RESP_FAKE(&fake, "4.7.5"),
@ -1830,8 +1847,8 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
&& (request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0) {
if ((session->features & SMTP_FEATURE_REQUIRETLS) != 0)
vstring_strcat(next_command, " REQUIRETLS");
else if ((request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0)
msg_panic("Can't happen: message requires REQUIRETLS, but "
else if (state->enforce_requiretls)
msg_panic("Can't happen: must enforce REQUIRETLS, but "
"host %s did not announce REQUIRETLS support",
session->namaddr);
}

View File

@ -82,6 +82,9 @@ SMTP_STATE *smtp_state_alloc(void)
state->iterator->saved_dest = vstring_alloc(100);
#ifdef USE_TLSRPT
state->tlsrpt = 0;
#endif
#ifdef USE_TLS
state->enforce_requiretls = 0;
#endif
if (var_smtp_cache_conn) {
state->dest_label = vstring_alloc(10);

View File

@ -346,8 +346,7 @@ void binhash_walk(BINHASH *table, void (*action) (BINHASH_INFO *, void *),
/* binhash_list - list all table members */
BINHASH_INFO **binhash_list(table)
BINHASH *table;
BINHASH_INFO **binhash_list(BINHASH *table)
{
BINHASH_INFO **list;
BINHASH_INFO *member;

View File

@ -46,9 +46,7 @@
/* close_on_exec - set/clear close-on-exec flag */
int close_on_exec(fd, on)
int fd;
int on;
int close_on_exec(int fd, int on)
{
int flags;

View File

@ -60,6 +60,10 @@
/* Request that match_list_match() logs a warning and returns
/* zero (with list->error set to a non-zero dictionary error
/* code) instead of raising a fatal run-time error.
/* .IP MATCH_FLAG_NOFILE
/* Disable special handling for /file/name.
/* .IP MATCH_FLAG_NODICT
/* Disable special handling for type:name.
/* .RE
/* Specify MATCH_FLAG_NONE to request none of the above.
/* .IP pattern_list
@ -84,6 +88,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* porcupine.org
/*--*/
/* System library. */
@ -152,7 +159,8 @@ static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list,
if (*item == 0)
/* No graceful degradation for this... */
msg_fatal("%s: no pattern after '!'", match_list->pname);
if (*item == '/') { /* /file/name */
if (*item == '/' /* /file/name */
&& (match_list->flags & MATCH_FLAG_NOFILE) == 0) {
if ((fp = vstream_fopen(item, O_RDONLY, 0)) == 0) {
/* Replace unusable pattern with pseudo table. */
vstring_sprintf(buf, "%s:%s", DICT_TYPE_NOFILE, item);
@ -169,7 +177,8 @@ static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list,
if (vstream_fclose(fp))
msg_fatal("%s: read file %s: %m", myname, item);
}
} else if (MATCH_DICTIONARY(item)) { /* type:table */
} else if (MATCH_DICTIONARY(item) /* type:table */
&&(match_list->flags & MATCH_FLAG_NODICT) == 0) {
vstring_sprintf(buf, "%s%s(%o,%s)", match ? "" : "!",
item, OPEN_FLAGS, dict_flags_str(DICT_FLAGS));
map_type_name_flags = STR(buf) + (match == 0);

View File

@ -38,8 +38,10 @@ struct MATCH_LIST {
#define MATCH_FLAG_NONE 0
#define MATCH_FLAG_PARENT (1<<0)
#define MATCH_FLAG_RETURN (1<<1)
#define MATCH_FLAG_ALL (MATCH_FLAG_PARENT | MATCH_FLAG_RETURN)
#define MATCH_FLAG_NOFILE (1<<2)
#define MATCH_FLAG_NODICT (1<<3)
#define MATCH_FLAG_ALL (MATCH_FLAG_PARENT | MATCH_FLAG_RETURN | \
MATCH_FLAG_NOFILE | MATCH_FLAG_NODICT)
extern MATCH_LIST *match_list_init(const char *, int, const char *, int,...);
extern int match_list_match(MATCH_LIST *,...);
extern void match_list_free(MATCH_LIST *);

View File

@ -52,9 +52,7 @@
/* non_blocking - set/clear non-blocking flag */
int non_blocking(fd, on)
int fd;
int on;
int non_blocking(int fd, int on)
{
int flags;

View File

@ -76,17 +76,14 @@
/* ring_init - initialize ring head */
void ring_init(ring)
RING *ring;
void ring_init(RING *ring)
{
ring->pred = ring->succ = ring;
}
/* ring_append - insert entry after ring head */
void ring_append(ring, entry)
RING *ring;
RING *entry;
void ring_append(RING *ring, RING *entry)
{
entry->succ = ring->succ;
entry->pred = ring;
@ -96,9 +93,7 @@ RING *entry;
/* ring_prepend - insert new entry before ring head */
void ring_prepend(ring, entry)
RING *ring;
RING *entry;
void ring_prepend(RING *ring, RING *entry)
{
entry->pred = ring->pred;
entry->succ = ring;
@ -108,8 +103,7 @@ RING *entry;
/* ring_detach - remove entry from ring */
void ring_detach(entry)
RING *entry;
void ring_detach(RING *entry)
{
RING *succ = entry->succ;
RING *pred = entry->pred;