2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-09-01 14:45:32 +00:00

postfix-3.4-20181113

This commit is contained in:
Wietse Venema
2018-11-13 00:00:00 -05:00
committed by Viktor Dukhovni
parent 17000226f6
commit 93be1eb79b
20 changed files with 933 additions and 166 deletions

View File

@@ -23758,3 +23758,30 @@ Apologies for any names omitted.
util/dict.c, util/dict.h, util/dict_cidr.c, util/dict_file.c,
util/dict_inline.c, util/dict_pcre.c, util/dict_random.c,
util/dict_regexp.c, util/dict_static.c.
20181106
Bugfix (introduced: 3.0): smtpd_discard_ehlo_keywords could
not disable "SMTPUTF8". because the lookup table was using
"EHLO_MASK_SMTPUTF8" instead. File: global/ehlo_mask.c.
Documentation: the postmap(1) manpage no longer refers to
compatibility with Sendmail's makemap command. File:
postmap/postmap.c.
Cleanup: don't use ssize_t for boolean result. File:
global/smtp_stream.c. Memory leak: the Berkeley DB client
leaked a small amount of memory asfter failing to open a
table. File: util/dict_db.c.
Cleanup: memory leak caused by missing dbenv->close() call
after failing to open a Berkeley DB table. File: util/dict_db.c.
20181112
Improved logging of TLS 1.3 summary information, and improved
reporting of the same info in Received: message headers.
Viktor Dukhovni. Files: proto/FORWARD_SECRECY_README.html,
smtpd/smtpd.c, tls/tls.h, tls/tls_client.c, tls/tls_misc.c,
tls/tls_proxy.h, tls/tls_proxy_context_print.c,
tls/tls_proxy_context_scan.c, tls/tls_server.c.

View File

@@ -294,7 +294,8 @@ verification status.
* With "smtp_tls_loglevel = 1" and "smtpd_tls_loglevel = 1", the Postfix SMTP
client and server will log TLS connection information to the maillog file.
The general logfile format is:
The general logfile format is shown below. With TLS 1.3 there may be
additional properties logged after the cipher name and bits.
postfix/smtp[process-id]: Untrusted TLS connection established
to host.example.com[192.168.0.2]:25: TLSv1 with cipher cipher-name
@@ -307,7 +308,8 @@ verification status.
* With "smtpd_tls_received_header = yes", the Postfix SMTP server will record
TLS connection information in the Received: header in the form of comments
(text inside parentheses). The general format depends on the
smtpd_tls_ask_ccert setting:
smtpd_tls_ask_ccert setting. With TLS 1.3 there may be additional
properties logged after the cipher name and bits.
Received: from host.example.com (host.example.com [192.168.0.2])
(using TLSv1 with cipher cipher-name
@@ -320,6 +322,47 @@ verification status.
(actual-key-size/raw-key-size bits))
(No client certificate requested)
TLS 1.3 examples. Some of the new attributes may not appear when not
applicable or not available in an older versions of the OpenSSL library.
Received: from localhost (localhost [127.0.0.1])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256
bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits)
server-digest SHA256)
(No client certificate requested)
Received: from localhost (localhost [127.0.0.1])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256
bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits)
server-digest SHA256
client-signature ECDSA (P-256) client-digest SHA256)
(Client CN "example.org", Issuer "example.org" (not verified))
o The "key-exchange" attribute records the type of "Diffie-Hellman" group
used for key agreement. Possible values include "DHE", "ECDHE",
"X25519" and "X448". With "DHE", the bit size of the prime will be
reported in parentheses after the algorithm name, with "ECDHE", the
curve name.
o The "server-signature" attribute shows the public key signature
algorithm used by the server. With "RSA-PSS", the bit size of the
modulus will be reported in parentheses. With "ECDSA", the curve name.
If, for example, the server has both an RSA and an ECDSA private key
and certificate, it will be possible to track which one was used for a
given connection.
o The new "server-digest" attribute records the digest algorithm used by
the server to prepare handshake messages for signing. The Ed25519 and
Ed448 signature algorithms do not make use of such a digest, so no
"server-digest" will be shown for these signature algorithms.
o When a client certificate is requested with "smtpd_tls_ask_ccert" and
the client uses a TLS client-certificate, the "client-signature" and
"client-digest" attributes will record the corresponding properties of
the client's TLS handshake signature.
The next sections will explain what cipher-name, key-size, and peer
verification status information to expect.
@@ -361,6 +404,51 @@ The actual key length and raw algorithm key length are generally the same with
non-export ciphers, but may they differ for the legacy export ciphers where the
actual key is artificially shortened.
Starting with TLS 1.3 the cipher name no longer contains enough information to
determine which forward-secrecy scheme was employed, but TLS 1.3 aallwwaayyss uses
forward-secrecy. On the client side, up-to-date Postfix releases log additional
information for TLS 1.3 connections, reporting the signature and key exchange
algorithms. Two examples below (the long single line messages are folded across
multiple lines for readability):
postfix/smtp[process-id]:
Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest
SHA256
client-signature ECDSA (P-256) client-digest SHA256
postfix/smtp[process-id]:
Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest
SHA256
In the above connections, the "key-exchange" value records the "Diffie-Hellman"
algorithm used for key agreement. The "server-signature" value records the
public key algoritm used by the server to sign the key exchange. The "server-
digest" value records any hash algorithm used to prepare the data for signing.
With "ED25519" and "ED448", no separate hash algorithm is used.
Examples of Postfix SMTP server logging:
postfix/smtpd[process-id]:
Untrusted TLS connection established from localhost[127.0.0.1]:25:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest
SHA256
client-signature ECDSA (P-256) client-digest SHA256
postfix/smtpd[process-id]:
Anonymous TLS connection established from localhost[127.0.0.1]:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
server-signature RSA-PSS (2048 bits) server-digest SHA256
postfix/smtpd[process-id]:
Anonymous TLS connection established from localhost[127.0.0.1]:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
server-signature ED25519
WWhhaatt ddoo ""AAnnoonnyymmoouuss"",, ""UUnnttrruusstteedd"",, eettcc.. iinn PPoossttffiixx llooggggiinngg mmeeaann??
The verification levels below are subject to man-in-the-middle attacks to

View File

