]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.7-20210926
authorWietse Venema <wietse@porcupine.org>
Sun, 26 Sep 2021 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Wed, 19 Jan 2022 06:36:07 +0000 (01:36 -0500)
22 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/FORWARD_SECRECY_README
postfix/RELEASE_NOTES
postfix/html/FORWARD_SECRECY_README.html
postfix/html/postconf.5.html
postfix/man/man5/postconf.5
postfix/mantools/postlink
postfix/proto/FORWARD_SECRECY_README.html
postfix/proto/postconf.proto
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/postconf/postconf_builtin.c
postfix/src/postconf/postconf_lookup.c
postfix/src/postconf/postconf_main.c
postfix/src/postconf/postconf_master.c
postfix/src/tls/tls.h
postfix/src/tls/tls_client.c
postfix/src/tls/tls_dh.c
postfix/src/tls/tls_misc.c
postfix/src/tls/tls_scache.c
postfix/src/tls/tls_server.c

index 4ea4616eaf88d63a2e083ce272dba711e7530afb..1f8431f0d3b8098a134d56ce47a5949101dad029 100644 (file)
 -TEC_KEY
 -TEDIT_FILE
 -TEVENT_MASK
+-TEVP_CIPHER_CTX
+-TEVP_MAC_CTX
+-TEVP_MD
 -TEVP_MD_CTX
 -TEVP_PKEY
 -TEXPAND_ATTR
 -THBC_TEST_CONTEXT
 -THEADER_OPTS
 -THEADER_TOKEN
+-THMAC_CTX
 -THOST
 -THTABLE
 -THTABLE_INFO
 -TLDAP
 -TLDAP_CONN
 -TLDAPMessage
+-TLDAPURLDesc
 -TLIB_DP
 -TLIB_FN
 -TLMTP_ATTR
 -TNAME_CODE
 -TNAME_MASK
 -TNBBIO
+-TNVTABLE_INFO
 -Toff_t
 -TOPTIONS
 -TPCF_DBMS_INFO
 -TSCAN_INFO
 -TSCAN_OBJ
 -TSENDER_LOGIN_MATCH
+-TSERVER_AC
 -TSESSION
 -Tsfsistat
 -TSHARED_PATH
index 4a589b54d4748f5b50453f137352ca3b432dd73c..a77b594c9eaefa61e35e6cde25d177ff3c34637d 100644 (file)
@@ -25749,3 +25749,34 @@ Apologies for any names omitted.
        backwards-compatible default value.
 
        Minor text and code cleanups. File: postlog/postlog.c.
+
+20210925
+
+       Prevent sharing of xxx_tls_session_cache_database instances
+       between different Postfix instances when a database is
+       not multi-writer safe. Like postscreen(8) and verify(8),
+       open such a database with a permanent lock, and raise
+       a fatal error when that database is already opened as
+       xxx_tls_session_cache_database. File: src/tls/tls_scache.c.
+
+       Bugfix (bug introduced: Postfix 2.10): postconf -x produced
+       incorrect output, because different functions were implicitly
+       sharing a buffer for intermediate results. Reported by raf, root
+       cause analysis by Viktor Dukhovni, and Wietse eliminated the
+       underlying anti-pattern. Files: postconf/postconf_builtin.c,
+       postconf/postconf_dbms.c, postconf/postconf_lookup.c,
+       postconf/postconf_main.c, postconf/postconf_master.c.
+
+       Documentation: missing lmtp_tls_wrappermode parameter
+       documentation. Viktor Dukhovni. Files: mantools/postlink,
+       proto/postconf.proto.
+
+20210926
+
+       OpenSSL 3.0.0 feature and bitrot updates. Viktor Dukhovni.
+       Files: proto/FORWARD_SECRECY_README.html, proto/postconf.proto,
+       tls/tls_client.c, tls/tls_dh.c, tls/tls.h, tls/tls_misc.c,
+       tls/tls_server.c/^+
+
+       Cleanup: don't hyperlink text that is already hyperlinked.
+       File: mantools/postlink.
index 0d3fb12c7200e50c898b8e7247fae39d9408935d..4615b89c1f20b1b0f86dd53d55bca07d7e134373 100644 (file)
@@ -248,8 +248,18 @@ security against pre-computation attacks and for compatibility with Debian-
 patched Exim SMTP clients that require a >= 2048-bit length for the non-export
 prime.
 
-Execute as root (prime group generation can take a few seconds to a few
-minutes):
+With Postfix >= 3.7 built against OpenSSL version is 3.0.0 or later, when the
+value of smtpd_tls_dh1024_param_file is either empty or "a\bau\but\bto\bo", the EDH
+parameter selection is delegated to the OpenSSL library, which selects
+appropriate parameters based on the TLS handshake. This choice is likely to be
+the most interoperable with SMTP clients using various TLS libraries, and
+custom local parameters are no longer recommended when using Postfix >= 3.7
+built against OpenSSL 3.0.0. Just leave smtpd_tls_dh1024_param_file at its
+default value (both in main.cf(5) and any master.cf(5) overrides, and let
+OpenSSL do the work.
+
+Otherwise, execute as root (prime group generation can take a few seconds to a
+few minutes):
 
     # cd /etc/postfix
     # umask 022
@@ -259,7 +269,8 @@ minutes):
     # chmod 644 dh512.pem dh1024.pem dh2048.pem
 
 The Postfix SMTP server EDH parameter files are not secret, after all these
