2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-22 01:49:47 +00:00

postfix-3.11-20250606

This commit is contained in:
Wietse Z Venema 2025-06-06 00:00:00 -05:00 committed by Viktor Dukhovni
parent 6a87331d09
commit 32475272ff
62 changed files with 1509 additions and 332 deletions

1
postfix/.indent.pro vendored
View File

@ -248,6 +248,7 @@
-TNBBIO
-TNVTABLE_INFO
-TOPTIONS
-TOSSL_DGST
-TPCF_DBMS_INFO
-TPCF_DEPR_PARAM_INFO
-TPCF_EVAL_CTX

View File

@ -29031,7 +29031,7 @@ Apologies for any names omitted.
causing information to become garbled. Fix by Michael
Tokarev. File: postconf/postconf_edit.c.
20259317
20250317
Documentation: added text to clarify the difference between
SMTP connection reuse and TLS session resumption, and that
@ -29095,10 +29095,102 @@ Apologies for any names omitted.
20250418
Code health: added unit tests for connection address and
Code health: added 16 unit tests for connection address and
port information received through haproxy or postscreen,
and improved error handling. Files: smtpd/smtpd_peer.c,
smtpd/smtpd_haproxy.c, smtpd/smtpd_peer_test.c.
Unit tests for 'direct' connections are deferred pending
support to mock or intercept system library function calls.
20250419
Documentation: Postfix LMDB locking protocol description.
File: proto/lmdb_table.
20250504
Logging: the memcache client truncated a memcached server
error message too aggressively. File: global/dict_memcache.c.
Code health: the dict_cache module did not expose a database
error to the caller. Files: util/dict_cache.[hc].
Code health: the verify(8) daemon now replies with 'address
verification status unavailable' when cache lookup fails
due to a database error, instead of replying with 'address
verification in progress'. File: verify/verify.c.
Code health: the verify(8) daemon no longer schedules an
address verification probe after a cache lookup for that
address failed due to a database error. File: verify/verify.c.
20250523
Documentation: load balancer workaround for Postfix <= 3.9.
Files: proto/mysql_table, proto/pgsql_table.
20250425
Documentation: TLSRPT_README typofix by Paul Menzel. File:
proto/TLSRPT_README.html.
20250509
Documentation: in "enable_idna2003_compatibility" descriptions,
confused zeta with final sigma. Geert Hendrickx. Files:
proto/SMTPUTF8_README, proto/postconf.proto.
Feature: specify "key_digest = name-of-openssl-digest" to
run memcache lookup keys through the named OpenSSL digest
and convert the result to lowercase hexadecimal characters,
after processing the key_format feature. This prevents a
database access error when keys may exceed the memcache
server's key length limit (usually, 250 bytes). Files:
20250523
Workaround: tweaked the timeout setting in postconf.proto
javascript. File: proto/postconf.html.prolog
20250525
Code health: don't allow the postmap or postalias "-i"
option together with one of the (-d, -q, or -s) options on
the command line. Files: postmap/postmap.c, postalias/postalias.c,
postmap/mode_conflict_test.*, postalias/mode_conflict_test.*.
Testing: some postalias and postmap tests depended on the
installed main.cf file. Files: postalias/Makefile.in,
postmap/Makefile.in.
Testing: 'nosleep' preload module to eliminate the delay
after logging a fatal error and before terminating a program.
Files: testing/Makefile.in, testing/nosleep.c,
postalias/Makefile.in, postmap/Makefile.in
20250526
Bugfix (defect introduced: Postfix 0.7.0, date 19990118):
postmap and postalias supported "-i" incremental updates
only for databases that support "bulk" create. With other
databases, the "-i" option was rejected with a misleading
error message "no 'map create' support". File: util/mkmap_open.c.
Usability: improved error message when a CDB table refuses
a delete or incremental update request (it complained about
some obscure POSIX open() flags). File: util/dict_cdb.c.
Cleanup: remove unnecessary newline characters in debug
logging. File: util/dict_db.c.
Debugging: added debug logging to the myflock() function.
File: util/myflock.c.
20250601
Changed the default smtp_tlsrpt_skip_reused_handshakes
setting from "yes" to "no". The new default is enabled with
compatibility level >= 3.11. Files: smtp/smtp_tlsrpt.c,
global/mail_params.[hc], proto/COMPATIBILITY_README.html.
proto/memcache_table, global/dict_memcache.c, util/hex_code.[hc].

View File

@ -12,7 +12,7 @@ DIRS = src/util src/global src/dns src/tls src/xsasl src/master src/milter \
src/postsuper src/qmqpd src/spawn src/flush src/verify \
src/virtual src/proxymap src/anvil src/scache src/discard src/tlsmgr \
src/postmulti src/postscreen src/dnsblog src/tlsproxy \
src/posttls-finger src/postlogd
src/posttls-finger src/postlogd src/testing
MANDIRS = proto man html
LIBEXEC = libexec/post-install libexec/postfix-script libexec/postfix-wrapper \
libexec/postmulti-script libexec/postfix-tls-script

View File

@ -57,6 +57,11 @@ Logged with compatibility_level < 3.6:
* Using backwards-compatible default setting respectful_logging=no
Logged with compatibility_level < 3.11:
* using backwards-compatible default setting
smtp_tlsrpt_skip_reused_handshakes=yes
If such a message is logged in the context of a legitimate request, the system
administrator should make the backwards-compatible setting permanent in main.cf
or master.cf, as detailed in the sections that follow.
@ -72,9 +77,9 @@ could result in unexpected non-delivery of email after Postfix is updated from
an older version. The backwards-compatibility safety net is designed to prevent
such surprises.
As long as the append_dot_mydomain parameter is left at its implicit default
value, and the compatibility_level setting is less than 1, Postfix may log one
of the following messages:
As long as the append_dot_mydomain parameter is left unspecified at its
implicit default value, and the compatibility_level setting is less than 1,
Postfix may log one of the following messages:
* Messages about missing "localhost" in mydestination or other address class:
@ -110,9 +115,9 @@ the chroot feature enabled after updating Postfix from an older version. The
backwards-compatibility safety net is designed allow the administrator to
choose if they want to keep the old behavior.
As long as a master.cf chroot field is left at its implicit default value, and
the compatibility_level setting is less than 1, Postfix may log the following
message while it reads the master.cf file:
As long as a master.cf chroot field is left unspecified at its implicit default
value, and the compatibility_level setting is less than 1, Postfix may log the
following message while it reads the master.cf file:
postfix/master[27664]: /etc/postfix/master.cf: line 72: using
backwards-compatible default setting chroot=y
@ -137,8 +142,8 @@ denied' errors after Postfix is updated from an older Postfix version. The
backwards-compatibility safety net is designed to prevent such surprises.
When the compatibility_level less than 1, and the smtpd_relay_restrictions
parameter is left at its implicit default setting, Postfix may log the
following message:
parameter is left unspecified at its implicit default setting, Postfix may log
the following message:
postfix/smtpd[38463]: using backwards-compatible default setting
"smtpd_relay_restrictions = (empty)" to avoid "Relay access
@ -160,10 +165,10 @@ that don't request SMTPUTF8 support, after Postfix is updated from an older
version. The backwards-compatibility safety net is designed to prevent such
surprises.
As long as the smtputf8_enable parameter is left at its implicit default value,
and the compatibility_level setting is less than 1, Postfix logs a warning each
time an SMTP command uses a non-ASCII address localpart without requesting
SMTPUTF8 support:
As long as the smtputf8_enable parameter is left unspecified at its implicit
default value, and the compatibility_level setting is less than 1, Postfix logs
a warning each time an SMTP command uses a non-ASCII address localpart without
requesting SMTPUTF8 support:
postfix/smtpd[27560]: using backwards-compatible default setting
smtputf8_enable=no to accept non-ASCII sender address
@ -188,9 +193,9 @@ could cause unexpected 'access denied' errors after Postfix is updated from an
older version. The backwards-compatibility safety net is designed to prevent
such surprises.
As long as the mynetworks and mynetworks_style parameters are left at their
implicit default values, and the compatibility_level setting is less than 2,
the Postfix SMTP server may log one of the following messages:
As long as the mynetworks and mynetworks_style parameters are left unspecified
at their implicit default values, and the compatibility_level setting is less
than 2, the Postfix SMTP server may log one of the following messages:
postfix/smtpd[17375]: using backwards-compatible default setting
mynetworks_style=subnet to permit request from client
@ -214,9 +219,9 @@ value. This could result in unexpected 'Relay access denied' errors or ETRN
errors after Postfix is updated from an older version. The backwards-
compatibility safety net is designed to prevent such surprises.
As long as the relay_domains parameter is left at its implicit default value,
and the compatibility_level setting is less than 2, Postfix may log one of the
following messages.
As long as the relay_domains parameter is left unspecified at its implicit
default value, and the compatibility_level setting is less than 2, Postfix may
log one of the following messages.
* Messages about accepting mail for a remote domain:
@ -263,10 +268,10 @@ deprecated) setting, you should consider switching to "sha256". This will
require updating any associated lookup table keys with the "sha256" digests of
the expected client certificate or public key.
As long as the smtpd_tls_fingerprint_digest parameter is left at its implicit
default value, and the compatibility_level setting is less than 3.6, Postfix
logs a warning each time a client certificate or public key fingerprint is
(potentially) used for access control:
As long as the smtpd_tls_fingerprint_digest parameter is left unspecified at
its implicit default value, and the compatibility_level setting is less than
3.6, Postfix logs a warning each time a client certificate or public key
fingerprint is (potentially) used for access control:
postfix/smtpd[27560]: using backwards-compatible default setting
smtpd_tls_fingerprint_digest=md5 to compute certificate fingerprints
@ -299,10 +304,10 @@ table to specify matching "sha256" digests of the expected server certificates
or public keys.
As long as the smtp_tls_fingerprint_digest (or LMTP equivalent) parameter is
left at its implicit default value, and the compatibility_level setting is less
than 3.6, Postfix logs a warning each time the "fingerprint" security level is
used to specify matching "md5" digests of trusted server certificates or public
keys:
left unspecified at its implicit default value, and the compatibility_level
setting is less than 3.6, Postfix logs a warning each time the "fingerprint"
security level is used to specify matching "md5" digests of trusted server
certificates or public keys:
postfix/smtp[27560]: using backwards-compatible default setting
smtp_tls_fingerprint_digest=md5 to compute certificate fingerprints
@ -332,8 +337,8 @@ behavior.
To maintain compatibility with earlier versions, Postfix will keep evaluating
smtpd_recipient_restrictions before smtpd_relay_restrictions, as long as the
compatibility_level is less than 3.6, and the
smtpd_relay_before_recipient_restrictions parameter is left at its implicit
default setting. As a reminder, Postfix may log the following message:
smtpd_relay_before_recipient_restrictions parameter is left unspecified at its
implicit default setting. As a reminder, Postfix may log the following message:
postfix/smtpd[54696]: using backwards-compatible default setting
smtpd_relay_before_recipient_restrictions=no to reject recipient
@ -356,10 +361,10 @@ backwards-compatible default values, the changes in logging could affect
logfile analysis tools.
To avoid breaking existing logfile analysis tools, Postfix will keep logging
the deprecated form, as long as the respectful_logging parameter is left at its
implicit default value, and the compatibility_level setting is less than 3.6.
As a reminder, Postfix may log the following when a remote SMTP client is
allowlisted or denylisted:
the deprecated form, as long as the respectful_logging parameter is left
unspecified at its implicit default value, and the compatibility_level setting
is less than 3.6. As a reminder, Postfix may log the following when a remote
SMTP client is allowlisted or denylisted:
postfix/postscreen[22642]: Using backwards-compatible default setting
respectful_logging=no for client [address]:port
@ -371,6 +376,29 @@ administrator should make the backwards-compatible setting "respectful_logging
# ppoossttccoonnff ""rreessppeeccttffuull__llooggggiinngg == nnoo""
# ppoossttffiixx rreellooaadd
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg
ssmmttpp__ttllssrrpptt__sskkiipp__rreeuusseedd__hhaannddsshhaakkeess==yyeess
Postfix version 3.11 changes the default value for
smtp_tlsrpt_skip_reused_handshakes from "yes" to "no". The backwards-
compatibility safety net is designed to prevent an unexpected change in
reporting behavior when Postfix is updated from an older version.
As long as the smtp_tlsrpt_skip_reused_handshakes parameter is left unspecified
at its implicit default value, and the compatibility_level setting is less than
3.11, Postfix will log a reminder that it is using the backwards-compatible
default:
postfix/smtp[388157] using backwards-compatible default setting
smtp_tlsrpt_skip_reused_handshakes=yes
To keep the old default setting, the system administrator should make the
backwards-compatible setting "smtp_tlsrpt_skip_reused_handshakes = yes"
permanent in main.cf:
# ppoossttccoonnff ssmmttpp__ttllssrrpptt__sskkiipp__rreeuusseedd__hhaannddsshhaakkeess==yyeess
# ppoossttffiixx rreellooaadd
TTuurrnniinngg ooffff tthhee bbaacckkwwaarrddss--ccoommppaattiibbiilliittyy ssaaffeettyy nneett
Backwards compatibility is turned off by updating the compatibility_level

View File

@ -278,8 +278,8 @@ current versions of the Firefox and Chrome web browsers. Specify
"enable_idna2003_compatibility = yes" to get the historical behavior.
This affects the conversion of domain names that contain for example the German
sz (ß) and the Greek zeta (ς). See https://unicode.org/cldr/utility/idna.jsp
for more examples.
sz (ß) and the Greek (final) sigma (ς). See https://unicode.org/cldr/utility/
idna.jsp for more examples.
CCrreeddiittss

View File

@ -188,11 +188,11 @@ Notes:
Untrusted TTLLSS ccoonnnneeccttiioonn rreeuusseedd to mail.example.com[ipaddr]:25:
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
* By default, Postfix does not report the TLSRPT status for a TLS handshake
that reuses a previously-negotiated TLS session (there would be no new
information to report). Specify "smtp_tlsrpt_skip_reused_handshakes = no"
to report the TLSRPT status for all TLS handshakes. This may be useful for
troubleshooting.
* With TLSRPT enabled, the Postfix SMTP client reports the TLSRPT status for
all TLS handshakes (the default as of Postfix 3.11). Specify
"smtp_tlsrpt_skip_reused_handshakes = yes" (the default with Postfix 3.10)
to skip reporting TLS handshakes that reuse a previously-negotiated TLS
session as there would be no new information to report.
* Postfix logging for certificate verification failures may differ between
new or reused TLS sessions.
@ -256,7 +256,7 @@ Options:
MMTTAA--SSTTSS SSuuppppoorrtt vviiaa ssmmttpp__ttllss__ppoolliiccyy__mmaappss
Postfix supports MTA-STS though an smtp_tls_policy_maps policy plugin, which
Postfix supports MTA-STS through an smtp_tls_policy_maps policy plugin, which
replies with a TLS security level and name=value attributes with certificate
matching requirements. Postfix 3.10 and later extend the policy plugin response
with additional name=value attributes that are needed for TLSRPT.

View File

