]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.11-20250606
authorWietse Z Venema <wietse@porcupine.org>
Fri, 6 Jun 2025 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Sat, 7 Jun 2025 02:48:22 +0000 (12:48 +1000)
62 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/Makefile.in
postfix/README_FILES/COMPATIBILITY_README
postfix/README_FILES/SMTPUTF8_README
postfix/README_FILES/TLSRPT_README
postfix/html/COMPATIBILITY_README.html
postfix/html/SMTPUTF8_README.html
postfix/html/TLSRPT_README.html
postfix/html/lmdb_table.5.html
postfix/html/memcache_table.5.html
postfix/html/mysql_table.5.html
postfix/html/pgsql_table.5.html
postfix/html/postconf.5.html
postfix/man/man5/lmdb_table.5
postfix/man/man5/memcache_table.5
postfix/man/man5/mysql_table.5
postfix/man/man5/pgsql_table.5
postfix/man/man5/postconf.5
postfix/proto/COMPATIBILITY_README.html
postfix/proto/SMTPUTF8_README.html
postfix/proto/TLSRPT_README.html
postfix/proto/lmdb_table
postfix/proto/memcache_table
postfix/proto/mysql_table
postfix/proto/pgsql_table
postfix/proto/postconf.html.prolog
postfix/proto/postconf.proto
postfix/proto/stop
postfix/proto/stop.double-cc
postfix/proto/stop.double-history
postfix/proto/stop.spell-cc
postfix/src/global/Makefile.in
postfix/src/global/dict_memcache.c
postfix/src/global/mail_params.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/postalias/Makefile.in
postfix/src/postalias/mode_conflict_test.in [new file with mode: 0644]
postfix/src/postalias/mode_conflict_test.ref [new file with mode: 0644]
postfix/src/postalias/postalias.c
postfix/src/postmap/Makefile.in
postfix/src/postmap/mode_conflict_test.in [new file with mode: 0644]
postfix/src/postmap/mode_conflict_test.ref [new file with mode: 0644]
postfix/src/postmap/postmap.c
postfix/src/smtp/smtp_tlsrpt.c
postfix/src/testing/.indent.pro [new symlink]
postfix/src/testing/Makefile.in [new file with mode: 0644]
postfix/src/testing/nosleep.c [new file with mode: 0644]
postfix/src/util/Makefile.in
postfix/src/util/dict_cache.c
postfix/src/util/dict_cache.h
postfix/src/util/dict_cdb.c
postfix/src/util/dict_db.c
postfix/src/util/hex_code.c
postfix/src/util/hex_code.h
postfix/src/util/mkmap_open.c
postfix/src/util/myflock.c
postfix/src/util/ossl_digest.c [new file with mode: 0644]
postfix/src/util/ossl_digest.h [new file with mode: 0644]
postfix/src/util/ossl_digest_test.c [new file with mode: 0644]
postfix/src/verify/verify.c

index f1671a6ec4e4207256e2cfa6c1d9aed1784061b7..86522dfde2f0d400e8aa9eeec61e8edd3d90ca55 100644 (file)
 -TNBBIO
 -TNVTABLE_INFO
 -TOPTIONS
+-TOSSL_DGST
 -TPCF_DBMS_INFO
 -TPCF_DEPR_PARAM_INFO
 -TPCF_EVAL_CTX