-parameters are sent to all remote SMTP clients in the clear. Mode 0644 is fine.
+parameters are sent to all remote SMTP clients in the clear. Mode 0644 is
+appropriate.
 
 You can improve security against pre-computation attacks further by
 regenerating the Postfix SMTP server EDH parameters periodically (an hourly or
index 8f8f4f3515494bdc28b0862a30ec7b4803909dac..ef4e4c9db20f28f0a39501494909022cba2f841f 100644 (file)
@@ -25,8 +25,8 @@ more recent Eclipse Public License 2.0. Recipients can choose to take
 the software under the license of their choice. Those who are more
 comfortable with the IPL can continue with that license.
 
-Major changes with snapshot 20210814-nonprod
-============================================
+Major changes with snapshot 20210815
+====================================
 
 Updated defense against remote clients or servers that 'trickle'
 SMTP or LMTP traffc. The new {smtpd,smtp,lmtp}_per_request_deadline
index 324bffc35b1dd83626865eab9add1d799de490e0..92622b4224e5e53d1fbb30c3a98bb97eb6e78600 100644 (file)
@@ -334,7 +334,17 @@ for improved security against pre-computation attacks and for
 compatibility with Debian-patched Exim SMTP clients that require a
 &ge; 2048-bit length for the non-export prime. </p>
 
-<p> Execute as root (prime group generation can take a
+<p> With Postfix &ge; 3.7 built against OpenSSL version is 3.0.0 or later, when
+the value of <a href="postconf.5.html#smtpd_tls_dh1024_param_file">smtpd_tls_dh1024_param_file</a> is either empty or "<b>auto</b>", the
+EDH parameter selection is delegated to the OpenSSL library, which selects
+appropriate parameters based on the TLS handshake.  This choice is likely to be
+the most interoperable with SMTP clients using various TLS libraries, and
+custom local parameters are no longer recommended when using Postfix &ge; 3.7
+built against OpenSSL 3.0.0.  Just leave <a href="postconf.5.html#smtpd_tls_dh1024_param_file">smtpd_tls_dh1024_param_file</a> at its
+default value (both in <a href="postconf.5.html">main.cf</a>(5) and any <a href="master.5.html">master.cf</a>(5) overrides, and let
+OpenSSL do the work.  </p>
+
+<p> Otherwise, execute as root (prime group generation can take a
 few seconds to a few minutes): </p>
 
 <blockquote>
@@ -350,7 +360,7 @@ few seconds to a few minutes): </p>
 
 <p> The Postfix SMTP server EDH parameter files are not secret,
 after all these parameters are sent to all remote SMTP clients in
-the clear. Mode 0644 is fine. </p>
+the clear. Mode 0644 is appropriate. </p>
 
 <p> You can improve security against pre-computation attacks further
 by regenerating the Postfix SMTP server EDH parameters periodically
index 35acee727da95b491c6f86104a5c948fdca36290..ab2f350e5563f6168fca1dc3b88d9f5d6d1f8498 100644 (file)
@@ -5714,6 +5714,17 @@ configuration parameter. See there for details. </p>
 <p> This feature is available in Postfix 2.3 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_tls_wrappermode">lmtp_tls_wrappermode</a>
+(default: no)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_wrappermode">smtp_tls_wrappermode</a> configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_use_tls">lmtp_use_tls</a>
@@ -11353,7 +11364,7 @@ href="https://tools.ietf.org/html/rfc7672">DANE</a> is not applicable
 to hosts resolved via "native" lookups.  </p>
 
 <p> As mentioned above, Postfix is not a validating <a
-href="<a href="https://tools.ietf.org/html/rfc4035#section-4.9">https://tools.ietf.org/html/rfc4035#section-4.9</a>">stub
+href="https://tools.ietf.org/html/rfc4035#section-4.9">stub
 resolver</a>; it relies on the system's configured DNSSEC-validating
 <a href="https://tools.ietf.org/html/rfc4035#section-3.2">recursive
 nameserver</a> to perform all DNSSEC validation.  Since this
@@ -14428,7 +14439,7 @@ contain the ":" character, and would otherwise be confused with a
 
 <p> Pattern matching of domain names is controlled by the presence
 or absence of "<a href="postconf.5.html#smtpd_client_event_limit_exceptions">smtpd_client_event_limit_exceptions</a>" in the
-<a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a> parameter value (postfix 3.0 and
+<a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a> parameter value (Postfix 3.0 and
 later).  </p>
 
 <p>
@@ -17668,6 +17679,14 @@ The DSA algorithm is obsolete and should not be used. </p>
 <p> File with DH parameters that the Postfix SMTP server should
 use with non-export EDH ciphers. </p>
 
+<p> With Postfix &ge; 3.7, built with OpenSSL version is 3.0.0 or later, if the
+parameter value is either empty or "<b>auto</b>", then the DH parameter
+selection is delegated to the OpenSSL library, which selects appropriate
+parameters based on the TLS handshake.  This choice is likely to be the most
+interoperable with SMTP clients using various TLS libraries, and custom local
+parameters are no longer recommended when using Postfix &ge; 3.7 built against
+OpenSSL 3.0.0.  </p>
+
 <p> The best-practice choice of parameters uses a 2048-bit prime.  This is fine,
 despite the historical "1024" in the parameter name.  Do not be tempted to use
 much larger values, performance degrades quickly, and you may also cease to
@@ -18898,7 +18917,7 @@ whitespace.  Each digest name may be followed by an optional
 "=&lt;number&gt;" suffix.  For example, "sha512" may instead be specified
 as "sha512=2" and "sha256" may instead be specified as "sha256=1".
 The optional number must match the <a
-href="<a href="https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#matching-types">https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#matching-types</a>"
+href="https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#matching-types"
 >IANA</a> assigned TLSA matching type number the algorithm in question.
 Postfix will check this constraint for the algorithms it knows about.
 Additional matching type algorithms registered with IANA can be added
@@ -19065,7 +19084,7 @@ is unwise to choose an "bleeding-edge" curve supported by only a
 small subset of clients.  </p>
 
 <p> The default "strong" curve is rated in NSA <a
-href="<a href="https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/">https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/</a>">Suite
+href="https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/">Suite
 B</a> for information classified up to SECRET.  </p>
 
 <p> Note: elliptic curve names are poorly standardized; different
@@ -19106,7 +19125,7 @@ curve must be implemented by OpenSSL (as reported by ecparam(1) with the
 of <a href="http://tools.ietf.org/html/rfc4492">RFC 4492</a>. You should not generally change this setting. </p>
 
 <p> This default "ultra" curve is rated in NSA <a
-href="<a href="https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/">https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/</a>">Suite
+href="https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/">Suite
 B</a> for information classified up to TOP SECRET. </p>
 
 <p> If you want to take maximal advantage of ciphers that offer <a
index 4b4752950d96653d78c6d0cdef35095fb9866d4c..d35c3840e9bacd6fb4aca9c5d42af17aff73a9a2 100644 (file)
@@ -3420,6 +3420,11 @@ The LMTP\-specific version of the smtp_tls_verify_cert_match
 configuration parameter. See there for details.
 .PP
 This feature is available in Postfix 2.3 and later.
+.SH lmtp_tls_wrappermode (default: no)
+The LMTP\-specific version of the smtp_tls_wrappermode configuration
+parameter. See there for details.
+.PP
+This feature is available in Postfix 3.0 and later.
 .SH lmtp_use_tls (default: no)
 The LMTP\-specific version of the smtp_use_tls configuration
 parameter.  See there for details.
@@ -9707,7 +9712,7 @@ contain the ":" character, and would otherwise be confused with a
 .PP
 Pattern matching of domain names is controlled by the presence
 or absence of "smtpd_client_event_limit_exceptions" in the
-parent_domain_matches_subdomains parameter value (postfix 3.0 and
+parent_domain_matches_subdomains parameter value (Postfix 3.0 and
 later).
 .PP
 This feature is available in Postfix 2.2 and later.
@@ -12251,6 +12256,14 @@ This feature is available in Postfix 2.2 and later.
 File with DH parameters that the Postfix SMTP server should
 use with non\-export EDH ciphers.
 .PP
+With Postfix >= 3.7, built with OpenSSL version is 3.0.0 or later, if the
+parameter value is either empty or "\fBauto\fR", then the DH parameter
+selection is delegated to the OpenSSL library, which selects appropriate
+parameters based on the TLS handshake.  This choice is likely to be the most
+interoperable with SMTP clients using various TLS libraries, and custom local
+parameters are no longer recommended when using Postfix >= 3.7 built against
+OpenSSL 3.0.0.
+.PP
 The best\-practice choice of parameters uses a 2048\-bit prime.  This is fine,
 despite the historical "1024" in the parameter name.  Do not be tempted to use
 much larger values, performance degrades quickly, and you may also cease to
index 01075f4554503585c5c3232a67bea9d0da281516..d4902b41a2f00d9b4c4c2319c398a35f89dee2dc 100755 (executable)
@@ -270,6 +270,7 @@ while (<>) {
     s;\blmtp_tls_loglevel\b;<a href="postconf.5.html#lmtp_tls_loglevel">$&</a>;g;
     s;\blmtp_tls_session_cache_database\b;<a href="postconf.5.html#lmtp_tls_session_cache_database">$&</a>;g;
     s;\blmtp_tls_session_cache_timeout\b;<a href="postconf.5.html#lmtp_tls_session_cache_timeout">$&</a>;g;
+    s;\blmtp_tls_wrappermode\b;<a href="postconf.5.html#lmtp_tls_wrappermode">$&</a>;g;
     s;\blmtp_generic_maps\b;<a href="postconf.5.html#lmtp_generic_maps">$&</a>;g;
     s;\blmtp_pix_workaround_threshold_time\b;<a href="postconf.5.html#lmtp_pix_workaround_threshold_time">$&</a>;g;
     s;\blmtp_pix_workaround_delay_time\b;<a href="postconf.5.html#lmtp_pix_workaround_delay_time">$&</a>;g;
@@ -1157,7 +1158,7 @@ while (<>) {
 
     # Hyperlink URLs and RFC documents
 
-    s/(https?:\/\/[^ ,"\(\)]*[^ ,"\(\):;!?.])/<a href="$1">$1<\/a>/;
+    if (!/href=/) { s/(https?:\/\/[^ ,"\(\)]*[^ ,"\(\):;!?.])/<a href="$1">$1<\/a>/; }
     s/(ftp:\/\/[^ ,"\(\)]*[^ ,"\(\):;!?.])/<a href="$1">$1<\/a>/;
     s/\bRFC\s*([1-9]\d*)/<a href="http:\/\/tools.ietf.org\/html\/rfc$1">$&<\/a>/g;
 
index 6cc9a60b9f77479055340b010abb72b8064fa692..d2bab2af7281dfe4b442d99e283b4cc33e108d5b 100644 (file)
@@ -334,7 +334,17 @@ for improved security against pre-computation attacks and for
 compatibility with Debian-patched Exim SMTP clients that require a
 &ge; 2048-bit length for the non-export prime. </p>
 
-<p> Execute as root (prime group generation can take a
+<p> With Postfix &ge; 3.7 built against OpenSSL version is 3.0.0 or later, when
+the value of smtpd_tls_dh1024_param_file is either empty or "<b>auto</b>", the
+EDH parameter selection is delegated to the OpenSSL library, which selects
+appropriate parameters based on the TLS handshake.  This choice is likely to be
+the most interoperable with SMTP clients using various TLS libraries, and
+custom local parameters are no longer recommended when using Postfix &ge; 3.7
+built against OpenSSL 3.0.0.  Just leave smtpd_tls_dh1024_param_file at its
+default value (both in main.cf(5) and any master.cf(5) overrides, and let
+OpenSSL do the work.  </p>
+
+<p> Otherwise, execute as root (prime group generation can take a
 few seconds to a few minutes): </p>
 
 <blockquote>
@@ -350,7 +360,7 @@ few seconds to a few minutes): </p>
 
 <p> The Postfix SMTP server EDH parameter files are not secret,
 after all these parameters are sent to all remote SMTP clients in
-the clear. Mode 0644 is fine. </p>
+the clear. Mode 0644 is appropriate. </p>
 
 <p> You can improve security against pre-computation attacks further
 by regenerating the Postfix SMTP server EDH parameters periodically
index 29164fb3558aecd08b682a4c68caca56226f30df..a44a51b992f647de85fe2e0e715b1d1efa3eac53 100644 (file)
@@ -4908,7 +4908,7 @@ contain the ":" character, and would otherwise be confused with a
 
 <p> Pattern matching of domain names is controlled by the presence
 or absence of "smtpd_client_event_limit_exceptions" in the
-parent_domain_matches_subdomains parameter value (postfix 3.0 and
+parent_domain_matches_subdomains parameter value (Postfix 3.0 and
 later).  </p>
 
 <p>
@@ -9810,6 +9810,14 @@ Postfix 2.3 and later; use smtpd_tls_mandatory_ciphers instead. </p>
 <p> File with DH parameters that the Postfix SMTP server should
 use with non-export EDH ciphers. </p>
 
+<p> With Postfix &ge; 3.7, built with OpenSSL version is 3.0.0 or later, if the
+parameter value is either empty or "<b>auto</b>", then the DH parameter
+selection is delegated to the OpenSSL library, which selects appropriate
+parameters based on the TLS handshake.  This choice is likely to be the most
+interoperable with SMTP clients using various TLS libraries, and custom local
+parameters are no longer recommended when using Postfix &ge; 3.7 built against
+OpenSSL 3.0.0.  </p>
+
 <p> The best-practice choice of parameters uses a 2048-bit prime.  This is fine,
 despite the historical "1024" in the parameter name.  Do not be tempted to use
 much larger values, performance degrades quickly, and you may also cease to
@@ -16925,6 +16933,13 @@ Postfix versions. </p>
 
 <p> This feature is available in Postfix 3.0 and later.  </p>
 
+%PARAM lmtp_tls_wrappermode no
+
+<p> The LMTP-specific version of the smtp_tls_wrappermode configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
 %PARAM smtp_tls_connection_reuse no
 
 <p> Try to make multiple deliveries per TLS-encrypted connection.
index 1e03ab6a3fadc16801360783e7d5a38e1a853454..e7679e0724cbfa045411d86ddd8377c7f5fd3442 100644 (file)
@@ -4111,7 +4111,7 @@ extern int var_smtpd_min_data_rate;
 
 #define VAR_SMTP_MIN_DATA_RATE "smtp_min_data_rate"
 #define DEF_SMTP_MIN_DATA_RATE 500
-#define VAR_LMTP_MIN_DATA_RATE "smtp_min_data_rate"
+#define VAR_LMTP_MIN_DATA_RATE "lmtp_min_data_rate"
 #define DEF_LMTP_MIN_DATA_RATE 500
 extern int var_smtp_min_data_rate;
 
index d0e749a70f1c390deb334b88f495c7ed23acb719..c85f9e648c98848d222eb3f48ea49c627322f408 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      "20210815"
+#define MAIL_RELEASE_DATE      "20210926"
 #define MAIL_VERSION_NUMBER    "3.7"
 
 #ifdef SNAPSHOT
index 8def3911c88bbb2303dae2895131306675f06c37..f430568bb32804ab9bbe2db9276f1cf24d712fe7 100644 (file)
@@ -250,6 +250,7 @@ static const char *pcf_check_mydomainname(void)
 static const char *pcf_mynetworks(void)
 {
     static const char *networks;
+    VSTRING *exp_buf;
     const char *junk;
 
     /*
@@ -258,10 +259,12 @@ static const char *pcf_mynetworks(void)
     if (networks)
        return (networks);
 
+    exp_buf = vstring_alloc(100);
+
     if (var_inet_interfaces == 0) {
        if ((pcf_cmd_mode & PCF_SHOW_DEFS)
            || (junk = mail_conf_lookup_eval(VAR_INET_INTERFACES)) == 0)
-           junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
+           junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode,
                                              DEF_INET_INTERFACES,
                                              (PCF_MASTER_ENT *) 0);
        var_inet_interfaces = mystrdup(junk);
@@ -269,7 +272,7 @@ static const char *pcf_mynetworks(void)
     if (var_mynetworks_style == 0) {
        if ((pcf_cmd_mode & PCF_SHOW_DEFS)
            || (junk = mail_conf_lookup_eval(VAR_MYNETWORKS_STYLE)) == 0)
-           junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
+           junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode,
                                              DEF_MYNETWORKS_STYLE,
                                              (PCF_MASTER_ENT *) 0);
        var_mynetworks_style = mystrdup(junk);
@@ -277,12 +280,13 @@ static const char *pcf_mynetworks(void)
     if (var_inet_protocols == 0) {
        if ((pcf_cmd_mode & PCF_SHOW_DEFS)
            || (junk = mail_conf_lookup_eval(VAR_INET_PROTOCOLS)) == 0)
-           junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
+           junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode,
                                              DEF_INET_PROTOCOLS,
                                              (PCF_MASTER_ENT *) 0);
        var_inet_protocols = mystrdup(junk);
        (void) inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);
     }
+    vstring_free(exp_buf);
     return (networks = mystrdup(mynetworks()));
 }
 
index 3cfa9f3b0473ec9aeba7c92b9ad9d117590a43c1..2237d9d89584fd6ee5e300ea11886d3b663bd9d9 100644 (file)
@@ -41,7 +41,7 @@
 /*
 /*     Arguments:
 /* .IP buf
-/*     Null buffer pointer, or pointer to user-supplied buffer.
+/*     Pointer to user-supplied buffer; must not be null.
 /* .IP mode
 /*     Bit-wise OR of zero or one of the following (other flags
 /*     are ignored):
@@ -163,13 +163,10 @@ char   *pcf_expand_parameter_value(VSTRING *buf, int mode, const char *value,
     PCF_EVAL_CTX eval_ctx;
 
     /*
-     * Initialize.
+     * Sanity check.
      */
-    if (buf == 0) {
-       if (local_buf == 0)
-           local_buf = vstring_alloc(10);
-       buf = local_buf;
-    }
+    if (buf == 0)
+       msg_panic("%s: null buffer pointer", myname);
 
     /*
      * Expand macros recursively.
index 07485f18873e19a4f8964265a4daa48a4656fa04..8e6e226f3cdc3eaa084a1bc6a3ff639243c4f787 100644 (file)
@@ -139,8 +139,12 @@ void    pcf_set_parameters(char **name_val_array)
 static void pcf_print_parameter(VSTREAM *fp, int mode, const char *name,
                                        PCF_PARAM_NODE *node)
 {
+    static VSTRING *exp_buf = 0;
     const char *value;
 
+    if (exp_buf == 0)
+       exp_buf = vstring_alloc(100);
+
     /*
      * Use the default or actual value.
      */
@@ -155,7 +159,7 @@ static void pcf_print_parameter(VSTREAM *fp, int mode, const char *name,
            pcf_print_line(fp, mode, "%s\n", name);
        } else {
            if ((mode & PCF_SHOW_EVAL) != 0 && PCF_RAW_PARAMETER(node) == 0)
-               value = pcf_expand_parameter_value((VSTRING *) 0, mode, value,
+               value = pcf_expand_parameter_value(exp_buf, mode, value,
                                                   (PCF_MASTER_ENT *) 0);
            if ((mode & PCF_HIDE_NAME) == 0) {
                pcf_print_line(fp, mode, "%s = %s\n", name, value);
index 1a70b5dcfc4acfd0ed4a312c95635f46c9974ba0..f4cb854da440f24a5dd582033fbae42aab54932a 100644 (file)
@@ -196,6 +196,8 @@ static const char *pcf_valid_master_types[] = {
 
 static const char pcf_valid_bool_types[] = "yn-";
 
+static VSTRING *pcf_exp_buf;
+
 #define STR(x) vstring_str(x)
 
 /* pcf_extract_field - extract text from {}, trim leading/trailing blanks */
@@ -492,6 +494,9 @@ void    pcf_print_master_entry(VSTREAM *fp, int mode, PCF_MASTER_ENT *masterp)
     while (0)
 #define ADD_SPACE ADD_TEXT(" ", 1)
 
+    if (pcf_exp_buf == 0)
+       pcf_exp_buf = vstring_alloc(100);
+
     /*
      * Show the standard fields at their preferred column position. Use at
      * least one-space column separation.
@@ -545,7 +550,7 @@ void    pcf_print_master_entry(VSTREAM *fp, int mode, PCF_MASTER_ENT *masterp)
                 */
                if (strcmp(arg, "-o") == 0
                    && (mode & PCF_SHOW_EVAL) != 0)
-                   aval = pcf_expand_parameter_value((VSTRING *) 0, mode,
+                   aval = pcf_expand_parameter_value(pcf_exp_buf, mode,
                                                      aval, masterp);
 
                /*
@@ -665,6 +670,9 @@ static void pcf_print_master_field(VSTREAM *fp, int mode,
     int     in_daemon_options;
     int     need_parens;
 
+    if (pcf_exp_buf == 0)
+       pcf_exp_buf = vstring_alloc(100);
+
     /*
      * Show the field value, or the first value in the case of a multi-column
      * field.
@@ -720,7 +728,7 @@ static void pcf_print_master_field(VSTREAM *fp, int mode,
                     */
                    if (strcmp(arg, "-o") == 0
                        && (mode & PCF_SHOW_EVAL) != 0)
-                       aval = pcf_expand_parameter_value((VSTRING *) 0, mode,
+                       aval = pcf_expand_parameter_value(pcf_exp_buf, mode,
                                                          aval, masterp);
 
                    /*
@@ -876,13 +884,16 @@ static void pcf_print_master_param(VSTREAM *fp, int mode,
                                           const char *param_name,
                                           const char *param_value)
 {
+    if (pcf_exp_buf == 0)
+       pcf_exp_buf = vstring_alloc(100);
+
     if (mode & PCF_HIDE_VALUE) {
        pcf_print_line(fp, mode, "%s%c%s\n",
                       masterp->name_space, PCF_NAMESP_SEP_CH,
                       param_name);
     } else {
        if ((mode & PCF_SHOW_EVAL) != 0)
-           param_value = pcf_expand_parameter_value((VSTRING *) 0, mode,
+           param_value = pcf_expand_parameter_value(pcf_exp_buf, mode,
                                                     param_value, masterp);
        if ((mode & PCF_HIDE_NAME) == 0) {
            pcf_print_line(fp, mode, "%s%c%s = %s\n",
index 2fdc90ae94f1da08bf3c0f9278a25387b47e85da..1e8d8f306324708c94d377a6c9ceb904c5d6f8fb 100644 (file)
@@ -74,6 +74,7 @@ extern const char *str_tls_level(int);
 #include <openssl/x509v3.h>
 #include <openssl/rand.h>
 #include <openssl/crypto.h>            /* Legacy SSLEAY_VERSION_NUMBER */
+#include <openssl/evp.h>               /* New OpenSSL 3.0 EVP_PKEY APIs */
 #include <openssl/opensslv.h>          /* OPENSSL_VERSION_NUMBER */
 #include <openssl/ssl.h>
 
@@ -83,6 +84,15 @@ extern const char *str_tls_level(int);
 #define ssl_cipher_stack_t STACK_OF(SSL_CIPHER)
 #define ssl_comp_stack_t STACK_OF(SSL_COMP)
 
+/*-
+ * Official way to check minimum OpenSSL API version from 3.0 onward.
+ * We simply define it false for all prior versions, where we typically also
+ * need the patch level to determine API compatibility.
+ */
+#ifndef OPENSSL_VERSION_PREREQ
+#define OPENSSL_VERSION_PREREQ(m,n) 0
+#endif
+
 #if (OPENSSL_VERSION_NUMBER < 0x1010100fUL)
 #error "OpenSSL releases prior to 1.1.1 are no longer supported"
 #endif
@@ -101,6 +111,16 @@ extern const char *str_tls_level(int);
 #define tls_get_peer_dh_pubkey SSL_get_server_tmp_key
 #else
 #define tls_get_peer_dh_pubkey SSL_get_peer_tmp_key
+#endif
+
+#if OPENSSL_VERSION_PREREQ(3,0)
+#define TLS_PEEK_PEER_CERT(ssl) SSL_get0_peer_certificate(ssl)
+#define TLS_FREE_PEER_CERT(x)   ((void) 0)
+#define tls_set_bio_callback    BIO_set_callback_ex
+#else
+#define TLS_PEEK_PEER_CERT(ssl) SSL_get_peer_certificate(ssl)
+#define TLS_FREE_PEER_CERT(x)   X509_free(x)
+#define tls_set_bio_callback    BIO_set_callback
 #endif
 
  /*
@@ -604,7 +624,7 @@ extern int tls_bio(int, int, TLS_SESS_STATE *,
   * tls_dh.c
   */
 extern void tls_set_dh_from_file(const char *);
-extern void tls_tmp_dh(SSL_CTX *);
+extern void tls_tmp_dh(SSL_CTX *, int);
 extern void tls_auto_eecdh_curves(SSL_CTX *, const char *);
 
  /*
@@ -655,7 +675,15 @@ extern void tls_check_version(void);
 extern long tls_bug_bits(void);
 extern void tls_print_errors(void);
 extern void tls_info_callback(const SSL *, int, int);
+
+#if OPENSSL_VERSION_PREREQ(3,0)
+extern long tls_bio_dump_cb(BIO *, int, const char *, size_t, int, long,
+                                   int, size_t *);
+
+#else
 extern long tls_bio_dump_cb(BIO *, int, const char *, int, long, long);
+
+#endif
 extern const EVP_MD *tls_validate_digest(const char *);
 
  /*
index 2c4a0e4cd723e66eb0cad3f58c66cb851bbdb60a..c9f259916b368099e3e2e1605c5f61db3bbef391 100644 (file)
@@ -1110,7 +1110,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
      * created for us, so we can use it for debugging purposes.
      */
     if (log_mask & TLS_LOG_TLSPKTS)
-       BIO_set_callback(SSL_get_rbio(TLScontext->con), tls_bio_dump_cb);
+       tls_set_bio_callback(SSL_get_rbio(TLScontext->con), tls_bio_dump_cb);
 
     /*
      * If we don't trigger the handshake in the library, leave control over
@@ -1161,7 +1161,7 @@ TLS_SESS_STATE *tls_client_post_connect(TLS_SESS_STATE *TLScontext,
 
     /* Turn off packet dump if only dumping the handshake */
     if ((TLScontext->log_mask & TLS_LOG_ALLPKTS) == 0)
-       BIO_set_callback(SSL_get_rbio(TLScontext->con), 0);
+       tls_set_bio_callback(SSL_get_rbio(TLScontext->con), 0);
 
     /*
      * The caller may want to know if this session was reused or if a new
@@ -1175,7 +1175,7 @@ TLS_SESS_STATE *tls_client_post_connect(TLS_SESS_STATE *TLScontext,
      * Do peername verification if requested and extract useful information
      * from the certificate for later use.
      */
-    if ((peercert = SSL_get_peer_certificate(TLScontext->con)) != 0) {
+    if ((peercert = TLS_PEEK_PEER_CERT(TLScontext->con)) != 0) {
        TLScontext->peer_status |= TLS_CERT_FLAG_PRESENT;
 
        /*
@@ -1195,7 +1195,6 @@ TLS_SESS_STATE *tls_client_post_connect(TLS_SESS_STATE *TLScontext,
                     TLScontext->peer_CN, TLScontext->issuer_CN,
                     TLScontext->peer_cert_fprint,
                     TLScontext->peer_pkey_fprint);
-       X509_free(peercert);
     } else {
        TLScontext->issuer_CN = mystrdup("");
        TLScontext->peer_CN = mystrdup("");
index a39a6390877b8044a047f517e1e00ca9b0df1d31..2992a591a916c431770a48c2e5d2b94cba1b6454 100644 (file)
@@ -14,8 +14,9 @@
 /*     SSL_CTX *ctx;
 /*     char    *configured;
 /*
-/*     void    tls_tmp_dh(ctx)
+/*     void    tls_tmp_dh(ctx, useauto)
 /*     SSL_CTX *ctx;
+/*     int     useauto;
 /* DESCRIPTION
 /*     This module maintains parameters for Diffie-Hellman key generation.
 /*
 /*     is as expected by the PEM_read_DHparams() routine.
 /*
 /*     tls_auto_eecdh_curves() enables negotiation of the most preferred curve
-/*     among the curves specified by the "configured" argument.
+/*     among the curves specified by the "configured" argument.  The useauto
+/*     argument enables OpenSSL-builtin group selection in preference to our
+/*     own compiled-in group.  This may interoperate better with overly strict
+/*     peers that accept only "standard" groups (bogus threat model).
 /* DIAGNOSTICS
 /*     In case of error, tls_set_dh_from_file() logs a warning and
 /*     ignores the request.
 #ifndef OPENSSL_NO_ECDH
 #include <openssl/ec.h>
 #endif
+#if OPENSSL_VERSION_PREREQ(3,0)
+#include <openssl/decoder.h>
+#endif
 
 /* Application-specific. */
 
  /*
   * Compiled-in FFDHE (finite-field ephemeral Diffie-Hellman) parameters.
   * Used when no parameters are explicitly loaded from a site-specific file.
+  * 
+  * With OpenSSL 3.0 and later when no explicit parameter file is specified by
+  * the administrator (or the setting is "auto"), we delegate group selection
+  * to OpenSSL via SSL_CTX_set_dh_auto(3).
+  * 
   * Using an ASN.1 DER encoding avoids the need to explicitly manipulate the
   * internal representation of DH parameter objects.
   * 
  /*-
   * Generated via:
   *   $ openssl dhparam -2 -outform DER 2048 2>/dev/null |
-  *     hexdump -ve '/1 "0x%02x, "' | fmt
+  *     hexdump -ve '/1 "0x%02x, "' | fmt -73
   * TODO: generate at compile-time. But that is no good for the majority of
   * sites that install pre-compiled binaries, and breaks reproducible builds.
   * Instead, generate at installation time and use main.cf configuration.
   */
-static unsigned char dh2048_der[] = {
-    0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0x9e, 0x28, 0x15,
-    0xc5, 0xcc, 0x9b, 0x5a, 0xb0, 0xe9, 0xab, 0x74, 0x8b, 0x2a, 0x23, 0xce,
-    0xea, 0x87, 0xa0, 0x18, 0x09, 0xd0, 0x40, 0x2c, 0x93, 0x23, 0x5d, 0xc0,
-    0xe9, 0x78, 0x2c, 0x53, 0xd9, 0x3e, 0x21, 0x14, 0x89, 0x5c, 0x79, 0x73,
-    0x1e, 0xbd, 0x23, 0x1e, 0x18, 0x65, 0x6d, 0xd2, 0x3c, 0xeb, 0x41, 0xca,
-    0xbb, 0xa9, 0x99, 0x55, 0x84, 0xae, 0x9e, 0x70, 0x57, 0x25, 0x21, 0x42,
-    0xaa, 0xdb, 0x82, 0xc6, 0xe6, 0xf1, 0xcf, 0xb7, 0xbc, 0x2a, 0x56, 0xcc,
-    0x55, 0x1f, 0xad, 0xe9, 0x68, 0x18, 0x22, 0xfc, 0x09, 0x62, 0xc3, 0x32,
-    0x1b, 0x05, 0x1f, 0xce, 0xec, 0xe3, 0x6d, 0xb5, 0x79, 0xe0, 0x89, 0x45,
-    0xf3, 0xf3, 0x26, 0xa3, 0x81, 0xd9, 0x59, 0xee, 0xed, 0x78, 0xbe, 0x0e,
-    0xdd, 0xf7, 0xef, 0xcb, 0x81, 0x3f, 0x01, 0xb7, 0x10, 0x8f, 0x0d, 0xbe,
-    0x29, 0x21, 0x13, 0xff, 0x2a, 0x13, 0x25, 0x75, 0x99, 0xec, 0xf5, 0x2d,
-    0x49, 0x01, 0x1d, 0xa4, 0x13, 0xe8, 0x2c, 0xc8, 0x13, 0x60, 0x57, 0x98,
-    0xb1, 0x06, 0x45, 0x77, 0xa4, 0x24, 0xf9, 0x27, 0x3f, 0x08, 0xe6, 0x9b,
-    0x4b, 0x20, 0x3b, 0x43, 0x69, 0xa3, 0xcc, 0x9a, 0xc4, 0x3c, 0x1e, 0xec,
-    0xb7, 0x35, 0xe4, 0x59, 0x6b, 0x6d, 0x2a, 0xdf, 0xf7, 0x0b, 0xd4, 0x5a,
-    0x0f, 0x79, 0x80, 0xe1, 0x75, 0x4c, 0x10, 0xea, 0x26, 0xf0, 0xd5, 0xf3,
-    0xa6, 0x15, 0xa9, 0x3e, 0x3d, 0x0d, 0xb8, 0x53, 0x50, 0x49, 0x77, 0x49,
-    0x47, 0x43, 0x39, 0xee, 0xb8, 0x8a, 0xe5, 0x14, 0xc4, 0xe3, 0x10, 0xfb,
-    0xf5, 0x52, 0xef, 0xa5, 0x8f, 0xa4, 0x7e, 0x57, 0xb9, 0x5f, 0xda, 0x00,
-    0x18, 0xf0, 0x72, 0x29, 0xd4, 0xfe, 0x90, 0x5a, 0x1f, 0x1a, 0x40, 0xee,
-    0x4e, 0xfa, 0x3e, 0xf3, 0x72, 0x4b, 0xea, 0x44, 0x53, 0x43, 0x53, 0x57,
-    0x9b, 0x02, 0x01, 0x02,
+static unsigned char builtin_der[] = {
+    0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xec, 0x02, 0x7b,
+    0x74, 0xc6, 0xd4, 0xb4, 0x89, 0x68, 0xfd, 0xbc, 0xe0, 0x82, 0xae, 0xd6,
+    0xf1, 0x4d, 0x93, 0xaa, 0x47, 0x07, 0x84, 0x3d, 0x86, 0xf8, 0x47, 0xf7,
+    0xdf, 0x08, 0x7b, 0xca, 0x04, 0xa4, 0x72, 0xec, 0x11, 0xe2, 0x38, 0x43,
+    0xb7, 0x94, 0xab, 0xaf, 0xe2, 0x85, 0x59, 0x43, 0x4e, 0x71, 0x85, 0xfe,
+    0x52, 0x0c, 0xe0, 0x1c, 0xb6, 0xc7, 0xb0, 0x1b, 0x06, 0xb3, 0x4d, 0x1b,
+    0x4f, 0xf6, 0x4b, 0x45, 0xbd, 0x1d, 0xb8, 0xe4, 0xa4, 0x48, 0x09, 0x28,
+    0x19, 0xd7, 0xce, 0xb1, 0xe5, 0x9a, 0xc4, 0x94, 0x55, 0xde, 0x4d, 0x86,
+    0x0f, 0x4c, 0x5e, 0x25, 0x51, 0x6c, 0x96, 0xca, 0xfa, 0xe3, 0x01, 0x69,
+    0x82, 0x6c, 0x8f, 0xf5, 0xe7, 0x0e, 0xb7, 0x8e, 0x52, 0xf1, 0xcf, 0x0b,
+    0x67, 0x10, 0xd0, 0xb3, 0x77, 0x79, 0xa4, 0xc1, 0xd0, 0x0f, 0x3f, 0xf5,
+    0x5c, 0x35, 0xf9, 0x46, 0xd2, 0xc7, 0xfb, 0x97, 0x6d, 0xd5, 0xbe, 0xe4,
+    0x8b, 0x5a, 0xf2, 0x88, 0xfa, 0x47, 0xdc, 0xc2, 0x4a, 0x4d, 0x69, 0xd3,
+    0x2a, 0xdf, 0x55, 0x6c, 0x5f, 0x71, 0x11, 0x1e, 0x87, 0x03, 0x68, 0xe1,
+    0xf4, 0x21, 0x06, 0x63, 0xd9, 0x65, 0xd4, 0x0c, 0x4d, 0xa7, 0x1f, 0x15,
+    0x53, 0x3a, 0x50, 0x1a, 0xf5, 0x9b, 0x50, 0x35, 0xe0, 0x16, 0xa1, 0xd7,
+    0xe6, 0xbf, 0xd7, 0xd9, 0xd9, 0x53, 0xe5, 0x8b, 0xf8, 0x7b, 0x45, 0x46,
+    0xb6, 0xac, 0x50, 0x16, 0x46, 0x42, 0xca, 0x76, 0x38, 0x4b, 0x8e, 0x83,
+    0xc6, 0x73, 0x13, 0x9c, 0x03, 0xd1, 0x7a, 0x3d, 0x8d, 0x99, 0x34, 0x10,
+    0x79, 0x67, 0x21, 0x23, 0xf9, 0x6f, 0x48, 0x9a, 0xa6, 0xde, 0xbf, 0x7f,
+    0x9c, 0x16, 0x53, 0xff, 0xf7, 0x20, 0x96, 0xeb, 0x34, 0xcb, 0x5b, 0x85,
+    0x2b, 0x7c, 0x98, 0x00, 0x23, 0x47, 0xce, 0xc2, 0x58, 0x12, 0x86, 0x2c,
+    0x57, 0x02, 0x01, 0x02,
 };
 
- /*
-  * Cached results.
-  */
-static DH *dh_2048 = 0;
+#if OPENSSL_VERSION_PREREQ(3,0)
+
+/* ------------------------------------- 3.0 API */
+
+static EVP_PKEY *dhp = 0;
+
+/* load_builtin - load compile-time FFDHE group */
+
+static void load_builtin(void)
+{
+    EVP_PKEY *tmp = 0;
+    OSSL_DECODER_CTX *d;
+    const unsigned char *endp = builtin_der;
+    size_t  dlen = sizeof(builtin_der);
+
+    d = OSSL_DECODER_CTX_new_for_pkey(&tmp, "DER", NULL, "DH",
+                                     OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                                     NULL, NULL);
+    /* Check decode succeeds and consumes all data (final dlen == 0) */
+    if (d && OSSL_DECODER_from_data(d, &endp, &dlen) && tmp && !dlen) {
+       dhp = tmp;
+    } else {
+       EVP_PKEY_free(tmp);
+       msg_warn("error loading compiled-in DH parameters");
+       tls_print_errors();
+    }
+    OSSL_DECODER_CTX_free(d);
+}
 
 /* tls_set_dh_from_file - set Diffie-Hellman parameters from file */
 
 void    tls_set_dh_from_file(const char *path)
 {
-    FILE   *paramfile;
+    FILE   *fp;
+    EVP_PKEY *tmp = 0;
+    OSSL_DECODER_CTX *d;
 
     /*
      * This function is the first to set the DH parameters, but free any
      * prior value just in case the call sequence changes some day.
      */
-    if (dh_2048) {
-       DH_free(dh_2048);
-       dh_2048 = 0;
+    if (dhp) {
+       EVP_PKEY_free(dhp);
+       dhp = 0;
     }
-    if ((paramfile = fopen(path, "r")) != 0) {
-       if ((dh_2048 = PEM_read_DHparams(paramfile, 0, 0, 0)) == 0) {
-           msg_warn("cannot load DH parameters from file %s"
-                    " -- using compiled-in defaults", path);
-           tls_print_errors();
-       }
-       (void) fclose(paramfile);               /* 200411 */
-    } else {
+    if (strcmp(path, "auto") == 0)
+       return;
+
+    if ((fp = fopen(path, "r")) == 0) {
        msg_warn("cannot load DH parameters from file %s: %m"
                 " -- using compiled-in defaults", path);
+       return;
+    }
+    d = OSSL_DECODER_CTX_new_for_pkey(&tmp, "PEM", NULL, "DH",
+                                     OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                                     NULL, NULL);
+    if (!d || !OSSL_DECODER_from_fp(d, fp) || !tmp) {
+       msg_warn("error loading compiled-in DH parameters");
+       tls_print_errors();
+    } else {
+       dhp = tmp;
     }
+    OSSL_DECODER_CTX_free(d);
+    (void) fclose(fp);
 }
 
 /* tls_tmp_dh - configure FFDHE group */
 
-void    tls_tmp_dh(SSL_CTX *ctx)
+void    tls_tmp_dh(SSL_CTX *ctx, int useauto)
 {
-    if (dh_2048 == 0) {
-       const unsigned char *endp = dh2048_der;
-       DH     *dh = 0;
-
-       if (d2i_DHparams(&dh, &endp, sizeof(dh2048_der))
-           && sizeof(dh2048_der) == endp - dh2048_der) {
-           dh_2048 = dh;
-       } else {
-           DH_free(dh);                        /* Unlikely non-zero, but by
-                                                * the book */
-           msg_warn("error loading compiled-in DH parameters");
-       }
+    if (!dhp && !useauto)
+       load_builtin();
+    if (!ctx)
+       return;
+    if (dhp) {
+       EVP_PKEY *tmp = EVP_PKEY_dup(dhp);
+
+       if (tmp && SSL_CTX_set0_tmp_dh_pkey(ctx, tmp) > 0)
+           return;
+       EVP_PKEY_free(tmp);
+       msg_warn("error configuring explicit DH parameters");
+       tls_print_errors();
+    } else {
+       if (SSL_CTX_set_dh_auto(ctx, 1) > 0)
+           return;
+       msg_warn("error configuring auto DH parameters");
+       tls_print_errors();
     }
-    if (ctx != 0 && dh_2048 != 0)
-       SSL_CTX_set_tmp_dh(ctx, dh_2048);
 }
 
+#else                                  /* OPENSSL_VERSION_PREREQ(3,0) */
+
+/* ------------------------------------- 1.1.1 API */
+
+static DH *dhp = 0;
+
+static void load_builtin(void)
+{
+    DH     *tmp = 0;
+    const unsigned char *endp = builtin_der;
+
+    if (d2i_DHparams(&tmp, &endp, sizeof(builtin_der))
+       && sizeof(builtin_der) == endp - builtin_der) {
+       dhp = tmp;
+    } else {
+       DH_free(tmp);
+       msg_warn("error loading compiled-in DH parameters");
+       tls_print_errors();
+    }
+}
+
+/* tls_set_dh_from_file - set Diffie-Hellman parameters from file */
+
+void    tls_set_dh_from_file(const char *path)
+{
+    FILE   *fp;
+
+    /*
+     * This function is the first to set the DH parameters, but free any
+     * prior value just in case the call sequence changes some day.
+     */
+    if (dhp) {
+       DH_free(dhp);
+       dhp = 0;
+    }
+
+    /*
+     * Forwards compatibility, support "auto" by using the builtin group when
+     * OpenSSL is < 3.0 and does not support automatic FFDHE group selection.
+     */
+    if (strcmp(path, "auto") == 0)
+       return;
+
+    if ((fp = fopen(path, "r")) == 0) {
+       msg_warn("cannot load DH parameters from file %s: %m"
+                " -- using compiled-in defaults", path);
+       return;
+    }
+    if ((dhp = PEM_read_DHparams(fp, 0, 0, 0)) == 0) {
+       msg_warn("cannot load DH parameters from file %s"
+                " -- using compiled-in defaults", path);
+       tls_print_errors();
+    }
+    (void) fclose(fp);
+}
+
+/* tls_tmp_dh - configure FFDHE group */
+
+void    tls_tmp_dh(SSL_CTX *ctx, int useauto)
+{
+    if (!dhp)
+       load_builtin();
+    if (!ctx || !dhp || SSL_CTX_set_tmp_dh(ctx, dhp) > 0)
+       return;
+    msg_warn("error configuring explicit DH parameters");
+    tls_print_errors();
+}
+
+#endif                                 /* OPENSSL_VERSION_PREREQ(3,0) */
+
+/* ------------------------------------- Common API */
+
 void    tls_auto_eecdh_curves(SSL_CTX *ctx, const char *configured)
 {
 #ifndef OPENSSL_NO_ECDH
@@ -253,8 +374,8 @@ void    tls_auto_eecdh_curves(SSL_CTX *ctx, const char *configured)
 
 int     main(int unused_argc, char **unused_argv)
 {
-    tls_tmp_dh(0);
-    return (dh_2048 == 0);
+    tls_tmp_dh(0, 0);
+    return (dhp == 0);
 }
 
 #endif
index 55af34d3cb3d834080652fab2f4feb45f3219cc3..338a63be4fe9eb576e6153588b677448972e1d1d 100644 (file)
 /*     int     where;
 /*     int     ret;
 /*
-/*     long    tls_bio_dump_cb(bio, cmd, argp, argi, argl, ret)
+/*     long    tls_bio_dump_cb(bio, cmd, argp, len, argi, argl, ret, processed)
 /*     BIO     *bio;
 /*     int     cmd;
 /*     const char *argp;
+/*     size_t  len;
 /*     int     argi;
 /*     long    argl; /* unused */
-/*     long    ret;
+/*     int     ret;
+/*     size_t  *processed;
 /*
 /*     int     tls_log_mask(log_param, log_level)
 /*     const char *log_param;
@@ -861,18 +863,50 @@ const char *tls_set_ciphers(TLS_SESS_STATE *TLScontext, const char *grade,
     return (vstring_str(buf));
 }
 
+/* ec_curve_name - copy EC key curve group name */
+
+#ifndef OPENSSL_NO_EC
+static char *ec_curve_name(EVP_PKEY *pkey)
+{
+    char   *curve = 0;
+
+#if OPENSSL_VERSION_PREREQ(3,0)
+    size_t  namelen;
+
+    if (EVP_PKEY_get_group_name(pkey, 0, 0, &namelen)) {
+       curve = mymalloc(++namelen);
+       if (!EVP_PKEY_get_group_name(pkey, curve, namelen, 0)) {
+           myfree(curve);
+           curve = 0;
+       }
+    }
+#else
+    EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey);
+    int     nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
+    const char *tmp = EC_curve_nid2nist(nid);
+
+    if (!tmp)
+       tmp = OBJ_nid2sn(nid);
+    if (tmp)
+       curve = mystrdup(tmp);
+#endif
+    return (curve);
+}
+
+#endif
+
 /* tls_get_signature_params - TLS 1.3 signature details */
 
 void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
 {
     const char *kex_name = 0;
-    const char *kex_curve = 0;
     const char *locl_sig_name = 0;
-    const char *locl_sig_curve = 0;
     const char *locl_sig_dgst = 0;
     const char *peer_sig_name = 0;
-    const char *peer_sig_curve = 0;
     const char *peer_sig_dgst = 0;
+    char   *kex_curve = 0;
+    char   *locl_sig_curve = 0;
+    char   *peer_sig_curve = 0;
     int     nid;
     SSL    *ssl = TLScontext->con;
     int     srvr = SSL_is_server(ssl);
@@ -882,11 +916,6 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
     X509   *peer_cert;
     EVP_PKEY *peer_pkey = 0;
 
-#ifndef OPENSSL_NO_EC
-    EC_KEY *eckey;
-
-#endif
-
 #define SIG_PROP(c, s, p) (*((s) ? &c->srvr_sig_##p : &c->clnt_sig_##p))
 
     if (SSL_version(ssl) < TLS1_3_VERSION)
@@ -906,11 +935,7 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
 #ifndef OPENSSL_NO_EC
        case EVP_PKEY_EC:
            kex_name = "ECDHE";
-           eckey = EVP_PKEY_get0_EC_KEY(dh_pkey);
-           nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
-           kex_curve = EC_curve_nid2nist(nid);
-           if (!kex_curve)
-               kex_curve = OBJ_nid2sn(nid);
+           kex_curve = ec_curve_name(dh_pkey);
            break;
 #endif
        }
@@ -951,11 +976,7 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
 #ifndef OPENSSL_NO_EC
            case EVP_PKEY_EC:
                locl_sig_name = "ECDSA";
-               eckey = EVP_PKEY_get0_EC_KEY(local_pkey);
-               nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
-               locl_sig_curve = EC_curve_nid2nist(nid);
-               if (!locl_sig_curve)
-                   locl_sig_curve = OBJ_nid2sn(nid);
+               locl_sig_curve = ec_curve_name(local_pkey);
                break;
 #endif
            }
@@ -970,7 +991,7 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
            locl_sig_dgst = OBJ_nid2sn(nid);
     }
     /* Signature algorithms for the peer end of the connection */
-    if ((peer_cert = SSL_get_peer_certificate(ssl)) != 0) {
+    if ((peer_cert = TLS_PEEK_PEER_CERT(ssl)) != 0) {
        peer_pkey = X509_get0_pubkey(peer_cert);
 
        /*
@@ -993,11 +1014,7 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
 #ifndef OPENSSL_NO_EC
            case EVP_PKEY_EC:
                peer_sig_name = "ECDSA";
-               eckey = EVP_PKEY_get0_EC_KEY(peer_pkey);
-               nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
-               peer_sig_curve = EC_curve_nid2nist(nid);
-               if (!peer_sig_curve)
-                   peer_sig_curve = OBJ_nid2sn(nid);
+               peer_sig_curve = ec_curve_name(peer_pkey);
                break;
 #endif
            }
@@ -1010,24 +1027,21 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
        if (SSL_get_peer_signature_nid(ssl, &nid) && nid != NID_undef)
            peer_sig_dgst = OBJ_nid2sn(nid);
 
-       X509_free(peer_cert);
+       TLS_FREE_PEER_CERT(peer_cert);
     }
     if (kex_name) {
        TLScontext->kex_name = mystrdup(kex_name);
-       if (kex_curve)
-           TLScontext->kex_curve = mystrdup(kex_curve);
+       TLScontext->kex_curve = kex_curve;
     }
     if (locl_sig_name) {
        SIG_PROP(TLScontext, srvr, name) = mystrdup(locl_sig_name);
-       if (locl_sig_curve)
-           SIG_PROP(TLScontext, srvr, curve) = mystrdup(locl_sig_curve);
+       SIG_PROP(TLScontext, srvr, curve) = locl_sig_curve;
        if (locl_sig_dgst)
            SIG_PROP(TLScontext, srvr, dgst) = mystrdup(locl_sig_dgst);
     }
     if (peer_sig_name) {
        SIG_PROP(TLScontext, !srvr, name) = mystrdup(peer_sig_name);
-       if (peer_sig_curve)
-           SIG_PROP(TLScontext, !srvr, curve) = mystrdup(peer_sig_curve);
+       SIG_PROP(TLScontext, !srvr, curve) = peer_sig_curve;
        if (peer_sig_dgst)
            SIG_PROP(TLScontext, !srvr, dgst) = mystrdup(peer_sig_dgst);
     }
@@ -1369,7 +1383,14 @@ void    tls_print_errors(void)
     int     line;
     int     flags;
 
-    while ((err = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
+#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)
            msg_warn("TLS library problem: %s:%s:%d:%s:",
@@ -1493,6 +1514,7 @@ static void tls_dump_buffer(const unsigned char *start, int len)
 
 /* taken from OpenSSL apps/s_cb.c */
 
+#if !OPENSSL_VERSION_PREREQ(3,0)
 long    tls_bio_dump_cb(BIO *bio, int cmd, const char *argp, int argi,
                                long unused_argl, long ret)
 {
@@ -1510,6 +1532,40 @@ long    tls_bio_dump_cb(BIO *bio, int cmd, const char *argp, int argi,
     return (ret);
 }
 
+#else
+long    tls_bio_dump_cb(BIO *bio, int cmd, const char *argp, size_t len,
+                    int argi, long unused_argl, int ret, size_t *processed)
+{
+    size_t  bytes = (ret > 0 && processed != NULL) ? *processed : len;
+
+    if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
+       if (ret > 0) {
+           msg_info("read from %08lX [%08lX] (%ld bytes => %ld (0x%lX))",
+                    (unsigned long) bio, (unsigned long) argp, (long) len,
+                    (long) bytes, (long) bytes);
+           tls_dump_buffer((unsigned char *) argp, (int) bytes);
+       } else {
+           msg_info("read from %08lX [%08lX] (%ld bytes => %d)",
+                    (unsigned long) bio, (unsigned long) argp,
+                    (long) len, ret);
+       }
+    } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
+       if (ret > 0) {
+           msg_info("write to %08lX [%08lX] (%ld bytes => %ld (0x%lX))",
+                    (unsigned long) bio, (unsigned long) argp, (long) len,
+                    (long) bytes, (long) bytes);
+           tls_dump_buffer((unsigned char *) argp, (int) bytes);
+       } else {
+           msg_info("write to %08lX [%08lX] (%ld bytes => %d)",
+                    (unsigned long) bio, (unsigned long) argp,
+                    (long) len, ret);
+       }
+    }
+    return ret;
+}
+
+#endif
+
 const EVP_MD *tls_validate_digest(const char *dgst)
 {
     const EVP_MD *md_alg;
index 408d2868183f30ee46779bf3619fe7db4ea2abcc..cf722ee7e56188cfc90b0d41aba245ef68680573 100644 (file)
@@ -481,14 +481,9 @@ TLS_SCACHE *tls_scache_open(const char *dbname, const char *cache_label,
      * Open the dictionary with O_TRUNC, so that we never have to worry about
      * opening a damaged file after some process terminated abnormally.
      */
-#ifdef SINGLE_UPDATER
-#define DICT_FLAGS (DICT_FLAG_DUP_REPLACE | DICT_FLAG_OPEN_LOCK \
-                   | DICT_FLAG_UTF8_REQUEST)
-#else
 #define DICT_FLAGS \
-       (DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE \
+       (DICT_FLAG_DUP_REPLACE | DICT_FLAG_OPEN_LOCK | DICT_FLAG_SYNC_UPDATE \
         | DICT_FLAG_UTF8_REQUEST)
-#endif
 
     dict = dict_open(dbname, O_RDWR | O_CREAT | O_TRUNC, DICT_FLAGS);
 
index 6162191d6d34e9690514d225e2ecb759e8dd0aa6..5b549f34edf047013239d41a3f0487ce749322ce 100644 (file)
 #include <tls_mgr.h>
 #define TLS_INTERNAL
 #include <tls.h>
+#if OPENSSL_VERSION_PREREQ(3,0)
+#include <openssl/core_names.h>                /* EVP_MAC parameters */
+#endif
 
 #define STR(x) vstring_str(x)
 #define LEN(x) VSTRING_LEN(x)
@@ -290,12 +293,57 @@ static int new_server_session_cb(SSL *ssl, SSL_SESSION *session)
 #define TLS_TKT_ACCEPT 1               /* Ticket decryptable and re-usable */
 #define TLS_TKT_REISSUE        2               /* Ticket decryptable, not re-usable */
 
+#if defined(SSL_OP_NO_TICKET) && !defined(OPENSSL_NO_TLSEXT)
+
+#if OPENSSL_VERSION_PREREQ(3,0)
+
 /* ticket_cb - configure tls session ticket encrypt/decrypt context */
 
-#if defined(SSL_OP_NO_TICKET) && !defined(OPENSSL_NO_TLSEXT)
+static int ticket_cb(SSL *con, unsigned char name[], unsigned char iv[],
+                        EVP_CIPHER_CTX *ctx, EVP_MAC_CTX *hctx, int create)
+{
+    OSSL_PARAM params[3];
+    static const EVP_CIPHER *ciph;
+    TLS_TICKET_KEY *key;
+    TLS_SESS_STATE *TLScontext = SSL_get_ex_data(con, TLScontext_index);
+    int     timeout = ((int) SSL_CTX_get_timeout(SSL_get_SSL_CTX(con))) / 2;
+
+    if ((!ciph && (ciph = EVP_get_cipherbyname(var_tls_tkt_cipher)) == 0)
+       || (key = tls_mgr_key(create ? 0 : name, timeout)) == 0
+       || (create && RAND_bytes(iv, TLS_TICKET_IVLEN) <= 0))
+       return (create ? TLS_TKT_NOKEYS : TLS_TKT_STALE);
+
+    params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+                                                LN_sha256, 0);
+    params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                 (char *) key->hmac,
+                                                 TLS_TICKET_MACLEN);
+    params[2] = OSSL_PARAM_construct_end();
+    if (!EVP_MAC_CTX_set_params(hctx, params))
+       return (create ? TLS_TKT_NOKEYS : TLS_TKT_STALE);
+
+    if (create) {
+       EVP_EncryptInit_ex(ctx, ciph, NOENGINE, key->bits, iv);
+       memcpy((void *) name, (void *) key->name, TLS_TICKET_NAMELEN);
+       if (TLScontext->log_mask & TLS_LOG_CACHE)
+           msg_info("%s: Issuing session ticket, key expiration: %ld",
+                    TLScontext->namaddr, (long) key->tout);
+    } else {
+       EVP_DecryptInit_ex(ctx, ciph, NOENGINE, key->bits, iv);
+       if (TLScontext->log_mask & TLS_LOG_CACHE)
+           msg_info("%s: Decrypting session ticket, key expiration: %ld",
+                    TLScontext->namaddr, (long) key->tout);
+    }
+    TLScontext->ticketed = 1;
+    return (TLS_TKT_ACCEPT);
+}
+
+#else                                  /* OPENSSL_VERSION_PREREQ(3,0) */
+
+/* ticket_cb - configure tls session ticket encrypt/decrypt context */
 
 static int ticket_cb(SSL *con, unsigned char name[], unsigned char iv[],
-                         EVP_CIPHER_CTX * ctx, HMAC_CTX * hctx, int create)
+                            EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int create)
 {
     static const EVP_MD *sha256;
     static const EVP_CIPHER *ciph;
@@ -327,7 +375,10 @@ static int ticket_cb(SSL *con, unsigned char name[], unsigned char iv[],
     return (TLS_TKT_ACCEPT);
 }
 
-#endif
+#endif                                 /* OPENSSL_VERSION_PREREQ(3,0) */
+
+#endif                                 /* defined(SSL_OP_NO_TICKET) &&
+                                        * !defined(OPENSSL_NO_TLSEXT) */
 
 /* tls_server_init - initialize the server-side TLS engine */
 
@@ -488,7 +539,11 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
        }
     }
     if (ticketable) {
+#if OPENSSL_VERSION_PREREQ(3,0)
+       SSL_CTX_set_tlsext_ticket_key_evp_cb(server_ctx, ticket_cb);
+#else
        SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, ticket_cb);
+#endif
 
        /*
         * OpenSSL 1.1.1 introduces support for TLS 1.3, which can issue more
@@ -605,8 +660,8 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
      */
     if (*props->dh1024_param_file != 0)
        tls_set_dh_from_file(props->dh1024_param_file);
-    tls_tmp_dh(server_ctx);
-    tls_tmp_dh(sni_ctx);
+    tls_tmp_dh(server_ctx, 1);
+    tls_tmp_dh(sni_ctx, 1);
 
     /*
      * Enable EECDH if available, errors are not fatal, we just keep going
@@ -822,7 +877,7 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props)
      * created for us, so we can use it for debugging purposes.
      */
     if (log_mask & TLS_LOG_TLSPKTS)
-       BIO_set_callback(SSL_get_rbio(TLScontext->con), tls_bio_dump_cb);
+       tls_set_bio_callback(SSL_get_rbio(TLScontext->con), tls_bio_dump_cb);
 
     /*
      * If we don't trigger the handshake in the library, leave control over
@@ -872,7 +927,7 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
 
     /* Turn off packet dump if only dumping the handshake */
     if ((TLScontext->log_mask & TLS_LOG_ALLPKTS) == 0)
-       BIO_set_callback(SSL_get_rbio(TLScontext->con), 0);
+       tls_set_bio_callback(SSL_get_rbio(TLScontext->con), 0);
 
     /*
      * The caller may want to know if this session was reused or if a new
@@ -887,7 +942,7 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
      * Let's see whether a peer certificate is available and what is the
      * actual information. We want to save it for later use.
      */
-    peer = SSL_get_peer_certificate(TLScontext->con);
+    peer = TLS_PEEK_PEER_CERT(TLScontext->con);
     if (peer != NULL) {
        TLScontext->peer_status |= TLS_CERT_FLAG_PRESENT;
        if (SSL_get_verify_result(TLScontext->con) == X509_V_OK)
@@ -914,7 +969,7 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
                     TLScontext->peer_cert_fprint,
                     TLScontext->peer_pkey_fprint);
        }
-       X509_free(peer);
+       TLS_FREE_PEER_CERT(peer);
 
        /*
         * Give them a clue. Problems with trust chain verification are