@ -102,6 +102,17 @@ default setting respectful_logging=no</a> </p>
</ul>
<p> Logged with <a href="postconf.5.html#compatibility_level">compatibility_level</a> &lt; 3.11: </p>
<ul>
<li> <p> <a href="#tlsrpt_reused"> using backwards-compatible default
setting smtp_tlsrpt_skip_reused_handshakes=yes</a> </p>
</ul>
<p>
<p> If such a message is logged in the context of a legitimate
request, the system administrator should make the backwards-compatible
setting permanent in <a href="postconf.5.html">main.cf</a> or <a href="master.5.html">master.cf</a>, as detailed in the
@ -120,7 +131,8 @@ to "no". This could result in unexpected non-delivery of email after
Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p>
<p> As long as the <a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a> parameter is left at
<p> As long as the <a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a> parameter is left unspecified
at
its implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is
less than 1, Postfix may log one of the following messages:</p>
@ -178,7 +190,7 @@ after updating Postfix from an older version. The backwards-compatibility
safety net is designed allow the administrator to choose if they
want to keep the old behavior. </p>
<p> As long as a <a href="master.5.html">master.cf</a> chroot field is left at its
<p> As long as a <a href="master.5.html">master.cf</a> chroot field is left unspecified at its
implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting
is less than 1, Postfix may log the following message while it
reads the <a href="master.5.html">master.cf</a> file: </p>
@ -218,7 +230,8 @@ from an older Postfix version. The backwards-compatibility safety
net is designed to prevent such surprises. </p>
<p> When the <a href="postconf.5.html#compatibility_level">compatibility_level</a> less than 1, and the
<a href="postconf.5.html#smtpd_relay_restrictions">smtpd_relay_restrictions</a> parameter is left at its implicit default
<a href="postconf.5.html#smtpd_relay_restrictions">smtpd_relay_restrictions</a> parameter is left unspecified at its
implicit default
setting, Postfix may log the following message: </p>
<blockquote>
@ -250,7 +263,8 @@ addresses from clients that don't request SMTPUTF8 support, after
Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p>
<p> As long as the <a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> parameter is left at its implicit
<p> As long as the <a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> parameter is left unspecified
at its implicit
default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is
less than 1, Postfix logs a warning each time an SMTP command uses a
non-ASCII address localpart without requesting SMTPUTF8 support: </p>
@ -293,7 +307,8 @@ Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p>
<p> As long as the <a href="postconf.5.html#mynetworks">mynetworks</a> and <a href="postconf.5.html#mynetworks_style">mynetworks_style</a> parameters are
left at their implicit default values, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a>
left unspecified at their implicit default values, and the
<a href="postconf.5.html#compatibility_level">compatibility_level</a>
setting is less than 2, the Postfix SMTP server may log one of the
following messages: </p>
@ -333,7 +348,8 @@ denied' errors or ETRN errors after Postfix is updated from an older
version. The backwards-compatibility safety net is designed to
prevent such surprises. </p>
<p> As long as the <a href="postconf.5.html#relay_domains">relay_domains</a> parameter is left at its implicit
<p> As long as the <a href="postconf.5.html#relay_domains">relay_domains</a> parameter is left unspecified at
its implicit
default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is less than 2,
Postfix may log one of the following messages. </p>
@ -408,7 +424,8 @@ secure digest of the client certificate. </p>
with the "sha256" digests of the expected client certificate or public
key. </p>
<p> As long as the <a href="postconf.5.html#smtpd_tls_fingerprint_digest">smtpd_tls_fingerprint_digest</a> parameter is left at its
<p> As long as the <a href="postconf.5.html#smtpd_tls_fingerprint_digest">smtpd_tls_fingerprint_digest</a> parameter is left
unspecified at its
implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is less than
3.6, Postfix logs a warning each time a client certificate or public key
fingerprint is (potentially) used for access control: </p>
@ -455,7 +472,8 @@ policies in the TLS policy table to specify matching "sha256" digests of
the expected server certificates or public keys. </p>
<p> As long as the <a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> (or LMTP equivalent)
parameter is left at its implicit default value, and the
parameter is left unspecified at its implicit default value, and
the
<a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is less than 3.6, Postfix logs a warning each
time the "fingerprint" security level is used to specify matching "md5"
digests of trusted server certificates or public keys: </p>
@ -499,7 +517,8 @@ command, and both support the same features. </p> </blockquote>
keep evaluating <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> before
<a href="postconf.5.html#smtpd_relay_restrictions">smtpd_relay_restrictions</a>, as long as the <a href="postconf.5.html#compatibility_level">compatibility_level</a> is
less than 3.6, and the <a href="postconf.5.html#smtpd_relay_before_recipient_restrictions">smtpd_relay_before_recipient_restrictions</a>
parameter is left at its implicit default setting. As a reminder,
parameter is left unspecified at its implicit default setting. As
a reminder,
Postfix may log the following message: </p>
<blockquote>
@ -533,7 +552,8 @@ the changes in logging could affect logfile analysis tools. </p>
<p> To avoid breaking existing logfile analysis tools, Postfix will keep
logging the deprecated form, as long as the <a href="postconf.5.html#respectful_logging">respectful_logging</a> parameter
is left at its implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a>
is left unspecified at its implicit default value, and the
<a href="postconf.5.html#compatibility_level">compatibility_level</a>
setting is less than 3.6. As a reminder, Postfix may log the following
when a remote SMTP client is allowlisted or denylisted: </p>
@ -555,6 +575,38 @@ system administrator should make the backwards-compatible setting
</pre>
</blockquote>
<h2> <a name="tlsrpt_reused"> Using backwards-compatible
default setting smtp_tlsrpt_skip_reused_handshakes=yes</a> </h2>
<p> Postfix version 3.11 changes the default value for
<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a> from "yes" to "no". The
backwards-compatibility safety net is designed to prevent an
unexpected change in reporting behavior when Postfix is updated
from an older version. </p>
<p> As long as the <a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a> parameter is
left unspecified at its implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a>
setting is less than 3.11, Postfix will log a reminder that it is
using the backwards-compatible default: </p>
<blockquote>
<pre>
postfix/smtp[388157] using backwards-compatible default setting
<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a>=yes
</pre>
</blockquote>
<p> To keep the old default setting, the system administrator should
make the backwards-compatible setting "<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a>
= yes" permanent in <a href="postconf.5.html">main.cf</a>:
<blockquote>
<pre>
# <b>postconf <a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a>=yes</b>
# <b>postfix reload</b>
</pre>
</blockquote>
<h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2>
<p> Backwards compatibility is turned off by updating the

View File

@ -375,7 +375,7 @@ Firefox and Chrome web browsers. Specify "<a href="postconf.5.html#enable_idna20
= yes" to get the historical behavior. </p>
<p> This affects the conversion of domain names that contain for
example the German sz (ß) and the Greek zeta (ς). See
example the German sz (ß) and the Greek (final) sigma (ς). See
<a href="https://unicode.org/cldr/utility/idna.jsp">https://unicode.org/cldr/utility/idna.jsp</a> for more examples. </p>
<h2> <a name="credits">Credits</a> </h2>

View File

@ -286,12 +286,12 @@ Untrusted <b>TLS connection reused</b> to mail.example.com[ipaddr]:25:
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
</pre>
<li> <p> By default, Postfix does not report the TLSRPT status for
a TLS handshake that reuses a previously-negotiated TLS session
(there would be no new information to report). Specify
"<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a> = no" to report the TLSRPT
status for all TLS handshakes. This may be useful for troubleshooting.
</p>
<li> <p> With TLSRPT enabled, the Postfix SMTP client reports the
TLSRPT status for all TLS handshakes (the default as of Postfix
3.11). Specify "<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a> = yes" (the
default with Postfix 3.10) to skip reporting TLS handshakes that
reuse a previously-negotiated TLS session as there would be no new
information to report. </p>
<li> <p> Postfix logging for certificate verification failures may
differ between new or reused TLS sessions. </p>
@ -373,7 +373,7 @@ generator's sender address): </p>
<h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps
</a></h2>
<p> Postfix supports MTA-STS though an <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> policy
<p> Postfix supports MTA-STS through an <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> policy
plugin, which replies with a TLS security level and name=value
attributes with certificate matching requirements. Postfix 3.10 and
later extend the policy plugin response with additional name=value

View File

@ -56,24 +56,25 @@ LMDB_TABLE(5) LMDB_TABLE(5)
<b><a name="synchronization">SYNCHRONIZATION</a></b>
The Postfix LMDB adapter does not use LMDB's built-in locking scheme,
because that would require world-writable lockfiles and would violate
the Postfix security model. Instead, Postfix uses fcntl(2) locks with
whole-file granularity. Programs that use LMDB's built-in locking pro-
tocol will corrupt a Postfix LMDB database or will read garbage.
because that would require world-writable lockfiles and therefore vio-
late the Postfix security model. Instead, Postfix uses fcntl(2) locks
with whole-file granularity. Programs that use LMDB's built-in locking
protocol will corrupt a Postfix LMDB database or will read garbage.
Every Postfix LMDB database read or write transaction must be protected
from start to end with a shared or exclusive fcntl(2) lock. A writer
may atomically downgrade an exclusive lock to a shared lock, but it
must hold an exclusive lock while opening another write transaction.
from start to end with a shared or exclusive fcntl(2) lock. A process
may atomically downgrade an exclusive lock to a shared lock before
opening a database read transaction, but it must hold an exclusive lock
while opening a write transaction.
Note that fcntl(2) locks do not protect transactions within the same
process against each other. If a program cannot avoid making simulta-
neous database requests, then it must protect its transactions with
Note that fcntl(2) locks do not protect transactions within the same
process against each other. If a program cannot avoid making simulta-
neous database requests, then it must protect its transactions with
in-process locks, in addition to the per-process fcntl(2) locks.
<b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
Short-lived programs automatically pick up changes to <a href="postconf.5.html">main.cf</a>. With
long-running daemon programs, Use the command "<b>postfix reload</b>" after a
Short-lived programs automatically pick up changes to <a href="postconf.5.html">main.cf</a>. With
long-running daemon programs, Use the command "<b>postfix reload</b>" after a
configuration change.
<b><a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> (16777216)</b>

View File