@@ -1,18 +1,15 @@
Wish list:
In dict_db.h, call dbenv->close() before bailing out
with a surrogate map.
With DICT_FLAG_RHS_IS_FILE, should dict_update() open a
file? base64-encode the value?
In smtpd(8) and postscreen(8), set the ehlo_discard_mask
to ~0 so that STARTTLS, BDAT, DSN, etc. won't work.
to ~0 so that STARTTLS, BDAT, DSN, etc. work only for clients
that send EHLO.
In postscreen, don't fork after 'postfix reload' when
psc_check_queue_length (and psc_post_queue_length?) is zero.
In smtp_stream.c, replace `ssize_t err' with `int err'.
In ehlo_mask.c, replace "EHLO_MASK_SMTPUTF8" with "SMTPUTF8".
With smtpd_reject_footer=$foo in master.cf, and foo defined
in main.cf, postconf complains about an unused setting in
main.cf. Note that "postconf -Px" will expand $name in

View File

@@ -397,7 +397,9 @@ peer certificate or public-key verification status. </p>
<li> <p> With "<a href="postconf.5.html#smtp_tls_loglevel">smtp_tls_loglevel</a> = 1" and "<a href="postconf.5.html#smtpd_tls_loglevel">smtpd_tls_loglevel</a> = 1",
the Postfix SMTP client and server will log TLS connection information
to the maillog file. The general logfile format is: </p>
to the maillog file. The general logfile format is shown below.
With TLS 1.3 there may be additional properties logged after the
cipher name and bits. </p>
<blockquote>
<pre>
@@ -414,7 +416,8 @@ from host.example.com[192.168.0.2]: TLSv1 with cipher <i>cipher-name</i>
<li> <p> With "<a href="postconf.5.html#smtpd_tls_received_header">smtpd_tls_received_header</a> = yes", the Postfix SMTP
server will record TLS connection information in the Received:
header in the form of comments (text inside parentheses). The general
format depends on the <a href="postconf.5.html#smtpd_tls_ask_ccert">smtpd_tls_ask_ccert</a> setting:
format depends on the <a href="postconf.5.html#smtpd_tls_ask_ccert">smtpd_tls_ask_ccert</a> setting. With TLS 1.3 there
may be additional properties logged after the cipher name and bits. </p>
<blockquote>
<pre>
@@ -430,6 +433,46 @@ Received: from host.example.com (host.example.com [192.168.0.2])
</pre>
</blockquote>
<p> TLS 1.3 examples. Some of the new attributes may not appear when not
applicable or not available in an older versions of the OpenSSL library. </p>
<blockquote>
<pre>
Received: from localhost (localhost [127.0.0.1])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256)
(No client certificate requested)
Received: from localhost (localhost [127.0.0.1])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature ECDSA (P-256) client-digest SHA256)
(Client CN "example.org", Issuer "example.org" (not verified))
</pre>
</blockquote>
<ul>
<li> <p> The "key-exchange" attribute records the type of "Diffie-Hellman"
group used for key agreement. Possible values include "DHE", "ECDHE", "X25519"
and "X448". With "DHE", the bit size of the prime will be reported in
parentheses after the algorithm name, with "ECDHE", the curve name. </p>
<li> <p> The "server-signature" attribute shows the public key signature
algorithm used by the server. With "RSA-PSS", the bit size of the modulus will
be reported in parentheses. With "ECDSA", the curve name. If, for example,
the server has both an RSA and an ECDSA private key and certificate, it will be
possible to track which one was used for a given connection. </p>
<li> <p> The new "server-digest" attribute records the digest algorithm used by
the server to prepare handshake messages for signing. The Ed25519 and Ed448
signature algorithms do not make use of such a digest, so no "server-digest"
will be shown for these signature algorithms. </p>
<li> <p> When a client certificate is requested with "<a href="postconf.5.html#smtpd_tls_ask_ccert">smtpd_tls_ask_ccert</a>" and
the client uses a TLS client-certificate, the "client-signature" and
"client-digest" attributes will record the corresponding properties of the
client's TLS handshake signature. </p> </ul>
</ul>
<p> The next sections will explain what <i>cipher-name</i>,
@@ -481,6 +524,58 @@ are generally the same with non-export ciphers, but may they
differ for the legacy export ciphers where the actual key
is artificially shortened. </p>
<p> Starting with TLS 1.3 the cipher name no longer contains enough
information to determine which forward-secrecy scheme was employed,
but TLS 1.3 <b>always</b> uses forward-secrecy. On the client side,
up-to-date Postfix releases log additional information for TLS 1.3
connections, reporting the signature and key exchange algorithms.
Two examples below (the long single line messages are folded across
multiple lines for readability): </p>
<blockquote>
<pre>
postfix/smtp[<i>process-id</i>]:
Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature ECDSA (P-256) client-digest SHA256
postfix/smtp[<i>process-id</i>]:
Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest SHA256
</pre>
</blockquote>
<p> In the above connections, the "key-exchange" value records the
"Diffie-Hellman" algorithm used for key agreement. The "server-signature" value
records the public key algoritm used by the server to sign the key exchange.
The "server-digest" value records any hash algorithm used to prepare the data
for signing. With "ED25519" and "ED448", no separate hash algorithm is used.
</p>
<p> Examples of Postfix SMTP server logging: </p>
<blockquote>
<pre>
postfix/smtpd[<i>process-id</i>]:
Untrusted TLS connection established from localhost[127.0.0.1]:25:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature ECDSA (P-256) client-digest SHA256
postfix/smtpd[<i>process-id</i>]:
Anonymous TLS connection established from localhost[127.0.0.1]:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
server-signature RSA-PSS (2048 bits) server-digest SHA256
postfix/smtpd[<i>process-id</i>]:
Anonymous TLS connection established from localhost[127.0.0.1]:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
server-signature ED25519
</pre>
</blockquote>
<h2><a name="status"> What do "Anonymous", "Untrusted", etc. in
Postfix logging mean? </a> </h2>

View File

@@ -15,10 +15,7 @@ POSTMAP(1) POSTMAP(1)
<b>DESCRIPTION</b>
The <a href="postmap.1.html"><b>postmap</b>(1)</a> command creates or queries one or more Postfix lookup
tables, or updates an existing one. The input and output file formats
are expected to be compatible with:
<b>makemap</b> <i>file</i><b>_</b><i>type file</i><b>_</b><i>name</i> &lt; <i>file</i><b>_</b><i>name</i>
tables, or updates an existing one.
If the result files do not exist they will be created with the same
group and other read permissions as their source file.

View File

