Also, I meant to put the d/changelog in the bug and forgot: postfix (3.5.13-0+deb11u1) bullseye; urgency=medium
[Scott Kitterman] * Update debian/watch to track v3.5 versions for stable updates * Refresh patches * Include compatibility_level in addition to postifx version when determining default value for chroot in master.cf. Closes: #995129 * Fixup errors in postifx-add-* man pages. Closes: #995031 * Update main/master.cf.proto on upgrade if not modified. Closes: #991513 * Update d/p/70_postfix-check.diff to exclude makedefs.out from synlink check. Closes: #926331 * Test that nothing is reported by postfix check in autopkgtest * Do not override user set default_transport in postinst. Closes: #988538 * Remove left-over ca-certificates.crt file from postfix chroot. Closes: #991609 * Add information about keeping resolv.conf up to date in the chroot with the resolvconf package. Closes: #964762 [Sergio Gelato] * Correct if-up.d to not error out if postfix can't send mail yet. Closes: #959864 [Miriam España Acebal] * Removed LDFLAG -Bsymbolic-functions to fix issue where TLS is disabled when private/tlmsgr socket is not found. lp: #1885403 [Paride Legovini] * d/postfix.postinst: tolerate search domain with a leading dot. Closes: #991950 [Wietse Venema] * 3.5.7 - Bugfix (introduced: Postfix 3.4, already fixed in Postfix 3.6): tlsproxy(8) was using the wrong DANE macro for connections with DANE trust anchors or with non-DANE trust anchors (WTF: Thorsten Habich found this bug in the use case that has nothing to do with DANE). This resulted in a global certificate verify function pointer race, between TLS handshakes that use TLS trust achors and handshakes that use PKI. No memory was corrupted in the course of all this. Viktor Dukhovni. File: tlsproxy/tlsproxy.c. - Cleanup: the posttls-finger '-X' option reported a false conflict with '-r'. File: posttls-finger/posttls-finger.c. * 3.5.8 - Bugfix (introduced: Postfix 2.0): smtp_sasl_mechanism_filter ignored table lookup errors, treating them as 'not found'. Found during Postfix 3.6 development. File: smtp/smtp_sasl_proto.c. - Bugfix (introduced: Postfix 2.3): when deleting a recipient with a milter, delete the recipient from the duplicate filter, so that the recipient can be added back. Backported from Postfix 3.6. Files: global/been_here.[hc], cleanup/cleanup_milter.c. - Bugfix (introduced: before Postfix alpha): the code that looks for Delivered-To: headers ignored headers longer than $line_length_limit. Backported from Postfix 3.6. File: global/delivered_hdr.c. - Bugfix (introduced: Postfix 2.8): save a copy of the postscreen_dnsbl_reply_map lookup result. This has no effect when the recommended texthash: look table is used, but it may avoid stale data with other lookup tables. File: postscreen/postscreen_dnsbl.c. - Bugfix (introduced: Postfix 2.2): after processing an XCCLIENT command, the smtps service was waiting for a TLS handshake. Found by Aki Tuomi. File: smtpd/smtpd.c. - Bugfix (introduced: Postfix 2.3): static maps did not free their casefolding buffer. File: util/dict_static.c. - Bugfix (introduced: Postfix 3.5): the Postfix SMTP client broke message headers longer than $line_length_limit, causing subsequent header content to become message body content. Reported by Andreas Weigel, fix by Viktor Dukhovni. File: smtp/smtp_proto.c. * 3.5.9 - Feature: when a Postfix program makes a DNS query that requests DNSSEC validation (usually for Postfix DANE support) but the DNS response is not DNSSEC validated, Postfix will send a DNS query configured with the "dnssec_probe" parameter to determine if DNSSEC support is available, and logs a warning if it is not. By default, the probe has type "ns" and domain name ".". The probe is sent once per process lifetime. Files: dns/dns.h, dns/dns_lookup.c, dns/dns_sec.c, test_dns_lookup.c, global/mail_params.[hc], mantools/postlink. - The default "smtp_tls_dane_insecure_mx_policy = dane" was causing unnecessary dnssec_probe activity. The default is now "dane" when smtp_tls_security_level is "dane", otherwise it is "may". File: global/mail_params.h. * 3.5.10 - Missing null pointer checks (introduced: Postfix 3.4) after an internal I/O error during the smtp(8) to tlsproxy(8) handshake. Found by Coverity, reported by Jaroslav Skarvada. Based on fix by Viktor Dukhovni. File: tls/tls_proxy_client_scan.c. - Null pointer bug (introduced: Postfix 3.0) and memory leak (introduced: Postfix 3.4) after an inline: table syntax error in main.cf or master.cf. Found by Coverity, reported by Jaroslav Skarvada. Based on fix by Viktor Dukhovni. File: util/dict_inline.c. - Incomplete null pointer check (introduced: Postfix 2.10) after truncated HaProxy version 1 handshake message. Found by Coverity, reported by Jaroslav Skarvada. Fix by Viktor Dukhovni. File: global/haproxy_srvr.c. - Missing null pointer check (introduced: Postfix alpha) after null argv[0] value. File: global/mail_task.c. * 3.5.11 - Bugfix (introduced: Postfix 2.11): the command "postmap lmdb:/file/name" handled duplicate keys ungracefully, discarding entries stored up to and including the duplicate key, and causing a double free() call with lmdb versions 0.9.17 and later. Reported by Adi Prasaja; double free() root cause analysis by Howard Chu. File: util/slmdb.c. - Typo (introduced: Postfix 3.4): silent_discard should be silent-discard. File: proto/BDAT_README.html. - Support for Postfix 3.6 compatibility_level syntax, to avoid fatal runtime errors when rolling back from Postfix 3.6 to an earlier supported version, or when sharing Postfix 3.6 configuration files with an earlier supported Postfix version. File: global/mail_params.c. * 3.5.12 - Bugfix (introduced: Postfix 3.4): the texthash: map implementation did not support "postmap -F" behavior. Reported by Christopher Gurnee, who also found the missing code in the postmap source. File: util/dict_thash.c. - Bugfix (introduced: 1999, Postfix 2.11) latent false "Result too large" (ERANGE) errors because an strtol() call had no 'errno = 0' statement before the call. Back-ported from Postfix 3.6. Files: postscreen/postscreen_tests.c, util/mac_expand.c. - Bugfix (introduced: Postfix 3.3): "null pointer read" error in the cleanup daemon when "header_from_format = standard" (the default as of Postfix 3.3) and email was submitted with /usr/sbin/sendmail without From: header, and an all-space full name was specified in 1) the password file, 2) with "sendmail -F", or 3) with the NAME environment variable. Found by Renaud Metrich. File: cleanup/cleanup_message.c. - Bugfix (introduced: 1999): the Postfix SMTP server was sending all session transcripts to the error_notice_recipient, instead of sending transcripts of bounced mail to the bounce_notice_recipient. File: smtpd/smtpd_chat.c. - Bugfix (introduced: Postfix 2.4): false "too many reverse jump" warnings in the showq daemon. The loop detection code was comparing memory addresses instead of queue file names. It now properly compares strings. Reported by Mehmet Avcioglu. File: global/record.c. * 3.5.13 - Bitrot: OpenSSL 3.x requires const. File: tls/tls_misc.c. - Bugfix (bug introduced: Postfix 2.10): postconf -x produced incorrect output, because different functions were implicitly sharing a buffer for intermediate results. Reported by raf, root cause analysis by Viktor Dukhovni. File: postconf/postconf_builtin.c. - Bugfix (problem introduced: Postfix 2.11): check_ccert_access worked as expected, but produced a spurious warning when Postfix was built without SASL support. Fix by Brad Barden. File: smtpd/smtpd_check.c. - Bugfix (introduced: Postfix 2.4): queue file corruption after a Milter (for example, MIMEDefang) made a request to replace the message body with a copy of that message body plus additional text (for example, a SpamAssassin report). The most likely impacts were a) the queue manager reporting a fatal error resulting in email delivery delays, or b) the queue manager reporting the corruption and moving the message to the corrupt queue for damaged messages. However, a determined adversary could craft an email message that would trigger the bug, and insert a content filter destination or a redirect email address into its queue file. Postfix would then deliver the message headers there, in most cases without delivering the message body. With enough experimentation, an attacker could make Postfix deliver both the message headers and body. The details of a successful attack depend on the Milter implementation, and on the Postfix and Milter configuration details; these can be determined remotely through experimentation. Failed experiments may be detected when the queue manager terminates with a fatal error, or when the queue manager moves damaged files to the "corrupt" queue as evidence. Technical details: when Postfix executes a "replace body" Milter request it will reuse queue file storage that was used by the existing email message body. If the new body is larger, Postfix will append body content to the end of the queue file. The corruption happened when a Milter (for example, MIMEDefang) made a request to replace the body of a message with a new body that contained a copy of the original body plus some new text, and the original body contained a line longer than $line_length_limit bytes (for example, an image encoded in base64 without hard or soft line breaks). In queue files, Postfix stores a long text line as multiple records with up to $line_length_limit bytes each. Unfortunately, Postfix's "replace body" support did not account for the additional queue file space needed to store the second etc. record headers. And thus, the last record(s) of a long text line could overwrite one or more queue file records immediately after the space that was previously occupied by the original message body. Problem report by Benoît Panizzon. * Fix duplicate bounce_notice_recipient entries in postconf output. Closes: #999694 Scott K
diff -Nru postfix-3.5.6/debian/changelog postfix-3.5.13/debian/changelog --- postfix-3.5.6/debian/changelog 2020-08-02 17:11:04.000000000 -0400 +++ postfix-3.5.13/debian/changelog 2022-01-07 00:14:16.000000000 -0500 @@ -1,3 +1,238 @@ +postfix (3.5.13-0+deb11u1) bullseye; urgency=medium + + [Scott Kitterman] + + * Update debian/watch to track v3.5 versions for stable updates + * Refresh patches + * Include compatibility_level in addition to postifx version when + determining default value for chroot in master.cf. Closes: #995129 + * Fixup errors in postifx-add-* man pages. Closes: #995031 + * Update main/master.cf.proto on upgrade if not modified. Closes: #991513 + * Update d/p/70_postfix-check.diff to exclude makedefs.out from synlink + check. Closes: #926331 + * Test that nothing is reported by postfix check in autopkgtest + * Do not override user set default_transport in postinst. Closes: #988538 + * Remove left-over ca-certificates.crt file from postfix chroot. + Closes: #991609 + * Add information about keeping resolv.conf up to date in the chroot with + the resolvconf package. Closes: #964762 + + [Sergio Gelato] + + * Correct if-up.d to not error out if postfix can't send mail yet. + Closes: #959864 + + [Miriam España Acebal] + + * Removed LDFLAG -Bsymbolic-functions to fix issue where TLS is disabled + when private/tlmsgr socket is not found. lp: #1885403 + + [Paride Legovini] + + * d/postfix.postinst: tolerate search domain with a leading dot. + Closes: #991950 + + [Wietse Venema] + + * 3.5.7 + - Bugfix (introduced: Postfix 3.4, already fixed in Postfix + 3.6): tlsproxy(8) was using the wrong DANE macro for + connections with DANE trust anchors or with non-DANE trust + anchors (WTF: Thorsten Habich found this bug in the use + case that has nothing to do with DANE). This resulted in a + global certificate verify function pointer race, between + TLS handshakes that use TLS trust achors and handshakes + that use PKI. No memory was corrupted in the course of all + this. Viktor Dukhovni. File: tlsproxy/tlsproxy.c. + + - Cleanup: the posttls-finger '-X' option reported a false + conflict with '-r'. File: posttls-finger/posttls-finger.c. + + * 3.5.8 + - Bugfix (introduced: Postfix 2.0): smtp_sasl_mechanism_filter + ignored table lookup errors, treating them as 'not found'. + Found during Postfix 3.6 development. File: smtp/smtp_sasl_proto.c. + + - Bugfix (introduced: Postfix 2.3): when deleting a recipient + with a milter, delete the recipient from the duplicate + filter, so that the recipient can be added back. Backported + from Postfix 3.6. Files: global/been_here.[hc], + cleanup/cleanup_milter.c. + + - Bugfix (introduced: before Postfix alpha): the code that + looks for Delivered-To: headers ignored headers longer than + $line_length_limit. Backported from Postfix 3.6. File: + global/delivered_hdr.c. + + - Bugfix (introduced: Postfix 2.8): save a copy of the + postscreen_dnsbl_reply_map lookup result. This has no effect + when the recommended texthash: look table is used, but it + may avoid stale data with other lookup tables. File: + postscreen/postscreen_dnsbl.c. + + - Bugfix (introduced: Postfix 2.2): after processing an + XCCLIENT command, the smtps service was waiting for a TLS + handshake. Found by Aki Tuomi. File: smtpd/smtpd.c. + + - Bugfix (introduced: Postfix 2.3): static maps did not free + their casefolding buffer. File: util/dict_static.c. + + - Bugfix (introduced: Postfix 3.5): the Postfix SMTP client + broke message headers longer than $line_length_limit, causing + subsequent header content to become message body content. + Reported by Andreas Weigel, fix by Viktor Dukhovni. File: + smtp/smtp_proto.c. + + * 3.5.9 + - Feature: when a Postfix program makes a DNS query that + requests DNSSEC validation (usually for Postfix DANE support) + but the DNS response is not DNSSEC validated, Postfix will + send a DNS query configured with the "dnssec_probe" parameter + to determine if DNSSEC support is available, and logs a + warning if it is not. By default, the probe has type "ns" + and domain name ".". The probe is sent once per process + lifetime. Files: dns/dns.h, dns/dns_lookup.c, dns/dns_sec.c, + test_dns_lookup.c, global/mail_params.[hc], mantools/postlink. + + - The default "smtp_tls_dane_insecure_mx_policy = dane" was + causing unnecessary dnssec_probe activity. The default is now + "dane" when smtp_tls_security_level is "dane", otherwise it is + "may". File: global/mail_params.h. + + * 3.5.10 + - Missing null pointer checks (introduced: Postfix 3.4) after + an internal I/O error during the smtp(8) to tlsproxy(8) + handshake. Found by Coverity, reported by Jaroslav Skarvada. + Based on fix by Viktor Dukhovni. File: tls/tls_proxy_client_scan.c. + + - Null pointer bug (introduced: Postfix 3.0) and memory leak + (introduced: Postfix 3.4) after an inline: table syntax + error in main.cf or master.cf. Found by Coverity, reported + by Jaroslav Skarvada. Based on fix by Viktor Dukhovni. File: + util/dict_inline.c. + + - Incomplete null pointer check (introduced: Postfix 2.10) + after truncated HaProxy version 1 handshake message. Found + by Coverity, reported by Jaroslav Skarvada. Fix by Viktor + Dukhovni. File: global/haproxy_srvr.c. + + - Missing null pointer check (introduced: Postfix alpha) after + null argv[0] value. File: global/mail_task.c. + + * 3.5.11 + - Bugfix (introduced: Postfix 2.11): the command "postmap + lmdb:/file/name" handled duplicate keys ungracefully, + discarding entries stored up to and including the duplicate + key, and causing a double free() call with lmdb versions + 0.9.17 and later. Reported by Adi Prasaja; double free() + root cause analysis by Howard Chu. File: util/slmdb.c. + + - Typo (introduced: Postfix 3.4): silent_discard should be + silent-discard. File: proto/BDAT_README.html. + + - Support for Postfix 3.6 compatibility_level syntax, to avoid + fatal runtime errors when rolling back from Postfix 3.6 to + an earlier supported version, or when sharing Postfix 3.6 + configuration files with an earlier supported Postfix + version. File: global/mail_params.c. + + * 3.5.12 + - Bugfix (introduced: Postfix 3.4): the texthash: map + implementation did not support "postmap -F" behavior. + Reported by Christopher Gurnee, who also found the missing + code in the postmap source. File: util/dict_thash.c. + + - Bugfix (introduced: 1999, Postfix 2.11) latent false "Result too + large" (ERANGE) errors because an strtol() call had no 'errno + = 0' statement before the call. Back-ported from Postfix 3.6. + Files: postscreen/postscreen_tests.c, util/mac_expand.c. + + - Bugfix (introduced: Postfix 3.3): "null pointer read" error + in the cleanup daemon when "header_from_format = standard" + (the default as of Postfix 3.3) and email was submitted + with /usr/sbin/sendmail without From: header, and an all-space + full name was specified in 1) the password file, 2) with + "sendmail -F", or 3) with the NAME environment variable. + Found by Renaud Metrich. File: cleanup/cleanup_message.c. + (Closes: #968057) + + - Bugfix (introduced: 1999): the Postfix SMTP server was + sending all session transcripts to the error_notice_recipient, + instead of sending transcripts of bounced mail to the + bounce_notice_recipient. File: smtpd/smtpd_chat.c. + + - Bugfix (introduced: Postfix 2.4): false "too many reverse + jump" warnings in the showq daemon. The loop detection code + was comparing memory addresses instead of queue file names. + It now properly compares strings. Reported by Mehmet Avcioglu. + File: global/record.c. + + * 3.5.13 + - Bitrot: OpenSSL 3.x requires const. File: tls/tls_misc.c. + + - Bugfix (bug introduced: Postfix 2.10): postconf -x produced + incorrect output, because different functions were implicitly + sharing a buffer for intermediate results. Reported + by raf, root cause analysis by Viktor Dukhovni. File: + postconf/postconf_builtin.c. + + - Bugfix (problem introduced: Postfix 2.11): check_ccert_access + worked as expected, but produced a spurious warning when + Postfix was built without SASL support. Fix by Brad Barden. + File: smtpd/smtpd_check.c. + + - Bugfix (introduced: Postfix 2.4): queue file corruption + after a Milter (for example, MIMEDefang) made a request to + replace the message body with a copy of that message body + plus additional text (for example, a SpamAssassin report). + + The most likely impacts were a) the queue manager reporting + a fatal error resulting in email delivery delays, or b) the + queue manager reporting the corruption and moving the message + to the corrupt queue for damaged messages. + + However, a determined adversary could craft an email message + that would trigger the bug, and insert a content filter + destination or a redirect email address into its queue file. + Postfix would then deliver the message headers there, in + most cases without delivering the message body. With enough + experimentation, an attacker could make Postfix deliver + both the message headers and body. + + The details of a successful attack depend on the Milter + implementation, and on the Postfix and Milter configuration + details; these can be determined remotely through + experimentation. Failed experiments may be detected when + the queue manager terminates with a fatal error, or when + the queue manager moves damaged files to the "corrupt" queue + as evidence. + + Technical details: when Postfix executes a "replace body" + Milter request it will reuse queue file storage that was + used by the existing email message body. If the new body + is larger, Postfix will append body content to the end of + the queue file. The corruption happened when a Milter (for + example, MIMEDefang) made a request to replace the body of + a message with a new body that contained a copy of the + original body plus some new text, and the original body + contained a line longer than $line_length_limit bytes (for + example, an image encoded in base64 without hard or soft + line breaks). In queue files, Postfix stores a long text + line as multiple records with up to $line_length_limit bytes + each. Unfortunately, Postfix's "replace body" support did + not account for the additional queue file space needed to + store the second etc. record headers. And thus, the last + record(s) of a long text line could overwrite one or more + queue file records immediately after the space that was + previously occupied by the original message body. + + Problem report by Benoît Panizzon. + + * Fix duplicate bounce_notice_recipient entries in postconf output. + Closes: #999694 + + -- Scott Kitterman <sc...@kitterman.com> Fri, 07 Jan 2022 00:14:16 -0500 + postfix (3.5.6-1) unstable; urgency=medium [Dominic Raferd] diff -Nru postfix-3.5.6/debian/configure-instance.sh postfix-3.5.13/debian/configure-instance.sh --- postfix-3.5.6/debian/configure-instance.sh 2020-08-02 17:05:47.000000000 -0400 +++ postfix-3.5.13/debian/configure-instance.sh 2022-01-07 00:07:24.000000000 -0500 @@ -36,7 +36,8 @@ config_dir=$($POSTCONF -hx config_directory) MAJOR_VER=$($POSTCONF -hx mail_version|cut -d. -f1) -[ $MAJOR_VER -ge 3 ] && CHROOT_TEST="[yY]" || CHROOT_TEST="[-yY]" +COMPAT=$($POSTCONF -xh compatibility_level|cut -d. -f1) +[ $MAJOR_VER -ge 3 ] && [ $COMPAT -ge 1 ] && CHROOT_TEST="[yY]" || CHROOT_TEST="[-yY]" # see if anything is running chrooted. NEED_CHROOT=$(awk '/^[0-9a-z]/ && ($5 ~ "'"$CHROOT_TEST"'") { print "y"; exit}' ${config_dir}/master.cf) diff -Nru postfix-3.5.6/debian/ip-up.d postfix-3.5.13/debian/ip-up.d --- postfix-3.5.6/debian/ip-up.d 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/ip-up.d 2022-01-07 00:07:24.000000000 -0500 @@ -38,6 +38,7 @@ # hanging around. Yes, sendmail is a symlink... if [ -n "$RUNNING" ]; then if [ -x /usr/sbin/sendmail ]; then - /usr/sbin/sendmail -q >/dev/null 2>&1 + # Don't propagate the exit code on failure; cf. #959864 + /usr/sbin/sendmail -q >/dev/null 2>&1 || true fi fi diff -Nru postfix-3.5.6/debian/patches/02_kfreebsd_support.diff postfix-3.5.13/debian/patches/02_kfreebsd_support.diff --- postfix-3.5.6/debian/patches/02_kfreebsd_support.diff 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/patches/02_kfreebsd_support.diff 2022-01-07 00:07:24.000000000 -0500 @@ -2,7 +2,7 @@ =================================================================== --- postfix.orig/makedefs +++ postfix/makedefs -@@ -608,7 +608,7 @@ EOF +@@ -595,7 +595,7 @@ EOF : ${SHLIB_ENV="LD_LIBRARY_PATH=`pwd`/lib"} : ${PLUGIN_LD="${CC-gcc} -shared"} ;; diff -Nru postfix-3.5.6/debian/patches/06_debian_paths.diff postfix-3.5.13/debian/patches/06_debian_paths.diff --- postfix-3.5.6/debian/patches/06_debian_paths.diff 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/patches/06_debian_paths.diff 2022-01-07 00:07:24.000000000 -0500 @@ -48,7 +48,7 @@ =================================================================== --- postfix.orig/makedefs +++ postfix/makedefs -@@ -509,11 +509,18 @@ case "$SYSTEM.$RELEASE" in +@@ -496,11 +496,18 @@ case "$SYSTEM.$RELEASE" in exit 1 fi SYSLIBS="-ldb" @@ -68,7 +68,7 @@ do test -e $lib/lib$name.a -o -e $lib/lib$name.so && { SYSLIBS="$SYSLIBS -l$name" -@@ -588,11 +595,18 @@ EOF +@@ -575,11 +582,18 @@ EOF exit 1 fi SYSLIBS="-ldb" @@ -88,7 +88,7 @@ do test -e $lib/lib$name.a -o -e $lib/lib$name.so && { SYSLIBS="$SYSLIBS -l$name" -@@ -626,11 +640,18 @@ EOF +@@ -613,11 +627,18 @@ EOF exit 1 fi SYSLIBS="-ldb" diff -Nru postfix-3.5.6/debian/patches/12_add_bind_now_and_relro_to_pie.diff postfix-3.5.13/debian/patches/12_add_bind_now_and_relro_to_pie.diff --- postfix-3.5.6/debian/patches/12_add_bind_now_and_relro_to_pie.diff 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/patches/12_add_bind_now_and_relro_to_pie.diff 2022-01-07 00:07:24.000000000 -0500 @@ -15,7 +15,7 @@ =================================================================== --- postfix.orig/makedefs +++ postfix/makedefs -@@ -1226,7 +1226,7 @@ case "$pie" in +@@ -1213,7 +1213,7 @@ case "$pie" in case " $CCARGS " in *" $CCARGS_PIE "*) CCARGS_PIE=;; esac diff -Nru postfix-3.5.6/debian/patches/70_postfix-check.diff postfix-3.5.13/debian/patches/70_postfix-check.diff --- postfix-3.5.6/debian/patches/70_postfix-check.diff 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/patches/70_postfix-check.diff 2022-01-07 00:07:24.000000000 -0500 @@ -1,8 +1,8 @@ -Index: postfix-dev/conf/postfix-script +Index: postfix/conf/postfix-script =================================================================== ---- postfix-dev.orig/conf/postfix-script 2019-03-01 11:47:22.941749233 -0500 -+++ postfix-dev/conf/postfix-script 2019-03-01 11:47:22.937749233 -0500 -@@ -341,9 +341,14 @@ +--- postfix.orig/conf/postfix-script ++++ postfix/conf/postfix-script +@@ -341,9 +341,17 @@ check-warn) find $todo ! -user root \ -exec $WARN not owned by root: {} \; @@ -12,7 +12,10 @@ -exec $WARN group or other writable: {} \; + find $todo -type l | while read f; do \ -+ readlink "$f" | grep -q / && $WARN symlink leaves directory: "$f"; \ ++ # makedefs out known to be a symlink and OK ++ if [ "$f" != "/etc/postfix/./makedefs.out" ]; then \ ++ readlink "$f" | grep -q / && $WARN symlink leaves directory: "$f"; \ ++ fi \ + done; \ + # Check Postfix mail_owner-owned directory tree owner/permissions. diff -Nru postfix-3.5.6/debian/patches/postfix-dup-postconf.patch postfix-3.5.13/debian/patches/postfix-dup-postconf.patch --- postfix-3.5.6/debian/patches/postfix-dup-postconf.patch 1969-12-31 19:00:00.000000000 -0500 +++ postfix-3.5.13/debian/patches/postfix-dup-postconf.patch 2022-01-07 00:07:24.000000000 -0500 @@ -0,0 +1,20 @@ +Description: Fix duplicate bounce_notice_recipient entries in postconf output. + Bug introduced on 2021-07-08. Reported by Vincent Lefevre. + https://marc.info/?l=postfix-users&m=163698504624352&w=2 +Bug-Debian: https://bugs.debian.org/999694 +Author: Wietse Venema <wie...@porcupine.org> +Last-Update: 2021-11-15 + +Index: postfix/src/smtpd/smtpd.c +=================================================================== +--- postfix.orig/src/smtpd/smtpd.c ++++ postfix/src/smtpd/smtpd.c +@@ -6419,7 +6419,7 @@ int main(int argc, char **argv) + VAR_EOD_CHECKS, DEF_EOD_CHECKS, &var_eod_checks, 0, 0, + VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0, + VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, 0, 0, +- VAR_BOUNCE_RCPT, DEF_ERROR_RCPT, &var_bounce_rcpt, 1, 0, ++ VAR_BOUNCE_RCPT, DEF_BOUNCE_RCPT, &var_bounce_rcpt, 1, 0, + VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0, + VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes, 0, 0, + VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0, diff -Nru postfix-3.5.6/debian/patches/series postfix-3.5.13/debian/patches/series --- postfix-3.5.6/debian/patches/series 2020-08-02 16:49:01.000000000 -0400 +++ postfix-3.5.13/debian/patches/series 2022-01-07 00:07:24.000000000 -0500 @@ -1,3 +1,4 @@ +postfix-dup-postconf.patch 02_kfreebsd_support.diff 03_ldap3_by_default.diff 04_remove_gdbm_support.diff diff -Nru postfix-3.5.6/debian/postfix-add-filter.8 postfix-3.5.13/debian/postfix-add-filter.8 --- postfix-3.5.6/debian/postfix-add-filter.8 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/postfix-add-filter.8 2022-01-07 00:07:24.000000000 -0500 @@ -13,8 +13,8 @@ .ad .fi The \fBpostfix-add-filter\fR(8) command adds an smtp service named -\fIsmtp service name\fR and and smtpd server listening on \fIsmtpd port\fR to -\/etc/postfix/master.cf to facilitate integration of SMTP filters such as +\fIsmtp service name\fR and an smtpd server listening on \fIsmtpd port\fR to +/etc/postfix/master.cf to facilitate integration of SMTP filters such as amavisd-new or clamsmtp. The configuration is based on the upstream recommendations for amavisd-new 2.6.0. Administrators should verify it is appropriate for their requirements. diff -Nru postfix-3.5.6/debian/postfix-add-policy.8 postfix-3.5.13/debian/postfix-add-policy.8 --- postfix-3.5.6/debian/postfix-add-policy.8 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/postfix-add-policy.8 2022-01-07 00:07:24.000000000 -0500 @@ -14,7 +14,7 @@ .fi The \fBpostfix-add-policy\fR(8) command adds an smtp policy server named \fIpolicy name\fR running using \fIusername\fR and called as \fIargv\fR to -\/etc/postfix/master.cf to facilitate integration of SMTP policy servers such as +/etc/postfix/master.cf to facilitate integration of SMTP policy servers such as postgrey or postfix-policyd-spf-perl. The configuration is based on the Postfix SMTPD_POLICY_README. Administrators should verify it is appropriate for their requirements. diff -Nru postfix-3.5.6/debian/postfix.postinst postfix-3.5.13/debian/postfix.postinst --- postfix-3.5.6/debian/postfix.postinst 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/postfix.postinst 2022-01-07 00:07:24.000000000 -0500 @@ -49,7 +49,7 @@ if [ $myhostname = ${myhostname%.*} ]; then if [ -f /etc/resolv.conf ]; then # The resolver uses the last one found, and ignores the rest - mydom=$(sed -n 's/^search[[:space:]]*\([^[:space:]]*\).*/\1/p;s/^domain[[:space:]]*\([^[:space:]]*\).*/\1/p' /etc/resolv.conf | tail -1) + mydom=$(sed -n 's/^search[[:space:]]*\.*\([^[:space:]]*\).*/\1/p;s/^domain[[:space:]]*\.*\([^[:space:]]*\).*/\1/p' /etc/resolv.conf | tail -1) myhostname="$myhostname${mydom:+.$mydom}" else myhostname="$myhostname.UNKNOWN" @@ -293,6 +293,14 @@ rmdir /etc/postfix/maildrop 2>/dev/null fi +# cleanup old ca-certificates.crt that should never have been in chroot #991609 +# can be removed after bookworm release +ca_bundle=/var/spool/postfix/etc/ssl/certs/ca-certificates.crt +if [ -f $ca_bundle ]; then + echo Removing unneeded chroot file $ca_bundle + rm -f $ca_bundle +fi + set_maildrop_perms postdrop if [ "$mailer" != "No configuration" ]; then # [ @@ -429,7 +437,11 @@ db_fget postfix/main_mailer_type changed if [ "$RET" = "true" ]; then - dtrans=smtp + # If the user has picked something other than sntp, keep it + dtrans=$(postconf -hx default_transport) + if [ $(postconf -hx default_transport) = error ]; then + dtrans=smtp + fi # already have mailer case "$mailer" in "Local only") val=loopback-only; dtrans=error;; @@ -578,9 +590,11 @@ # Make sure we have main/master.cf.proto for multi-inst (#838528) if [ ! -f /etc/postfix/main.cf.proto ]; then cp /usr/share/postfix/main.cf.dist /etc/postfix/main.cf.proto + rm -rf /etc/postfix/main.cf.proto.old fi if [ ! -f /etc/postfix/master.cf.proto ]; then cp /usr/share/postfix/master.cf.dist /etc/postfix/master.cf.proto + rm -rf /etc/postfix/master.cf.proto.old fi if [ "$mailer" != "No configuration" ] || [ -f /etc/postfix/main.cf ]; then diff -Nru postfix-3.5.6/debian/postfix.preinst postfix-3.5.13/debian/postfix.preinst --- postfix-3.5.6/debian/postfix.preinst 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/postfix.preinst 2022-01-07 00:07:24.000000000 -0500 @@ -269,6 +269,15 @@ rm -f /etc/postfix/postfix-script fi + # If user has not modified master/main.proto, move aside so new version + # is installed (#991513) + cmp -s /usr/share/postfix/main.cf.dist /etc/postfix/main.cf.proto && \ + mv /etc/postfix/main.cf.proto /etc/postfix/main.cf.proto.old \ + || echo "/etc/postfix/main.cf.proto modified, not updating." + cmp -s /usr/share/postfix/master.cf.dist /etc/postfix/master.cf.proto && \ + mv /etc/postfix/master.cf.proto /etc/postfix/master.cf.proto.old \ + || echo "/etc/postfix/master.cf.proto modified, not updating." + if grep -q '^tlsmgr[[:space:]]*fifo' $MASTER; then tlsmgr_warning fi @@ -335,6 +344,14 @@ ;; abort-upgrade) + if [ -f /etc/postfix/main.cf.proto.old ]; then + mv /etc/postfix/main.cf.proto.old /etc/postfix/main.cf.proto + echo "Restoring old /etc/postfix/main.cf.proto on failed upgrade." + fi + if [ -f /etc/postfix/master.cf.proto.old ]; then + mv /etc/postfix/master.cf.proto.old /etc/postfix/master.cf.proto + echo "Restoring old /etc/postfix/master.cf.proto on failed upgrade." + fi ;; *) diff -Nru postfix-3.5.6/debian/README.Debian postfix-3.5.13/debian/README.Debian --- postfix-3.5.6/debian/README.Debian 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/README.Debian 2022-01-07 00:07:24.000000000 -0500 @@ -32,6 +32,10 @@ described in the upstream documentation is order to problem integrate with Debian features such as using the system CA certificate bundle and proper chroot configuration with system libraries and services. +2A. In the standard Debian networking configuration, postfix is not notified + if /etc/resolv.conf is updated, so the copy in the postfix chroot may + become stale. Installation of the resolvconf package should prevent this + problem for networking configurations where it is an issue. 3. For policy reasons: a. SASL configuration goes in /etc/postfix/sasl b. myhostname=/path/to/file is supported (and used) in main.cf diff -Nru postfix-3.5.6/debian/rules postfix-3.5.13/debian/rules --- postfix-3.5.6/debian/rules 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/rules 2022-01-07 00:07:24.000000000 -0500 @@ -15,6 +15,7 @@ DISTRO:=$(shell (lsb_release -is 2>/dev/null || echo Debian) | sed s:Debian:Debian/GNU:) export DEB_BUILD_MAINT_OPTIONS = hardening=+all +export DEB_LDFLAGS_MAINT_STRIP = -Wl,-Bsymbolic-functions DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/buildflags.mk diff -Nru postfix-3.5.6/debian/tests/test-postfix.py postfix-3.5.13/debian/tests/test-postfix.py --- postfix-3.5.6/debian/tests/test-postfix.py 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/tests/test-postfix.py 2022-01-07 00:07:24.000000000 -0500 @@ -41,6 +41,19 @@ import unittest, subprocess, re, pexpect, smtplib, socket, os, time, tempfile import testlib +import sys +''' Test for postfix check output''' +result = subprocess.run(['postconf', 'maillog_file = /dev/stdout'], capture_output=True, text=True) +result = subprocess.run(['postfix', 'check'], capture_output=True, text=True) +if result.returncode != 0: + print('postfix check failed with error code: {0}.'.format(result.returncode)) + sys.exit(1) +if result.stdout: + print('postfix check warning/error: {0}'.format(result.stdout[26:])) + subprocess.run(['postconf', 'maillog_file ='], capture_output=True, text=True) + sys.exit(1) +subprocess.run(['postconf', 'maillog_file ='], capture_output=True, text=True) + class PostfixTest(testlib.TestlibCase): '''Test Postfix MTA.''' @@ -96,6 +109,7 @@ subprocess.call(['mkdir','-p','/var/run/saslauthd']) subprocess.call(['/usr/sbin/service', 'saslauthd', 'stop'], stdout=subprocess.PIPE) subprocess.call(['/usr/sbin/service', 'saslauthd', 'start'], stdout=subprocess.PIPE) + subprocess.call(['cp', '/etc/sasldb2', '/var/spool/postfix/etc/sasldb2']) def tearDown(self): '''Clean up after each test_* function''' diff -Nru postfix-3.5.6/debian/watch postfix-3.5.13/debian/watch --- postfix-3.5.6/debian/watch 2020-08-02 16:36:19.000000000 -0400 +++ postfix-3.5.13/debian/watch 2022-01-07 00:07:24.000000000 -0500 @@ -1,3 +1,3 @@ version=3 -opts=pasv,pgpsigurlmangle=s/$/.gpg2/ ftp://ftp.porcupine.org/mirrors/postfix-release/official/postfix-([\d+\.]+)\.tar\.gz +opts=pasv,pgpsigurlmangle=s/$/.gpg2/ ftp://ftp.porcupine.org/mirrors/postfix-release/official/postfix-(3.5.[\d+\.]+)\.tar\.gz diff -Nru postfix-3.5.6/HISTORY postfix-3.5.13/HISTORY --- postfix-3.5.6/HISTORY 2020-07-26 14:28:09.000000000 -0400 +++ postfix-3.5.13/HISTORY 2021-11-07 18:09:38.000000000 -0500 @@ -24819,3 +24819,239 @@ the system-wide OpenSSL configuration of allowed TLS protocol versions, for sessions where the remote SMTP client sends SNI. It's better to be safe than sorry. File: tls/tls_server.c. + +20200821 + + Bugfix (introduced: Postfix 3.4, already fixed in Postfix + 3.6): tlsproxy(8) was using the wrong DANE macro for + connections with DANE trust anchors or with non-DANE trust + anchors (WTF: Thorsten Habich found this bug in the use + case that has nothing to do with DANE). This resulted in a + global certificate verify function pointer race, between + TLS handshakes that use TLS trust achors and handshakes + that use PKI. No memory was corrupted in the course of all + this. Viktor Dukhovni. File: tlsproxy/tlsproxy.c. + + Cleanup: the posttls-finger '-X' option reported a false + conflict with '-r'. File: posttls-finger/posttls-finger.c. + +20200830 + + Bugfix (introduced: Postfix 2.0): smtp_sasl_mechanism_filter + ignored table lookup errors, treating them as 'not found'. + Found during Postfix 3.6 development. File: smtp/smtp_sasl_proto.c. + +202000920 + + Bugfix (introduced: Postfix 2.3): when deleting a recipient + with a milter, delete the recipient from the duplicate + filter, so that the recipient can be added back. Backported + from Postfix 3.6. Files: global/been_here.[hc], + cleanup/cleanup_milter.c. + +20200925 + + Bugfix (introduced: before Postfix alpha): the code that + looks for Delivered-To: headers ignored headers longer than + $line_length_limit. Backported from Postfix 3.6. File: + global/delivered_hdr.c. + +20201011 + + Bugfix (introduced: Postfix 2.8): save a copy of the + postscreen_dnsbl_reply_map lookup result. This has no effect + when the recommended texthash: look table is used, but it + may avoid stale data with other lookup tables. File: + postscreen/postscreen_dnsbl.c. + +20201022 + + Bugfix (introduced: Postfix 2.2): after processing an + XCCLIENT command, the smtps service was waiting for a TLS + handshake. Found by Aki Tuomi. File: smtpd/smtpd.c. + +20201025 + + Bugfix (introduced: Postfix 2.3): static maps did not free + their casefolding buffer. File: util/dict_static.c. + +20201104 + + Bugfix (introduced: Postfix 3.5): the Postfix SMTP client + broke message headers longer than $line_length_limit, causing + subsequent header content to become message body content. + Reported by Andreas Weigel, fix by Viktor Dukhovni. File: + smtp/smtp_proto.c. + +20210116 + + Feature: when a Postfix program makes a DNS query that + requests DNSSEC validation (usually for Postfix DANE support) + but the DNS response is not DNSSEC validated, Postfix will + send a DNS query configured with the "dnssec_probe" parameter + to determine if DNSSEC support is available, and logs a + warning if it is not. By default, the probe has type "ns" + and domain name ".". The probe is sent once per process + lifetime. Files: dns/dns.h, dns/dns_lookup.c, dns/dns_sec.c, + test_dns_lookup.c, global/mail_params.[hc], mantools/postlink. + + The makedefs script no longer disables DNSSEC when Postfix + is built with libc-musl. Instead Postfix will rely on the + new dnssec_probe feature, and will log a warning when Postfix + requests DNSSEC validation, but the infrastructure does not + validate DNSSEC signatures. File: makedefs. + + The default "smtp_tls_dane_insecure_mx_policy = dane" was + causing unnecessary dnssec_probe activity. The default is now + "dane" when smtp_tls_security_level is "dane", otherwise it is + "may". File: global/mail_params.h. + +20210411 + + Missing null pointer checks (introduced: Postfix 3.4) after + an internal I/O error during the smtp(8) to tlsproxy(8) + handshake. Found by Coverity, reported by Jaroslav Skarvada. + Based on fix by Viktor Dukhovni. File: tls/tls_proxy_client_scan.c. + + Null pointer bug (introduced: Postfix 3.0) and memory leak + (introduced: Postfix 3.4) after an inline: table syntax + error in main.cf or master.cf. Found by Coverity, reported + by Jaroslav Skarvada. Based on fix by Viktor Dukhovni. File: + util/dict_inline.c. + + Incomplete null pointer check (introduced: Postfix 2.10) + after truncated HaProxy version 1 handshake message. Found + by Coverity, reported by Jaroslav Skarvada. Fix by Viktor + Dukhovni. File: global/haproxy_srvr.c. + + Missing null pointer check (introduced: Postfix alpha) after + null argv[0] value. File: global/mail_task.c. + +20210601 + + Bugfix (introduced: Postfix 2.11): the command "postmap + lmdb:/file/name" handled duplicate keys ungracefully, + discarding entries stored up to and including the duplicate + key, and causing a double free() call with lmdb versions + 0.9.17 and later. Reported by Adi Prasaja; double free() + root cause analysis by Howard Chu. File: util/slmdb.c. + +20210609 + + Typo (introduced: Postfix 3.4): silent_discard should be + silent-discard. File: proto/BDAT_README.html. + +20210612 + + Support for Postfix 3.6 compatibility_level syntax, to avoid + fatal runtime errors when rolling back from Postfix 3.6 to + an earlier supported version, or when sharing Postfix 3.6 + configuration files with an earlier supported Postfix + version. File: global/mail_params.c. + +20210615 + + Bugfix (introduced: Postfix 3.4): the texthash: map + implementation did not support "postmap -F" behavior. + Reported by Christopher Gurnee, who also found the missing + code in the postmap source. File: util/dict_thash.c. + +20210623 + + Bugfix (introduced: 1999, Postfix 2.11) latent false "Result too + large" (ERANGE) errors because an strtol() call had no 'errno + = 0' statement before the call. Back-ported from Postfix 3.6. + Files: postscreen/postscreen_tests.c, util/mac_expand.c. + +20210705 + + Bugfix (introduced: Postfix 3.3): "null pointer read" error + in the cleanup daemon when "header_from_format = standard" + (the default as of Postfix 3.3) and email was submitted + with /usr/sbin/sendmail without From: header, and an all-space + full name was specified in 1) the password file, 2) with + "sendmail -F", or 3) with the NAME environment variable. + Found by Renaud Metrich. File: cleanup/cleanup_message.c. + +20210708 + + Bugfix (introduced: 1999): the Postfix SMTP server was + sending all session transcripts to the error_notice_recipient, + instead of sending transcripts of bounced mail to the + bounce_notice_recipient. File: smtpd/smtpd_chat.c. + +20210713 + + Bugfix (introduced: Postfix 2.4): false "too many reverse + jump" warnings in the showq daemon. The loop detection code + was comparing memory addresses instead of queue file names. + It now properly compares strings. Reported by Mehmet Avcioglu. + File: global/record.c. + +20210811 + + Bitrot: OpenSSL 3.x requires const. File: tls/tls_misc.c. + +20210925 + + Bugfix (bug introduced: Postfix 2.10): postconf -x produced + incorrect output, because different functions were implicitly + sharing a buffer for intermediate results. Reported + by raf, root cause analysis by Viktor Dukhovni. File: + postconf/postconf_builtin.c. + +20211030 + + Bugfix (problem introduced: Postfix 2.11): check_ccert_access + worked as expected, but produced a spurious warning when + Postfix was built without SASL support. Fix by Brad Barden. + File: smtpd/smtpd_check.c. + +20211105 + + Bugfix (introduced: Postfix 2.4): queue file corruption + after a Milter (for example, MIMEDefang) made a request to + replace the message body with a copy of that message body + plus additional text (for example, a SpamAssassin report). + + The most likely impacts were a) the queue manager reporting + a fatal error resulting in email delivery delays, or b) the + queue manager reporting the corruption and moving the message + to the corrupt queue for damaged messages. + + However, a determined adversary could craft an email message + that would trigger the bug, and insert a content filter + destination or a redirect email address into its queue file. + Postfix would then deliver the message headers there, in + most cases without delivering the message body. With enough + experimentation, an attacker could make Postfix deliver + both the message headers and body. + + The details of a successful attack depend on the Milter + implementation, and on the Postfix and Milter configuration + details; these can be determined remotely through + experimentation. Failed experiments may be detected when + the queue manager terminates with a fatal error, or when + the queue manager moves damaged files to the "corrupt" queue + as evidence. + + Technical details: when Postfix executes a "replace body" + Milter request it will reuse queue file storage that was + used by the existing email message body. If the new body + is larger, Postfix will append body content to the end of + the queue file. The corruption happened when a Milter (for + example, MIMEDefang) made a request to replace the body of + a message with a new body that contained a copy of the + original body plus some new text, and the original body + contained a line longer than $line_length_limit bytes (for + example, an image encoded in base64 without hard or soft + line breaks). In queue files, Postfix stores a long text + line as multiple records with up to $line_length_limit bytes + each. Unfortunately, Postfix's "replace body" support did + not account for the additional queue file space needed to + store the second etc. record headers. And thus, the last + record(s) of a long text line could overwrite one or more + queue file records immediately after the space that was + previously occupied by the original message body. + + Problem report by Benoît Panizzon. diff -Nru postfix-3.5.6/html/BDAT_README.html postfix-3.5.13/html/BDAT_README.html --- postfix-3.5.6/html/BDAT_README.html 2019-02-10 17:47:44.000000000 -0500 +++ postfix-3.5.13/html/BDAT_README.html 2021-06-13 15:02:04.000000000 -0400 @@ -51,7 +51,7 @@ # The logging alternative: <a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = chunking # The non-logging alternative: - <a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = chunking, silent_discard + <a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = chunking, silent-discard </pre> </blockquote> diff -Nru postfix-3.5.6/html/lmtp.8.html postfix-3.5.13/html/lmtp.8.html --- postfix-3.5.6/html/lmtp.8.html 2020-03-08 11:09:09.000000000 -0400 +++ postfix-3.5.13/html/lmtp.8.html 2021-01-16 18:19:54.000000000 -0500 @@ -365,6 +365,13 @@ The email address form that will be used in non-debug logging (info, warning, etc.). + Available in Postfix 3.5.9 and later: + + <b><a href="postconf.5.html#dnssec_probe">dnssec_probe</a> (ns:.)</b> + The DNS query type (default: "ns") and DNS query name (default: + ".") that Postfix may use to determine whether DNSSEC validation + is available. + <b>MIME PROCESSING CONTROLS</b> Available in Postfix version 2.0 and later: diff -Nru postfix-3.5.6/html/postconf.5.html postfix-3.5.13/html/postconf.5.html --- postfix-3.5.6/html/postconf.5.html 2020-05-09 11:51:27.000000000 -0400 +++ postfix-3.5.13/html/postconf.5.html 2021-01-17 10:10:20.000000000 -0500 @@ -3031,6 +3031,66 @@ </DD> +<DT><b><a name="dnssec_probe">dnssec_probe</a> +(default: ns:.)</b></DT><DD> + +<p> The DNS query type (default: "ns") and DNS query name (default: +".") that Postfix may use to determine whether DNSSEC validation +is available. +</p> + +<p> Background: DNSSEC validation is needed for Postfix DANE support; +this ensures that Postfix receives TLSA records with secure TLS +server certificate info. When DNSSEC validation is unavailable, +mail deliveries using <i>opportunistic</i> DANE will not be protected +by server certificate info in TLSA records, and mail deliveries +using <i>mandatory</i> DANE will not be made at all. </p> + +<p> By default, a Postfix process will send a DNSSEC probe after +1) the process made a DNS query that requested DNSSEC validation, +2) the process did not receive a DNSSEC validated response to this +query or to an earlier query, and 3) the process did not already +send a DNSSEC probe. <p> + +<p> When the DNSSEC probe has no response, or when the response is +not DNSSEC validated, Postfix logs a warning that DNSSEC validation +may be unavailable. </p> + +<p> Example: </p> + +<pre> +warning: DNSSEC validation may be unavailable +warning: reason: <a href="postconf.5.html#dnssec_probe">dnssec_probe</a> 'ns:.' received a response that is not DNSSEC validated +warning: reason: <a href="postconf.5.html#dnssec_probe">dnssec_probe</a> 'ns:.' received no response: Server failure +</pre> + +<p> Possible reasons why DNSSEC validation may be unavailable: </p> + +<ul> + +<li> The local /etc/resolv.conf file specifies a DNS resolver that +does not validate DNSSEC signatures (that's +$<a href="postconf.5.html#queue_directory">queue_directory</a>/etc/resolv.conf when a Postfix daemon runs in a +chroot jail). + +<li> The local system library does not pass on the "DNSSEC validated" +bit to Postfix, or Postfix does not know how to ask the library to +do that. + +</ul> + +<p> By default, the DNSSEC probe asks for the DNS root zone NS +records, because resolvers should always have that information +cached. If Postfix runs on a network where the DNS root zone is not +reachable, specify a different probe, or specify an empty <a href="postconf.5.html#dnssec_probe">dnssec_probe</a> +value to disable the feature. </p> + +<p> This feature was backported from Postfix 3.6 to Postfix versions +3.5.9, 3.4.19, 3.3.16. 3.2.21. </p> + + +</DD> + <DT><b><a name="dont_remove">dont_remove</a> (default: 0)</b></DT><DD> @@ -12377,7 +12437,7 @@ </DD> <DT><b><a name="smtp_tls_dane_insecure_mx_policy">smtp_tls_dane_insecure_mx_policy</a> -(default: dane)</b></DT><DD> +(default: see "postconf -d" output)</b></DT><DD> <p> The TLS policy for MX hosts with "secure" TLSA records when the nexthop destination security level is <b>dane</b>, but the MX @@ -12401,6 +12461,12 @@ "Verified", because the MX host name could have been forged. </dd> </dl> +<p> The default setting for Postfix ≥ 3.6 is "dane" with +"<a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = dane", otherwise "may". This behavior +was backported to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21. +With earlier +Postfix versions the default setting was always "dane". </p> + <p> Though with "insecure" MX records an active attacker can compromise SMTP transport security by returning forged MX records, such attacks are "tamper-evident" since any forged MX hostnames diff -Nru postfix-3.5.6/html/smtp.8.html postfix-3.5.13/html/smtp.8.html --- postfix-3.5.6/html/smtp.8.html 2020-03-08 11:09:09.000000000 -0400 +++ postfix-3.5.13/html/smtp.8.html 2021-01-16 18:19:54.000000000 -0500 @@ -365,6 +365,13 @@ The email address form that will be used in non-debug logging (info, warning, etc.). + Available in Postfix 3.5.9 and later: + + <b><a href="postconf.5.html#dnssec_probe">dnssec_probe</a> (ns:.)</b> + The DNS query type (default: "ns") and DNS query name (default: + ".") that Postfix may use to determine whether DNSSEC validation + is available. + <b>MIME PROCESSING CONTROLS</b> Available in Postfix version 2.0 and later: diff -Nru postfix-3.5.6/makedefs postfix-3.5.13/makedefs --- postfix-3.5.6/makedefs 2020-05-06 10:10:47.000000000 -0400 +++ postfix-3.5.13/makedefs 2021-01-16 10:10:00.000000000 -0500 @@ -228,19 +228,6 @@ *) echo usage: $0 [system release] 1>&2; exit 1;; esac -case "$SYSTEM" in - Linux) - case "`PATH=/bin:/usr/bin ldd /bin/sh`" in - *-musl-*) - case "$CCARGS" in - *-DNO_DNSSEC*) ;; - *) echo Warning: libc-musl breaks DANE/TLSA security. 1>&2 - echo This build will not support DANE/TLSA. 1>&2 - CCARGS="$CCARGS -DNO_DNSSEC";; - esac;; - esac;; -esac - case "$SYSTEM.$RELEASE" in SCO_SV.3.2) SYSTYPE=SCO5 # Use the native compiler by default diff -Nru postfix-3.5.6/man/man5/postconf.5 postfix-3.5.13/man/man5/postconf.5 --- postfix-3.5.6/man/man5/postconf.5 2020-05-09 11:52:30.000000000 -0400 +++ postfix-3.5.13/man/man5/postconf.5 2021-01-17 10:10:20.000000000 -0500 @@ -1897,6 +1897,60 @@ service performs DNS white/blacklist lookups. .PP This feature is available in Postfix 2.8 and later. +.SH dnssec_probe (default: ns:.) +The DNS query type (default: "ns") and DNS query name (default: +".") that Postfix may use to determine whether DNSSEC validation +is available. +.PP +Background: DNSSEC validation is needed for Postfix DANE support; +this ensures that Postfix receives TLSA records with secure TLS +server certificate info. When DNSSEC validation is unavailable, +mail deliveries using \fIopportunistic\fR DANE will not be protected +by server certificate info in TLSA records, and mail deliveries +using \fImandatory\fR DANE will not be made at all. +.PP +By default, a Postfix process will send a DNSSEC probe after +1) the process made a DNS query that requested DNSSEC validation, +2) the process did not receive a DNSSEC validated response to this +query or to an earlier query, and 3) the process did not already +send a DNSSEC probe. +.PP +When the DNSSEC probe has no response, or when the response is +not DNSSEC validated, Postfix logs a warning that DNSSEC validation +may be unavailable. +.PP +Example: +.PP +.nf +.na +.ft C +warning: DNSSEC validation may be unavailable +warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated +warning: reason: dnssec_probe 'ns:.' received no response: Server failure +.fi +.ad +.ft R +.PP +Possible reasons why DNSSEC validation may be unavailable: +.IP \(bu +The local /etc/resolv.conf file specifies a DNS resolver that +does not validate DNSSEC signatures (that's +$queue_directory/etc/resolv.conf when a Postfix daemon runs in a +chroot jail). +.IP \(bu +The local system library does not pass on the "DNSSEC validated" +bit to Postfix, or Postfix does not know how to ask the library to +do that. +.br +.PP +By default, the DNSSEC probe asks for the DNS root zone NS +records, because resolvers should always have that information +cached. If Postfix runs on a network where the DNS root zone is not +reachable, specify a different probe, or specify an empty dnssec_probe +value to disable the feature. +.PP +This feature was backported from Postfix 3.6 to Postfix versions +3.5.9, 3.4.19, 3.3.16. 3.2.21. .SH dont_remove (default: 0) Don't remove queue files and save them to the "saved" mail queue. This is a debugging aid. To inspect the envelope information and @@ -7921,7 +7975,7 @@ TLS connection reuse" for background details. .PP This feature is available in Postfix 3.4 and later. -.SH smtp_tls_dane_insecure_mx_policy (default: dane) +.SH smtp_tls_dane_insecure_mx_policy (default: see "postconf \-d" output) The TLS policy for MX hosts with "secure" TLSA records when the nexthop destination security level is \fBdane\fR, but the MX record was found via an "insecure" MX lookup. The choices are: @@ -7942,6 +7996,12 @@ "Verified", because the MX host name could have been forged. .br .br +The default setting for Postfix >= 3.6 is "dane" with +"smtp_tls_security_level = dane", otherwise "may". This behavior +was backported to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21. +With earlier +Postfix versions the default setting was always "dane". +.PP Though with "insecure" MX records an active attacker can compromise SMTP transport security by returning forged MX records, such attacks are "tamper\-evident" since any forged MX hostnames diff -Nru postfix-3.5.6/man/man8/smtp.8 postfix-3.5.13/man/man8/smtp.8 --- postfix-3.5.6/man/man8/smtp.8 2020-03-08 11:09:08.000000000 -0400 +++ postfix-3.5.13/man/man8/smtp.8 2021-01-16 18:19:54.000000000 -0500 @@ -356,6 +356,12 @@ .IP "\fBinfo_log_address_format (external)\fR" The email address form that will be used in non\-debug logging (info, warning, etc.). +.PP +Available in Postfix 3.5.9 and later: +.IP "\fBdnssec_probe (ns:.)\fR" +The DNS query type (default: "ns") and DNS query name (default: +".") that Postfix may use to determine whether DNSSEC validation +is available. .SH "MIME PROCESSING CONTROLS" .na .nf diff -Nru postfix-3.5.6/mantools/postlink postfix-3.5.13/mantools/postlink --- postfix-3.5.6/mantools/postlink 2020-01-26 12:34:39.000000000 -0500 +++ postfix-3.5.13/mantools/postlink 2021-01-16 17:31:12.000000000 -0500 @@ -695,6 +695,7 @@ s;\bsmtp_per_record_deadline\b;<a href="postconf.5.html#smtp_per_record_deadline">$&</a>;g; s;\bsmtp_send_dummy_mail_auth\b;<a href="postconf.5.html#smtp_send_dummy_mail_auth">$&</a>;g; s;\bsmtp_balance_inet_protocols\b;<a href="postconf.5.html#smtp_balance_inet_protocols">$&</a>;g; + s;\bdnssec_probe\b;<a href="postconf.5.html#dnssec_probe">$&</a>;g; s;\bsmtp_tls_connection_reuse\b;<a href="postconf.5.html#smtp_tls_connection_reuse">$&</a>;g; s;\blmtp_tls_connection_reuse\b;<a href="postconf.5.html#lmtp_tls_connection_reuse">$&</a>;g; s;\bsmtpd_enforce_tls\b;<a href="postconf.5.html#smtpd_enforce_tls">$&</a>;g; diff -Nru postfix-3.5.6/proto/BDAT_README.html postfix-3.5.13/proto/BDAT_README.html --- postfix-3.5.6/proto/BDAT_README.html 2019-02-10 17:47:33.000000000 -0500 +++ postfix-3.5.13/proto/BDAT_README.html 2021-06-09 08:47:01.000000000 -0400 @@ -51,7 +51,7 @@ # The logging alternative: smtpd_discard_ehlo_keywords = chunking # The non-logging alternative: - smtpd_discard_ehlo_keywords = chunking, silent_discard + smtpd_discard_ehlo_keywords = chunking, silent-discard </pre> </blockquote> diff -Nru postfix-3.5.6/proto/postconf.proto postfix-3.5.13/proto/postconf.proto --- postfix-3.5.6/proto/postconf.proto 2020-05-09 11:51:27.000000000 -0400 +++ postfix-3.5.13/proto/postconf.proto 2021-01-17 10:10:15.000000000 -0500 @@ -16815,7 +16815,7 @@ This feature is available in Postfix 3.1 and later. </p> -%PARAM smtp_tls_dane_insecure_mx_policy dane +%PARAM smtp_tls_dane_insecure_mx_policy see "postconf -d" output <p> The TLS policy for MX hosts with "secure" TLSA records when the nexthop destination security level is <b>dane</b>, but the MX @@ -16839,6 +16839,12 @@ "Verified", because the MX host name could have been forged. </dd> </dl> +<p> The default setting for Postfix ≥ 3.6 is "dane" with +"smtp_tls_security_level = dane", otherwise "may". This behavior +was backported to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21. +With earlier +Postfix versions the default setting was always "dane". </p> + <p> Though with "insecure" MX records an active attacker can compromise SMTP transport security by returning forged MX records, such attacks are "tamper-evident" since any forged MX hostnames @@ -17698,3 +17704,59 @@ such games to circumvent Postfix access policies. </p> <p> This feature is available in Postfix 3.5 and later. </p> + +%PARAM dnssec_probe ns:. + +<p> The DNS query type (default: "ns") and DNS query name (default: +".") that Postfix may use to determine whether DNSSEC validation +is available. +</p> + +<p> Background: DNSSEC validation is needed for Postfix DANE support; +this ensures that Postfix receives TLSA records with secure TLS +server certificate info. When DNSSEC validation is unavailable, +mail deliveries using <i>opportunistic</i> DANE will not be protected +by server certificate info in TLSA records, and mail deliveries +using <i>mandatory</i> DANE will not be made at all. </p> + +<p> By default, a Postfix process will send a DNSSEC probe after +1) the process made a DNS query that requested DNSSEC validation, +2) the process did not receive a DNSSEC validated response to this +query or to an earlier query, and 3) the process did not already +send a DNSSEC probe. <p> + +<p> When the DNSSEC probe has no response, or when the response is +not DNSSEC validated, Postfix logs a warning that DNSSEC validation +may be unavailable. </p> + +<p> Example: </p> + +<pre> +warning: DNSSEC validation may be unavailable +warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated +warning: reason: dnssec_probe 'ns:.' received no response: Server failure +</pre> + +<p> Possible reasons why DNSSEC validation may be unavailable: </p> + +<ul> + +<li> The local /etc/resolv.conf file specifies a DNS resolver that +does not validate DNSSEC signatures (that's +$queue_directory/etc/resolv.conf when a Postfix daemon runs in a +chroot jail). + +<li> The local system library does not pass on the "DNSSEC validated" +bit to Postfix, or Postfix does not know how to ask the library to +do that. + +</ul> + +<p> By default, the DNSSEC probe asks for the DNS root zone NS +records, because resolvers should always have that information +cached. If Postfix runs on a network where the DNS root zone is not +reachable, specify a different probe, or specify an empty dnssec_probe +value to disable the feature. </p> + +<p> This feature was backported from Postfix 3.6 to Postfix versions +3.5.9, 3.4.19, 3.3.16. 3.2.21. </p> diff -Nru postfix-3.5.6/README_FILES/BDAT_README postfix-3.5.13/README_FILES/BDAT_README --- postfix-3.5.6/README_FILES/BDAT_README 2019-02-10 17:47:44.000000000 -0500 +++ postfix-3.5.13/README_FILES/BDAT_README 2021-06-13 15:02:04.000000000 -0400 @@ -23,7 +23,7 @@ # The logging alternative: smtpd_discard_ehlo_keywords = chunking # The non-logging alternative: - smtpd_discard_ehlo_keywords = chunking, silent_discard + smtpd_discard_ehlo_keywords = chunking, silent-discard Specify '-o smtpd_discard_ehlo_keywords=' in master.cf for the submission and smtps services, if you have clients that benefit from CHUNKING support. diff -Nru postfix-3.5.6/README_FILES/RELEASE_NOTES postfix-3.5.13/README_FILES/RELEASE_NOTES --- postfix-3.5.6/README_FILES/RELEASE_NOTES 2020-05-16 17:20:59.000000000 -0400 +++ postfix-3.5.13/README_FILES/RELEASE_NOTES 2021-01-16 17:24:24.000000000 -0500 @@ -25,9 +25,50 @@ the software under the license of their choice. Those who are more comfortable with the IPL can continue with that license. +Runtime detection of DNSSEC support +----------------------------------- + +The Postfix build system will no longer automatically disable DNSSEC +support when it determines that Postfix will use libc-musl. This removes +the earlier libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12, +and 3.5.2. + +Now, when a Postfix process requests DNSSEC support (typically, for +Postfix DANE support), the process may do a runtime test to determine if +DNSSEC validation is available. DNSSEC support may be broken because of +local configuration, libc incompatibility, or other infrastructure issues. + +Background: DNSSEC validation is needed for Postfix DANE support; +this ensures that Postfix receives TLSA records with secure TLS +server certificate info. When DNSSEC validation is unavailable, +mail deliveries using opportunistic DANE will not be protected by +server certificate info in TLSA records, and mail deliveries using +mandatory DANE will not be made at all. + +The dnssec_probe parameter specifies the DNS query type (default: +"ns") and DNS query name (default: ".") that Postfix may use to +determine whether DNSSEC validation is available. Specify an empty +value to disable this feature. + +By default, a Postfix process will send a DNSSEC probe after 1) the +process made a DNS query that requested DNSSEC validation, 2) the +process did not receive a DNSSEC validated response to this query +or to an earlier query, and 3) the process did not already send a +DNSSEC probe. + +When the DNSSEC probe has no response, or when the response is not +DNSSEC validated, Postfix logs a warning that DNSSEC validation may +be unavailable. Examples: + +warning: DNSSEC validation may be unavailable +warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated +warning: reason: dnssec_probe 'ns:.' received no response: Server failure + +This feature was backported from Postfix 3.6. + libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12, and 3.5.2 ------------------------------------------------------------------ - + Security: this release disables DANE support on Linux systems with libc-musl, because libc-musl provides no indication whether DNS responses are authentic. This broke DANE support without a clear diff -Nru postfix-3.5.6/RELEASE_NOTES postfix-3.5.13/RELEASE_NOTES --- postfix-3.5.6/RELEASE_NOTES 2020-05-16 17:20:59.000000000 -0400 +++ postfix-3.5.13/RELEASE_NOTES 2021-01-16 17:24:24.000000000 -0500 @@ -25,9 +25,50 @@ the software under the license of their choice. Those who are more comfortable with the IPL can continue with that license. +Runtime detection of DNSSEC support +----------------------------------- + +The Postfix build system will no longer automatically disable DNSSEC +support when it determines that Postfix will use libc-musl. This removes +the earlier libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12, +and 3.5.2. + +Now, when a Postfix process requests DNSSEC support (typically, for +Postfix DANE support), the process may do a runtime test to determine if +DNSSEC validation is available. DNSSEC support may be broken because of +local configuration, libc incompatibility, or other infrastructure issues. + +Background: DNSSEC validation is needed for Postfix DANE support; +this ensures that Postfix receives TLSA records with secure TLS +server certificate info. When DNSSEC validation is unavailable, +mail deliveries using opportunistic DANE will not be protected by +server certificate info in TLSA records, and mail deliveries using +mandatory DANE will not be made at all. + +The dnssec_probe parameter specifies the DNS query type (default: +"ns") and DNS query name (default: ".") that Postfix may use to +determine whether DNSSEC validation is available. Specify an empty +value to disable this feature. + +By default, a Postfix process will send a DNSSEC probe after 1) the +process made a DNS query that requested DNSSEC validation, 2) the +process did not receive a DNSSEC validated response to this query +or to an earlier query, and 3) the process did not already send a +DNSSEC probe. + +When the DNSSEC probe has no response, or when the response is not +DNSSEC validated, Postfix logs a warning that DNSSEC validation may +be unavailable. Examples: + +warning: DNSSEC validation may be unavailable +warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated +warning: reason: dnssec_probe 'ns:.' received no response: Server failure + +This feature was backported from Postfix 3.6. + libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12, and 3.5.2 ------------------------------------------------------------------ - + Security: this release disables DANE support on Linux systems with libc-musl, because libc-musl provides no indication whether DNS responses are authentic. This broke DANE support without a clear diff -Nru postfix-3.5.6/src/cleanup/cleanup_body_edit.c postfix-3.5.13/src/cleanup/cleanup_body_edit.c --- postfix-3.5.6/src/cleanup/cleanup_body_edit.c 2017-12-27 17:29:44.000000000 -0500 +++ postfix-3.5.13/src/cleanup/cleanup_body_edit.c 2021-11-05 18:39:27.000000000 -0400 @@ -207,7 +207,7 @@ /* * Finally, output the queue file record. */ - CLEANUP_OUT_BUF(state, REC_TYPE_NORM, buf); + CLEANUP_OUT_BUF(state, rec_type, buf); curr_rp->write_offs = vstream_ftell(state->dst); return (0); diff -Nru postfix-3.5.6/src/cleanup/cleanup_message.c postfix-3.5.13/src/cleanup/cleanup_message.c --- postfix-3.5.6/src/cleanup/cleanup_message.c 2019-11-09 18:23:23.000000000 -0500 +++ postfix-3.5.13/src/cleanup/cleanup_message.c 2021-07-24 18:20:43.000000000 -0400 @@ -776,9 +776,12 @@ } else { token = tok822_alloc(TOK822_QSTRING, state->fullname); } - tok822_externalize(state->temp2, token, TOK822_STR_NONE); - tok822_free(token); - vstring_sprintf_append(state->temp2, " <%s>", + if (token) { + tok822_externalize(state->temp2, token, TOK822_STR_NONE); + tok822_free(token); + vstring_strcat(state->temp2, " "); + } + vstring_sprintf_append(state->temp2, "<%s>", vstring_str(state->temp1)); break; diff -Nru postfix-3.5.6/src/cleanup/cleanup_milter.c postfix-3.5.13/src/cleanup/cleanup_milter.c --- postfix-3.5.6/src/cleanup/cleanup_milter.c 2020-03-08 11:42:19.000000000 -0400 +++ postfix-3.5.13/src/cleanup/cleanup_milter.c 2021-11-05 18:39:27.000000000 -0400 @@ -1803,6 +1803,10 @@ } count++; } + if (var_enable_orcpt) + been_here_drop(state->dups, "%s\n%d\n%s\n%s", + dsn_orcpt ? dsn_orcpt : "", dsn_notify, + orig_rcpt ? orig_rcpt : "", STR(int_rcpt_buf)); /* FALLTHROUGH */ case REC_TYPE_DRCP: /* canceled recipient */ case REC_TYPE_DONE: /* can't happen */ @@ -1818,6 +1822,8 @@ break; } } + if (var_enable_orcpt == 0 && count > 0) + been_here_drop_fixed(state->dups, STR(int_rcpt_buf)); if (msg_verbose) msg_info("%s: deleted %d records for recipient \"%s\"", @@ -1828,7 +1834,8 @@ /* cleanup_repl_body - replace message body */ -static const char *cleanup_repl_body(void *context, int cmd, VSTRING *buf) +static const char *cleanup_repl_body(void *context, int cmd, int rec_type, + VSTRING *buf) { const char *myname = "cleanup_repl_body"; CLEANUP_STATE *state = (CLEANUP_STATE *) context; @@ -1840,7 +1847,7 @@ */ switch (cmd) { case MILTER_BODY_LINE: - if (cleanup_body_edit_write(state, REC_TYPE_NORM, buf) < 0) + if (cleanup_body_edit_write(state, rec_type, buf) < 0) return (cleanup_milter_error(state, errno)); break; case MILTER_BODY_START: diff -Nru postfix-3.5.6/src/dns/dns.h postfix-3.5.13/src/dns/dns.h --- postfix-3.5.6/src/dns/dns.h 2020-04-16 13:07:58.000000000 -0400 +++ postfix-3.5.13/src/dns/dns.h 2021-01-16 17:37:12.000000000 -0500 @@ -244,7 +244,12 @@ (lflags), (ltype)) /* - * Request flags. + * The dns_lookup() rflag that requests DNSSEC validation. + */ +#define DNS_WANT_DNSSEC_VALIDATION(rflags) ((rflags) & RES_USE_DNSSEC) + + /* + * lflags. */ #define DNS_REQ_FLAG_STOP_OK (1<<0) #define DNS_REQ_FLAG_STOP_INVAL (1<<1) @@ -309,6 +314,18 @@ */ const char *dns_str_resflags(unsigned long); + /* + * dns_sec.c. + */ +#define DNS_SEC_FLAG_AVAILABLE (1<<0) /* got some DNSSEC validated reply */ +#define DNS_SEC_FLAG_DONT_PROBE (1<<1) /* probe already sent, or disabled */ + +#define DNS_SEC_STATS_SET(flags) (dns_sec_stats |= (flags)) +#define DNS_SEC_STATS_TEST(flags) (dns_sec_stats & (flags)) + +extern int dns_sec_stats; /* See DNS_SEC_FLAG_XXX above */ +extern void dns_sec_probe(int); + /* LICENSE /* .ad /* .fi diff -Nru postfix-3.5.6/src/dns/dns_lookup.c postfix-3.5.13/src/dns/dns_lookup.c --- postfix-3.5.6/src/dns/dns_lookup.c 2020-04-16 13:07:58.000000000 -0400 +++ postfix-3.5.13/src/dns/dns_lookup.c 2021-01-16 11:24:08.000000000 -0500 @@ -171,6 +171,12 @@ /* Pointer to storage for the reply RCODE value. This gives /* more detailed information than DNS_FAIL, DNS_RETRY, etc. /* DIAGNOSTICS +/* If DNSSEC validation is requested but the response is not +/* DNSSEC validated, dns_lookup() will send a one-time probe +/* query as configured with the \fBdnssec_probe\fR configuration +/* parameter, and will log a warning when the probe response +/* was not DNSSEC validated. +/* .PP /* dns_lookup() returns one of the following codes and sets the /* \fIwhy\fR argument accordingly: /* .IP DNS_OK @@ -463,7 +469,7 @@ */ #define XTRA_FLAGS (RES_USE_EDNS0 | RES_TRUSTAD) - if (flags & RES_USE_DNSSEC) + if (DNS_WANT_DNSSEC_VALIDATION(flags)) flags |= (RES_USE_EDNS0 | RES_TRUSTAD); /* @@ -510,6 +516,8 @@ _res.options |= saved_options; reply_header = (HEADER *) reply->buf; reply->rcode = reply_header->rcode; + if ((reply->dnssec_ad = !!reply_header->ad) != 0) + DNS_SEC_STATS_SET(DNS_SEC_FLAG_AVAILABLE); if (h_errno != 0) { if (why) vstring_sprintf(why, "Host or domain name not found. " @@ -561,13 +569,8 @@ /* * Initialize the reply structure. Some structure members are filled on - * the fly while the reply is being parsed. Coerce AD bit to boolean. + * the fly while the reply is being parsed. */ -#if RES_USE_DNSSEC != 0 - reply->dnssec_ad = (flags & RES_USE_DNSSEC) ? !!reply_header->ad : 0; -#else - reply->dnssec_ad = 0; -#endif SET_HAVE_DNS_REPLY_PACKET(reply, len); reply->query_start = reply->buf + sizeof(HEADER); reply->answer_start = 0; @@ -885,7 +888,9 @@ CORRUPT(DNS_RETRY); if ((status = dns_get_fixed(pos, &fixed)) != DNS_OK) CORRUPT(status); - if (!valid_rr_name(rr_name, "resource name", fixed.type, reply)) + if (strcmp(orig_name, ".") == 0 && *rr_name == 0) + /* Allow empty response name for root queries. */ ; + else if (!valid_rr_name(rr_name, "resource name", fixed.type, reply)) CORRUPT(DNS_INVAL); if (fqdn) vstring_strcpy(fqdn, rr_name); @@ -973,7 +978,7 @@ /* * The Linux resolver misbehaves when given an invalid domain name. */ - if (!valid_hostname(name, DONT_GRIPE)) { + if (strcmp(name, ".") && !valid_hostname(name, DONT_GRIPE)) { if (why) vstring_sprintf(why, "Name service error for %s: invalid host or domain name", @@ -1010,6 +1015,10 @@ (void) dns_get_answer(orig_name, &reply, T_SOA, rrlist, fqdn, cname, c_len, &maybe_secure); } + if (DNS_WANT_DNSSEC_VALIDATION(flags) + && !DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE | \ + DNS_SEC_FLAG_DONT_PROBE)) + dns_sec_probe(flags); /* XXX Clobbers 'reply' */ return (status); } @@ -1019,6 +1028,10 @@ */ status = dns_get_answer(orig_name, &reply, type, rrlist, fqdn, cname, c_len, &maybe_secure); + if (DNS_WANT_DNSSEC_VALIDATION(flags) + && !DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE | \ + DNS_SEC_FLAG_DONT_PROBE)) + dns_sec_probe(flags); /* XXX Clobbers 'reply' */ switch (status) { default: if (why) diff -Nru postfix-3.5.6/src/dns/dns_sec.c postfix-3.5.13/src/dns/dns_sec.c --- postfix-3.5.6/src/dns/dns_sec.c 1969-12-31 19:00:00.000000000 -0500 +++ postfix-3.5.13/src/dns/dns_sec.c 2021-01-11 18:32:06.000000000 -0500 @@ -0,0 +1,144 @@ +/*++ +/* NAME +/* dns_sec 3 +/* SUMMARY +/* DNSSEC validation availability +/* SYNOPSIS +/* #include <dns.h> +/* +/* DNS_SEC_STATS_SET( +/* int flags) +/* +/* DNS_SEC_STATS_TEST( +/* int flags) +/* +/* void dns_sec_probe( +/* int rflags) +/* DESCRIPTION +/* This module maintains information about the availability of +/* DNSSEC validation, in global flags that summarize +/* process-lifetime history. +/* .IP DNS_SEC_FLAG_AVAILABLE +/* The process has received at least one DNSSEC validated +/* response to a query that requested DNSSEC validation. +/* .IP DNS_SEC_FLAG_DONT_PROBE +/* The process has sent a DNSSEC probe (see below), or DNSSEC +/* probing is disabled by configuration. +/* .PP +/* DNS_SEC_STATS_SET() sets one or more DNS_SEC_FLAG_* flags, +/* and DNS_SEC_STATS_TEST() returns non-zero if any of the +/* specified flags is set. +/* +/* dns_sec_probe() generates a query to the target specified +/* with the \fBdnssec_probe\fR configuration parameter. It +/* sets the DNS_SEC_FLAG_DONT_PROBE flag, and it calls +/* dns_lookup() which sets DNS_SEC_FLAG_AVAILABLE if it receives +/* a DNSSEC validated response. Preconditions: +/* .IP \(bu +/* The rflags argument must request DNSSEC validation (in the +/* same manner as dns_lookup() rflags argument). +/* .IP \(bu +/* The DNS_SEC_FLAG_AVAILABLE and DNS_SEC_FLAG_DONT_PROBE +/* flags must be false. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA +/*--*/ + +#include <sys_defs.h> + + /* + * Utility library. + */ +#include <msg.h> +#include <mymalloc.h> +#include <split_at.h> +#include <vstring.h> + + /* + * Global library. + */ +#include <mail_params.h> + + /* + * DNS library. + */ +#include <dns.h> + +int dns_sec_stats; + +/* dns_sec_probe - send a probe to establish DNSSEC viability */ + +void dns_sec_probe(int rflags) +{ + const char myname[] = "dns_sec_probe"; + char *saved_dnssec_probe; + char *qname; + int qtype; + DNS_RR *rrlist = 0; + int dns_status; + VSTRING *why; + + /* + * Sanity checks. + */ + if (!DNS_WANT_DNSSEC_VALIDATION(rflags)) + msg_panic("%s: DNSSEC is not requested", myname); + if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_DONT_PROBE)) + msg_panic("%s: DNSSEC probe was already sent, or probing is disabled", + myname); + if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE)) + msg_panic("%s: already have validated DNS response", myname); + + /* + * Don't recurse. + */ + DNS_SEC_STATS_SET(DNS_SEC_FLAG_DONT_PROBE); + + /* + * Don't probe. + */ + if (*var_dnssec_probe == 0) + return; + + /* + * Parse the probe spec. Format is type:resource. + */ + saved_dnssec_probe = mystrdup(var_dnssec_probe); + if ((qname = split_at(saved_dnssec_probe, ':')) == 0 || *qname == 0 + || (qtype = dns_type(saved_dnssec_probe)) == 0) + msg_fatal("malformed %s value: %s format is qtype:qname", + VAR_DNSSEC_PROBE, var_dnssec_probe); + + why = vstring_alloc(100); + dns_status = dns_lookup(qname, qtype, rflags, &rrlist, (VSTRING *) 0, why); + if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE)) + msg_warn("DNSSEC validation may be unavailable"); + else if (msg_verbose) + msg_info(VAR_DNSSEC_PROBE + " '%s' received a response that is DNSSEC validated", + var_dnssec_probe); + switch (dns_status) { + default: + if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE)) + msg_warn("reason: " VAR_DNSSEC_PROBE + " '%s' received a response that is not DNSSEC validated", + var_dnssec_probe); + if (rrlist) + dns_rr_free(rrlist); + break; + case DNS_RETRY: + case DNS_FAIL: + msg_warn("reason: " VAR_DNSSEC_PROBE " '%s' received no response: %s", + var_dnssec_probe, vstring_str(why)); + break; + } + myfree(saved_dnssec_probe); + vstring_free(why); +} diff -Nru postfix-3.5.6/src/dns/Makefile.in postfix-3.5.13/src/dns/Makefile.in --- postfix-3.5.6/src/dns/Makefile.in 2019-12-14 19:01:17.000000000 -0500 +++ postfix-3.5.13/src/dns/Makefile.in 2021-01-08 20:23:37.000000000 -0500 @@ -1,10 +1,10 @@ SHELL = /bin/sh SRCS = dns_lookup.c dns_rr.c dns_strerror.c dns_strtype.c dns_rr_to_pa.c \ dns_sa_to_rr.c dns_rr_eq_sa.c dns_rr_to_sa.c dns_strrecord.c \ - dns_rr_filter.c dns_str_resflags.c + dns_rr_filter.c dns_str_resflags.c dns_sec.c OBJS = dns_lookup.o dns_rr.o dns_strerror.o dns_strtype.o dns_rr_to_pa.o \ dns_sa_to_rr.o dns_rr_eq_sa.o dns_rr_to_sa.o dns_strrecord.o \ - dns_rr_filter.o dns_str_resflags.o + dns_rr_filter.o dns_str_resflags.o dns_sec.o HDRS = dns.h TESTSRC = test_dns_lookup.c test_alias_token.c DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) @@ -76,7 +76,7 @@ done cd $(INC_DIR); chmod 644 $(HDRS) -test_dns_lookup: test_dns_lookup.c $(LIB) $(LIBS) +test_dns_lookup: test_dns_lookup.c all $(LIB) $(LIBS) $(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS) dns_rr_to_pa: $(LIB) $(LIBS) @@ -346,6 +346,18 @@ dns_sa_to_rr.o: ../../include/vstring.h dns_sa_to_rr.o: dns.h dns_sa_to_rr.o: dns_sa_to_rr.c +dns_sec.o: ../../include/check_arg.h +dns_sec.o: ../../include/mail_params.h +dns_sec.o: ../../include/msg.h +dns_sec.o: ../../include/myaddrinfo.h +dns_sec.o: ../../include/mymalloc.h +dns_sec.o: ../../include/sock_addr.h +dns_sec.o: ../../include/split_at.h +dns_sec.o: ../../include/sys_defs.h +dns_sec.o: ../../include/vbuf.h +dns_sec.o: ../../include/vstring.h +dns_sec.o: dns.h +dns_sec.o: dns_sec.c dns_str_resflags.o: ../../include/check_arg.h dns_str_resflags.o: ../../include/myaddrinfo.h dns_str_resflags.o: ../../include/name_mask.h diff -Nru postfix-3.5.6/src/dns/test_dns_lookup.c postfix-3.5.13/src/dns/test_dns_lookup.c --- postfix-3.5.6/src/dns/test_dns_lookup.c 2016-02-21 18:06:59.000000000 -0500 +++ postfix-3.5.13/src/dns/test_dns_lookup.c 2021-01-16 11:24:08.000000000 -0500 @@ -77,6 +77,9 @@ int ch; int lflags = DNS_REQ_FLAG_NONE; + if (var_dnssec_probe == 0) + var_dnssec_probe = mystrdup(DEF_DNSSEC_PROBE); + msg_vstream_init(argv[0], VSTREAM_ERR); while ((ch = GETOPT(argc, argv, "f:npv")) > 0) { switch (ch) { diff -Nru postfix-3.5.6/src/global/been_here.c postfix-3.5.13/src/global/been_here.c --- postfix-3.5.6/src/global/been_here.c 2019-02-09 18:26:28.000000000 -0500 +++ postfix-3.5.13/src/global/been_here.c 2020-11-04 16:06:12.000000000 -0500 @@ -26,6 +26,14 @@ /* BH_TABLE *dup_filter; /* char *format; /* +/* int been_here_drop_fixed(dup_filter, string) +/* BH_TABLE *dup_filter; +/* char *string; +/* +/* int been_here_drop(dup_filter, format, ...) +/* BH_TABLE *dup_filter; +/* char *format; +/* /* void been_here_free(dup_filter) /* BH_TABLE *dup_filter; /* DESCRIPTION @@ -46,6 +54,16 @@ /* been_here_check_fixed() and been_here_check() are similar /* but do not update the duplicate filter. /* +/* been_here_drop_fixed() looks up a fixed string in the given +/* table, and deletes the entry if the string was found. The +/* result is non-zero (true) if the string was found, zero +/* (false) otherwise. +/* +/* been_here_drop() formats its arguments, looks up the result +/* in the given table, and removes the entry if the formatted +/* result was found. The result is non-zero (true) if the +/* formatted result was found, zero (false) otherwise. +/* /* been_here_free() releases storage for a duplicate filter. /* /* Arguments: @@ -243,6 +261,67 @@ /* * Cleanup. + */ + if (folded_string) + vstring_free(folded_string); + + return (status); +} + +/* been_here_drop - remove filter entry with finer control */ + +int been_here_drop(BH_TABLE *dup_filter, const char *fmt,...) +{ + VSTRING *buf = vstring_alloc(100); + int status; + va_list ap; + + /* + * Construct the string to be dropped. + */ + va_start(ap, fmt); + vstring_vsprintf(buf, fmt, ap); + va_end(ap); + + /* + * Drop the filter entry. + */ + status = been_here_drop_fixed(dup_filter, vstring_str(buf)); + + /* + * Cleanup. + */ + vstring_free(buf); + return (status); +} + +/* been_here_drop_fixed - remove filter entry */ + +int been_here_drop_fixed(BH_TABLE *dup_filter, const char *string) +{ + VSTRING *folded_string; + const char *lookup_key; + int status; + + /* + * Special processing: case insensitive lookup. + */ + if (dup_filter->flags & BH_FLAG_FOLD) { + folded_string = vstring_alloc(100); + lookup_key = casefold(folded_string, string); + } else { + folded_string = 0; + lookup_key = string; + } + + /* + * Drop the filter entry. + */ + if ((status = been_here_check_fixed(dup_filter, lookup_key)) != 0) + htable_delete(dup_filter->table, lookup_key, (void (*) (void *)) 0); + + /* + * Cleanup. */ if (folded_string) vstring_free(folded_string); diff -Nru postfix-3.5.6/src/global/been_here.h postfix-3.5.13/src/global/been_here.h --- postfix-3.5.6/src/global/been_here.h 2019-02-09 18:26:58.000000000 -0500 +++ postfix-3.5.13/src/global/been_here.h 2020-11-04 16:06:12.000000000 -0500 @@ -35,6 +35,8 @@ extern int PRINTFLIKE(2, 3) been_here(BH_TABLE *, const char *,...); extern int been_here_check_fixed(BH_TABLE *, const char *); extern int PRINTFLIKE(2, 3) been_here_check(BH_TABLE *, const char *,...); +extern int been_here_drop_fixed(BH_TABLE *, const char *); +extern int PRINTFLIKE(2, 3) been_here_drop(BH_TABLE *, const char *,...); /* LICENSE /* .ad diff -Nru postfix-3.5.6/src/global/delivered_hdr.c postfix-3.5.13/src/global/delivered_hdr.c --- postfix-3.5.6/src/global/delivered_hdr.c 2015-01-27 10:22:33.000000000 -0500 +++ postfix-3.5.13/src/global/delivered_hdr.c 2020-11-04 16:10:00.000000000 -0500 @@ -115,6 +115,8 @@ char *cp; DELIVERED_HDR_INFO *info; const HEADER_OPTS *hdr; + int curr_type; + int prev_type; /* * Sanity check. @@ -130,15 +132,20 @@ /* * XXX Assume that mail_copy() produces delivered-to headers that fit in - * a REC_TYPE_NORM record. Lowercase the delivered-to addresses for - * consistency. + * a REC_TYPE_NORM or REC_TYPE_CONT record. Lowercase the delivered-to + * addresses for consistency. * * XXX Don't get bogged down by gazillions of delivered-to headers. */ #define DELIVERED_HDR_LIMIT 1000 - while (rec_get(fp, info->buf, 0) == REC_TYPE_NORM - && info->table->used < DELIVERED_HDR_LIMIT) { + for (prev_type = REC_TYPE_NORM; + info->table->used < DELIVERED_HDR_LIMIT + && ((curr_type = rec_get(fp, info->buf, 0)) == REC_TYPE_NORM + || curr_type == REC_TYPE_CONT); + prev_type = curr_type) { + if (prev_type != REC_TYPE_NORM) + continue; if (is_header(STR(info->buf))) { if ((hdr = header_opts_find(STR(info->buf))) != 0 && hdr->type == HDR_DELIVERED_TO) { diff -Nru postfix-3.5.6/src/global/haproxy_srvr.c postfix-3.5.13/src/global/haproxy_srvr.c --- postfix-3.5.6/src/global/haproxy_srvr.c 2020-03-08 10:50:26.000000000 -0400 +++ postfix-3.5.13/src/global/haproxy_srvr.c 2021-04-03 19:46:12.000000000 -0400 @@ -201,6 +201,8 @@ if (msg_verbose) msg_info("haproxy_srvr_parse: proto=%s", STR_OR_NULL(str)); + if (str == 0) + return (-1); #ifdef AF_INET6 if (strcasecmp(str, "TCP6") == 0) { if (strchr((char *) proto_info->sa_family_list, AF_INET6) != 0) { diff -Nru postfix-3.5.6/src/global/mail_params.c postfix-3.5.13/src/global/mail_params.c --- postfix-3.5.6/src/global/mail_params.c 2020-05-12 19:32:37.000000000 -0400 +++ postfix-3.5.13/src/global/mail_params.c 2021-06-13 15:20:12.000000000 -0400 @@ -152,6 +152,8 @@ /* char *var_maillog_file_comp; /* char *var_maillog_file_stamp; /* char *var_postlog_service; +/* +/* char *var_dnssec_probe; /* DESCRIPTION /* This module (actually the associated include file) defines /* the names and defaults of all mail configuration parameters. @@ -362,6 +364,8 @@ char *var_maillog_file_stamp; char *var_postlog_service; +char *var_dnssec_probe; + const char null_format_string[1] = ""; /* @@ -689,6 +693,7 @@ VAR_MAILLOG_FILE_COMP, DEF_MAILLOG_FILE_COMP, &var_maillog_file_comp, 1, 0, VAR_MAILLOG_FILE_STAMP, DEF_MAILLOG_FILE_STAMP, &var_maillog_file_stamp, 1, 0, VAR_POSTLOG_SERVICE, DEF_POSTLOG_SERVICE, &var_postlog_service, 1, 0, + VAR_DNSSEC_PROBE, DEF_DNSSEC_PROBE, &var_dnssec_probe, 0, 0, 0, }; static const CONFIG_BOOL_TABLE first_bool_defaults[] = { @@ -830,6 +835,17 @@ const char *cp; /* + * Ignore the Postfix >= 3.6 compatibility_level's minor and patch + * fields, to allow rollback from Postfix >= 3.6, and to allow + * configuration sharing with Postfix >= 3.6. + */ + const char *compat_level_str; + + if ((compat_level_str = mail_conf_lookup(VAR_COMPAT_LEVEL)) != 0 + && ISDIGIT(compat_level_str[0]) && strchr(compat_level_str, '.') != 0) + set_mail_conf_int(VAR_COMPAT_LEVEL, atoi(compat_level_str)); + + /* * Extract compatibility level first, so that we can determine what * parameters of interest are left at their legacy defaults. */ diff -Nru postfix-3.5.6/src/global/mail_params.h postfix-3.5.13/src/global/mail_params.h --- postfix-3.5.6/src/global/mail_params.h 2020-05-09 11:51:27.000000000 -0400 +++ postfix-3.5.13/src/global/mail_params.h 2021-01-17 08:11:47.000000000 -0500 @@ -1617,7 +1617,7 @@ /* SMTP only */ #define VAR_SMTP_TLS_INSECURE_MX_POLICY "smtp_tls_dane_insecure_mx_policy" -#define DEF_SMTP_TLS_INSECURE_MX_POLICY "dane" +#define DEF_SMTP_TLS_INSECURE_MX_POLICY "${{$smtp_tls_security_level} == {dane} ? {dane} : {may}}" extern char *var_smtp_tls_insecure_mx_policy; /* @@ -4202,6 +4202,13 @@ #define DEF_INFO_LOG_ADDR_FORM INFO_LOG_ADDR_FORM_NAME_EXTERNAL extern char *var_info_log_addr_form; + /* + * DNSSEC probing, to find out if DNSSEC validation is available. + */ +#define VAR_DNSSEC_PROBE "dnssec_probe" +#define DEF_DNSSEC_PROBE "ns:." +extern char *var_dnssec_probe; + /* LICENSE /* .ad /* .fi diff -Nru postfix-3.5.6/src/global/mail_task.c postfix-3.5.13/src/global/mail_task.c --- postfix-3.5.6/src/global/mail_task.c 2019-01-29 17:24:42.000000000 -0500 +++ postfix-3.5.13/src/global/mail_task.c 2021-04-04 16:18:38.000000000 -0400 @@ -17,8 +17,8 @@ /* /* The result is overwritten with each call. /* -/* A null argv0 argument requests that the current -/* result is returned. +/* A null argv0 argument requests that the current result is +/* returned, or "unknown" when no current result exists. /* LICENSE /* .ad /* .fi @@ -59,6 +59,8 @@ const char *slash; const char *tag; + if (argv0 == 0 && canon_name == 0) + argv0 = "unknown"; if (argv0) { if (canon_name == 0) canon_name = vstring_alloc(10); diff -Nru postfix-3.5.6/src/global/mail_version.h postfix-3.5.13/src/global/mail_version.h --- postfix-3.5.6/src/global/mail_version.h 2020-07-26 14:14:48.000000000 -0400 +++ postfix-3.5.13/src/global/mail_version.h 2021-11-07 17:35:31.000000000 -0500 @@ -20,8 +20,8 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20200726" -#define MAIL_VERSION_NUMBER "3.5.6" +#define MAIL_RELEASE_DATE "20211107" +#define MAIL_VERSION_NUMBER "3.5.13" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff -Nru postfix-3.5.6/src/global/record.c postfix-3.5.13/src/global/record.c --- postfix-3.5.6/src/global/record.c 2018-11-27 17:39:42.000000000 -0500 +++ postfix-3.5.13/src/global/record.c 2021-07-24 19:07:44.000000000 -0400 @@ -323,7 +323,7 @@ int rec_goto(VSTREAM *stream, const char *buf) { off_t offset; - static const char *saved_path; + static char *saved_path; static off_t saved_offset; static int reverse_count; @@ -336,11 +336,12 @@ * is likely to insert 10000 message headers, but someone might append * 10000 recipients. */ -#define STREQ(x,y) ((x) == (y) && strcmp((x), (y)) == 0) #define REVERSE_JUMP_LIMIT 10000 - if (!STREQ(saved_path, VSTREAM_PATH(stream))) { - saved_path = VSTREAM_PATH(stream); + if (saved_path == 0 || strcmp(saved_path, VSTREAM_PATH(stream)) != 0) { + if (saved_path) + myfree(saved_path); + saved_path = mystrdup(VSTREAM_PATH(stream)); reverse_count = 0; saved_offset = 0; } diff -Nru postfix-3.5.6/src/milter/milter8.c postfix-3.5.13/src/milter/milter8.c --- postfix-3.5.6/src/milter/milter8.c 2020-02-02 15:49:15.000000000 -0500 +++ postfix-3.5.13/src/milter/milter8.c 2021-11-05 18:39:27.000000000 -0400 @@ -1147,10 +1147,12 @@ if (edit_resp == 0 && LEN(body_line_buf) > 0) edit_resp = parent->repl_body(parent->chg_context, MILTER_BODY_LINE, + REC_TYPE_NORM, body_line_buf); if (edit_resp == 0) edit_resp = parent->repl_body(parent->chg_context, MILTER_BODY_END, + /* unused*/ 0, (VSTRING *) 0); body_edit_lockout = 1; vstring_free(body_line_buf); @@ -1546,6 +1548,7 @@ body_line_buf = vstring_alloc(var_line_limit); edit_resp = parent->repl_body(parent->chg_context, MILTER_BODY_START, + /* unused */ 0, (VSTRING *) 0); } /* Extract lines from the on-the-wire CRLF format. */ @@ -1559,9 +1562,18 @@ LEN(body_line_buf) - 1); edit_resp = parent->repl_body(parent->chg_context, MILTER_BODY_LINE, + REC_TYPE_NORM, body_line_buf); VSTRING_RESET(body_line_buf); } else { + /* Preserves \r if not followed by \n. */ + if (LEN(body_line_buf) == var_line_limit) { + edit_resp = parent->repl_body(parent->chg_context, + MILTER_BODY_LINE, + REC_TYPE_CONT, + body_line_buf); + VSTRING_RESET(body_line_buf); + } VSTRING_ADDCH(body_line_buf, ch); } } diff -Nru postfix-3.5.6/src/milter/milter.h postfix-3.5.13/src/milter/milter.h --- postfix-3.5.6/src/milter/milter.h 2020-02-02 15:49:15.000000000 -0500 +++ postfix-3.5.13/src/milter/milter.h 2021-11-05 18:39:27.000000000 -0400 @@ -100,7 +100,7 @@ typedef const char *(*MILTER_EDIT_FROM_FN) (void *, const char *, const char *); typedef const char *(*MILTER_EDIT_RCPT_FN) (void *, const char *); typedef const char *(*MILTER_EDIT_RCPT_PAR_FN) (void *, const char *, const char *); -typedef const char *(*MILTER_EDIT_BODY_FN) (void *, int, VSTRING *); +typedef const char *(*MILTER_EDIT_BODY_FN) (void *, int, int, VSTRING *); typedef struct MILTERS { MILTER *milter_list; /* linked list of Milters */ diff -Nru postfix-3.5.6/src/postconf/postconf_builtin.c postfix-3.5.13/src/postconf/postconf_builtin.c --- postfix-3.5.6/src/postconf/postconf_builtin.c 2018-01-14 20:30:12.000000000 -0500 +++ postfix-3.5.13/src/postconf/postconf_builtin.c 2021-09-25 19:01:43.000000000 -0400 @@ -244,6 +244,7 @@ static const char *pcf_mynetworks(void) { static const char *networks; + VSTRING *exp_buf; const char *junk; /* @@ -252,10 +253,12 @@ if (networks) return (networks); + exp_buf = vstring_alloc(100); + if (var_inet_interfaces == 0) { if ((pcf_cmd_mode & PCF_SHOW_DEFS) || (junk = mail_conf_lookup_eval(VAR_INET_INTERFACES)) == 0) - junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode, + junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode, DEF_INET_INTERFACES, (PCF_MASTER_ENT *) 0); var_inet_interfaces = mystrdup(junk); @@ -263,7 +266,7 @@ if (var_mynetworks_style == 0) { if ((pcf_cmd_mode & PCF_SHOW_DEFS) || (junk = mail_conf_lookup_eval(VAR_MYNETWORKS_STYLE)) == 0) - junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode, + junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode, DEF_MYNETWORKS_STYLE, (PCF_MASTER_ENT *) 0); var_mynetworks_style = mystrdup(junk); @@ -271,12 +274,13 @@ if (var_inet_protocols == 0) { if ((pcf_cmd_mode & PCF_SHOW_DEFS) || (junk = mail_conf_lookup_eval(VAR_INET_PROTOCOLS)) == 0) - junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode, + junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode, DEF_INET_PROTOCOLS, (PCF_MASTER_ENT *) 0); var_inet_protocols = mystrdup(junk); (void) inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols); } + vstring_free(exp_buf); return (networks = mystrdup(mynetworks())); } diff -Nru postfix-3.5.6/src/postscreen/postscreen_dnsbl.c postfix-3.5.13/src/postscreen/postscreen_dnsbl.c --- postfix-3.5.6/src/postscreen/postscreen_dnsbl.c 2017-02-18 20:58:20.000000000 -0500 +++ postfix-3.5.13/src/postscreen/postscreen_dnsbl.c 2020-11-04 16:16:47.000000000 -0500 @@ -231,6 +231,7 @@ int weight; HTABLE_INFO *ht; char *parse_err; + const char *safe_dnsbl; /* * Parse the required DNSBL domain name, the optional reply filter and @@ -271,8 +272,9 @@ ht = htable_enter(dnsbl_site_cache, saved_site, (void *) head); /* Translate the DNSBL name into a safe name if available. */ if (psc_dnsbl_reply == 0 - || (head->safe_dnsbl = dict_get(psc_dnsbl_reply, saved_site)) == 0) - head->safe_dnsbl = ht->key; + || (safe_dnsbl = dict_get(psc_dnsbl_reply, saved_site)) == 0) + safe_dnsbl = ht->key; + head->safe_dnsbl = mystrdup(safe_dnsbl); if (psc_dnsbl_reply && psc_dnsbl_reply->error) msg_fatal("%s:%s lookup error", psc_dnsbl_reply->type, psc_dnsbl_reply->name); diff -Nru postfix-3.5.6/src/postscreen/postscreen_tests.c postfix-3.5.13/src/postscreen/postscreen_tests.c --- postfix-3.5.6/src/postscreen/postscreen_tests.c 2017-12-27 17:29:45.000000000 -0500 +++ postfix-3.5.13/src/postscreen/postscreen_tests.c 2021-07-24 18:20:43.000000000 -0400 @@ -175,6 +175,7 @@ * at the time that the cache entry was written. */ for (sp = time_stamps; sp < time_stamps + PSC_TINDX_COUNT; sp++) { + errno = 0; *sp = strtoul(start, &cp, 10); if (*start == 0 || (*cp != '\0' && *cp != ';') || errno == ERANGE) *sp = PSC_TIME_STAMP_DISABLED; diff -Nru postfix-3.5.6/src/posttls-finger/posttls-finger.c postfix-3.5.13/src/posttls-finger/posttls-finger.c --- postfix-3.5.6/src/posttls-finger/posttls-finger.c 2019-02-12 08:17:45.000000000 -0500 +++ postfix-3.5.13/src/posttls-finger/posttls-finger.c 2020-08-21 19:17:03.000000000 -0400 @@ -1988,7 +1988,7 @@ msg_fatal("bad '-a' option value: %s", state->options.addr_pref); #ifdef USE_TLS - if (state->tlsproxy_mode && state->reconnect) + if (state->tlsproxy_mode && state->reconnect >= 0) msg_fatal("The -X and -r options are mutually exclusive"); #endif diff -Nru postfix-3.5.6/src/smtp/smtp.c postfix-3.5.13/src/smtp/smtp.c --- postfix-3.5.6/src/smtp/smtp.c 2020-03-08 10:53:22.000000000 -0400 +++ postfix-3.5.13/src/smtp/smtp.c 2021-01-16 11:30:07.000000000 -0500 @@ -330,6 +330,12 @@ /* .IP "\fBinfo_log_address_format (external)\fR" /* The email address form that will be used in non-debug logging /* (info, warning, etc.). +/* .PP +/* Available in Postfix 3.5.9 and later: +/* .IP "\fBdnssec_probe (ns:.)\fR" +/* The DNS query type (default: "ns") and DNS query name (default: +/* ".") that Postfix may use to determine whether DNSSEC validation +/* is available. /* MIME PROCESSING CONTROLS /* .ad /* .fi diff -Nru postfix-3.5.6/src/smtp/smtp_proto.c postfix-3.5.13/src/smtp/smtp_proto.c --- postfix-3.5.6/src/smtp/smtp_proto.c 2019-06-13 17:08:33.000000000 -0400 +++ postfix-3.5.13/src/smtp/smtp_proto.c 2020-11-04 16:26:11.000000000 -0500 @@ -1389,17 +1389,17 @@ /* smtp_out_raw_or_mime - output buffer, raw output or MIME-aware */ -static int smtp_out_raw_or_mime(SMTP_STATE *state, VSTRING *buf) +static int smtp_out_raw_or_mime(SMTP_STATE *state, int rec_type, VSTRING *buf) { SMTP_SESSION *session = state->session; int mime_errs; if (session->mime_state == 0) { - smtp_text_out((void *) state, REC_TYPE_NORM, vstring_str(buf), + smtp_text_out((void *) state, rec_type, vstring_str(buf), VSTRING_LEN(buf), (off_t) 0); } else { mime_errs = - mime_state_update(session->mime_state, REC_TYPE_NORM, + mime_state_update(session->mime_state, rec_type, vstring_str(buf), VSTRING_LEN(buf)); if (mime_errs) { smtp_mime_fail(state, mime_errs); @@ -1423,7 +1423,7 @@ vstring_str(session->scratch2), QUOTE_FLAG_DEFAULT | QUOTE_FLAG_APPEND); vstring_strcat(session->scratch, gt); - return (smtp_out_raw_or_mime(state, session->scratch)); + return (smtp_out_raw_or_mime(state, REC_TYPE_NORM, session->scratch)); } /* smtp_out_add_headers - output additional headers, uses session->scratch* */ @@ -2307,7 +2307,8 @@ while ((rec_type = rec_get(state->src, session->scratch, 0)) > 0) { if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT) break; - if (smtp_out_raw_or_mime(state, session->scratch) < 0) + if (smtp_out_raw_or_mime(state, rec_type, + session->scratch) < 0) RETURN(0); prev_type = rec_type; } diff -Nru postfix-3.5.6/src/smtp/smtp_sasl_proto.c postfix-3.5.13/src/smtp/smtp_sasl_proto.c --- postfix-3.5.6/src/smtp/smtp_sasl_proto.c 2014-12-12 14:33:27.000000000 -0500 +++ postfix-3.5.13/src/smtp/smtp_sasl_proto.c 2020-11-04 18:33:50.000000000 -0500 @@ -102,6 +102,8 @@ if (VSTRING_LEN(buf) > 0) VSTRING_ADDCH(buf, ' '); vstring_strcat(buf, mech); + } else if (smtp_sasl_mechs->error) { + msg_fatal("SASL mechanism filter failed for: '%s'", mech); } } myfree(save_mech); diff -Nru postfix-3.5.6/src/smtpd/smtpd.c postfix-3.5.13/src/smtpd/smtpd.c --- postfix-3.5.6/src/smtpd/smtpd.c 2020-03-12 11:15:34.000000000 -0400 +++ postfix-3.5.13/src/smtpd/smtpd.c 2021-07-24 18:20:43.000000000 -0400 @@ -1291,6 +1291,7 @@ int var_defer_code; int var_smtpd_err_sleep; int var_non_fqdn_code; +char *var_bounce_rcpt; char *var_error_rcpt; int var_smtpd_delay_reject; char *var_rest_classes; @@ -5458,7 +5459,8 @@ * obsolete, so we don't have to provide perfect support. */ #ifdef USE_TLS - if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_tls_wrappermode) { + if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_tls_wrappermode + && state->tls_context == 0) { #ifdef USE_TLSPROXY /* We garbage-collect the VSTREAM in smtpd_state_reset() */ state->tlsproxy = @@ -6417,6 +6419,7 @@ VAR_EOD_CHECKS, DEF_EOD_CHECKS, &var_eod_checks, 0, 0, VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0, VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, 0, 0, + VAR_BOUNCE_RCPT, DEF_ERROR_RCPT, &var_bounce_rcpt, 1, 0, VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0, VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes, 0, 0, VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0, diff -Nru postfix-3.5.6/src/smtpd/smtpd_chat.c postfix-3.5.13/src/smtpd/smtpd_chat.c --- postfix-3.5.6/src/smtpd/smtpd_chat.c 2018-08-27 17:54:59.000000000 -0400 +++ postfix-3.5.13/src/smtpd/smtpd_chat.c 2021-07-24 18:20:43.000000000 -0400 @@ -316,7 +316,8 @@ #define INDENT 4 notice = post_mail_fopen_nowait(mail_addr_double_bounce(), - var_error_rcpt, + (state->error_mask & MAIL_ERROR_BOUNCE) ? + var_bounce_rcpt : var_error_rcpt, MAIL_SRC_MASK_NOTIFY, NULL_TRACE_FLAGS, SMTPUTF8_FLAG_NONE, NO_QUEUE_ID); if (notice == 0) { diff -Nru postfix-3.5.6/src/smtpd/smtpd_check.c postfix-3.5.13/src/smtpd/smtpd_check.c --- postfix-3.5.6/src/smtpd/smtpd_check.c 2020-05-05 18:33:34.000000000 -0400 +++ postfix-3.5.13/src/smtpd/smtpd_check.c 2021-11-06 19:44:46.000000000 -0400 @@ -4338,8 +4338,8 @@ } } else if (is_map_command(state, name, CHECK_CCERT_ACL, &cpp)) { status = check_ccert_access(state, *cpp, def_acl); -#ifdef USE_SASL_AUTH } else if (is_map_command(state, name, CHECK_SASL_ACL, &cpp)) { +#ifdef USE_SASL_AUTH if (var_smtpd_sasl_enable) { if (state->sasl_username && state->sasl_username[0]) status = check_sasl_access(state, *cpp, def_acl); diff -Nru postfix-3.5.6/src/tls/tls_misc.c postfix-3.5.13/src/tls/tls_misc.c --- postfix-3.5.6/src/tls/tls_misc.c 2020-07-26 13:03:13.000000000 -0400 +++ postfix-3.5.13/src/tls/tls_misc.c 2021-08-11 15:10:00.000000000 -0400 @@ -838,7 +838,7 @@ EVP_PKEY *pkey = 0; #ifndef OPENSSL_NO_EC - EC_KEY *eckey; + const EC_KEY *eckey; #endif diff -Nru postfix-3.5.6/src/tls/tls_proxy_client_scan.c postfix-3.5.13/src/tls/tls_proxy_client_scan.c --- postfix-3.5.6/src/tls/tls_proxy_client_scan.c 2019-02-11 08:32:27.000000000 -0500 +++ postfix-3.5.13/src/tls/tls_proxy_client_scan.c 2021-04-03 12:13:35.000000000 -0400 @@ -430,7 +430,8 @@ if (buf) vstring_free(buf); if (ret != 1) { - tls_proxy_client_certs_free(head); + if (head) + tls_proxy_client_certs_free(head); head = 0; } *(TLS_CERTS **) ptr = head; @@ -489,7 +490,8 @@ if (buf) vstring_free(buf); if (ret != 1) { - tls_proxy_client_pkeys_free(head); + if (head) + tls_proxy_client_pkeys_free(head); head = 0; } *(TLS_PKEYS **) ptr = head; @@ -538,7 +540,8 @@ ret = (ret == 3 ? 1 : -1); } if (ret != 1) { - tls_proxy_client_tlsa_free(head); + if (head) + tls_proxy_client_tlsa_free(head); head = 0; } *(TLS_TLSA **) ptr = head; diff -Nru postfix-3.5.6/src/tlsproxy/tlsproxy.c postfix-3.5.13/src/tlsproxy/tlsproxy.c --- postfix-3.5.6/src/tlsproxy/tlsproxy.c 2020-06-20 14:55:59.000000000 -0400 +++ postfix-3.5.13/src/tlsproxy/tlsproxy.c 2020-08-21 19:37:21.000000000 -0400 @@ -998,8 +998,17 @@ state->client_start_props->fd = state->ciphertext_fd; /* These predicates and warning belong inside tls_client_start(). */ if (!tls_dane_avail() /* mandatory side effects!! */ - &&TLS_DANE_BASED(state->client_start_props->tls_level)) - msg_warn("%s: DANE requested, but not available", + + /* + * Why not test for TLS_DANE_BASED()? Because the tlsproxy(8) client has + * already converted its DANE TLSA records into trust anchors, and + * therefore TLS_DANE_HASTA() will be true instead. That exercises the + * code path that updates the shared SSL_CTX with custom X.509 + * verification callbacks for trust anchors. + */ + &&TLS_DANE_HASTA(state->client_start_props->dane)) + msg_warn("%s: DANE or local trust anchor based chain" + " verification requested, but not available", state->client_start_props->namaddr); else state->tls_context = tls_client_start(state->client_start_props); @@ -1427,7 +1436,15 @@ } state->appl_state = tlsp_client_init(state->tls_params, state->client_init_props, - TLS_DANE_BASED(state->client_start_props->tls_level)); + + /* + * Why not test for TLS_DANE_BASED()? Because the tlsproxy(8) client + * has already converted its DANE TLSA records into trust anchors, + * and therefore TLS_DANE_HASTA() will be true instead. That + * exercises the code path that updates the shared SSL_CTX with + * custom X.509 verification callbacks for trust anchors. + */ + TLS_DANE_HASTA(state->client_start_props->dane) != 0); ready = state->appl_state != 0; break; case TLS_PROXY_FLAG_ROLE_SERVER: diff -Nru postfix-3.5.6/src/util/dict_inline.c postfix-3.5.13/src/util/dict_inline.c --- postfix-3.5.6/src/util/dict_inline.c 2018-11-05 19:25:30.000000000 -0500 +++ postfix-3.5.13/src/util/dict_inline.c 2021-04-03 19:46:12.000000000 -0400 @@ -113,9 +113,9 @@ dict = dict_open3(DICT_TYPE_HT, name, open_flags, dict_flags); dict_type_override(dict, DICT_TYPE_INLINE); while ((nameval = mystrtokq(&cp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) { - if ((nameval[0] != CHARS_BRACE[0] - || (err = free_me = extpar(&nameval, CHARS_BRACE, EXTPAR_FLAG_STRIP)) == 0) - && (err = split_qnameval(nameval, &vname, &value)) != 0) + if (nameval[0] == CHARS_BRACE[0]) + err = free_me = extpar(&nameval, CHARS_BRACE, EXTPAR_FLAG_STRIP); + if (err != 0 || (err = split_qnameval(nameval, &vname, &value)) != 0) break; if ((dict->flags & DICT_FLAG_SRC_RHS_IS_FILE) != 0) { diff -Nru postfix-3.5.6/src/util/dict_static.c postfix-3.5.13/src/util/dict_static.c --- postfix-3.5.6/src/util/dict_static.c 2018-11-05 19:25:30.000000000 -0500 +++ postfix-3.5.13/src/util/dict_static.c 2020-11-04 16:37:34.000000000 -0500 @@ -73,6 +73,8 @@ if (dict_static->value) myfree(dict_static->value); + if (dict->fold_buf) + vstring_free(dict->fold_buf); dict_free(dict); } diff -Nru postfix-3.5.6/src/util/dict_thash.c postfix-3.5.13/src/util/dict_thash.c --- postfix-3.5.6/src/util/dict_thash.c 2017-12-27 17:29:45.000000000 -0500 +++ postfix-3.5.13/src/util/dict_thash.c 2021-06-14 16:20:18.000000000 -0400 @@ -46,6 +46,7 @@ /* Utility library. */ #include <msg.h> +#include <mymalloc.h> #include <iostuff.h> #include <vstring.h> #include <stringops.h> @@ -180,6 +181,24 @@ " is this an alias file?", path, lineno); /* + * Optionally treat the value as a filename, and replace the value + * with the BASE64-encoded content of the named file. + */ + if (dict_flags & DICT_FLAG_SRC_RHS_IS_FILE) { + VSTRING *base64_buf; + char *err; + + if ((base64_buf = dict_file_to_b64(dict, value)) == 0) { + err = dict_file_get_error(dict); + msg_warn("%s, line %d: %s: skipping this entry", + VSTREAM_PATH(fp), lineno, err); + myfree(err); + continue; + } + value = vstring_str(base64_buf); + } + + /* * Store the value under the key. Handle duplicates * appropriately. XXX Move this into dict_ht, but 1) that map * ignores duplicates by default and we would have to check that diff -Nru postfix-3.5.6/src/util/mac_expand.c postfix-3.5.13/src/util/mac_expand.c --- postfix-3.5.6/src/util/mac_expand.c 2018-01-21 13:13:34.000000000 -0500 +++ postfix-3.5.13/src/util/mac_expand.c 2021-07-24 18:20:43.000000000 -0400 @@ -226,6 +226,7 @@ long result; char *remainder; + errno = 0; result = strtol(strval, &remainder, 10); if (*strval == 0 /* can't happen */ || *remainder != 0 || errno == ERANGE) msg_fatal("mac_exp_eval: bad conversion: %s", strval); diff -Nru postfix-3.5.6/src/util/slmdb.c postfix-3.5.13/src/util/slmdb.c --- postfix-3.5.6/src/util/slmdb.c 2017-02-18 20:58:21.000000000 -0500 +++ postfix-3.5.13/src/util/slmdb.c 2021-06-01 17:02:52.000000000 -0400 @@ -386,12 +386,16 @@ * - With a bulk-mode transaction we commit when the database is closed. */ if (slmdb->open_flags & O_TRUNC) { - if ((status = mdb_drop(slmdb->txn, slmdb->dbi, 0)) != 0) + if ((status = mdb_drop(slmdb->txn, slmdb->dbi, 0)) != 0) { + mdb_txn_abort(slmdb->txn); + slmdb->txn = 0; return (status); + } if ((slmdb->slmdb_flags & SLMDB_FLAG_BULK) == 0) { - if ((status = mdb_txn_commit(slmdb->txn)) != 0) - return (status); + status = mdb_txn_commit(slmdb->txn); slmdb->txn = 0; + if (status != 0) + return (status); } } else if ((slmdb->lmdb_flags & MDB_RDONLY) != 0 || (slmdb->slmdb_flags & SLMDB_FLAG_BULK) == 0) { @@ -582,11 +586,15 @@ * Do the update. */ if ((status = mdb_put(txn, slmdb->dbi, mdb_key, mdb_value, flags)) != 0) { - mdb_txn_abort(txn); if (status != MDB_KEYEXIST) { + mdb_txn_abort(txn); if ((status = slmdb_recover(slmdb, status)) == 0) status = slmdb_put(slmdb, mdb_key, mdb_value, flags); SLMDB_API_RETURN(slmdb, status); + } else { + /* Abort non-bulk transaction only. */ + if (slmdb->txn == 0) + mdb_txn_abort(txn); } }
signature.asc
Description: This is a digitally signed message part.