@ -99,18 +99,30 @@ MEMCACHE_TABLE(5) MEMCACHE_TABLE(5)
time. Smaller values are relative to the time of the update.
<b><a name="memcache_key_parameters">MEMCACHE KEY PARAMETERS</a></b>
<b>key_digest (default: empty)</b>
After processing the <b>key_format</b> setting, and before sending a
request to the memcache server, run the key through the named
message digest algorithm and convert the result to lowercase
hexadecimal characters. This prevents a database access error
when keys may exceed the memcache server's key length limit
(usually, 250 bytes). Specify the name of a message digest algo-
rithm that is supported by OpenSSL, for example, <b>sha256</b>.
This feature is available in Postfix 3.11 and later, and
requires that Postfix is built with TLS support.
<b>key_format (default: %s)</b>
Format of the lookup and update keys that the Postfix memcache
client sends to the memcache server. By default, these are the
same as the lookup and update keys that the memcache client
Format of the lookup and update keys that the Postfix memcache
client sends to the memcache server. By default, these are the
same as the lookup and update keys that the memcache client
receives from Postfix applications.
NOTE 1: The <b>key_format</b> feature is not used for <b>backup</b> database
NOTE 1: The <b>key_format</b> feature is not used for <b>backup</b> database
requests.
NOTE 2: When multiple tables share the same memcache database,
each table should prepend its own unique string to the lookup
key. Otherwise, automatic <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache
NOTE 2: When multiple tables share the same memcache database,
each table should prepend its own unique string to the lookup
key. Otherwise, automatic <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache
cleanup may not work.
Examples:
@ -126,37 +138,37 @@ MEMCACHE_TABLE(5) MEMCACHE_TABLE(5)
<b>%s</b> This is replaced by the memcache client input key.
<b>%u</b> When the input key is an address of the form user@domain,
<b>%u</b> is replaced by the SQL quoted local part of the
address. Otherwise, <b>%u</b> is replaced by the entire search
string. If the localpart is empty, a lookup is silently
suppressed and returns no results (an update is skipped
<b>%u</b> is replaced by the SQL quoted local part of the
address. Otherwise, <b>%u</b> is replaced by the entire search
string. If the localpart is empty, a lookup is silently
suppressed and returns no results (an update is skipped
with a warning).
<b>%d</b> When the input key is an address of the form user@domain,
<b>%d</b> is replaced by the domain part of the address. Other-
wise, a lookup is silently suppressed and returns no
wise, a lookup is silently suppressed and returns no
results (an update is skipped with a warning).
<b>%[SUD]</b> The upper-case equivalents of the above expansions behave
in the <b>key_format</b> parameter identically to their
in the <b>key_format</b> parameter identically to their
lower-case counter-parts.
<b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced by the corre-
sponding most significant component of the input key's
domain. If the input key is <i>user@mail.example.com</i>, then
<b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced by the corre-
sponding most significant component of the input key's
domain. If the input key is <i>user@mail.example.com</i>, then
%1 is <b>com</b>, %2 is <b>example</b> and %3 is <b>mail</b>. If the input key
is unqualified or does not have enough domain components
to satisfy all the specified patterns, a lookup is
silently suppressed and returns no results (an update is
is unqualified or does not have enough domain components
to satisfy all the specified patterns, a lookup is
silently suppressed and returns no results (an update is
skipped with a warning).
<b>domain (default: no domain list)</b>
This feature can significantly reduce database server load.
Specify a list of domain names, paths to files, or "<a href="DATABASE_README.html">type:table</a>"
databases. When specified, only fully qualified search keys
with a *non-empty* localpart and a matching domain are eligible
for lookup or update: bare 'user' lookups, bare domain lookups
and "@domain" lookups are silently skipped (updates are skipped
This feature can significantly reduce database server load.
Specify a list of domain names, paths to files, or "<a href="DATABASE_README.html">type:table</a>"
databases. When specified, only fully qualified search keys
with a *non-empty* localpart and a matching domain are eligible
for lookup or update: bare 'user' lookups, bare domain lookups
and "@domain" lookups are silently skipped (updates are skipped
with a warning). Example:
domain = example.com, <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/searchdomains
@ -169,30 +181,30 @@ MEMCACHE_TABLE(5) MEMCACHE_TABLE(5)
The maximal memcache reply line length in bytes.
<b>max_try (default: 2)</b>
The number of times to try a memcache command before giving up.
The memcache client does not retry a command when the memcache
The number of times to try a memcache command before giving up.
The memcache client does not retry a command when the memcache
server accepts no connection.
<b>retry_pause (default: 1)</b>
The time in seconds before retrying a failed memcache command.
<b>timeout (default: 2)</b>
The time limit for sending a memcache command and for receiving
The time limit for sending a memcache command and for receiving
a memcache reply.
<b><a name="bugs">BUGS</a></b>
The Postfix memcache client cannot be used for security-sensitive
The Postfix memcache client cannot be used for security-sensitive
tables such as <b><a href="postconf.5.html#alias_maps">alias_maps</a></b> (these may contain "<i>|command</i> and "<i>/file/name</i>"
destinations), or <b><a href="postconf.5.html#virtual_uid_maps">virtual_uid_maps</a></b>, <b><a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a></b> and <b><a href="postconf.5.html#virtual_mailbox_maps">virtual_mail</a>-</b>
<b><a href="postconf.5.html#virtual_mailbox_maps">box_maps</a></b> (these specify UNIX process privileges or "<i>/file/name</i>" desti-
nations). In a typical deployment a memcache database is writable by
any process that can talk to the memcache server; in contrast, secu-
rity-sensitive tables must never be writable by the unprivileged Post-
destinations), or <b><a href="postconf.5.html#virtual_uid_maps">virtual_uid_maps</a></b>, <b><a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a></b> and <b><a href="postconf.5.html#virtual_mailbox_maps">virtual_mail</a>-</b>
<b><a href="postconf.5.html#virtual_mailbox_maps">box_maps</a></b> (these specify UNIX process privileges for "<i>/file/name</i>" desti-
nations). In a typical deployment a memcache database is writable by
any process that can talk to the memcache server; in contrast, secu-
rity-sensitive tables must never be writable by the unprivileged Post-
fix user.
The Postfix memcache client requires additional configuration when used
as <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache. For details see the <b>backup</b> and
<b>ttl</b> parameter discussions in the MEMCACHE MAIN PARAMETERS section
as <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache. For details see the <b>backup</b> and
<b>ttl</b> parameter discussions in the MEMCACHE MAIN PARAMETERS section
above.
<b><a name="see_also">SEE ALSO</a></b>

View File

@ -61,16 +61,15 @@ MYSQL_TABLE(5) MYSQL_TABLE(5)
TCP you have to specify
hosts = 127.0.0.1
NOTE: if the <b>hosts</b> setting specifies one server, this client
assumes that the target is a load balancer and will reconnect
immediately after a single failure, instead of failing all
requests temporarily. With older versions of this client, spec-
ify the same server twice.
NOTE: if the <b>hosts</b> setting specifies only one server, this
client assumes that the target is a load balancer and will
reconnect immediately after a single failure. With Postfix ver-
sions 3.9 and earlier, specify the same server twice.
<b>user</b>
<b>password</b>
The user name and password to log into the mysql server. Exam-
The user name and password to log into the mysql server. Exam-
ple:
user = someone
password = some_password
@ -79,15 +78,15 @@ MYSQL_TABLE(5) MYSQL_TABLE(5)
dbname = customer_database
<b>charset (default: utf8mb4)</b>
The default MySQL client character set; this also implies the
The default MySQL client character set; this also implies the
collation order.
This parameter is available with Postfix 3.9 and later. With
earlier Postfix versions, the default was chosen by the MySQL
This parameter is available with Postfix 3.9 and later. With
earlier Postfix versions, the default was chosen by the MySQL
implementation (<b>utf8mb4</b> as of MySQL 8.0, <b>latin1</b> historically).
<b>idle_interval (default: 60)</b>
The number of seconds after which an idle database connection
The number of seconds after which an idle database connection
will be closed.
This feature is available in Postfix 3.9 and later.
@ -96,11 +95,10 @@ MYSQL_TABLE(5) MYSQL_TABLE(5)
The number of seconds that a database connection will be skipped
after an error.
NOTE: if the <b>hosts</b> setting specifies one server, this client
assumes that the target is a load balancer and will reconnect
immediately after a single failure, instead of failing all
requests temporarily. With older versions of this client, spec-
ify the same server twice.
NOTE: if the <b>hosts</b> setting specifies only one server, this
client assumes that the target is a load balancer and will
reconnect immediately after a single failure. With Postfix ver-
sions 3.9 and earlier, specify the same server twice.
This feature is available in Postfix 3.9 and later.

View File

@ -65,16 +65,15 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
URI, the Postfix PostgreSQL client will ignore the <b>dbname</b>, <b>user</b>,
and <b>password</b> settings for that connection.
NOTE: if the <b>hosts</b> setting specifies one server, this client
assumes that the target is a load balancer and will reconnect
immediately after a single failure, instead of failing all
requests temporarily. With older versions of this client, spec-
ify the same server twice.
NOTE: if the <b>hosts</b> setting specifies only one server, this
client assumes that the target is a load balancer and will
reconnect immediately after a single failure. With Postfix ver-
sions 3.9 and earlier, specify the same server twice.
<b>user</b>
<b>password</b>
The user name and password to log into the pgsql server. Exam-
The user name and password to log into the pgsql server. Exam-
ple:
user = someone
password = some_password
@ -85,25 +84,25 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
<b>dbname</b> The database name on the servers. Example:
dbname = customer_database
The <b>dbname</b> setting is ignored for <b>hosts</b> connections that are
The <b>dbname</b> setting is ignored for <b>hosts</b> connections that are
specified as an URI.
The <b>dbname</b> setting is required with Postfix 3.10 and later, when
<b>hosts</b> specifies any non-URI connection; it is always required
<b>hosts</b> specifies any non-URI connection; it is always required
with earlier Postfix versions.
<b>encoding</b>
The encoding used by the database client. The default setting
The encoding used by the database client. The default setting
is:
encoding = UTF8
Historically, the database client was hard coded to use LATIN1
Historically, the database client was hard coded to use LATIN1
in an attempt to disable multibyte character support.
This feature is available in Postfix 3.8 and later.
<b>idle_interval (default: 60)</b>
The number of seconds after which an idle database connection
The number of seconds after which an idle database connection
will be closed.
This feature is available in Postfix 3.9 and later.
@ -112,11 +111,10 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
The number of seconds that a database connection will be skipped
after an error.
NOTE: if the <b>hosts</b> setting specifies one server, this client
assumes that the target is a load balancer and will reconnect
immediately after a single failure, instead of failing all
requests temporarily. With older versions of this client, spec-
ify the same server twice.
NOTE: if the <b>hosts</b> setting specifies only one server, this
client assumes that the target is a load balancer and will
reconnect immediately after a single failure. With Postfix ver-
sions 3.9 and earlier, specify the same server twice.
This feature is available in Postfix 3.9 and later.

View File

@ -20,7 +20,7 @@ if (hash && isChrome) {
setTimeout(function() {
window.location.hash = "";
window.location.hash = hash;
}, 1000);
}, 1500);
}
</script>
@ -3349,7 +3349,7 @@ with older Postfix versions). </p>
when converting UTF-8 domain names to/from the ASCII form that is
used for DNS lookups. Specify "yes" for compatibility with Postfix
&le; 3.1 (not recommended). This affects the conversion of domain
names that contain for example the German sz and the Greek zeta.
names that contain for example the German sz and the Greek sigma.
See <a href="https://unicode.org/cldr/utility/idna.jsp">https://unicode.org/cldr/utility/idna.jsp</a> for more examples.
</p>
@ -14870,13 +14870,11 @@ requirements for MTA-STS <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls
</DD>
<DT><b><a name="smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a>
(default: yes)</b></DT><DD>
(default: Postfix &ge; 3.11: no, Postfix 3.10: yes)</b></DT><DD>
<p> Do not report the TLSRPT status for TLS protocol handshakes
that reuse a previously-negotiated TLS session (there is no new
information to report). Report the TLSRPT status only for "new" TLS
sessions. Set this to "no" to log the TLSRPT status of all TLS
handshakes, for example to troubleshoot Postfix TLSRPT support.
<p> When set to "yes", report the TLSRPT status only for "new" TLS
sessions. When set to "no", also report the TLSRPT status for TLS
protocol handshakes that reuse a previously-negotiated TLS session.
</p>
<p> Note: if an SMTP over TLS connection is reused, there is no

View File

@ -72,16 +72,17 @@ postscreen(8) services.
.fi
The Postfix LMDB adapter does not use LMDB's built\-in locking
scheme, because that would require world\-writable lockfiles
and would violate the Postfix security model. Instead,
and therefore violate the Postfix security model. Instead,
Postfix uses fcntl(2) locks with whole\-file granularity.
Programs that use LMDB's built\-in locking protocol will
corrupt a Postfix LMDB database or will read garbage.
Every Postfix LMDB database read or write transaction must
be protected from start to end with a shared or exclusive
fcntl(2) lock. A writer may atomically downgrade an exclusive
lock to a shared lock, but it must hold an exclusive lock
while opening another write transaction.
fcntl(2) lock. A process may atomically downgrade an exclusive
lock to a shared lock before opening a database read transaction,
but it must hold an exclusive lock while opening a write
transaction.
Note that fcntl(2) locks do not protect transactions within
the same process against each other. If a program cannot

View File

@ -112,6 +112,17 @@ time. Smaller values are relative to the time of the update.
.nf
.ad
.fi
.IP "\fBkey_digest (default: empty)\fB"
After processing the \fBkey_format\fR setting, and before sending
a request to the memcache server, run the key through the named
message digest algorithm and convert the result to lowercase
hexadecimal characters. This prevents a database access error
when keys may exceed the memcache server's key length limit
(usually, 250 bytes). Specify the name of a message digest
algorithm that is supported by OpenSSL, for example, \fBsha256\fR.
This feature is available in Postfix 3.11 and later, and requires
that Postfix is built with TLS support.
.IP "\fBkey_format (default: %s)\fB"
Format of the lookup and update keys that the Postfix
memcache client sends to the memcache server.
@ -207,7 +218,7 @@ tables such as \fBalias_maps\fR (these may contain
"\fI|command\fR and "\fI/file/name\fR" destinations), or
\fBvirtual_uid_maps\fR, \fBvirtual_gid_maps\fR and
\fBvirtual_mailbox_maps\fR (these specify UNIX process
privileges or "\fI/file/name\fR" destinations). In a typical
privileges for "\fI/file/name\fR" destinations). In a typical
deployment a memcache database is writable by any process
that can talk to the memcache server; in contrast,
security\-sensitive tables must never be writable by the

View File

@ -77,11 +77,10 @@ localhost over TCP you have to specify
hosts = 127.0.0.1
.fi
NOTE: if the \fBhosts\fR setting specifies one server, this client
assumes that the target is a load balancer and will reconnect
immediately after a single failure, instead of failing all
requests temporarily. With older versions of this client,
specify the same server twice.
NOTE: if the \fBhosts\fR setting specifies only one server,
this client assumes that the target is a load balancer and
will reconnect immediately after a single failure. With Postfix
versions 3.9 and earlier, specify the same server twice.
.IP "\fBuser\fR"
.IP "\fBpassword\fR"
The user name and password to log into the mysql server.
@ -112,11 +111,10 @@ This feature is available in Postfix 3.9 and later.
The number of seconds that a database connection will be
skipped after an error.
NOTE: if the \fBhosts\fR setting specifies one server, this client
assumes that the target is a load balancer and will reconnect
immediately after a single failure, instead of failing all
requests temporarily. With older versions of this client,
specify the same server twice.
NOTE: if the \fBhosts\fR setting specifies only one server,
this client assumes that the target is a load balancer and
will reconnect immediately after a single failure. With Postfix
versions 3.9 and earlier, specify the same server twice.
This feature is available in Postfix 3.9 and later.
.IP "\fBquery\fR"

View File

@ -81,11 +81,10 @@ NOTE: if the \fBhosts\fR setting specifies a PostgreSQL connection
URI, the Postfix PostgreSQL client will ignore the \fBdbname\fR,
\fBuser\fR, and \fBpassword\fR settings for that connection.
NOTE: if the \fBhosts\fR setting specifies one server, this client
assumes that the target is a load balancer and will reconnect
immediately after a single failure, instead of failing all
requests temporarily. With older versions of this client,
specify the same server twice.
NOTE: if the \fBhosts\fR setting specifies only one server,
this client assumes that the target is a load balancer and
will reconnect immediately after a single failure. With Postfix
versions 3.9 and earlier, specify the same server twice.
.IP "\fBuser\fR"
.IP "\fBpassword\fR"
The user name and password to log into the pgsql server.
@ -129,11 +128,10 @@ This feature is available in Postfix 3.9 and later.
The number of seconds that a database connection will be
skipped after an error.
NOTE: if the \fBhosts\fR setting specifies one server, this client
assumes that the target is a load balancer and will reconnect
immediately after a single failure, instead of failing all
requests temporarily. With older versions of this client,
specify the same server twice.
NOTE: if the \fBhosts\fR setting specifies only one server,
this client assumes that the target is a load balancer and
will reconnect immediately after a single failure. With Postfix
versions 3.9 and earlier, specify the same server twice.
This feature is available in Postfix 3.9 and later.
.IP "\fBquery\fR"

View File

@ -2079,7 +2079,7 @@ Enable 'transitional' compatibility between IDNA2003 and IDNA2008,
when converting UTF\-8 domain names to/from the ASCII form that is
used for DNS lookups. Specify "yes" for compatibility with Postfix
<= 3.1 (not recommended). This affects the conversion of domain
names that contain for example the German sz and the Greek zeta.
names that contain for example the German sz and the Greek sigma.
See https://unicode.org/cldr/utility/idna.jsp for more examples.
.PP
This feature is available in Postfix 3.2 and later.
@ -9921,12 +9921,10 @@ See TLSRPT_README for configuration examples and additional
requirements for MTA\-STS smtp_tls_policy_maps plugins.
.PP
This feature is available in Postfix >= 3.10.
.SH smtp_tlsrpt_skip_reused_handshakes (default: yes)
Do not report the TLSRPT status for TLS protocol handshakes
that reuse a previously\-negotiated TLS session (there is no new
information to report). Report the TLSRPT status only for "new" TLS
sessions. Set this to "no" to log the TLSRPT status of all TLS
handshakes, for example to troubleshoot Postfix TLSRPT support.
.SH smtp_tlsrpt_skip_reused_handshakes (default: Postfix >= 3.11: no, Postfix 3.10: yes)
When set to "yes", report the TLSRPT status only for "new" TLS
sessions. When set to "no", also report the TLSRPT status for TLS
protocol handshakes that reuse a previously\-negotiated TLS session.
.PP
Note: if an SMTP over TLS connection is reused, there is no
second etc. TLS handshake to report.

View File