@@ -16,12 +16,7 @@ Postfix lookup table management
.ad
.fi
The \fBpostmap\fR(1) command creates or queries one or more Postfix
lookup tables, or updates an existing one. The input and output
file formats are expected to be compatible with:
.nf
\fBmakemap \fIfile_type\fR \fIfile_name\fR < \fIfile_name\fR
.fi
lookup tables, or updates an existing one.
If the result files do not exist they will be created with the
same group and other read permissions as their source file.

View File

@@ -397,7 +397,9 @@ peer certificate or public-key verification status. </p>
<li> <p> With "smtp_tls_loglevel = 1" and "smtpd_tls_loglevel = 1",
the Postfix SMTP client and server will log TLS connection information
to the maillog file. The general logfile format is: </p>
to the maillog file. The general logfile format is shown below.
With TLS 1.3 there may be additional properties logged after the
cipher name and bits. </p>
<blockquote>
<pre>
@@ -414,7 +416,8 @@ from host.example.com[192.168.0.2]: TLSv1 with cipher <i>cipher-name</i>
<li> <p> With "smtpd_tls_received_header = yes", the Postfix SMTP
server will record TLS connection information in the Received:
header in the form of comments (text inside parentheses). The general
format depends on the smtpd_tls_ask_ccert setting:
format depends on the smtpd_tls_ask_ccert setting. With TLS 1.3 there
may be additional properties logged after the cipher name and bits. </p>
<blockquote>
<pre>
@@ -430,6 +433,46 @@ Received: from host.example.com (host.example.com [192.168.0.2])
</pre>
</blockquote>
<p> TLS 1.3 examples. Some of the new attributes may not appear when not
applicable or not available in an older versions of the OpenSSL library. </p>
<blockquote>
<pre>
Received: from localhost (localhost [127.0.0.1])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256)
(No client certificate requested)
Received: from localhost (localhost [127.0.0.1])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature ECDSA (P-256) client-digest SHA256)
(Client CN "example.org", Issuer "example.org" (not verified))
</pre>
</blockquote>
<ul>
<li> <p> The "key-exchange" attribute records the type of "Diffie-Hellman"
group used for key agreement. Possible values include "DHE", "ECDHE", "X25519"
and "X448". With "DHE", the bit size of the prime will be reported in
parentheses after the algorithm name, with "ECDHE", the curve name. </p>
<li> <p> The "server-signature" attribute shows the public key signature
algorithm used by the server. With "RSA-PSS", the bit size of the modulus will
be reported in parentheses. With "ECDSA", the curve name. If, for example,
the server has both an RSA and an ECDSA private key and certificate, it will be
possible to track which one was used for a given connection. </p>
<li> <p> The new "server-digest" attribute records the digest algorithm used by
the server to prepare handshake messages for signing. The Ed25519 and Ed448
signature algorithms do not make use of such a digest, so no "server-digest"
will be shown for these signature algorithms. </p>
<li> <p> When a client certificate is requested with "smtpd_tls_ask_ccert" and
the client uses a TLS client-certificate, the "client-signature" and
"client-digest" attributes will record the corresponding properties of the
client's TLS handshake signature. </p> </ul>
</ul>
<p> The next sections will explain what <i>cipher-name</i>,
@@ -481,6 +524,58 @@ are generally the same with non-export ciphers, but may they
differ for the legacy export ciphers where the actual key
is artificially shortened. </p>
<p> Starting with TLS 1.3 the cipher name no longer contains enough
information to determine which forward-secrecy scheme was employed,
but TLS 1.3 <b>always</b> uses forward-secrecy. On the client side,
up-to-date Postfix releases log additional information for TLS 1.3
connections, reporting the signature and key exchange algorithms.
Two examples below (the long single line messages are folded across
multiple lines for readability): </p>
<blockquote>
<pre>
postfix/smtp[<i>process-id</i>]:
Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature ECDSA (P-256) client-digest SHA256
postfix/smtp[<i>process-id</i>]:
Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest SHA256
</pre>
</blockquote>
<p> In the above connections, the "key-exchange" value records the
"Diffie-Hellman" algorithm used for key agreement. The "server-signature" value
records the public key algoritm used by the server to sign the key exchange.
The "server-digest" value records any hash algorithm used to prepare the data
for signing. With "ED25519" and "ED448", no separate hash algorithm is used.
</p>
<p> Examples of Postfix SMTP server logging: </p>
<blockquote>
<pre>
postfix/smtpd[<i>process-id</i>]:
Untrusted TLS connection established from localhost[127.0.0.1]:25:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature ECDSA (P-256) client-digest SHA256
postfix/smtpd[<i>process-id</i>]:
Anonymous TLS connection established from localhost[127.0.0.1]:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
server-signature RSA-PSS (2048 bits) server-digest SHA256
postfix/smtpd[<i>process-id</i>]:
Anonymous TLS connection established from localhost[127.0.0.1]:
TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
server-signature ED25519
</pre>
</blockquote>
<h2><a name="status"> What do "Anonymous", "Untrusted", etc. in
Postfix logging mean? </a> </h2>

View File