index 489e0f9e98acd75fea2f22a1d5bc24fadd9aa9aa..13b6b27d6b4368c40a1a215a39e3016d4ad3985e 100644 (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].
index 12789cad7eb8298cee9299c643de229448375510..fc7be73865a67490060c146744dc926d8670f099 100644 (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
index aa9e7f6a7d516d6273ea25fd8d380d91f3ead4ef..e06ef17eb251561277c922a799d5ce625e1dfae4 100644 (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
     # p\bpo\bos\bst\btc\bco\bon\bnf\bf "\b"r\bre\bes\bsp\bpe\bec\bct\btf\bfu\bul\bl_\b_l\blo\bog\bgg\bgi\bin\bng\bg =\b= n\bno\bo"\b"
     # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
 
+U\bUs\bsi\bin\bng\bg b\bba\bac\bck\bkw\bwa\bar\brd\bds\bs-\b-c\bco\bom\bmp\bpa\bat\bti\bib\bbl\ble\be d\bde\bef\bfa\bau\bul\blt\bt s\bse\bet\btt\bti\bin\bng\bg
+s\bsm\bmt\btp\bp_\b_t\btl\bls\bsr\brp\bpt\bt_\b_s\bsk\bki\bip\bp_\b_r\bre\beu\bus\bse\bed\bd_\b_h\bha\ban\bnd\bds\bsh\bha\bak\bke\bes\bs=\b=y\bye\bes\bs
+
+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:
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf s\bsm\bmt\btp\bp_\b_t\btl\bls\bsr\brp\bpt\bt_\b_s\bsk\bki\bip\bp_\b_r\bre\beu\bus\bse\bed\bd_\b_h\bha\ban\bnd\bds\bsh\bha\bak\bke\bes\bs=\b=y\bye\bes\bs
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
 T\bTu\bur\brn\bni\bin\bng\bg o\bof\bff\bf t\bth\bhe\be b\bba\bac\bck\bkw\bwa\bar\brd\bds\bs-\b-c\bco\bom\bmp\bpa\bat\bti\bib\bbi\bil\bli\bit\bty\by s\bsa\baf\bfe\bet\bty\by n\bne\bet\bt
 
 Backwards compatibility is turned off by updating the compatibility_level
index 0b07374b849ac948ca5b6fa7c48b877a2f4f03cd..42170970f6045c82a493182453d4f12cedfc7ab4 100644 (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.
 
 C\bCr\bre\bed\bdi\bit\bts\bs
 
index 4a2e88f356d4fe5bc790b895102d072c20d43e67..e4a00ee81e3fcf537ef4ad23c628570efb2a322e 100644 (file)
@@ -188,11 +188,11 @@ Notes:
     Untrusted T\bTL\bLS\bS c\bco\bon\bnn\bne\bec\bct\bti\bio\bon\bn r\bre\beu\bus\bse\bed\bd 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:
 
 M\bMT\bTA\bA-\b-S\bST\bTS\bS S\bSu\bup\bpp\bpo\bor\brt\bt v\bvi\bia\ba s\bsm\bmt\btp\bp_\b_t\btl\bls\bs_\b_p\bpo\bol\bli\bic\bcy\by_\b_m\bma\bap\bps\bs
 
-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.
index f2cf4c2d5051ec3c2b6af3a128a1ea1cbaaa765a..29446db7e1d2f4f615605875b93e0f53f02482fb 100644 (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
index 10f22e4e60f828632d76d774c20da2ed97a6a61e..cb42d06a0bd4c27db37c49f845358fff016f06bc 100644 (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>
index 6d3746e4c81a18a4ce7379708f8ca5b7e994cd29..3a361d71298bac214892a3aab01e777ed5ecf145 100644 (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
index 60624494eb3b64d16c5a35bc211a8df8c4abd548..ac0221335f3e70a86762569b72ef180d71d02c30 100644 (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.
-
-       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
+       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
        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>
index 42796b71763410da36be3dd81661f3b70da5cba7..47c9aa396e0615197ef263ee6ff76a01c1abfbde 100644 (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>
index c759066415154cf14fab068f0b1d1a85226b94f6..8c8e5588ea0ac391dfff00fee85e6aa534382e08 100644 (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.
 
index e44279000691b5c5bd81b84faea53b6d26e69fba..cab95ff899608d095ae6b40a42786c1e4af7f825 100644 (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.
 
index 03d029cd0d2e5c1d53a833df1a065e04aa209c10..0d63f28ee5f9f9795eb4b3d54e08fde388d3352e 100644 (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
index c4c74d6349ce19ea6907e35c6d90234c20f00b59..eec44147fd9c3d6c4f6efade7f040f271ef94e4d 100644 (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
index 430f73c515105aaeeac43b00517e22263e3b099c..8d90a3df3c89f09de660fc2ee8d2cff0c8fbb304 100644 (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
index 865f9d07f5368646a5bec08cb1f29382ceb67449..3cca85eb23acd6feebd619045a4ab7ecb9c1dc9d 100644 (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"
index 51df7338ecfc5038c0172796674cbe3ad26a715d..1deaa3fe89a01c8cca5a21b20d66551908a97585 100644 (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"
index afb9cc97b5b7b870eb99e4fabcc318dd0a3c4e72..24351183c30fa4a5261a14200b8f90f0817303c6 100644 (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.
index 801d0d9a52e59e0ddd19e1792b16e0e038b006f5..d0fd5d90209fa6d3ffe361de502b046d0b8e6176 100644 (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
index 5948f85fcab3f05e89dfb7870fab2d3e431d2fcc..e2713c41bc49b85da3934d69f7acc7fcf5105a01 100644 (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>
index 0531b0381ae5652983e9d6bbe8355bb78d2bb445..755b5e3ee7d9b81340cc1ff18caa504f04a2cd85 100644 (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
index 5bbbc14d3835fed9433c1248eb1e8bc533a7c073..ad81a4622fe23ed4fc19f2c89a31fc1c166e3c3e 100644 (file)
 # .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
index c97a9b449844e4464550920953a4233223c6ab08..6d424039467b93bacaa2d8798793a0310b5a5ae8 100644 (file)
 # 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.
 #      "\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
index fc1c238c839d418b20785f1a97a08e7e8df2f64d..d93d405a80041d7aa9e7eb3990984d37239970e0 100644 (file)
 #          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.
 #      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"
index cba9e45f48be5b273ec0a9f0db1c65b67d86d06a..edc50b619c0ba2e40ae5b760e7834fb69ead5c6f 100644 (file)
 #      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.
 #      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"
index cb91af19072172f2cfb88ee9a1d89fc86fbcde6e..73cfb1607c5b6bff99697035d358b0dc08b428f9 100644 (file)
@@ -20,7 +20,7 @@ if (hash && isChrome) {
     setTimeout(function() {
         window.location.hash = "";
         window.location.hash = hash;
-    }, 1000);
+    }, 1500);
 }
 
 </script>
index 4aef0b2d39a826301474c67bf43265d3b1ca36a7..b1130e134d846772662099e70990df3cf26d13a2 100644 (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
index 7c06d7ee4c5561187b8a3f60d73e78f67e58d9c1..ef6aab0a2e443a9526f8fc9acb5857df3864f3a7 100644 (file)
@@ -1674,3 +1674,11 @@ MLKEM
 cleartext
 redacted
 subclassed
+nosleep
+preload
+memcached
+Geert
+Hendrickx
+typofix
+LD
+PRELOAD
index e80d33312467d826236b0e73464b7db07b0fdd40..0179fe90fc3a4594dc479a88db2249100c39ec91 100644 (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 
index 62e45e6b29ecea0beaeb8250b25a4c41fe7e4711..782732fda6452512935a8084caf379232d9c5979 100644 (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 
index 3fa8e952895133858ff035edd3dbc22c98c78de4..506c2d2c8c1ae38a8b9e873dcc90d0a939fa93a5 100644 (file)
@@ -1860,3 +1860,7 @@ XXXSENDOPTS
 xtra
 HAPROXY
 SRVR
+DGST
+DIGEST
+OSSL
+ossl
index 8a2e26ca071449a7d072801c358f66008d080b02..dfc28b6319097f62023a506ddec648e7900eeb48 100644 (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
index f249f68e9059fb604f252ddd1e226855a8ace815..09c5cb658b5c647e87b1d71d30071a3edbe6260a 100644 (file)
 
 /* 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);
 }
index 5d2171d0ac26a2e05f4d8de9df0ec0536e00c689..6032ea39a734947ebcfcdc2fe2da6a95a5cef14d 100644 (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.
index 0aa05ba0024e95c930eae61dfe705c3d4c661355..40aa5c2ba88b083115ede52426f9215293d7fb14 100644 (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;
index 1d3ab0d81f265cd07bca339d88cf462cfec813cd..102c9cd24f05109a41d74c1f2c49f37766921d8a 100644 (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
index 5ed9bbb2c274a5eadb167627285078b4f442575c..751a55995daa8bb8188501917f0ccef761ed15d9 100644 (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
diff --git a/postfix/src/postalias/mode_conflict_test.in b/postfix/src/postalias/mode_conflict_test.in
new file mode 100644 (file)
index 0000000..552c19d
--- /dev/null
@@ -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
diff --git a/postfix/src/postalias/mode_conflict_test.ref b/postfix/src/postalias/mode_conflict_test.ref
new file mode 100644 (file)
index 0000000..da3d7b8
--- /dev/null
@@ -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
index 5033f9da2fdd0e9be9ea5126127bd9fe3bd7a0f1..c17b6a1d609b5fce7f156a7a2ae173db3241785e 100644 (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':
index 4f114f50417116a9ced9f0dd3e77e9ab2d4bc4a2..b415d57b1f37862f3816d3c41262009c5ebd5886 100644 (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
 
diff --git a/postfix/src/postmap/mode_conflict_test.in b/postfix/src/postmap/mode_conflict_test.in
new file mode 100644 (file)
index 0000000..8ccdad0
--- /dev/null
@@ -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
diff --git a/postfix/src/postmap/mode_conflict_test.ref b/postfix/src/postmap/mode_conflict_test.ref
new file mode 100644 (file)
index 0000000..89827db
--- /dev/null
@@ -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
index 739045081713c9a5a5999baa47bfe869afd29a4e..9e8c7838186d16610b6e9c328831741e2c01e20c 100644 (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':
index cef46d5cd1601bf50bf671316c3b722597b58619..b22be52c36de496923812ed370173b071707c605 100644 (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,
diff --git a/postfix/src/testing/.indent.pro b/postfix/src/testing/.indent.pro
new file mode 120000 (symlink)
index 0000000..5c837ec
--- /dev/null
@@ -0,0 +1 @@
+../../.indent.pro
\ No newline at end of file
diff --git a/postfix/src/testing/Makefile.in b/postfix/src/testing/Makefile.in
new file mode 100644 (file)
index 0000000..ad624de
--- /dev/null
@@ -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
diff --git a/postfix/src/testing/nosleep.c b/postfix/src/testing/nosleep.c
new file mode 100644 (file)
index 0000000..dbbe40b
--- /dev/null
@@ -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);
+}
index e749eb0db7a3f825753b72c6b3ff0a3d8f982e5a..7c99ae23a67ed084d79b174abafbe73005dde1f4 100644 (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
index 4a24089f363db67b2a434fdddc87275a0a747fb8..f87c83e53d1dbb99a663958de98475d707bddcaa 100644 (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;
 /* .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
index 2d403b529ba455b49094fabf8d44481340c2d6ca..ff5859679d62c3b54995669ec0d57d8b6c59fe36 100644 (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 */
index ea98363ff100a0393f1acef2c6bacd9ead616430..885efc289df79bbb9e1b33168f5f8aecff848811 100644 (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");
     }
index b2d0c336f3bc441a88d86a9efa3404363b6d094b..0a3a87afb6836d291f165886673f4461e470d50a 100644 (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
index 07d2248957c174c60de0a2a011451a212e42ff8e..2abf9511a287e716397125ed54760f6a17845c99 100644 (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},
 };
 
index ad923c9e24695cf1d33b78e8421a375de45c929b..c9a3e0c97df9fcc62026dd98c656d516ed05f11a 100644 (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)
index 961f54403ece2458849a1ebfd4cc27e85407e46d..64cb5bedd3f27ac2df9ddc80dbdc83a0d20c3a0c 100644 (file)
 /*     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.
+     */
+    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.
      */
-    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 */
+    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);
 
index bd903ee700568385334a129730cb07535f181cdd..2c8ad5d8ab0103890428197645a3c5e5db728176 100644 (file)
 
 #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);
diff --git a/postfix/src/util/ossl_digest.c b/postfix/src/util/ossl_digest.c
new file mode 100644 (file)
index 0000000..6174695
--- /dev/null
@@ -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 */
diff --git a/postfix/src/util/ossl_digest.h b/postfix/src/util/ossl_digest.h
new file mode 100644 (file)
index 0000000..7465172
--- /dev/null
@@ -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_ */
diff --git a/postfix/src/util/ossl_digest_test.c b/postfix/src/util/ossl_digest_test.c
new file mode 100644 (file)
index 0000000..721e6bb
--- /dev/null
@@ -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
index 8e8dd25175eed25542b04606030ff1ca2961c3f9..e18c6c2468f949bb3aa2c40b2898719359904b4d 100644 (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,