@ -102,6 +102,17 @@ default setting respectful_logging=no</a> </p>
</ul>
<p> Logged with compatibility_level &lt; 3.11: </p>
<ul>
<li> <p> <a href="#tlsrpt_reused"> using backwards-compatible default
setting smtp_tlsrpt_skip_reused_handshakes=yes</a> </p>
</ul>
<p>
<p> If such a message is logged in the context of a legitimate
request, the system administrator should make the backwards-compatible
setting permanent in main.cf or master.cf, as detailed in the
@ -120,7 +131,8 @@ to "no". This could result in unexpected non-delivery of email after
Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p>
<p> As long as the append_dot_mydomain parameter is left at
<p> As long as the append_dot_mydomain parameter is left unspecified
at
its implicit default value, and the compatibility_level setting is
less than 1, Postfix may log one of the following messages:</p>
@ -178,7 +190,7 @@ after updating Postfix from an older version. The backwards-compatibility
safety net is designed allow the administrator to choose if they
want to keep the old behavior. </p>
<p> As long as a master.cf chroot field is left at its
<p> As long as a master.cf chroot field is left unspecified at its
implicit default value, and the compatibility_level setting
is less than 1, Postfix may log the following message while it
reads the master.cf file: </p>
@ -218,7 +230,8 @@ from an older Postfix version. The backwards-compatibility safety
net is designed to prevent such surprises. </p>
<p> When the compatibility_level less than 1, and the
smtpd_relay_restrictions parameter is left at its implicit default
smtpd_relay_restrictions parameter is left unspecified at its
implicit default
setting, Postfix may log the following message: </p>
<blockquote>
@ -250,7 +263,8 @@ addresses from clients that don't request SMTPUTF8 support, after
Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p>
<p> As long as the smtputf8_enable parameter is left at its implicit
<p> As long as the smtputf8_enable parameter is left unspecified
at its implicit
default value, and the compatibility_level setting is
less than 1, Postfix logs a warning each time an SMTP command uses a
non-ASCII address localpart without requesting SMTPUTF8 support: </p>
@ -293,7 +307,8 @@ Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p>
<p> As long as the mynetworks and mynetworks_style parameters are
left at their implicit default values, and the compatibility_level
left unspecified at their implicit default values, and the
compatibility_level
setting is less than 2, the Postfix SMTP server may log one of the
following messages: </p>
@ -333,7 +348,8 @@ denied' errors or ETRN errors after Postfix is updated from an older
version. The backwards-compatibility safety net is designed to
prevent such surprises. </p>
<p> As long as the relay_domains parameter is left at its implicit
<p> As long as the relay_domains parameter is left unspecified at
its implicit
default value, and the compatibility_level setting is less than 2,
Postfix may log one of the following messages. </p>
@ -408,7 +424,8 @@ secure digest of the client certificate. </p>
with the "sha256" digests of the expected client certificate or public
key. </p>
<p> As long as the smtpd_tls_fingerprint_digest parameter is left at its
<p> As long as the smtpd_tls_fingerprint_digest parameter is left
unspecified at its
implicit default value, and the compatibility_level setting is less than
3.6, Postfix logs a warning each time a client certificate or public key
fingerprint is (potentially) used for access control: </p>
@ -455,7 +472,8 @@ policies in the TLS policy table to specify matching "sha256" digests of
the expected server certificates or public keys. </p>
<p> As long as the smtp_tls_fingerprint_digest (or LMTP equivalent)
parameter is left at its implicit default value, and the
parameter is left unspecified at its implicit default value, and
the
compatibility_level setting is less than 3.6, Postfix logs a warning each
time the "fingerprint" security level is used to specify matching "md5"
digests of trusted server certificates or public keys: </p>
@ -499,7 +517,8 @@ command, and both support the same features. </p> </blockquote>
keep evaluating smtpd_recipient_restrictions before
smtpd_relay_restrictions, as long as the compatibility_level is
less than 3.6, and the smtpd_relay_before_recipient_restrictions
parameter is left at its implicit default setting. As a reminder,
parameter is left unspecified at its implicit default setting. As
a reminder,
Postfix may log the following message: </p>
<blockquote>
@ -533,7 +552,8 @@ the changes in logging could affect logfile analysis tools. </p>
<p> To avoid breaking existing logfile analysis tools, Postfix will keep
logging the deprecated form, as long as the respectful_logging parameter
is left at its implicit default value, and the compatibility_level
is left unspecified at its implicit default value, and the
compatibility_level
setting is less than 3.6. As a reminder, Postfix may log the following
when a remote SMTP client is allowlisted or denylisted: </p>
@ -555,6 +575,38 @@ system administrator should make the backwards-compatible setting
</pre>
</blockquote>
<h2> <a name="tlsrpt_reused"> Using backwards-compatible
default setting smtp_tlsrpt_skip_reused_handshakes=yes</a> </h2>
<p> Postfix version 3.11 changes the default value for
smtp_tlsrpt_skip_reused_handshakes from "yes" to "no". The
backwards-compatibility safety net is designed to prevent an
unexpected change in reporting behavior when Postfix is updated
from an older version. </p>
<p> As long as the smtp_tlsrpt_skip_reused_handshakes parameter is
left unspecified at its implicit default value, and the compatibility_level
setting is less than 3.11, Postfix will log a reminder that it is
using the backwards-compatible default: </p>
<blockquote>
<pre>
postfix/smtp[388157] using backwards-compatible default setting
smtp_tlsrpt_skip_reused_handshakes=yes
</pre>
</blockquote>
<p> To keep the old default setting, the system administrator should
make the backwards-compatible setting "smtp_tlsrpt_skip_reused_handshakes
= yes" permanent in main.cf:
<blockquote>
<pre>
# <b>postconf smtp_tlsrpt_skip_reused_handshakes=yes</b>
# <b>postfix reload</b>
</pre>
</blockquote>
<h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2>
<p> Backwards compatibility is turned off by updating the

View File

@ -375,7 +375,7 @@ Firefox and Chrome web browsers. Specify "enable_idna2003_compatibility
= yes" to get the historical behavior. </p>
<p> This affects the conversion of domain names that contain for
example the German sz (ß) and the Greek zeta (ς). See
example the German sz (ß) and the Greek (final) sigma (ς). See
https://unicode.org/cldr/utility/idna.jsp for more examples. </p>
<h2> <a name="credits">Credits</a> </h2>

View File

@ -286,12 +286,12 @@ Untrusted <b>TLS connection reused</b> to mail.example.com[ipaddr]:25:
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
</pre>
<li> <p> By default, Postfix does not report the TLSRPT status for
a TLS handshake that reuses a previously-negotiated TLS session
(there would be no new information to report). Specify
"smtp_tlsrpt_skip_reused_handshakes = no" to report the TLSRPT
status for all TLS handshakes. This may be useful for troubleshooting.
</p>
<li> <p> With TLSRPT enabled, the Postfix SMTP client reports the
TLSRPT status for all TLS handshakes (the default as of Postfix
3.11). Specify "smtp_tlsrpt_skip_reused_handshakes = yes" (the
default with Postfix 3.10) to skip reporting TLS handshakes that
reuse a previously-negotiated TLS session as there would be no new
information to report. </p>
<li> <p> Postfix logging for certificate verification failures may
differ between new or reused TLS sessions. </p>
@ -373,7 +373,7 @@ generator's sender address): </p>
<h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps
</a></h2>
<p> Postfix supports MTA-STS though an smtp_tls_policy_maps policy
<p> Postfix supports MTA-STS through an smtp_tls_policy_maps policy
plugin, which replies with a TLS security level and name=value
attributes with certificate matching requirements. Postfix 3.10 and
later extend the policy plugin response with additional name=value

View File

@ -60,16 +60,17 @@
# .fi
# The Postfix LMDB adapter does not use LMDB's built-in locking
# scheme, because that would require world-writable lockfiles
# and would violate the Postfix security model. Instead,
# and therefore violate the Postfix security model. Instead,
# Postfix uses fcntl(2) locks with whole-file granularity.
# Programs that use LMDB's built-in locking protocol will
# corrupt a Postfix LMDB database or will read garbage.
#
# Every Postfix LMDB database read or write transaction must
# be protected from start to end with a shared or exclusive
# fcntl(2) lock. A writer may atomically downgrade an exclusive
# lock to a shared lock, but it must hold an exclusive lock
# while opening another write transaction.
# fcntl(2) lock. A process may atomically downgrade an exclusive
# lock to a shared lock before opening a database read transaction,
# but it must hold an exclusive lock while opening a write
# transaction.
#
# Note that fcntl(2) locks do not protect transactions within
# the same process against each other. If a program cannot

View File

@ -102,6 +102,17 @@
# MEMCACHE KEY PARAMETERS
# .ad
# .fi
# .IP "\fBkey_digest (default: empty)\fB"
# After processing the \fBkey_format\fR setting, and before sending
# a request to the memcache server, run the key through the named
# message digest algorithm and convert the result to lowercase
# hexadecimal characters. This prevents a database access error
# when keys may exceed the memcache server's key length limit
# (usually, 250 bytes). Specify the name of a message digest
# algorithm that is supported by OpenSSL, for example, \fBsha256\fR.
#
# This feature is available in Postfix 3.11 and later, and requires
# that Postfix is built with TLS support.
# .IP "\fBkey_format (default: %s)\fB"
# Format of the lookup and update keys that the Postfix
# memcache client sends to the memcache server.
@ -193,7 +204,7 @@
# "\fI|command\fR and "\fI/file/name\fR" destinations), or
# \fBvirtual_uid_maps\fR, \fBvirtual_gid_maps\fR and
# \fBvirtual_mailbox_maps\fR (these specify UNIX process
# privileges or "\fI/file/name\fR" destinations). In a typical
# privileges for "\fI/file/name\fR" destinations). In a typical
# deployment a memcache database is writable by any process
# that can talk to the memcache server; in contrast,
# security-sensitive tables must never be writable by the

View File

@ -67,11 +67,10 @@
# hosts = 127.0.0.1
# .fi
#
# NOTE: if the \fBhosts\fR setting specifies one server, this client
# assumes that the target is a load balancer and will reconnect
# immediately after a single failure, instead of failing all
# requests temporarily. With older versions of this client,
# specify the same server twice.
# NOTE: if the \fBhosts\fR setting specifies only one server,
# this client assumes that the target is a load balancer and
# will reconnect immediately after a single failure. With Postfix
# versions 3.9 and earlier, specify the same server twice.
# .IP "\fBuser\fR"
# .IP "\fBpassword\fR"
# The user name and password to log into the mysql server.
@ -102,11 +101,10 @@
# The number of seconds that a database connection will be
# skipped after an error.
#
# NOTE: if the \fBhosts\fR setting specifies one server, this client
# assumes that the target is a load balancer and will reconnect
# immediately after a single failure, instead of failing all
# requests temporarily. With older versions of this client,
# specify the same server twice.
# NOTE: if the \fBhosts\fR setting specifies only one server,
# this client assumes that the target is a load balancer and
# will reconnect immediately after a single failure. With Postfix
# versions 3.9 and earlier, specify the same server twice.
#
# This feature is available in Postfix 3.9 and later.
# .IP "\fBquery\fR"

View File

@ -71,11 +71,10 @@
# URI, the Postfix PostgreSQL client will ignore the \fBdbname\fR,
# \fBuser\fR, and \fBpassword\fR settings for that connection.
#
# NOTE: if the \fBhosts\fR setting specifies one server, this client
# assumes that the target is a load balancer and will reconnect
# immediately after a single failure, instead of failing all
# requests temporarily. With older versions of this client,
# specify the same server twice.
# NOTE: if the \fBhosts\fR setting specifies only one server,
# this client assumes that the target is a load balancer and
# will reconnect immediately after a single failure. With Postfix
# versions 3.9 and earlier, specify the same server twice.
# .IP "\fBuser\fR"
# .IP "\fBpassword\fR"
# The user name and password to log into the pgsql server.
@ -119,11 +118,10 @@
# The number of seconds that a database connection will be
# skipped after an error.
#
# NOTE: if the \fBhosts\fR setting specifies one server, this client
# assumes that the target is a load balancer and will reconnect
# immediately after a single failure, instead of failing all
# requests temporarily. With older versions of this client,
# specify the same server twice.
# NOTE: if the \fBhosts\fR setting specifies only one server,
# this client assumes that the target is a load balancer and
# will reconnect immediately after a single failure. With Postfix
# versions 3.9 and earlier, specify the same server twice.
#
# This feature is available in Postfix 3.9 and later.
# .IP "\fBquery\fR"

View File

@ -20,7 +20,7 @@ if (hash && isChrome) {
setTimeout(function() {
window.location.hash = "";
window.location.hash = hash;
}, 1000);
}, 1500);
}
</script>

View File

@ -17765,7 +17765,7 @@ Milter support should be disabled. </p>
when converting UTF-8 domain names to/from the ASCII form that is
used for DNS lookups. Specify "yes" for compatibility with Postfix
&le; 3.1 (not recommended). This affects the conversion of domain
names that contain for example the German sz and the Greek zeta.
names that contain for example the German sz and the Greek sigma.
See https://unicode.org/cldr/utility/idna.jsp for more examples.
</p>
@ -19521,13 +19521,11 @@ requirements for MTA-STS smtp_tls_policy_maps plugins. </p>
<p> This feature is available in Postfix &ge; 3.10. </p>
%PARAM smtp_tlsrpt_skip_reused_handshakes yes
%PARAM smtp_tlsrpt_skip_reused_handshakes Postfix &ge; 3.11: no, Postfix 3.10: yes
<p> Do not report the TLSRPT status for TLS protocol handshakes
that reuse a previously-negotiated TLS session (there is no new
information to report). Report the TLSRPT status only for "new" TLS
sessions. Set this to "no" to log the TLSRPT status of all TLS
handshakes, for example to troubleshoot Postfix TLSRPT support.
<p> When set to "yes", report the TLSRPT status only for "new" TLS
sessions. When set to "no", also report the TLSRPT status for TLS
protocol handshakes that reuse a previously-negotiated TLS session.
</p>
<p> Note: if an SMTP over TLS connection is reused, there is no

View File

@ -1674,3 +1674,11 @@ MLKEM
cleartext
redacted
subclassed
nosleep
preload
memcached
Geert
Hendrickx
typofix
LD
PRELOAD

View File

@ -343,3 +343,4 @@ additional_info additional_info
ignored ignored
USE_TLSRPT USE_TLSRPT
encoded encoded text can contain only alpha digit
ossl_digest_new ossl_digest_new returns NULL after error ossl_digest_data

View File

@ -166,3 +166,8 @@ proto proto socketmap_table
global mail_params h smtpd smtpd c
global mail_params h proto postconf proto smtp smtp c
proto postconf proto proto TLS_README html
the command line Files postmap postmap c postalias postalias c
verification in progress File verify verify c
+ address failed File verify verify c
address failed File verify verify c
address failed due to a database error File verify verify c

View File

@ -1860,3 +1860,7 @@ XXXSENDOPTS
xtra
HAPROXY
SRVR
DGST
DIGEST
OSSL
ossl

View File

@ -1223,10 +1223,12 @@ dict_memcache.o: ../../include/argv.h
dict_memcache.o: ../../include/auto_clnt.h
dict_memcache.o: ../../include/check_arg.h
dict_memcache.o: ../../include/dict.h
dict_memcache.o: ../../include/hex_code.h
dict_memcache.o: ../../include/match_list.h
dict_memcache.o: ../../include/msg.h
dict_memcache.o: ../../include/myflock.h
dict_memcache.o: ../../include/mymalloc.h
dict_memcache.o: ../../include/ossl_digest.h
dict_memcache.o: ../../include/stringops.h
dict_memcache.o: ../../include/sys_defs.h
dict_memcache.o: ../../include/vbuf.h

View File