@@ -83,6 +83,7 @@ static const NAME_MASK ehlo_mask_table[] = {
"ENHANCEDSTATUSCODES", EHLO_MASK_ENHANCEDSTATUSCODES,
"DSN", EHLO_MASK_DSN,
"EHLO_MASK_SMTPUTF8", EHLO_MASK_SMTPUTF8,
"SMTPUTF8", EHLO_MASK_SMTPUTF8,
"CHUNKING", EHLO_MASK_CHUNKING,
"SILENT-DISCARD", EHLO_MASK_SILENT, /* XXX In-band signaling */
0,

View File

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

View File

@@ -429,7 +429,7 @@ int smtp_get_noexcept(VSTRING *vp, VSTREAM *stream, ssize_t bound, int flags
void smtp_fputs(const char *cp, ssize_t todo, VSTREAM *stream)
{
ssize_t err;
int err;
if (todo < 0)
msg_panic("smtp_fputs: negative todo %ld", (long) todo);
@@ -454,7 +454,7 @@ void smtp_fputs(const char *cp, ssize_t todo, VSTREAM *stream)
void smtp_fwrite(const char *cp, ssize_t todo, VSTREAM *stream)
{
ssize_t err;
int err;
if (todo < 0)
msg_panic("smtp_fwrite: negative todo %ld", (long) todo);

View File

@@ -10,12 +10,7 @@
/* [\fIfile_type\fR:]\fIfile_name\fR ...
/* DESCRIPTION
/* The \fBpostmap\fR(1) command creates or queries one or more Postfix
/* lookup tables, or updates an existing one. The input and output
/* file formats are expected to be compatible with:
/*
/* .nf
/* \fBmakemap \fIfile_type\fR \fIfile_name\fR < \fIfile_name\fR
/* .fi
/* lookup tables, or updates an existing one.
/*
/* If the result files do not exist they will be created with the
/* same group and other read permissions as their source file.

View File

@@ -3307,12 +3307,70 @@ static void common_pre_message_handling(SMTPD_STATE *state,
#ifdef USE_TLS
if (var_smtpd_tls_received_header && state->tls_context) {
out_fprintf(out_stream, REC_TYPE_NORM,
"\t(using %s with cipher %s (%d/%d bits))",
int cont = 0;
vstring_sprintf(state->buffer,
"\t(using %s with cipher %s (%d/%d bits)",
state->tls_context->protocol,
state->tls_context->cipher_name,
state->tls_context->cipher_usebits,
state->tls_context->cipher_algbits);
if (state->tls_context->kex_name && *state->tls_context->kex_name) {
out_record(out_stream, REC_TYPE_NORM, STR(state->buffer),
LEN(state->buffer));
vstring_sprintf(state->buffer, "\t key-exchange %s",
state->tls_context->kex_name);
if (state->tls_context->kex_curve
&& *state->tls_context->kex_curve)
vstring_sprintf_append(state->buffer, " (%s)",
state->tls_context->kex_curve);
else if (state->tls_context->kex_bits > 0)
vstring_sprintf_append(state->buffer, " (%d bits)",
state->tls_context->kex_bits);
cont = 1;
}
if (state->tls_context->locl_sig_name
&& *state->tls_context->locl_sig_name) {
if (cont) {
vstring_sprintf_append(state->buffer, " server-signature %s",
state->tls_context->locl_sig_name);
} else {
out_record(out_stream, REC_TYPE_NORM, STR(state->buffer),
LEN(state->buffer));
vstring_sprintf(state->buffer, "\t server-signature %s",
state->tls_context->locl_sig_name);
}
if (state->tls_context->locl_sig_curve
&& *state->tls_context->locl_sig_curve)
vstring_sprintf_append(state->buffer, " (%s)",
state->tls_context->locl_sig_curve);
else if (state->tls_context->locl_sig_bits > 0)
vstring_sprintf_append(state->buffer, " (%d bits)",
state->tls_context->locl_sig_bits);
if (state->tls_context->locl_sig_dgst
&& *state->tls_context->locl_sig_dgst)
vstring_sprintf_append(state->buffer, " server-digest %s",
state->tls_context->locl_sig_dgst);
}
if (state->tls_context->peer_sig_name
&& *state->tls_context->peer_sig_name) {
out_record(out_stream, REC_TYPE_NORM, STR(state->buffer),
LEN(state->buffer));
vstring_sprintf(state->buffer, "\t client-signature %s",
state->tls_context->peer_sig_name);
if (state->tls_context->peer_sig_curve
&& *state->tls_context->peer_sig_curve)
vstring_sprintf_append(state->buffer, " (%s)",
state->tls_context->peer_sig_curve);
else if (state->tls_context->peer_sig_bits > 0)
vstring_sprintf_append(state->buffer, " (%d bits)",
state->tls_context->peer_sig_bits);
if (state->tls_context->peer_sig_dgst
&& *state->tls_context->peer_sig_dgst)
vstring_sprintf_append(state->buffer, " client-digest %s",
state->tls_context->peer_sig_dgst);
}
out_fprintf(out_stream, REC_TYPE_NORM, "%s)", STR(state->buffer));
if (TLS_CERT_IS_PRESENT(state->tls_context)) {
peer_CN = VSTRING_STRDUP(state->tls_context->peer_CN);
comment_sanitize(peer_CN);

View File

@@ -112,6 +112,30 @@ extern const char *str_tls_level(int);
/* Backwards compatibility with OpenSSL < 1.1.1 */
#if OPENSSL_VERSION_NUMBER < 0x1010100fUL
#define SSL_CTX_set_num_tickets(ctx, num) ((void)0)
#endif
/*-
* Backwards compatibility with OpenSSL < 1.1.1a (or some later version).
*
* The client-only interface SSL_get_server_tmp_key() is slated to be made to
* work on both client and server, and renamed to SSL_get_peer_tmp_key(), with
* the original name left behind as an alias. We'll use the new name if/when
* available.
*
* XXX: Set corresponding OpenSSL version floor below when OpenSSL pull
* request:
*
* <https://github.com/openssl/openssl/pull/7608>
*
* is merged, perhaps in the upcoming 1.1.1a release (at which point the XXX
* part of this comment can be deleted).
*/
#if OPENSSL_VERSION_NUMBER < 0x1010101fUL
#undef SSL_get_signature_nid
#define SSL_get_signature_nid(ssl, pnid) (NID_undef)
#define tls_get_peer_dh_pubkey SSL_get_server_tmp_key
#else
#define tls_get_peer_dh_pubkey SSL_get_peer_tmp_key
#endif
/* SSL_CIPHER_get_name() got constified in 0.9.7g */
@@ -239,6 +263,17 @@ typedef struct {
const char *cipher_name;
int cipher_usebits;
int cipher_algbits;
const char *kex_name; /* shared key-exchange algorithm */
const char *kex_curve; /* shared key-exchange ECDHE curve */
int kex_bits; /* shared FFDHE key exchange bits */
const char *locl_sig_name; /* local signature key algorithm */
const char *locl_sig_curve; /* local ECDSA curve name */
int locl_sig_bits; /* local RSA signature key bits */
const char *locl_sig_dgst; /* local signature digest */
const char *peer_sig_name; /* peer's signature key algorithm */
const char *peer_sig_curve; /* peer's ECDSA curve name */
int peer_sig_bits; /* peer's RSA signature key bits */
const char *peer_sig_dgst; /* peer's signature digest */
/* Private. */
SSL *con;
char *cache_type; /* tlsmgr(8) cache type if enabled */
@@ -378,7 +413,8 @@ extern void tls_param_init(void);
#endif
/*
* OpenSSL 1.1.1 does not define a TXT macro for TLS 1.3, so we roll our own.
* OpenSSL 1.1.1 does not define a TXT macro for TLS 1.3, so we roll our
* own.
*/
#define TLS_PROTOCOL_TXT_TLSV1_3 "TLSv1.3"
@@ -433,7 +469,12 @@ extern const NAME_CODE tls_cipher_grade_table[];
extern const char *tls_set_ciphers(TLS_APPL_STATE *, const char *,
const char *, const char *);
#endif
/*
* Populate TLS context with TLS 1.3-related signature parameters.
*/
extern void tls_get_signature_params(TLS_SESS_STATE *);
#endif /* TLS_INTERNAL */
/*
* tls_client.c

View File

@@ -860,6 +860,62 @@ static void verify_extract_print(TLS_SESS_STATE *TLScontext, X509 *peercert,
TLS_CERT_FLAG_TRUSTED | TLS_CERT_FLAG_MATCHED;
}
/* log_summary - TLS loglevel 1 one-liner, embellished with TLS 1.3 details */
static void log_summary(TLS_SESS_STATE *TLScontext,
const TLS_CLIENT_START_PROPS *props)
{
VSTRING *msg = vstring_alloc(100);
vstring_sprintf(msg, "%s TLS connection established to %s: %s"
" with cipher %s (%d/%d bits)",
!TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous" :
TLS_CERT_IS_SECURED(TLScontext) ? "Verified" :
TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted",
props->namaddr, TLScontext->protocol,
TLScontext->cipher_name, TLScontext->cipher_usebits,
TLScontext->cipher_algbits);
if (TLScontext->kex_name && *TLScontext->kex_name) {
vstring_sprintf_append(msg, " key-exchange %s",
TLScontext->kex_name);
if (TLScontext->kex_curve && *TLScontext->kex_curve)
vstring_sprintf_append(msg, " (%s)",
TLScontext->kex_curve);
else if (TLScontext->kex_bits > 0)
vstring_sprintf_append(msg, " (%d bits)",
TLScontext->kex_bits);
}
if (TLScontext->peer_sig_name && *TLScontext->peer_sig_name) {
vstring_sprintf_append(msg, " server-signature %s",
TLScontext->peer_sig_name);
if (TLScontext->peer_sig_curve && *TLScontext->peer_sig_curve)
vstring_sprintf_append(msg, " (%s)",
TLScontext->peer_sig_curve);
else if (TLScontext->peer_sig_bits > 0)
vstring_sprintf_append(msg, " (%d bits)",
TLScontext->peer_sig_bits);
if (TLScontext->peer_sig_dgst && *TLScontext->peer_sig_dgst)
vstring_sprintf_append(msg, " server-digest %s",
TLScontext->peer_sig_dgst);
}
if (TLScontext->locl_sig_name && *TLScontext->locl_sig_name) {
vstring_sprintf_append(msg, " client-signature %s",
TLScontext->locl_sig_name);
if (TLScontext->locl_sig_curve && *TLScontext->locl_sig_curve)
vstring_sprintf_append(msg, " (%s)",
TLScontext->locl_sig_curve);
else if (TLScontext->locl_sig_bits > 0)
vstring_sprintf_append(msg, " (%d bits)",
TLScontext->locl_sig_bits);
if (TLScontext->locl_sig_dgst && *TLScontext->locl_sig_dgst)
vstring_sprintf_append(msg, " client-digest %s",
TLScontext->locl_sig_dgst);
}
msg_info("%s", vstring_str(msg));
vstring_free(msg);
}
/*
* This is the actual startup routine for the connection. We expect that the
* buffers are flushed and the "220 Ready to start TLS" was received by us,
@@ -1191,17 +1247,10 @@ TLS_SESS_STATE *tls_client_post_connect(TLS_SESS_STATE *TLScontext,
&& !TLS_NEVER_SECURED(props->tls_level))
TLScontext->peer_status |= TLS_CERT_FLAG_SECURED;
/*
* All the key facts in a single log entry.
*/
tls_get_signature_params(TLScontext);
if (TLScontext->log_mask & TLS_LOG_SUMMARY)
msg_info("%s TLS connection established to %s: %s with cipher %s "
"(%d/%d bits)",
!TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous" :
TLS_CERT_IS_SECURED(TLScontext) ? "Verified" :
TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted",
props->namaddr, TLScontext->protocol, TLScontext->cipher_name,
TLScontext->cipher_usebits, TLScontext->cipher_algbits);
log_summary(TLScontext, props);
tls_int_seed();

View File

@@ -62,6 +62,9 @@
/* int grade;
/* const char *exclusions;
/*
/* void tls_get_signature_params(TLScontext)
/* TLS_SESS_STATE *TLScontext;
/*
/* void tls_print_errors()
/*
/* void tls_info_callback(ssl, where, ret)
@@ -143,6 +146,12 @@
/* When the input is invalid, tls_set_ciphers() logs a warning with
/* the specified context, and returns a null pointer result.
/*
/* tls_get_signature_params() updates the "TLScontext" with handshake
/* signature parameters pertaining to TLS 1.3, where the ciphersuite
/* no longer describes the asymmetric algorithms employed in the
/* handshake, which are negotiated separately. This function
/* has no effect for TLS 1.2 and earlier.
/*
/* tls_print_errors() queries the OpenSSL error stack,
/* logs the error messages, and clears the error stack.
/*
@@ -362,14 +371,15 @@ static const LONG_NAME_MASK ssl_bug_tweaks[] = {
NAMEBUG(TLSEXT_PADDING),
#if 0
/*
* XXX: New with OpenSSL 1.1.1, this is turned on implicitly in SSL_CTX_new()
* and is not included in SSL_OP_ALL. Allowing users to disable this would
* thus a code change that would clearing bug work-around bits in SSL_CTX,
* after setting SSL_OP_ALL. Since this is presumably required for TLS 1.3 on
* today's Internet, the code change will be done separately later. For now
* this implicit bug work-around cannot be disabled via supported Postfix
* mechanisms.
* XXX: New with OpenSSL 1.1.1, this is turned on implicitly in
* SSL_CTX_new() and is not included in SSL_OP_ALL. Allowing users to
* disable this would thus be a code change that would require clearing
* bug work-around bits in SSL_CTX, after setting SSL_OP_ALL. Since this
* is presumably required for TLS 1.3 on today's Internet, the code
* change will be done separately later. For now this implicit bug
* work-around cannot be disabled via supported Postfix mechanisms.
*/
#ifndef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
#define SSL_OP_ENABLE_MIDDLEBOX_COMPAT 0
@@ -825,6 +835,175 @@ const char *tls_set_ciphers(TLS_APPL_STATE *app_ctx, const char *context,
return (app_ctx->cipher_list = mystrdup(new_list));
}
/* 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;
#if OPENSSL_VERSION_NUMBER >= 0x1010100fUL && defined(TLS1_3_VERSION)
#ifndef OPENSSL_NO_EC
EC_KEY *eckey;
#endif
int nid;
int got_kex_key;
SSL *ssl = TLScontext->con;
X509 *cert;
EVP_PKEY *pkey = 0;
if (SSL_version(ssl) != TLS1_3_VERSION)
return;
if (tls_get_peer_dh_pubkey(ssl, &pkey)) {
switch (nid = EVP_PKEY_id(pkey)) {
default:
kex_name = OBJ_nid2sn(EVP_PKEY_type(nid));
break;
case EVP_PKEY_DH:
kex_name = "DHE";
TLScontext->kex_bits = EVP_PKEY_bits(pkey);
break;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
kex_name = "ECDHE";
eckey = EVP_PKEY_get0_EC_KEY(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);
break;
#endif
}
EVP_PKEY_free(pkey);
}
/*
* On the client end, the certificate may be preset, but not used, so we
* check via SSL_get_signature_nid(). This means that local signature
* data on clients requires at least 1.1.1a.
*/
if (SSL_is_server(ssl) || SSL_get_signature_nid(ssl, &nid))
cert = SSL_get_certificate(ssl);
else
cert = 0;
/* Signature algorithms for the local end of the connection */
if (cert) {
pkey = X509_get0_pubkey(cert);
/*
* Override the built-in name for the "ECDSA" algorithms OID, with
* the more familiar name. For "RSA" keys report "RSA-PSS", which
* must be used with TLS 1.3.
*/
if ((nid = EVP_PKEY_type(EVP_PKEY_id(pkey))) != NID_undef) {
switch (nid) {
default:
locl_sig_name = OBJ_nid2sn(nid);
break;
case EVP_PKEY_RSA:
/* For RSA, TLS 1.3 mandates PSS signatures */
locl_sig_name = "RSA-PSS";
TLScontext->locl_sig_bits = EVP_PKEY_bits(pkey);
break;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
locl_sig_name = "ECDSA";
eckey = EVP_PKEY_get0_EC_KEY(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);
break;
#endif
}
}
/*
* With Ed25519 and Ed448 there is no pre-signature digest, but the
* accessor does not fail, rather we get NID_undef.
*/
if (SSL_get_signature_nid(ssl, &nid) && nid != NID_undef)
locl_sig_dgst = OBJ_nid2sn(nid);
}
/* Signature algorithms for the peer end of the connection */
if ((cert = SSL_get_peer_certificate(ssl)) != 0) {
pkey = X509_get0_pubkey(cert);
/*
* Override the built-in name for the "ECDSA" algorithms OID, with
* the more familiar name. For "RSA" keys report "RSA-PSS", which
* must be used with TLS 1.3.
*/
if ((nid = EVP_PKEY_type(EVP_PKEY_id(pkey))) != NID_undef) {
switch (nid) {
default:
peer_sig_name = OBJ_nid2sn(nid);
break;
case EVP_PKEY_RSA:
/* For RSA, TLS 1.3 mandates PSS signatures */
peer_sig_name = "RSA-PSS";
TLScontext->peer_sig_bits = EVP_PKEY_bits(pkey);
break;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
peer_sig_name = "ECDSA";
eckey = EVP_PKEY_get0_EC_KEY(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);
break;
#endif
}
}
/*
* With Ed25519 and Ed448 there is no pre-signature digest, but the
* accessor does not fail, rather we get NID_undef.
*/
if (SSL_get_peer_signature_nid(ssl, &nid) && nid != NID_undef)
peer_sig_dgst = OBJ_nid2sn(nid);
}
#endif /* OPENSSL_VERSION_NUMBER >=
* 0x1010100fUL &&
* defined(TLS1_3_VERSION) */
if (kex_name) {
TLScontext->kex_name = mystrdup(kex_name);
if (kex_curve)
TLScontext->kex_curve = mystrdup(kex_curve);
}
if (locl_sig_name) {
TLScontext->locl_sig_name = mystrdup(locl_sig_name);
if (locl_sig_curve)
TLScontext->locl_sig_curve = mystrdup(locl_sig_curve);
if (locl_sig_dgst)
TLScontext->locl_sig_dgst = mystrdup(locl_sig_dgst);
}
if (peer_sig_name) {
TLScontext->peer_sig_name = mystrdup(peer_sig_name);
if (peer_sig_curve)
TLScontext->peer_sig_curve = mystrdup(peer_sig_curve);
if (peer_sig_dgst)
TLScontext->peer_sig_dgst = mystrdup(peer_sig_dgst);
}
}
/* tls_alloc_app_context - allocate TLS application context */
TLS_APPL_STATE *tls_alloc_app_context(SSL_CTX *ssl_ctx, int log_mask)
@@ -892,6 +1071,14 @@ TLS_SESS_STATE *tls_alloc_sess_context(int log_mask, const char *namaddr)
TLScontext->peer_pkey_fprint = 0;
TLScontext->protocol = 0;
TLScontext->cipher_name = 0;
TLScontext->kex_name = 0;
TLScontext->kex_curve = 0;
TLScontext->locl_sig_name = 0;
TLScontext->locl_sig_curve = 0;
TLScontext->locl_sig_dgst = 0;
TLScontext->peer_sig_name = 0;
TLScontext->peer_sig_curve = 0;
TLScontext->peer_sig_dgst = 0;
TLScontext->log_mask = log_mask;
TLScontext->namaddr = lowercase(mystrdup(namaddr));
TLScontext->mdalg = 0; /* Alias for props->mdalg */

View File

@@ -106,6 +106,17 @@ extern void tls_proxy_server_start_free(TLS_SERVER_START_PROPS *);
#define TLS_ATTR_CIPHER_NAME "cipher_name"
#define TLS_ATTR_CIPHER_USEBITS "cipher_usebits"
#define TLS_ATTR_CIPHER_ALGBITS "cipher_algbits"
#define TLS_ATTR_KEX_NAME "key_exchange"
#define TLS_ATTR_KEX_CURVE "key_exchange_curve"
#define TLS_ATTR_KEX_BITS "key_exchange_bits"
#define TLS_ATTR_LOCL_SIG_NAME "locl_signature"
#define TLS_ATTR_LOCL_SIG_CURVE "locl_signature_curve"
#define TLS_ATTR_LOCL_SIG_BITS "locl_signature_bits"
#define TLS_ATTR_LOCL_SIG_DGST "locl_signature_digest"
#define TLS_ATTR_PEER_SIG_NAME "peer_signature"
#define TLS_ATTR_PEER_SIG_CURVE "peer_signature_curve"
#define TLS_ATTR_PEER_SIG_BITS "peer_signature_bits"
#define TLS_ATTR_PEER_SIG_DGST "peer_signature_digest"
/*
* TLS_SERVER_INIT_PROPS attributes.

View File

@@ -80,6 +80,28 @@ int tls_proxy_context_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
tp->cipher_usebits),
SEND_ATTR_INT(TLS_ATTR_CIPHER_ALGBITS,
tp->cipher_algbits),
SEND_ATTR_STR(TLS_ATTR_KEX_NAME,
STRING_OR_EMPTY(tp->kex_name)),
SEND_ATTR_STR(TLS_ATTR_KEX_CURVE,
STRING_OR_EMPTY(tp->kex_curve)),
SEND_ATTR_INT(TLS_ATTR_KEX_BITS,
tp->kex_bits),
SEND_ATTR_STR(TLS_ATTR_LOCL_SIG_NAME,
STRING_OR_EMPTY(tp->locl_sig_name)),
SEND_ATTR_STR(TLS_ATTR_LOCL_SIG_CURVE,
STRING_OR_EMPTY(tp->locl_sig_curve)),
SEND_ATTR_INT(TLS_ATTR_LOCL_SIG_BITS,
tp->locl_sig_bits),
SEND_ATTR_STR(TLS_ATTR_LOCL_SIG_DGST,
STRING_OR_EMPTY(tp->locl_sig_dgst)),
SEND_ATTR_STR(TLS_ATTR_PEER_SIG_NAME,
STRING_OR_EMPTY(tp->peer_sig_name)),
SEND_ATTR_STR(TLS_ATTR_PEER_SIG_CURVE,
STRING_OR_EMPTY(tp->peer_sig_curve)),
SEND_ATTR_INT(TLS_ATTR_PEER_SIG_BITS,
tp->peer_sig_bits),
SEND_ATTR_STR(TLS_ATTR_PEER_SIG_DGST,
STRING_OR_EMPTY(tp->peer_sig_dgst)),
ATTR_TYPE_END);
/* Do not flush the stream. */
return (ret);

View File

@@ -78,6 +78,14 @@ int tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
VSTRING *peer_pkey_fprint = vstring_alloc(60); /* 60 for SHA-1 */
VSTRING *protocol = vstring_alloc(25);
VSTRING *cipher_name = vstring_alloc(25);
VSTRING *kex_name = vstring_alloc(25);
VSTRING *kex_curve = vstring_alloc(25);
VSTRING *locl_sig_name = vstring_alloc(25);
VSTRING *locl_sig_curve = vstring_alloc(25);
VSTRING *locl_sig_dgst = vstring_alloc(25);
VSTRING *peer_sig_name = vstring_alloc(25);
VSTRING *peer_sig_curve = vstring_alloc(25);
VSTRING *peer_sig_dgst = vstring_alloc(25);
if (msg_verbose)
msg_info("begin tls_proxy_context_scan");
@@ -99,6 +107,17 @@ int tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
&tls_context->cipher_usebits),
RECV_ATTR_INT(TLS_ATTR_CIPHER_ALGBITS,
&tls_context->cipher_algbits),
RECV_ATTR_STR(TLS_ATTR_KEX_NAME, kex_name),
RECV_ATTR_STR(TLS_ATTR_KEX_CURVE, kex_curve),
RECV_ATTR_INT(TLS_ATTR_KEX_BITS, &tls_context->kex_bits),
RECV_ATTR_STR(TLS_ATTR_LOCL_SIG_NAME, locl_sig_name),
RECV_ATTR_STR(TLS_ATTR_LOCL_SIG_CURVE, locl_sig_curve),
RECV_ATTR_INT(TLS_ATTR_LOCL_SIG_BITS, &tls_context->locl_sig_bits),
RECV_ATTR_STR(TLS_ATTR_LOCL_SIG_DGST, locl_sig_dgst),
RECV_ATTR_STR(TLS_ATTR_PEER_SIG_NAME, peer_sig_name),
RECV_ATTR_STR(TLS_ATTR_PEER_SIG_CURVE, peer_sig_curve),
RECV_ATTR_INT(TLS_ATTR_PEER_SIG_BITS, &tls_context->peer_sig_bits),
RECV_ATTR_STR(TLS_ATTR_PEER_SIG_DGST, peer_sig_dgst),
ATTR_TYPE_END);
/* Always construct a well-formed structure. */
tls_context->peer_CN = vstring_export(peer_CN);
@@ -107,7 +126,15 @@ int tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
tls_context->peer_pkey_fprint = vstring_export(peer_pkey_fprint);
tls_context->protocol = vstring_export(protocol);
tls_context->cipher_name = vstring_export(cipher_name);
ret = (ret == 9 ? 1 : -1);
tls_context->kex_name = vstring_export(kex_name);
tls_context->kex_curve = vstring_export(kex_curve);
tls_context->locl_sig_name = vstring_export(locl_sig_name);
tls_context->locl_sig_curve = vstring_export(locl_sig_curve);
tls_context->locl_sig_dgst = vstring_export(locl_sig_dgst);
tls_context->peer_sig_name = vstring_export(peer_sig_name);
tls_context->peer_sig_curve = vstring_export(peer_sig_curve);
tls_context->peer_sig_dgst = vstring_export(peer_sig_dgst);
ret = (ret == 20 ? 1 : -1);
if (ret != 1) {
tls_proxy_context_free(tls_context);
tls_context = 0;
@@ -134,6 +161,22 @@ void tls_proxy_context_free(TLS_SESS_STATE *tls_context)
myfree((void *) tls_context->protocol);
if (tls_context->cipher_name)
myfree((void *) tls_context->cipher_name);
if (tls_context->kex_name)
myfree((void *) tls_context->kex_name);
if (tls_context->kex_curve)
myfree((void *) tls_context->kex_curve);
if (tls_context->locl_sig_name)
myfree((void *) tls_context->locl_sig_name);
if (tls_context->locl_sig_curve)
myfree((void *) tls_context->locl_sig_curve);
if (tls_context->locl_sig_dgst)
myfree((void *) tls_context->locl_sig_dgst);
if (tls_context->peer_sig_name)
myfree((void *) tls_context->peer_sig_name);
if (tls_context->peer_sig_curve)
myfree((void *) tls_context->peer_sig_curve);
if (tls_context->peer_sig_dgst)
myfree((void *) tls_context->peer_sig_dgst);
myfree((void *) tls_context);
}

View File

@@ -345,6 +345,60 @@ static int ticket_cb(SSL *con, unsigned char name[], unsigned char iv[],
#endif
/* log_summary - TLS loglevel 1 one-liner, embellished with TLS 1.3 details */
static void log_summary(TLS_SESS_STATE *TLScontext)
{
VSTRING *msg = vstring_alloc(100);
vstring_sprintf(msg, "%s TLS connection established from %s: %s"
" with cipher %s (%d/%d bits)",
!TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous" :
TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted",
TLScontext->namaddr, TLScontext->protocol,
TLScontext->cipher_name, TLScontext->cipher_usebits,
TLScontext->cipher_algbits);
if (TLScontext->kex_name && *TLScontext->kex_name) {
vstring_sprintf_append(msg, " key-exchange %s",
TLScontext->kex_name);
if (TLScontext->kex_curve && *TLScontext->kex_curve)
vstring_sprintf_append(msg, " (%s)",
TLScontext->kex_curve);
else if (TLScontext->kex_bits > 0)
vstring_sprintf_append(msg, " (%d bits)",
TLScontext->kex_bits);
}
if (TLScontext->locl_sig_name && *TLScontext->locl_sig_name) {
vstring_sprintf_append(msg, " server-signature %s",
TLScontext->locl_sig_name);
if (TLScontext->locl_sig_curve && *TLScontext->locl_sig_curve)
vstring_sprintf_append(msg, " (%s)",
TLScontext->locl_sig_curve);
else if (TLScontext->locl_sig_bits > 0)
vstring_sprintf_append(msg, " (%d bits)",
TLScontext->locl_sig_bits);
if (TLScontext->locl_sig_dgst && *TLScontext->locl_sig_dgst)
vstring_sprintf_append(msg, " server-digest %s",
TLScontext->locl_sig_dgst);
}
if (TLScontext->peer_sig_name && *TLScontext->peer_sig_name) {
vstring_sprintf_append(msg, " client-signature %s",
TLScontext->peer_sig_name);
if (TLScontext->peer_sig_curve && *TLScontext->peer_sig_curve)
vstring_sprintf_append(msg, " (%s)",
TLScontext->peer_sig_curve);
else if (TLScontext->peer_sig_bits > 0)
vstring_sprintf_append(msg, " (%d bits)",
TLScontext->peer_sig_bits);
if (TLScontext->peer_sig_dgst && *TLScontext->peer_sig_dgst)
vstring_sprintf_append(msg, " client-digest %s",
TLScontext->peer_sig_dgst);
}
msg_info("%s", vstring_str(msg));
vstring_free(msg);
}
/* tls_server_init - initialize the server-side TLS engine */
TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
@@ -504,17 +558,18 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
}
if (ticketable) {
SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, ticket_cb);
/*
* OpenSSL 1.1.1 introduces support for TLS 1.3, which can issue more
* than one ticket per handshake. While this may be appropriate for
* communication between browsers and webservers, it is not terribly
* useful for MTAs, many of which other than Postfix don't do TLS
* session caching at all, and Postfix has no mechanism for storing
* multiple session tickets, if more than one sent, the second clobbers
* the first. OpenSSL 1.1.1 servers default to issuing two tickets for
* non-resumption handshakes, we reduce this to one. Our ticket
* decryption callback already (since 2.11) asks OpenSSL to avoid
* issuing new tickets when the presented ticket is re-usable.
* multiple session tickets, if more than one sent, the second
* clobbers the first. OpenSSL 1.1.1 servers default to issuing two
* tickets for non-resumption handshakes, we reduce this to one. Our
* ticket decryption callback already (since 2.11) asks OpenSSL to
* avoid issuing new tickets when the presented ticket is re-usable.
*/
SSL_CTX_set_num_tickets(server_ctx, 1);
}
@@ -951,15 +1006,16 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
if (TLScontext->stream != 0)
tls_stream_start(TLScontext->stream, TLScontext);
/*
* With the handshake done, extract TLS 1.3 signature metadata.
*/
tls_get_signature_params(TLScontext);
/*
* All the key facts in a single log entry.
*/
if (TLScontext->log_mask & TLS_LOG_SUMMARY)
msg_info("%s TLS connection established from %s: %s with cipher %s "
"(%d/%d bits)", !TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous"
: TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted",
TLScontext->namaddr, TLScontext->protocol, TLScontext->cipher_name,
TLScontext->cipher_usebits, TLScontext->cipher_algbits);
log_summary(TLScontext);
tls_int_seed();

View File

@@ -629,7 +629,7 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
#endif
#if DB_VERSION_MAJOR > 2
DB_ENV *dbenv;
DB_ENV *dbenv = 0;
#endif
@@ -674,12 +674,22 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
* db_open() create a non-existent file for us.
*/
#define LOCK_OPEN_FLAGS(f) ((f) & ~(O_CREAT|O_TRUNC))
#if DB_VERSION_MAJOR <= 2
#define FREE_RETURN(e) do { \
DICT *_dict = (e); if (db) DICT_DB_CLOSE(db); \
if (lock_fd >= 0) (void) close(lock_fd); \
if (db_base_buf) vstring_free(db_base_buf); \
if (db_path) myfree(db_path); return (_dict); \
} while (0)
#else
#define FREE_RETURN(e) do { \
DICT *_dict = (e); if (db) DICT_DB_CLOSE(db); \
if (dbenv) dbenv->close(dbenv, 0); \
if (lock_fd >= 0) (void) close(lock_fd); \
if (db_base_buf) vstring_free(db_base_buf); \
if (db_path) myfree(db_path); return (_dict); \
} while (0)
#endif
if (dict_flags & DICT_FLAG_LOCK) {
if ((lock_fd = open(db_path, LOCK_OPEN_FLAGS(open_flags), 0644)) < 0) {