@ -50,9 +50,11 @@
/* Utility library. */
#include <hex_code.h>
#include <msg.h>
#include <mymalloc.h>
#include <dict.h>
#include <ossl_digest.h>
#include <vstring.h>
#include <stringops.h>
#include <auto_clnt.h>
@ -75,6 +77,9 @@ typedef struct {
DICT dict; /* parent class */
CFG_PARSER *parser; /* common parameter parser */
void *dbc_ctxt; /* db_common context */
char *key_digest; /* digest the query key */
OSSL_DGST *key_dgst_eng; /* digest engine */
VSTRING *key_dgst_out; /* digest result */
char *key_format; /* query key translation */
int timeout; /* client timeout */
int mc_ttl; /* memcache update expiration */
@ -99,6 +104,7 @@ typedef struct {
#define DICT_MC_DEF_PORT "11211"
#define DICT_MC_DEF_MEMCACHE "inet:" DICT_MC_DEF_HOST ":" DICT_MC_DEF_PORT
#define DICT_MC_DEF_KEY_FMT "%s"
#define DICT_MC_DEF_KEY_DGST ""
#define DICT_MC_DEF_MC_TTL 3600
#define DICT_MC_DEF_MC_TIMEOUT 2
#define DICT_MC_DEF_MC_FLAGS 0
@ -109,6 +115,7 @@ typedef struct {
#define DICT_MC_NAME_MEMCACHE "memcache"
#define DICT_MC_NAME_BACKUP "backup"
#define DICT_MC_NAME_KEY_DGST "key_digest"
#define DICT_MC_NAME_KEY_FMT "key_format"
#define DICT_MC_NAME_MC_TTL "ttl"
#define DICT_MC_NAME_MC_TIMEOUT "timeout"
@ -163,7 +170,7 @@ static int dict_memcache_set(DICT_MC *dict_mc, const char *value, int ttl)
DICT_TYPE_MEMCACHE, dict_mc->dict.name);
} else if (strcmp(STR(dict_mc->clnt_buf), "STORED") != 0) {
if (count > 0)
msg_warn("database %s:%s: update failed: %.30s",
msg_warn("database %s:%s: update failed: %.100s",
DICT_TYPE_MEMCACHE, dict_mc->dict.name,
STR(dict_mc->clnt_buf));
} else {
@ -285,6 +292,18 @@ static ssize_t dict_memcache_prepare_key(DICT_MC *dict_mc, const char *name)
} else {
vstring_strcpy(dict_mc->key_buf, name);
}
if (dict_mc->key_dgst_eng) {
if (ossl_digest_data(dict_mc->key_dgst_eng, STR(dict_mc->key_buf),
LEN(dict_mc->key_buf), dict_mc->key_dgst_out) < 0) {
ossl_digest_log_errors(msg_warn);
msg_warn("%s:%s: %s message digest failed",
DICT_TYPE_MEMCACHE, dict_mc->dict.name,
dict_mc->key_digest);
return (-1);
}
hex_encode_opt(dict_mc->key_buf, STR(dict_mc->key_dgst_out),
LEN(dict_mc->key_dgst_out), HEX_ENCODE_FLAG_LOWERCASE);
}
/*
* The length indicates whether the expansion is empty or not.
@ -315,8 +334,10 @@ static int dict_memcache_valid_key(DICT_MC *dict_mc,
DICT_MC_SKIP("domain mismatch");
if (rc < 0)
DICT_ERR_VAL_RETURN(dict_mc, rc, 0);
if (dict_memcache_prepare_key(dict_mc, name) == 0)
if ((rc = dict_memcache_prepare_key(dict_mc, name)) == 0)
DICT_MC_SKIP("empty lookup key expansion");
if (rc < 0)
DICT_ERR_VAL_RETURN(dict_mc, rc, 0);
for (cp = (unsigned char *) STR(dict_mc->key_buf); *cp; cp++)
if (isascii(*cp) && isspace(*cp))
DICT_MC_SKIP("name contains space");
@ -480,6 +501,12 @@ static void dict_memcache_close(DICT *dict)
cfg_parser_free(dict_mc->parser);
db_common_free_ctx(dict_mc->dbc_ctxt);
if (dict_mc->key_digest)
myfree(dict_mc->key_digest);
if (dict_mc->key_dgst_eng)
ossl_digest_free(dict_mc->key_dgst_eng);
if (dict_mc->key_dgst_out)
vstring_free(dict_mc->key_dgst_out);
if (dict_mc->key_format)
myfree(dict_mc->key_format);
myfree(dict_mc->memcache);
@ -542,6 +569,17 @@ DICT *dict_memcache_open(const char *name, int open_flags, int dict_flags)
* Parse the configuration file.
*/
dict_mc->parser = parser;
dict_mc->key_digest = cfg_get_str(dict_mc->parser, DICT_MC_NAME_KEY_DGST,
DICT_MC_DEF_KEY_DGST, 0, 0);
if (*dict_mc->key_digest) {
if ((dict_mc->key_dgst_eng = ossl_digest_new(dict_mc->key_digest)) == 0)
/* See below for dict_surrogate() error propagation. */
ossl_digest_log_errors(msg_warn);
dict_mc->key_dgst_out = vstring_alloc(1);
} else {
dict_mc->key_dgst_eng = 0;
dict_mc->key_dgst_out = 0;
}
dict_mc->key_format = cfg_get_str(dict_mc->parser, DICT_MC_NAME_KEY_FMT,
DICT_MC_DEF_KEY_FMT, 0, 0);
dict_mc->timeout = cfg_get_int(dict_mc->parser, DICT_MC_NAME_MC_TIMEOUT,
@ -594,5 +632,15 @@ DICT *dict_memcache_open(const char *name, int open_flags, int dict_flags)
dict_mc->dict.flags |= DICT_FLAG_MULTI_WRITER;
if (*dict_mc->key_digest && dict_mc->key_dgst_eng == 0) {
/* See above for ossl_digest_new() error detection. */
DICT *d = dict_surrogate(DICT_TYPE_MEMCACHE, name,
open_flags, dict_flags,
"open %s: key digest %s is not available",
name, dict_mc->key_digest);
dict_memcache_close(&dict_mc->dict);
return (d);
}
return (&dict_mc->dict);
}

View File

@ -390,6 +390,11 @@ char *var_known_tcp_ports;
const char null_format_string[1] = "";
/*
* Compatibility level 3.11.
*/
int warn_compat_break_smtp_tlsrpt_skip_reused_hs;
/*
* Compatibility level 3.6.
*/
@ -662,6 +667,15 @@ static void check_legacy_defaults(void)
* bits.
*/
/*
* Look for specific parameters whose default changed when the
* compatibility level changed to 3.11.
*/
if (compat_level < compat_level_from_string(COMPAT_LEVEL_3_11, msg_panic)) {
if (mail_conf_lookup(VAR_SMTP_TLSRPT_SKIP_REUSED_HS) == 0)
warn_compat_break_smtp_tlsrpt_skip_reused_hs = 1;
}
/*
* Look for specific parameters whose default changed when the
* compatibility level changed to 3.6.

View File

@ -51,10 +51,11 @@ extern bool var_show_unk_rcpt_table;
* updating the current compatibility level.
*/
#define COMPAT_LEVEL_0 "0"
#define COMPAT_LEVEL_1 "1"
#define COMPAT_LEVEL_2 "2"
#define COMPAT_LEVEL_1 "1" /* Introduced: Postfix 3.0 */
#define COMPAT_LEVEL_2 "2" /* Introduced: Postfix 3.0 */
#define COMPAT_LEVEL_3_6 "3.6"
#define LAST_COMPAT_LEVEL COMPAT_LEVEL_3_6
#define COMPAT_LEVEL_3_11 "3.11"
#define LAST_COMPAT_LEVEL COMPAT_LEVEL_3_11
#define VAR_COMPAT_LEVEL "compatibility_level"
#define DEF_COMPAT_LEVEL COMPAT_LEVEL_0
@ -75,6 +76,8 @@ extern int warn_compat_break_lmtp_tls_fpt_dgst;
extern int warn_compat_relay_before_rcpt_checks;
extern int warn_compat_respectful_logging;
extern int warn_compat_break_smtp_tlsrpt_skip_reused_hs;
extern long compat_level;
/*
@ -4483,7 +4486,7 @@ extern bool var_smtp_tlsrpt_enable;
extern char *var_smtp_tlsrpt_sockname;
#define VAR_SMTP_TLSRPT_SKIP_REUSED_HS "smtp_tlsrpt_skip_reused_handshakes"
#define DEF_SMTP_TLSRPT_SKIP_REUSED_HS "yes"
#define DEF_SMTP_TLSRPT_SKIP_REUSED_HS "no"
#define VAR_LMTP_TLSRPT_SKIP_REUSED_HS "lmtp_tlsrpt_skip_reused_handshakes"
#define DEF_LMTP_TLSRPT_SKIP_REUSED_HS DEF_SMTP_TLSRPT_SKIP_REUSED_HS
extern int var_smtp_tlsrpt_skip_reused_hs;

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
#define MAIL_RELEASE_DATE "20250418"
#define MAIL_RELEASE_DATE "20250606"
#define MAIL_VERSION_NUMBER "3.11"
#ifdef SNAPSHOT

View File

@ -10,6 +10,7 @@ PROG = postalias
INC_DIR = ../../include
LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
NOSLEEP = LD_PRELOAD=../../lib/nosleep.so
.c.o:; $(CC) $(CFLAGS) -c $*.c
@ -23,42 +24,55 @@ Makefile: Makefile.in
update: ../../bin/$(PROG)
tests: test1 test2 fail_test
tests: test1 test2 fail_test mode_conflict_test
root_tests:
test1: $(PROG) map.in map-abc1.ref map-ghi1.ref map-uABC1.ref
${SHLIB_ENV} ${VALGRIND} ./$(PROG) map.in
rm -f main.cf
touch -t 197101010000 main.cf
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . map.in
for key in abc ghi; \
do \
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -q $${key} map.in | diff map-$${key}1.ref -; \
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -q $${key} map.in | diff map-$${key}1.ref -; \
done
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -f map.in
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -f map.in
for key in ABC; \
do \
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -fq $${key} map.in | diff map-u$${key}1.ref -; \
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -fq $${key} map.in | diff map-u$${key}1.ref -; \
done
rm -f map.in.db
rm -f map.in.db main.cf
test2: $(PROG) map.in map-abc2.ref map-ghi2.ref map-uABC2.ref
${SHLIB_ENV} ${VALGRIND} ./$(PROG) map.in
rm -f main.cf
touch -t 197101010000 main.cf
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . map.in
for key in abc ghi; \
do \
echo $${key} | ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -q - map.in | diff map-$${key}2.ref -; \
echo $${key} | ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -q - map.in | diff map-$${key}2.ref -; \
done
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -f map.in
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -f map.in
for key in ABC; \
do \
echo $${key} | ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -fq - map.in | diff map-u$${key}2.ref -; \
echo $${key} | ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -fq - map.in | diff map-u$${key}2.ref -; \
done
rm -f map.in.db
rm -f map.in.db main.cf
fail_test: $(PROG) aliases fail_test.in fail_test.ref
-(${SHLIB_ENV} sh fail_test.in 2>&1 || exit 0) | sed \
rm -f main.cf
touch -t 197101010000 main.cf
-(${SHLIB_ENV} MAIL_CONFIG=. $(NOSLEEP) sh fail_test.in 2>&1 || exit 0) | sed \
-e 's/No error:/Unknown error:/' \
-e 's/Success/Unknown error: 0/' > fail_test.tmp
diff fail_test.ref fail_test.tmp
rm -f fail_test.tmp
rm -f fail_test.tmp main.cf
mode_conflict_test: $(PROG) mode_conflict_test.in mode_conflict_test.ref
rm -f main.cf
touch -t 197101010000 main.cf
$(SHLIB_ENV) MAIL_CONFIG=. $(NOSLEEP) sh -x mode_conflict_test.in >mode_conflict_test.tmp 2>&1
diff mode_conflict_test.ref mode_conflict_test.tmp
rm -f mode_conflict_test.tmp main.cf
../../bin/$(PROG): $(PROG)
cp $(PROG) ../../bin

View File

@ -0,0 +1,21 @@
${VALGRIND} ./postalias -d yy -d xx whatever:whatever && exit 1
${VALGRIND} ./postalias -d yy -i whatever:whatever && exit 1
${VALGRIND} ./postalias -d yy -q xx whatever:whatever && exit 1
${VALGRIND} ./postalias -d yy -s whatever:whatever && exit 1
${VALGRIND} ./postalias -i -d xx whatever:whatever && exit 1
${VALGRIND} ./postalias -i -i whatever:whatever && exit 1
${VALGRIND} ./postalias -i -q xx whatever:whatever && exit 1
${VALGRIND} ./postalias -i -s whatever:whatever && exit 1
${VALGRIND} ./postalias -q yy -d xx whatever:whatever && exit 1
${VALGRIND} ./postalias -q yy -i whatever:whatever && exit 1
${VALGRIND} ./postalias -q yy -q xx whatever:whatever && exit 1
${VALGRIND} ./postalias -q yy -s whatever:whatever && exit 1
${VALGRIND} ./postalias -s -d xx whatever:whatever && exit 1
${VALGRIND} ./postalias -s -i whatever:whatever && exit 1
${VALGRIND} ./postalias -s -q xx whatever:whatever && exit 1
${VALGRIND} ./postalias -s -s whatever:whatever && exit 1
exit 0

View File

@ -0,0 +1,33 @@
+ ./postalias -d yy -d xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -d yy -i whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -d yy -q xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -d yy -s whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -i -d xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -i -i whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -i -q xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -i -s whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -q yy -d xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -q yy -i whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -q yy -q xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -q yy -s whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -s -d xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -s -i whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -s -q xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -s -s whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ exit 0

View File

@ -734,6 +734,7 @@ int main(int argc, char **argv)
int open_flags = O_RDWR | O_CREAT | O_TRUNC;
int dict_flags = (DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_FIX
| DICT_FLAG_UTF8_REQUEST);
int update = 0;
char *query = 0;
char *delkey = 0;
int sequence = 0;
@ -798,14 +799,17 @@ int main(int argc, char **argv)
msg_fatal("out of memory");
break;
case 'd':
if (sequence || query || delkey)
msg_fatal("specify only one of -s -q or -d");
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
delkey = optarg;
break;
case 'f':
dict_flags &= ~DICT_FLAG_FOLD_FIX;
break;
case 'i':
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
update = 1;
open_flags &= ~O_TRUNC;
break;
case 'n':
@ -819,8 +823,8 @@ int main(int argc, char **argv)
postalias_flags &= ~POSTALIAS_FLAG_SAVE_PERM;
break;
case 'q':
if (sequence || query || delkey)
msg_fatal("specify only one of -s -q or -d");
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
query = optarg;
break;
case 'r':
@ -828,8 +832,8 @@ int main(int argc, char **argv)
dict_flags |= DICT_FLAG_DUP_REPLACE;
break;
case 's':
if (query || delkey)
msg_fatal("specify only one of -s or -q or -d");
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
sequence = 1;
break;
case 'u':

View File

@ -10,6 +10,7 @@ PROG = postmap
INC_DIR = ../../include
LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
NOSLEEP = LD_PRELOAD=../../lib/nosleep.so
.c.o:; $(CC) $(CFLAGS) -c $*.c
@ -27,52 +28,70 @@ update: ../../bin/$(PROG)
cp $(PROG) ../../bin
tests: test1 test2 fail_test quote_test file_test lmdb_abb_test \
lmdb_bulk_test lmdb_incr_test cdb_bulk_test
lmdb_bulk_test lmdb_incr_test cdb_bulk_test mode_conflict_test
root_tests:
test1: $(PROG) map.in map-abc1.ref map-ghi1.ref map-uABC1.ref
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) map.in
rm -f main.cf
touch -t 197101010000 main.cf
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . map.in
for key in abc ghi; \
do \
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -q $${key} map.in | diff map-$${key}1.ref -; \
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -q $${key} map.in | diff map-$${key}1.ref -; \
done
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -f map.in
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -f map.in
for key in ABC; \
do \
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -fq $${key} map.in | diff map-u$${key}1.ref -; \
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -fq $${key} map.in | diff map-u$${key}1.ref -; \
done
rm -f map.in.db
rm -f map.in.db main.cf
test2: $(PROG) map.in map-abc2.ref map-ghi2.ref map-uABC2.ref
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) map.in
rm -f main.cf
touch -t 197101010000 main.cf
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . map.in
for key in abc ghi; \
do \
echo $${key} | $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -q - map.in | diff map-$${key}2.ref -; \
echo $${key} | $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -q - map.in | diff map-$${key}2.ref -; \
done
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -f map.in
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -f map.in
for key in ABC; \
do \
echo $${key} | $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -fq - map.in | diff map-u$${key}2.ref -; \
echo $${key} | $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -fq - map.in | diff map-u$${key}2.ref -; \
done
rm -f map.in.db
rm -f map.in.db main.cf
fail_test: $(PROG) aliases fail_test.in fail_test.ref
-($(SHLIB_ENV) sh fail_test.in || exit 0) >fail_test.tmp 2>&1
rm -f main.cf
touch -t 197101010000 main.cf
-($(SHLIB_ENV) MAIL_CONFIG=. $(NOSLEEP) sh fail_test.in || exit 0) >fail_test.tmp 2>&1
diff fail_test.ref fail_test.tmp
rm -f fail_test.tmp
rm -f fail_test.tmp main.cf
quote_test: $(PROG) aliases quote_test.in quote_test.ref
rm -f main.cf
touch -t 197101010000 main.cf
rm -f quote_test_map.*
$(SHLIB_ENV) sh quote_test.in >quote_test.tmp 2>&1
$(SHLIB_ENV) MAIL_CONFIG=. sh quote_test.in >quote_test.tmp 2>&1
diff quote_test.ref quote_test.tmp
rm -f quote_test.tmp quote_test_map.*
rm -f quote_test.tmp quote_test_map.* main.cf
file_test: $(PROG) file_test.in file_test.ref
rm -f main.cf
touch -t 197101010000 main.cf
rm -f file_test_map.* postmap-file-1 postmap-file-2
$(SHLIB_ENV) sh file_test.in >file_test.tmp 2>&1
$(SHLIB_ENV) MAIL_CONFIG=. $(NOSLEEP) sh file_test.in >file_test.tmp 2>&1
diff file_test.ref file_test.tmp
rm -f file_test.tmp file_test_map.* postmap-file-1 postmap-file-2
rm -f file_test.tmp file_test_map.* postmap-file-1 postmap-file-2 \
main.cf
mode_conflict_test: $(PROG) mode_conflict_test.in mode_conflict_test.ref
rm -f main.cf
touch -t 197101010000 main.cf
$(SHLIB_ENV) MAIL_CONFIG=. $(NOSLEEP) sh -x mode_conflict_test.in >mode_conflict_test.tmp 2>&1
diff mode_conflict_test.ref mode_conflict_test.tmp
rm -f mode_conflict_test.tmp main.cf
cdb_bulk_test: $(PROG)
rm -f cdb_bulk.cdb main.cf
@ -80,15 +99,17 @@ cdb_bulk_test: $(PROG)
sed -e 's/.*/& &/' -e 10000q| LANG=C sort -u >cdb_bulk
touch -t 197101010000 main.cf
($(SHLIB_ENV) $(VALGRIND) ./postmap -c . cdb:cdb_bulk; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -s cdb:cdb_bulk | \
$(SHLIB_ENV) $(VALGRIND) ./postmap -c . -s cdb:cdb_bulk | \
LANG=C sort > cdb_bulk.tmp)
cmp cdb_bulk cdb_bulk.tmp
rm -f cdb_bulk cdb_bulk.tmp cdb_bulk.cdb main.cf
lmdb_abb_test: $(PROG) lmdb_abb lmdb_abb.ref
rm -f main.cf
touch -t 197101010000 main.cf
rm -f lmdb_abb.lmdb
($(SHLIB_ENV) $(VALGRIND) ./postmap lmdb:lmdb_abb; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_abb | sort) >lmdb_abb.tmp 2>&1
($(SHLIB_ENV) $(VALGRIND) ./postmap -c . lmdb:lmdb_abb; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -c . -s lmdb:lmdb_abb | sort) >lmdb_abb.tmp 2>&1
diff lmdb_abb.ref lmdb_abb.tmp
rm -f lmdb_abb.tmp lmdb_abb.lmdb
@ -99,7 +120,7 @@ lmdb_bulk_test: $(PROG)
echo lmdb_map_size=10240 >main.cf
touch -t 197101010000 main.cf
($(SHLIB_ENV) $(VALGRIND) ./postmap -c . lmdb:lmdb_retry; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_retry | \
$(SHLIB_ENV) $(VALGRIND) ./postmap -c . -s lmdb:lmdb_retry | \
LANG=C sort > lmdb_retry.tmp)
cmp lmdb_retry lmdb_retry.tmp
rm -f lmdb_retry lmdb_retry.tmp lmdb_retry.lmdb main.cf
@ -111,13 +132,13 @@ lmdb_incr_test: $(PROG)
echo lmdb_map_size=10240 >main.cf
touch -t 197101010000 main.cf
($(SHLIB_ENV) $(VALGRIND) ./postmap -ic . lmdb:lmdb_retry <lmdb_retry; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_retry | \
$(SHLIB_ENV) $(VALGRIND) ./postmap -c . -s lmdb:lmdb_retry | \
LANG=C sort > lmdb_retry.tmp)
cmp lmdb_retry lmdb_retry.tmp
rm -f lmdb_retry lmdb_retry.tmp lmdb_retry.lmdb main.cf
clean:
rm -f *.o *core $(PROG) $(TESTPROG) *.tmp junk *.db
rm -f *.o *core $(PROG) $(TESTPROG) *.tmp junk *.db main.cf master.cf
tidy: clean

View File

@ -0,0 +1,21 @@
${VALGRIND} ./postmap -d yy -d xx whatever:whatever && exit 1
${VALGRIND} ./postmap -d yy -i whatever:whatever && exit 1
${VALGRIND} ./postmap -d yy -q xx whatever:whatever && exit 1
${VALGRIND} ./postmap -d yy -s whatever:whatever && exit 1
${VALGRIND} ./postmap -i -d xx whatever:whatever && exit 1
${VALGRIND} ./postmap -i -i whatever:whatever && exit 1
${VALGRIND} ./postmap -i -q xx whatever:whatever && exit 1
${VALGRIND} ./postmap -i -s whatever:whatever && exit 1
${VALGRIND} ./postmap -q yy -d xx whatever:whatever && exit 1
${VALGRIND} ./postmap -q yy -i whatever:whatever && exit 1
${VALGRIND} ./postmap -q yy -q xx whatever:whatever && exit 1
${VALGRIND} ./postmap -q yy -s whatever:whatever && exit 1
${VALGRIND} ./postmap -s -d xx whatever:whatever && exit 1
${VALGRIND} ./postmap -s -i whatever:whatever && exit 1
${VALGRIND} ./postmap -s -q xx whatever:whatever && exit 1
${VALGRIND} ./postmap -s -s whatever:whatever && exit 1
exit 0

View File

@ -0,0 +1,33 @@
+ ./postmap -d yy -d xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -d yy -i whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -d yy -q xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -d yy -s whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -i -d xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -i -i whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -i -q xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -i -s whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -q yy -d xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -q yy -i whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -q yy -q xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -q yy -s whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -s -d xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -s -i whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -s -q xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -s -s whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ exit 0

View File

@ -957,6 +957,7 @@ int main(int argc, char **argv)
int open_flags = O_RDWR | O_CREAT | O_TRUNC;
int dict_flags = (DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_FIX
| DICT_FLAG_UTF8_REQUEST);
int update = 0;
char *query = 0;
char *delkey = 0;
int sequence = 0;
@ -1025,8 +1026,8 @@ int main(int argc, char **argv)
msg_fatal("out of memory");
break;
case 'd':
if (sequence || query || delkey)
msg_fatal("specify only one of -s -q or -d");
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
delkey = optarg;
break;
case 'f':
@ -1039,6 +1040,9 @@ int main(int argc, char **argv)
postmap_flags |= POSTMAP_FLAG_HEADER_KEY;
break;
case 'i':
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
update = 1;
open_flags &= ~O_TRUNC;
break;
case 'm':
@ -1055,8 +1059,8 @@ int main(int argc, char **argv)
postmap_flags &= ~POSTMAP_FLAG_SAVE_PERM;
break;
case 'q':
if (sequence || query || delkey)
msg_fatal("specify only one of -s -q or -d");
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
query = optarg;
break;
case 'r':
@ -1064,8 +1068,8 @@ int main(int argc, char **argv)
dict_flags |= DICT_FLAG_DUP_REPLACE;
break;
case 's':
if (query || delkey)
msg_fatal("specify only one of -s or -q or -d");
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
sequence = 1;
break;
case 'u':

View File

@ -250,6 +250,12 @@ void smtp_tlsrpt_create_wrapper(SMTP_STATE *state, const char *domain)
if (msg_verbose)
msg_info("%s: domain %s has policy %.100s",
smtp_tlsrpt_support, domain, rr->data);
if (warn_compat_break_smtp_tlsrpt_skip_reused_hs) {
msg_info("using using backwards-compatible default setting "
VAR_SMTP_TLSRPT_SKIP_REUSED_HS "=yes");
var_smtp_tlsrpt_skip_reused_hs = 1;
warn_compat_break_smtp_tlsrpt_skip_reused_hs = 0;
}
state->tlsrpt = trw_create(
/* rpt_socket_name= */ var_smtp_tlsrpt_sockname,
/* rpt_policy_domain= */ adomain,

1
postfix/src/testing/.indent.pro vendored Symbolic link
View File

@ -0,0 +1 @@
../../.indent.pro

View File

@ -0,0 +1,35 @@
LIB_SO = nosleep.so
LIB_DIR = ../../lib
INC_DIR = ../../include
all: $(LIB_SO)
Makefile: Makefile.in
cat ../../conf/makedefs.out $? >$@
nosleep.so: nosleep.c
$(CC) $(CFLAGS) -fPIC -shared -o $@ $?
update: lib_so_update
lib_so_update: $(LIB_SO)
for i in $(LIB_SO); do \
cmp -s $$i $(LIB_DIR)/$$i 2>/dev/null || cp $$i $(LIB_DIR); \
done
clean:
rm -f $(LIB_SO) *.o
tidy: clean
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
$(CC) -E $(DEFS) $(INCL) $$i | grep -v '[<>]' | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' \
-e 's/o: \.\//o: /' -e p -e '}' ; \
done | LANG=C sort -u) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
@$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
nosleep.o: nosleep.c

View File

@ -0,0 +1,29 @@
/*++
/* NAME
/* nosleep 3
/* SUMMARY
/* override the system sleep(3) implementation
/* SYNOPSIS
/* LD_PRELOAD=/path/to/nosleep.so command....
/*
/* int sleep(unsigned int seconds)
/* DESCRIPTION
/* This sleep(3) implementation returns zero immediately. The purpose
/* is to speed up error handler tests by skipping the delay between
/* reporting a fatal error and before terminating the process.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* porcupine.org
/*--*/
#include <unistd.h>
unsigned int sleep(unsigned int seconds)
{
/* Don't sleep. */
return (0);
}

View File

@ -47,7 +47,7 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c inet_prefix_top.c \
inet_addr_sizes.c quote_for_json.c mystrerror.c \
sane_sockaddr_to_hostaddr.c normalize_ws.c valid_uri_scheme.c \
clean_ascii_cntrl_space.c normalize_v4mapped_addr.c
clean_ascii_cntrl_space.c normalize_v4mapped_addr.c ossl_digest.c
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@ -96,7 +96,7 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
mkmap_fail.o mkmap_open.o inet_prefix_top.o inet_addr_sizes.o \
quote_for_json.o mystrerror.o sane_sockaddr_to_hostaddr.o \
normalize_ws.o valid_uri_scheme.o clean_ascii_cntrl_space.o \
normalize_v4mapped_addr.o
normalize_v4mapped_addr.o ossl_digest.o
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros.
@ -129,7 +129,7 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \
known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h \
inet_prefix_top.h inet_addr_sizes.h valid_uri_scheme.h \
clean_ascii_cntrl_space.h normalize_v4mapped_addr.h
clean_ascii_cntrl_space.h normalize_v4mapped_addr.h ossl_digest.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
DEFS = -I. -D$(SYSTYPE)
@ -153,7 +153,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
known_tcp_ports dict_stream find_inet binhash hash_fnv argv \
clean_env inet_prefix_top printable readlline quote_for_json \
normalize_ws valid_uri_scheme clean_ascii_cntrl_space \
normalize_v4mapped_addr_test
normalize_v4mapped_addr_test ossl_digest_test
PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) $(LIB_PREFIX)lmdb$(LIB_SUFFIX) \
$(LIB_PREFIX)cdb$(LIB_SUFFIX) $(LIB_PREFIX)sdbm$(LIB_SUFFIX)
HTABLE_FIX = NORANDOMIZE=1
@ -635,6 +635,9 @@ clean_ascii_cntrl_space: $(LIB)
normalize_v4mapped_addr_test: normalize_v4mapped_addr_test.c $(LIB)
$(CC) $(CFLAGS) -o $@ normalize_v4mapped_addr_test.c $(LIB) $(SYSLIBS)
ossl_digest_test: ossl_digest_test.c $(LIB)
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(SYSLIBS)
tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
hex_quote_test ctable_test inet_addr_list_test base64_code_test \
attr_scan64_test attr_scan0_test host_port_test dict_tests \
@ -647,7 +650,7 @@ tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
binhash_test argv_test inet_prefix_top_test printable_test \
valid_utf8_string_test readlline_test quote_for_json_test \
normalize_ws_test valid_uri_scheme_test clean_ascii_cntrl_space_test \
test_normalize_v4mapped_addr
test_normalize_v4mapped_addr test_ossl_digest
dict_tests: all dict_test \
dict_pcre_tests dict_cidr_test dict_thash_test dict_static_test \
@ -1136,6 +1139,9 @@ clean_ascii_cntrl_space_test: clean_ascii_cntrl_space
test_normalize_v4mapped_addr: update normalize_v4mapped_addr_test
$(SHLIB_ENV) ${VALGRIND} ./normalize_v4mapped_addr_test
test_ossl_digest: update ossl_digest_test
$(SHLIB_ENV) ${VALGRIND} ./ossl_digest_test
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
@ -2480,10 +2486,14 @@ myaddrinfo.o: sys_defs.h
myaddrinfo.o: valid_hostname.h
myaddrinfo.o: vbuf.h
myaddrinfo.o: vstring.h
myflock.o: check_arg.h
myflock.o: msg.h
myflock.o: myflock.c
myflock.o: myflock.h
myflock.o: name_mask.h
myflock.o: sys_defs.h
myflock.o: vbuf.h
myflock.o: vstring.h
mymalloc.o: msg.h
mymalloc.o: mymalloc.c
mymalloc.o: mymalloc.h

View File

@ -32,6 +32,9 @@
/* int first_next;
/* const char **cache_key;
/* const char **cache_val;
/*
/* int dict_cache_error(cache)
/* DICT_CACHE *cache;
/* AUXILIARY FUNCTIONS
/* void dict_cache_control(cache, name, value, ...)
/* DICT_CACHE *cache;
@ -122,6 +125,9 @@
/* .PP
/* dict_cache_name() returns the name of the specified cache.
/*
/* dict_cache_error() returns the error status for the underlying
/* dictionary.
/*
/* Arguments:
/* .IP "dbname, open_flags, dict_flags"
/* These are passed unchanged to dict_open(). The cache must
@ -681,14 +687,21 @@ const char *dict_cache_name(DICT_CACHE *cp)
{
/*
* This is used for verbose logging or warning messages, so the cost of
* call is only made where needed (well sort off - code that does not
* This is used for verbose logging or warning messages, so the cost of a
* call is only made where needed (well sort of - code that does not
* execute still presents overhead for the processor pipeline, processor
* cache, etc).
*/
return (cp->name);
}
/* dict_cache_error - get the dictionary error status */
int dict_cache_error(DICT_CACHE *cp)
{
return (cp->error);
}
/*
* Test driver with support for interleaved access. First, enter a number of
* requests to look up, update or delete a sequence of cache entries, then

View File

@ -31,6 +31,7 @@ extern int dict_cache_delete(DICT_CACHE *, const char *);
extern int dict_cache_sequence(DICT_CACHE *, int, const char **, const char **);
extern void dict_cache_control(DICT_CACHE *,...);
extern const char *dict_cache_name(DICT_CACHE *);
extern int dict_cache_error(DICT_CACHE *);
#define DICT_CACHE_FLAG_VERBOSE (1<<0) /* verbose operation */
#define DICT_CACHE_FLAG_STATISTICS (1<<1) /* log cache statistics */

View File

@ -494,12 +494,18 @@ static DICT *dict_cdbm_open(const char *path, int dict_flags)
DICT *dict_cdb_open(const char *path, int open_flags, int dict_flags)
{
switch (open_flags & (O_RDONLY | O_RDWR | O_WRONLY | O_CREAT | O_TRUNC)) {
case O_RDONLY: /* query mode */
case O_RDONLY: /* query mode */
return dict_cdbq_open(path, dict_flags);
case O_WRONLY | O_CREAT | O_TRUNC: /* create mode */
case O_RDWR | O_CREAT | O_TRUNC: /* sloppiness */
return dict_cdbm_open(path, dict_flags);
case O_RDWR | O_CREAT:
case O_RDWR:
/* User error. */
return (dict_surrogate(DICT_TYPE_CDB, path, open_flags, dict_flags,
"unsupported non-bulk change request"));
default:
/* Programmer error. */
msg_fatal("dict_cdb_open: inappropriate open flags for cdb database"
" - specify O_RDONLY or O_WRONLY|O_CREAT|O_TRUNC");
}

View File

@ -650,9 +650,9 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
major_version, minor_version, patch_version));
if (msg_verbose) {
msg_info("Compiled against Berkeley DB: %d.%d.%d\n",
msg_info("Compiled against Berkeley DB: %d.%d.%d",
DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH);
msg_info("Run-time linked against Berkeley DB: %d.%d.%d\n",
msg_info("Run-time linked against Berkeley DB: %d.%d.%d",
major_version, minor_version, patch_version);
}
#else

View File

@ -46,6 +46,8 @@
/* Inserts one ":" between bytes.
/* .IP HEX_ENCODE_FLAG_APPEND
/* Append output to the buffer.
/* .IP HEX_ENCODE_FLAG_LOWERCASE
/* Output lowercase characters.
/* .PP
/* hex_decode_opt() enables extended functionality as controlled
/* with \fIflags\fR.
@ -91,7 +93,8 @@
/* Application-specific. */
static const unsigned char hex_chars[] = "0123456789ABCDEF";
static const unsigned char lower_hex_chars[] = "0123456789abcdef";
static const unsigned char upper_hex_chars[] = "0123456789ABCDEF";
#define UCHAR_PTR(x) ((const unsigned char *)(x))
@ -108,12 +111,17 @@ VSTRING *hex_encode(VSTRING *result, const char *in, ssize_t len)
VSTRING *hex_encode_opt(VSTRING *result, const char *in, ssize_t len, int flags)
{
const unsigned char *hex_chars;
const unsigned char *cp;
int ch;
ssize_t count;
if ((flags & HEX_ENCODE_FLAG_APPEND) == 0)
VSTRING_RESET(result);
if ((flags & HEX_ENCODE_FLAG_LOWERCASE) != 0)
hex_chars = lower_hex_chars;
else
hex_chars = upper_hex_chars;
for (cp = UCHAR_PTR(in), count = len; count > 0; count--, cp++) {
ch = *cp;
VSTRING_ADDCH(result, hex_chars[(ch >> 4) & 0xf]);
@ -256,6 +264,34 @@ static const TEST_CASE test_cases[] = {
0,
0,
},
{"hex_encode_to_lowercase", hex_encode_opt,
"\377\376\375\374\373\372",
sizeof("\377\376\375\374\373\372") - 1,
HEX_ENCODE_FLAG_LOWERCASE,
"fffefdfcfbfa",
sizeof("fffefdfcfbfa") - 1,
},
{"hex_decode_from_lowercase", hex_decode_opt,
"fffefdfcfbfa",
sizeof("fffefdfcfbfa") - 1,
0,
"\377\376\375\374\373\372",
sizeof("\377\376\375\374\373\372") - 1,
},
{"hex_encode_to_uppercase", hex_encode_opt,
"\377\376\375\374\373\372",
sizeof("\377\376\375\374\373\372") - 1,
0,
"FFFEFDFCFBFA",
sizeof("FFFEFDFCFBFA") - 1,
},
{"hex_decode_from_uppercase", hex_decode_opt,
"FFFEFDFCFBFA",
sizeof("FFFEFDFCFBFA") - 1,
0,
"\377\376\375\374\373\372",
sizeof("\377\376\375\374\373\372") - 1,
},
{0},
};

View File

@ -22,6 +22,7 @@
#define HEX_ENCODE_FLAG_NONE (0)
#define HEX_ENCODE_FLAG_USE_COLON (1<<0)
#define HEX_ENCODE_FLAG_APPEND (1<<1)
#define HEX_ENCODE_FLAG_LOWERCASE (1<<2)
#define HEX_DECODE_FLAG_NONE (0)
#define HEX_DECODE_FLAG_ALLOW_COLON (1<<0)

View File

@ -29,24 +29,33 @@
/* void mkmap_close(mkmap)
/* MKMAP *mkmap;
/* DESCRIPTION
/* This module implements support for creating Postfix databases.
/* It is a dict(3) wrapper that adds global locking to dict-level
/* routines where appropriate.
/* This module adds support for creating Postfix databases from
/* scratch. See dict(3) for a description of the \fBopen_flags\fR
/* and \fBdict_flags\fR arguments.
/*
/* mkmap_open() creates or truncates the named database, after
/* appending the appropriate suffixes to the specified filename.
/* Before the database is updated, it is locked for exclusive
/* access, and signal delivery is suspended.
/* See dict(3) for a description of \fBopen_flags\fR and
/* \fBdict_flags\fR. All errors are fatal.
/* To create a database from scratch (open_flags contains O_TRUNC),
/* the plugin code for the database type must provide a
/* mkmap_<type>_open() function that maintains a global lock for
/* exclusive access until the database is closed.
/*
/* To access a database type that has no global locking support
/* (no mkmap_<type>_open() function), mkmap_open() opens the database
/* requesting its dict(3) built-in per-update locking.
/*
/* mkmap_open() suspends signal delivery before opening a database
/* and resumes signal delivery when it is safe: before the first
/* update if the database implements transaction safety, otherwise
/* after the database is closed.
/*
/* All mkmap_open() errors are fatal.
/*
/* mkmap_append() appends the named (key, value) pair to the
/* database. Update errors are fatal; duplicate keys are ignored
/* (but a warning is issued).
/* \fBlineno\fR is used for diagnostics.
/* (but a warning is issued). The \fBlineno\fR argument is used
/* for diagnostic messages.
/*
/* mkmap_close() closes the database, releases any locks,
/* and resumes signal delivery. All errors are fatal.
/* mkmap_close() closes the database, releases any locks, and
/* resumes signal delivery. All errors are fatal.
/* SEE ALSO
/* sigdelay(3) suspend/resume signal delivery
/* LICENSE
@ -63,6 +72,9 @@
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
/* Wietse Venema
/* porcupine.org
/*--*/
/* System library. */
@ -125,7 +137,7 @@ MKMAP *mkmap_open(const char *type, const char *path,
*/
if ((dp = dict_open_lookup(type)) == 0)
msg_fatal("unsupported map type: %s", type);
if (dp->mkmap_fn == 0)
if (dp->mkmap_fn == 0 && (open_flags & O_TRUNC) != 0)
msg_fatal("no 'map create' support for this type: %s", type);
if (msg_verbose)
msg_info("open %s %s", type, path);
@ -136,7 +148,8 @@ MKMAP *mkmap_open(const char *type, const char *path,
* dict modules implement locking only for individual record operations,
* because most Postfix applications don't need global exclusive locks.
*/
mkmap = dp->mkmap_fn(path);
if (dp->mkmap_fn != 0)
mkmap = dp->mkmap_fn(path);
/*
* Delay signal delivery, so that we won't leave the database in an
@ -145,16 +158,28 @@ MKMAP *mkmap_open(const char *type, const char *path,
sigdelay();
/*
* Truncate the database upon open, and update it. Read-write mode is
* needed because the underlying routines read as well as write. We
* explicitly clobber lock_fd to trigger a fatal error when a map wants
* to unlock the database after individual transactions: that would
* result in race condition problems. We clobbber stat_fd as well,
* because that, too, is used only for individual-transaction clients.
* Create or open a database that supports global locking. We explicitly
* clobber the per-table lock_fd to trigger a fatal error when a table
* wants to release its lock after an individual transaction. We clobber
* stat_fd as well, because that, too, is used only for non-bulk
* applications.
*/
mkmap->dict = mkmap->open(path, open_flags, dict_flags);
mkmap->dict->lock_fd = -1; /* XXX just in case */
mkmap->dict->stat_fd = -1; /* XXX just in case */
if (dp->mkmap_fn != 0) { /* Global lock */
mkmap->dict = mkmap->open(path, open_flags, dict_flags);
mkmap->dict->lock_fd = -1; /* XXX just in case */
mkmap->dict->stat_fd = -1; /* XXX just in case */
}
/*
* Otherwise, craft a surrogate MKMAP structure and request per-update
* locks.
*/
else { /* Per-update lock */
mkmap = (MKMAP *) mymalloc(sizeof(*mkmap));
mkmap->dict = dp->dict_fn(path, open_flags, dict_flags | DICT_FLAG_LOCK);
mkmap->after_open = 0; /* No global lock */
mkmap->after_close = 0; /* No global unlock */
}
mkmap->dict->flags |= DICT_FLAG_DUP_WARN;
mkmap->multi_writer = (mkmap->dict->flags & DICT_FLAG_MULTI_WRITER);

View File

@ -81,12 +81,39 @@
#include "msg.h"
#include "myflock.h"
#include "name_mask.h"
#include "vstring.h"
/* myflock - lock/unlock entire open file */
int myflock(int fd, int lock_style, int operation)
{
int status;
const static NAME_MASK lock_masks[] = {
"MYFLOCK_STYLE_FLOCK", MYFLOCK_STYLE_FLOCK,
"MYFLOCK_STYLE_FCNTL", MYFLOCK_STYLE_FCNTL,
0,
};
const static NAME_MASK op_masks[] = {
"MYFLOCK_OP_SHARED", MYFLOCK_OP_SHARED,
"MYFLOCK_OP_EXCLUSIVE", MYFLOCK_OP_EXCLUSIVE,
"MYFLOCK_OP_NOWAIT", MYFLOCK_OP_NOWAIT,
0,
};
if (msg_verbose) {
VSTRING *style_buf = vstring_alloc(100);
VSTRING *op_buf = vstring_alloc(100);
msg_info("myflock(%d, %s, %s)", fd,
str_name_mask_opt(style_buf, "lock_style", lock_masks,
lock_style, NAME_MASK_PIPE | NAME_MASK_NUMBER),
operation == MYFLOCK_OP_NONE ? "MYFLOCK_OP_NONE" :
str_name_mask_opt(op_buf, "operation", op_masks,
operation, NAME_MASK_PIPE | NAME_MASK_NUMBER));
vstring_free(style_buf);
vstring_free(op_buf);
}
/*
* Sanity check.
@ -139,13 +166,15 @@ int myflock(int fd, int lock_style, int operation)
default:
msg_panic("myflock: unsupported lock style: 0x%x", lock_style);
}
if (msg_verbose)
msg_info("myflock() returns %d", status);
/*
* Return a consistent result. Some systems return EACCES when a lock is
* taken by someone else, and that would complicate error processing.
*/
if (status < 0 && (operation & MYFLOCK_OP_NOWAIT) != 0)
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EACCES)
if (errno == EWOULDBLOCK || errno == EACCES)
errno = EAGAIN;
return (status);

View File

@ -0,0 +1,244 @@
/*++
/* NAME
/* ossl_digest 3
/* SUMMARY
/* OpenSSL message digest wrapper
/* SYNOPSIS
/* #define USE_TLS
/*
/* #include <ossl_digest.h>
/*
/* OSSL_DGST *ossl_digest_new(
/* const char *alg_name)
/*
/* int ossl_digest_data(
/* OSSL_DGST *dgst,
/* const void *data,
/* ssize_t data_len,
/* VSTRING *out);
/*
/* ARGV *ossl_digest_get_errors(void)
/*
/* ARGV *ossl_digest_log_errors(
/* void (*logger)(const char *,...))
/*
/* ssize_t ossl_digest_get_size(
/* OSSL_DGST *dgst)
/*
/* void ossl_digest_free(
/* OSSL_DGST *dgst)
/* DESCRIPTION
/* ossl_digest_new() allocates a wrapper for the named message
/* digest algorithm. This wrapper can be used in multiple successive
/* calls to compute a digest, and can be disposed of with
/* ossl_digest_free().
/*
/* ossl_digest_data() uses the specified message digest wrapper to
/* compute a digest over the specified data.
/*
/* ossl_digest_get_errors() dumps and clears the OpenSSL error stack.
/* Each stack entry is copied to one ARGV element. NOTE: The caller
/* should be prepared for the call to return an empty result,
/* and always report their own error info.
/*
/* ossl_digest_log_errors() logs and clears the OpenSSL error stack.
/* Each stack entry is logged by the specified function. NOTE:
/* The caller should be prepared for the call to return an empty
/* result, and log their own error message.
/*
/* ossl_digest_get_size() returns the output byte count for the
/* specified message digest wrapper.
/*
/* ossl_digest_free() releases storage allocated for or by the
/* specified message wrapper.
/* DIAGNOSTICS
/* Panic: ossl_digest_data() was called with an invalid data_len
/* argument; an ossl_digest_free() argument was not created with
/* ossl_digest_new().
/*
/* ossl_digest_new() returns NULL after error. ossl_digest_data()
/* returns 0 after success, -1 after error.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* porcupine.org
/*--*/
#ifdef USE_TLS
/*
* System library.
*/
#include <sys_defs.h>
/*
* OpenSSL library.
*/
#include <openssl/err.h>
#include <openssl/evp.h>
/*
* Utility library.
*/
#include <msg.h>
#include <mymalloc.h>
#include <ossl_digest.h>
#include <vstring.h>
#ifndef OPENSSL_VERSION_PREREQ
#define OPENSSL_VERSION_PREREQ(m,n) 0
#endif
/*
* OpenSSL 1.1.1 compatibility crutches. Note: EVP_get_digestbyname()
* returns const EVP_MD * which can't be passed to EVP_MD_free(EVP_MD *).
*/
#if !OPENSSL_VERSION_PREREQ(3,0)
#define EVP_MD_fetch(ct, alg_name, pr) EVP_get_digestbyname(alg_name)
#define BC_CONST const
#define EVP_MD_free(m) /* */
#define EVP_MD_get_size EVP_MD_size
#else
#define BC_CONST /* */
#endif
/*
* Opaque object.
*/
struct OSSL_DGST {
EVP_MD_CTX *mdctx;
BC_CONST EVP_MD *dgst_alg;
};
/*
* SLMs.
*/
#define STR(x) vstring_str(x)
#define LEN(x) VSTRING_LEN(x)
/* ossl_digest_new - create OpenSSL digest wrapper */
OSSL_DGST *ossl_digest_new(const char *alg_name)
{
OSSL_DGST *dgst = (OSSL_DGST *) mymalloc(sizeof(*dgst));
/*
* https://docs.openssl.org/3.3/man7/ossl-guide-libcrypto-introduction
* "If you perform the same operation many times with the same algorithm
* then it is recommended to use a single explicit fetch of the algorithm
* and then reuse the explicitly fetched algorithm each subsequent time.
* This will typically be faster than implicitly fetching the algorithm
* every time you use it".
*
* That same text mentions that calling, for example, EVP_sha256(3), uses
* implicit fetching.
*/
if ((dgst->dgst_alg = EVP_MD_fetch(NULL, alg_name, NULL)) != 0) {
if ((dgst->mdctx = EVP_MD_CTX_new()) != 0) {
/* Success. */
return (dgst);
}
EVP_MD_free(dgst->dgst_alg);
}
/* Failure. */
myfree(dgst);
return (0);
}
/* ossl_digest_data - digest one data buffer */
int ossl_digest_data(OSSL_DGST *dgst, const void *data,
ssize_t data_len, VSTRING *out)
{
unsigned int out_len;
if (data_len < 0)
msg_panic("ossl_digest_data: bad data_len %ld", (long) data_len);
VSTRING_RESET(out);
VSTRING_SPACE(out, EVP_MD_get_size(dgst->dgst_alg));
if (EVP_DigestInit_ex(dgst->mdctx, dgst->dgst_alg, 0) != 1
|| EVP_DigestUpdate(dgst->mdctx, data, data_len) != 1
|| EVP_DigestFinal_ex(dgst->mdctx, (void *) STR(out),
&out_len) != 1)
return (-1);
vstring_set_payload_size(out, out_len);
return (0);
}
/* ossl_digest_get_size - determine digest output byte count */
ssize_t ossl_digest_get_size(OSSL_DGST *dgst)
{
return (EVP_MD_get_size(dgst->dgst_alg));
}
/* ossl_digest_get_errors - export and clear OpenSSL error stack */
ARGV *ossl_digest_get_errors(void)
{
ARGV *argv = argv_alloc(1);
VSTRING *tmp = vstring_alloc(100);
unsigned long err;
char buffer[1024]; /* XXX */
const char *file;
const char *data;
int line;
int flags;
/*
* Shamelessly copied from Postfix TLS library.
*/
#if OPENSSL_VERSION_PREREQ(3,0)
/* XXX: We're ignoring the function name, do we want to log it? */
#define ERRGET(fi, l, d, fl) ERR_get_error_all(fi, l, 0, d, fl)
#else
#define ERRGET(fi, l, d, fl) ERR_get_error_line_data(fi, l, d, fl)
#endif
while ((err = ERRGET(&file, &line, &data, &flags)) != 0) {
ERR_error_string_n(err, buffer, sizeof(buffer));
if (flags & ERR_TXT_STRING)
vstring_sprintf(tmp, "%s:%s:%d:%s:",
buffer, file, line, data);
else
vstring_sprintf(tmp, "%s:%s:%d:", buffer, file, line);
argv_add(argv, STR(tmp), (char *) 0);
}
vstring_free(tmp);
return (argv);
}
/* ossl_digest_log_errors - log and clear OpenSSL error stack */
void ossl_digest_log_errors(void (*logger)(const char *, ...))
{
unsigned long err;
char buffer[1024]; /* XXX */
const char *file;
const char *data;
int line;
int flags;
while ((err = ERRGET(&file, &line, &data, &flags)) != 0) {
ERR_error_string_n(err, buffer, sizeof(buffer));
if (flags & ERR_TXT_STRING)
logger("%s:%s:%d:%s:", buffer, file, line, data);
else
logger("%s:%s:%d:", buffer, file, line);
}
}
/* ossl_digest_free - dispose of digest wrapper */
void ossl_digest_free(OSSL_DGST *dgst)
{
EVP_MD_CTX_destroy(dgst->mdctx);
EVP_MD_free(dgst->dgst_alg);
myfree(dgst);
}
#endif /* USE_TLS */

View File

@ -0,0 +1,51 @@
#ifndef _OSSL_DIGEST_H_INCLUDED_
#define _OSSL_DIGEST_H_INCLUDED_
#ifdef USE_TLS
/*++
/* NAME
/* ossl_digest 3h
/* SUMMARY
/* OpenSSL message digest wrapper
/* SYNOPSIS
/* #include <ossl_digest.h>
/* DESCRIPTION
/* .nf
/*
* System library.
*/
#include <sys_defs.h>
/*
* Utility library.
*/
#include <argv.h>
#include <vstring.h>
/*
* External interface.
*/
typedef struct OSSL_DGST OSSL_DGST;
extern OSSL_DGST *ossl_digest_new(const char *);
extern int ossl_digest_data(OSSL_DGST *, const void *data, ssize_t data_len,
VSTRING *out);
extern ARGV *ossl_digest_get_errors(void);
extern void ossl_digest_log_errors(void (*logger) (const char *,...));
extern ssize_t ossl_digest_get_size(OSSL_DGST *);
extern void ossl_digest_free(OSSL_DGST *);
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* porcupine.org
/*--*/
#endif /* USE_TLS */
#endif /* _OSSL_DIGEST_H_INCLUDED_ */

View File

@ -0,0 +1,204 @@
/*++
/* NAME
/* ossl_digest_test 1t
/* SUMMARY
/* ossl_digest unit tests
/* SYNOPSIS
/* ./ossl_digest_test
/* DESCRIPTION
/* ossl_digest_test runs and logs each configured test, reports if
/* a test is a PASS or FAIL, and returns an exit status of zero if
/* all tests are a PASS.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* porcupine.org
/*--*/
/*
* System library.
*/
#include <sys_defs.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*
* Utility library.
*/
#include <argv.h>
#include <hex_code.h>
#include <msg.h>
#include <mymalloc.h>
#include <ossl_digest.h>
#include <stringops.h>
#include <vstring.h>
#ifdef USE_TLS
#define LEN(x) VSTRING_LEN(x)
#define STR(x) vstring_str(x)
#define PASS 1
#define FAIL 0
/* get_error_string - return error info as one string */
static char *get_error_string(void)
{
VSTRING *err_string;
ARGV *err_list;
err_list = ossl_digest_get_errors();
err_string = vstring_alloc(100);
argv_join(err_string, err_list, '\n');
argv_free(err_list);
return (vstring_export(err_string));
}
static int reports_bad_digest_name(void)
{
const char *bad_digest_name = "doesnotexist";
OSSL_DGST *dgst;
int status = PASS;
if ((dgst = ossl_digest_new(bad_digest_name)) != 0) {
msg_warn("want: NULL, got: %p", (void *) dgst);
ossl_digest_free(dgst);
status = FAIL;
} else {
char *err_string;
err_string = get_error_string();
if (strstr(err_string, bad_digest_name) == 0) {
status = FAIL;
msg_warn("want: '%s', got: '%s'", bad_digest_name, err_string);
}
myfree(err_string);
}
return (status);
}
static int computes_sha256_digests(void)
{
OSSL_DGST *dgst;
struct DGST_TEST {
const char *in;
const char *want_hex;
};
static const struct DGST_TEST sha256_tests[] = {
{"",
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
},
{"one",
"7692c3ad3540bb803c020b3aee66cd8887123234ea0c6e7143c0add73ff431ed",
},
{"two",
"3fc4ccfe745870e2c0d99f71f30ff0656c8dedd41cc1d7d3d376b0dbe685e2f3",
},
{0},
};
const struct DGST_TEST *dp;
int status = PASS;
if ((dgst = ossl_digest_new("sha256")) == 0) {
char *err_string = get_error_string();
msg_warn("want: noerror, got: '%s'", err_string);
myfree(err_string);
status = FAIL;
} else {
VSTRING *out = vstring_alloc(10);
VSTRING *got_hex = vstring_alloc(10);
for (dp = sha256_tests; dp->in != 0; dp++) {
if (ossl_digest_data(dgst, dp->in, strlen(dp->in), out) < 0) {
char *err_string = get_error_string();
msg_warn("want: noerror, got: '%s'", err_string);
myfree(err_string);
status = FAIL;
continue;
}
hex_encode(got_hex, STR(out), LEN(out));
lowercase(STR(got_hex));
if (strcmp(STR(got_hex), dp->want_hex) != 0) {
msg_warn("got: '%s', want: '%s'", STR(got_hex), dp->want_hex);
status = FAIL;
continue;
}
}
ossl_digest_free(dgst);
vstring_free(got_hex);
vstring_free(out);
}
return (status);
}
static int returns_sha256_output_size(void)
{
OSSL_DGST *dgst;
ssize_t got_size, want_size = 256 / 8;
int status = PASS;
if ((dgst = ossl_digest_new("sha256")) == 0) {
char *err_string;
err_string = get_error_string();
msg_warn("want: noerror, got: '%s'", err_string);
myfree(err_string);
status = FAIL;
} else {
if ((got_size = ossl_digest_get_size(dgst)) != want_size) {
msg_warn("want: %ld, got: %ld", (long) got_size, (long) want_size);
status = FAIL;
}
ossl_digest_free(dgst);
}
return (status);
}
struct TEST_CASE {
const char *label;
int (*action) (void);
};
static const struct TEST_CASE test_cases[] = {
{"reports_bad_digest_name", reports_bad_digest_name,},
/* TODO(wietse) test ossl_digest_log_errors() */
{"computes_sha256_digests", computes_sha256_digests,},
{"returns_sha256_output_size", returns_sha256_output_size,},
{0},
};
int main(int argc, char **argv)
{
static int tests_passed = 0;
static int tests_failed = 0;
const struct TEST_CASE *tp;
for (tp = test_cases; tp->label; tp++) {
msg_info("RUN %s", tp->label);
if (tp->action() == PASS) {
msg_info("PASS %s", tp->label);
tests_passed += 1;
} else {
msg_info("FAIL %s", tp->label);
tests_failed += 1;
}
}
msg_info("PASS=%d FAIL=%d", tests_passed, tests_failed);
exit(tests_failed != 0);
}
#else
int main(int argc, char **argv)
{
msg_fatal("this program requires `#define USE_TLS'");
}
#endif

View File

@ -481,14 +481,20 @@ static void verify_query_service(VSTREAM *client_stream)
/* FIX 200501 IPv6 patch did not neuter ":" in address literals. */
translit(STR(addr), ":", "_");
if ((raw_data = dict_cache_lookup(verify_map, STR(addr))) == 0 /* not found */
|| ((get_buf = vstring_alloc(10)),
vstring_strcpy(get_buf, raw_data), /* malformed */
verify_parse_entry(STR(get_buf), &addr_status, &probed,
&updated, &text) < 0)
|| (now - probed > PROBE_TTL /* safe to probe */
&& (POSITIVE_ENTRY_EXPIRED(addr_status, updated)
|| NEGATIVE_ENTRY_EXPIRED(addr_status, updated)))) {
raw_data = dict_cache_lookup(verify_map, STR(addr));
if (dict_cache_error(verify_map) != 0) {
addr_status = DEL_RCPT_STAT_DEFER;
probed = 0;
updated = 0;
text = "Address verification status unavailable";
} else if (raw_data == 0 /* not found */
|| ((get_buf = vstring_alloc(10)),
vstring_strcpy(get_buf, raw_data), /* malformed */
verify_parse_entry(STR(get_buf), &addr_status, &probed,
&updated, &text) < 0)
|| (now - probed > PROBE_TTL /* safe to probe */
&& (POSITIVE_ENTRY_EXPIRED(addr_status, updated)
|| NEGATIVE_ENTRY_EXPIRED(addr_status, updated)))) {
addr_status = DEL_RCPT_STAT_TODO;
probed = 0;
updated = 0;
@ -525,7 +531,7 @@ static void verify_query_service(VSTREAM *client_stream)
#define NEGATIVE_REFRESH_NEEDED(addr_status, updated) \
(addr_status != DEL_RCPT_STAT_OK && updated + var_verify_neg_try < now)
if (now - probed > PROBE_TTL
if (dict_cache_error(verify_map) == 0 && now - probed > PROBE_TTL
&& (POSITIVE_REFRESH_NEEDED(addr_status, updated)
|| NEGATIVE_REFRESH_NEEDED(addr_status, updated))) {
if (msg_verbose)
@ -534,7 +540,7 @@ static void verify_query_service(VSTREAM *client_stream)
post_mail_fopen_async(make_verify_sender_addr(), STR(addr),
MAIL_SRC_MASK_VERIFY,
DEL_REQ_FLAG_MTA_VRFY,
/* TODO(wietse) disable REQUIRETLS? */
/* TODO(wietse) disable REQUIRETLS? */
SMTPUTF8_FLAG_NONE,
(VSTRING *) 0,
verify_post_mail_action,