mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 06:05:37 +00:00
postfix-3.4-20181113
This commit is contained in:
committed by
Viktor Dukhovni
parent
17000226f6
commit
93be1eb79b
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -15,16 +15,13 @@ 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:
|
||||
tables, or updates an existing one.
|
||||
|
||||
<b>makemap</b> <i>file</i><b>_</b><i>type file</i><b>_</b><i>name</i> < <i>file</i><b>_</b><i>name</i>
|
||||
|
||||
If the result files do not exist they will be created with the same
|
||||
If the result files do not exist they will be created with the same
|
||||
group and other read permissions as their source file.
|
||||
|
||||
While the table update is in progress, signal delivery is postponed,
|
||||
and an exclusive, advisory, lock is placed on the entire table, in
|
||||
While the table update is in progress, signal delivery is postponed,
|
||||
and an exclusive, advisory, lock is placed on the entire table, in
|
||||
order to avoid surprises in spectator processes.
|
||||
|
||||
<b>INPUT FILE FORMAT</b>
|
||||
@@ -34,153 +31,153 @@ POSTMAP(1) POSTMAP(1)
|
||||
|
||||
<i>key</i> whitespace <i>value</i>
|
||||
|
||||
<b>o</b> Empty lines and whitespace-only lines are ignored, as are lines
|
||||
<b>o</b> Empty lines and whitespace-only lines are ignored, as are lines
|
||||
whose first non-whitespace character is a `#'.
|
||||
|
||||
<b>o</b> A logical line starts with non-whitespace text. A line that
|
||||
<b>o</b> A logical line starts with non-whitespace text. A line that
|
||||
starts with whitespace continues a logical line.
|
||||
|
||||
The <i>key</i> and <i>value</i> are processed as is, except that surrounding white
|
||||
space is stripped off. Whitespace in lookup keys is supported as of
|
||||
The <i>key</i> and <i>value</i> are processed as is, except that surrounding white
|
||||
space is stripped off. Whitespace in lookup keys is supported as of
|
||||
Postfix 3.2.
|
||||
|
||||
When the <b>-F</b> option is given, the <i>value</i> must specify a filename;
|
||||
<a href="postmap.1.html"><b>postmap</b>(1)</a> will store the base64-encoded content of that file instead
|
||||
When the <b>-F</b> option is given, the <i>value</i> must specify a filename;
|
||||
<a href="postmap.1.html"><b>postmap</b>(1)</a> will store the base64-encoded content of that file instead
|
||||
of the <i>value</i> itself.
|
||||
|
||||
When the <i>key</i> specifies email address information, the localpart should
|
||||
When the <i>key</i> specifies email address information, the localpart should
|
||||
be enclosed with double quotes if required by <a href="http://tools.ietf.org/html/rfc5322">RFC 5322</a>. For example, an
|
||||
address localpart that contains ";", or a localpart that starts or ends
|
||||
with ".".
|
||||
|
||||
By default the lookup key is mapped to lowercase to make the lookups
|
||||
By default the lookup key is mapped to lowercase to make the lookups
|
||||
case insensitive; as of Postfix 2.3 this case folding happens only with
|
||||
tables whose lookup keys are fixed-case strings such as <a href="DATABASE_README.html#types">btree</a>:, <a href="DATABASE_README.html#types">dbm</a>: or
|
||||
<a href="DATABASE_README.html#types">hash</a>:. With earlier versions, the lookup key is folded even with tables
|
||||
where a lookup field can match both upper and lower case text, such as
|
||||
<a href="regexp_table.5.html">regexp</a>: and <a href="pcre_table.5.html">pcre</a>:. This resulted in loss of information with $<i>number</i>
|
||||
where a lookup field can match both upper and lower case text, such as
|
||||
<a href="regexp_table.5.html">regexp</a>: and <a href="pcre_table.5.html">pcre</a>:. This resulted in loss of information with $<i>number</i>
|
||||
substitutions.
|
||||
|
||||
<b>COMMAND-LINE ARGUMENTS</b>
|
||||
<b>-b</b> Enable message body query mode. When reading lookup keys from
|
||||
standard input with "<b>-q -</b>", process the input as if it is an
|
||||
email message in <a href="http://tools.ietf.org/html/rfc5322">RFC 5322</a> format. Each line of body content
|
||||
<b>-b</b> Enable message body query mode. When reading lookup keys from
|
||||
standard input with "<b>-q -</b>", process the input as if it is an
|
||||
email message in <a href="http://tools.ietf.org/html/rfc5322">RFC 5322</a> format. Each line of body content
|
||||
becomes one lookup key.
|
||||
|
||||
By default, the <b>-b</b> option starts generating lookup keys at the
|
||||
first non-header line, and stops when the end of the message is
|
||||
reached. To simulate <a href="header_checks.5.html"><b>body_checks</b>(5)</a> processing, enable MIME
|
||||
parsing with <b>-m</b>. With this, the <b>-b</b> option generates no
|
||||
body-style lookup keys for attachment MIME headers and for
|
||||
By default, the <b>-b</b> option starts generating lookup keys at the
|
||||
first non-header line, and stops when the end of the message is
|
||||
reached. To simulate <a href="header_checks.5.html"><b>body_checks</b>(5)</a> processing, enable MIME
|
||||
parsing with <b>-m</b>. With this, the <b>-b</b> option generates no
|
||||
body-style lookup keys for attachment MIME headers and for
|
||||
attached message/* headers.
|
||||
|
||||
NOTE: with "<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = yes", the <b>-b</b> option option dis-
|
||||
ables UTF-8 syntax checks on query keys and lookup results.
|
||||
NOTE: with "<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = yes", the <b>-b</b> option option dis-
|
||||
ables UTF-8 syntax checks on query keys and lookup results.
|
||||
Specify the <b>-U</b> option to force UTF-8 syntax checks anyway.
|
||||
|
||||
This feature is available in Postfix version 2.6 and later.
|
||||
|
||||
<b>-c</b> <i>config</i><b>_</b><i>dir</i>
|
||||
Read the <a href="postconf.5.html"><b>main.cf</b></a> configuration file in the named directory
|
||||
Read the <a href="postconf.5.html"><b>main.cf</b></a> configuration file in the named directory
|
||||
instead of the default configuration directory.
|
||||
|
||||
<b>-d</b> <i>key</i> Search the specified maps for <i>key</i> and remove one entry per map.
|
||||
The exit status is zero when the requested information was
|
||||
<b>-d</b> <i>key</i> Search the specified maps for <i>key</i> and remove one entry per map.
|
||||
The exit status is zero when the requested information was
|
||||
found.
|
||||
|
||||
If a key value of <b>-</b> is specified, the program reads key values
|
||||
from the standard input stream. The exit status is zero when at
|
||||
If a key value of <b>-</b> is specified, the program reads key values
|
||||
from the standard input stream. The exit status is zero when at
|
||||
least one of the requested keys was found.
|
||||
|
||||
<b>-f</b> Do not fold the lookup key to lower case while creating or
|
||||
<b>-f</b> Do not fold the lookup key to lower case while creating or
|
||||
querying a table.
|
||||
|
||||
With Postfix version 2.3 and later, this option has no effect
|
||||
With Postfix version 2.3 and later, this option has no effect
|
||||
for regular expression tables. There, case folding is controlled
|
||||
by appending a flag to a pattern.
|
||||
|
||||
<b>-F</b> When creating a map from source file, replace each value with
|
||||
the base64-encoded content of the named file. When querying a
|
||||
<b>-F</b> When creating a map from source file, replace each value with
|
||||
the base64-encoded content of the named file. When querying a
|
||||
map, or listing a map, base64-decode each value.
|
||||
|
||||
<b>-h</b> Enable message header query mode. When reading lookup keys from
|
||||
standard input with "<b>-q -</b>", process the input as if it is an
|
||||
email message in <a href="http://tools.ietf.org/html/rfc5322">RFC 5322</a> format. Each logical header line
|
||||
becomes one lookup key. A multi-line header becomes one lookup
|
||||
<b>-h</b> Enable message header query mode. When reading lookup keys from
|
||||
standard input with "<b>-q -</b>", process the input as if it is an
|
||||
email message in <a href="http://tools.ietf.org/html/rfc5322">RFC 5322</a> format. Each logical header line
|
||||
becomes one lookup key. A multi-line header becomes one lookup
|
||||
key with one or more embedded newline characters.
|
||||
|
||||
By default, the <b>-h</b> option generates lookup keys until the first
|
||||
non-header line is reached. To simulate <a href="header_checks.5.html"><b>header_checks</b>(5)</a> pro-
|
||||
cessing, enable MIME parsing with <b>-m</b>. With this, the <b>-h</b> option
|
||||
also generates header-style lookup keys for attachment MIME
|
||||
By default, the <b>-h</b> option generates lookup keys until the first
|
||||
non-header line is reached. To simulate <a href="header_checks.5.html"><b>header_checks</b>(5)</a> pro-
|
||||
cessing, enable MIME parsing with <b>-m</b>. With this, the <b>-h</b> option
|
||||
also generates header-style lookup keys for attachment MIME
|
||||
headers and for attached message/* headers.
|
||||
|
||||
NOTE: with "<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = yes", the <b>-b</b> option option dis-
|
||||
ables UTF-8 syntax checks on query keys and lookup results.
|
||||
NOTE: with "<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = yes", the <b>-b</b> option option dis-
|
||||
ables UTF-8 syntax checks on query keys and lookup results.
|
||||
Specify the <b>-U</b> option to force UTF-8 syntax checks anyway.
|
||||
|
||||
This feature is available in Postfix version 2.6 and later.
|
||||
|
||||
<b>-i</b> Incremental mode. Read entries from standard input and do not
|
||||
truncate an existing database. By default, <a href="postmap.1.html"><b>postmap</b>(1)</a> creates a
|
||||
<b>-i</b> Incremental mode. Read entries from standard input and do not
|
||||
truncate an existing database. By default, <a href="postmap.1.html"><b>postmap</b>(1)</a> creates a
|
||||
new database from the entries in <b>file_name</b>.
|
||||
|
||||
<b>-m</b> Enable MIME parsing with "<b>-b</b>" and "<b>-h</b>".
|
||||
|
||||
This feature is available in Postfix version 2.6 and later.
|
||||
|
||||
<b>-N</b> Include the terminating null character that terminates lookup
|
||||
keys and values. By default, <a href="postmap.1.html"><b>postmap</b>(1)</a> does whatever is the
|
||||
<b>-N</b> Include the terminating null character that terminates lookup
|
||||
keys and values. By default, <a href="postmap.1.html"><b>postmap</b>(1)</a> does whatever is the
|
||||
default for the host operating system.
|
||||
|
||||
<b>-n</b> Don't include the terminating null character that terminates
|
||||
lookup keys and values. By default, <a href="postmap.1.html"><b>postmap</b>(1)</a> does whatever is
|
||||
<b>-n</b> Don't include the terminating null character that terminates
|
||||
lookup keys and values. By default, <a href="postmap.1.html"><b>postmap</b>(1)</a> does whatever is
|
||||
the default for the host operating system.
|
||||
|
||||
<b>-o</b> Do not release root privileges when processing a non-root input
|
||||
file. By default, <a href="postmap.1.html"><b>postmap</b>(1)</a> drops root privileges and runs as
|
||||
<b>-o</b> Do not release root privileges when processing a non-root input
|
||||
file. By default, <a href="postmap.1.html"><b>postmap</b>(1)</a> drops root privileges and runs as
|
||||
the source file owner instead.
|
||||
|
||||
<b>-p</b> Do not inherit the file access permissions from the input file
|
||||
when creating a new file. Instead, create a new file with
|
||||
<b>-p</b> Do not inherit the file access permissions from the input file
|
||||
when creating a new file. Instead, create a new file with
|
||||
default access permissions (mode 0644).
|
||||
|
||||
<b>-q</b> <i>key</i> Search the specified maps for <i>key</i> and write the first value
|
||||
found to the standard output stream. The exit status is zero
|
||||
<b>-q</b> <i>key</i> Search the specified maps for <i>key</i> and write the first value
|
||||
found to the standard output stream. The exit status is zero
|
||||
when the requested information was found.
|
||||
|
||||
Note: this performs a single query with the key as specified,
|
||||
and does not make iterative queries with substrings of the key
|
||||
as described for <a href="access.5.html">access(5)</a>, <a href="canonical.5.html">canonical(5)</a>, <a href="transport.5.html">transport(5)</a>, <a href="virtual.5.html">vir-</a>
|
||||
Note: this performs a single query with the key as specified,
|
||||
and does not make iterative queries with substrings of the key
|
||||
as described for <a href="access.5.html">access(5)</a>, <a href="canonical.5.html">canonical(5)</a>, <a href="transport.5.html">transport(5)</a>, <a href="virtual.5.html">vir-</a>
|
||||
<a href="virtual.5.html">tual(5)</a> and other Postfix table-driven features.
|
||||
|
||||
If a key value of <b>-</b> is specified, the program reads key values
|
||||
from the standard input stream and writes one line of <i>key value</i>
|
||||
If a key value of <b>-</b> is specified, the program reads key values
|
||||
from the standard input stream and writes one line of <i>key value</i>
|
||||
output for each key that was found. The exit status is zero when
|
||||
at least one of the requested keys was found.
|
||||
|
||||
<b>-r</b> When updating a table, do not complain about attempts to update
|
||||
<b>-r</b> When updating a table, do not complain about attempts to update
|
||||
existing entries, and make those updates anyway.
|
||||
|
||||
<b>-s</b> Retrieve all database elements, and write one line of <i>key value</i>
|
||||
output for each element. The elements are printed in database
|
||||
order, which is not necessarily the same as the original input
|
||||
<b>-s</b> Retrieve all database elements, and write one line of <i>key value</i>
|
||||
output for each element. The elements are printed in database
|
||||
order, which is not necessarily the same as the original input
|
||||
order.
|
||||
|
||||
This feature is available in Postfix version 2.2 and later, and
|
||||
This feature is available in Postfix version 2.2 and later, and
|
||||
is not available for all database types.
|
||||
|
||||
<b>-u</b> Disable UTF-8 support. UTF-8 support is enabled by default when
|
||||
"<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = yes". It requires that keys and values are
|
||||
<b>-u</b> Disable UTF-8 support. UTF-8 support is enabled by default when
|
||||
"<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = yes". It requires that keys and values are
|
||||
valid UTF-8 strings.
|
||||
|
||||
<b>-U</b> With "<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = yes", force UTF-8 syntax checks with the
|
||||
<b>-b</b> and <b>-h</b> options.
|
||||
|
||||
<b>-v</b> Enable verbose logging for debugging purposes. Multiple <b>-v</b>
|
||||
<b>-v</b> Enable verbose logging for debugging purposes. Multiple <b>-v</b>
|
||||
options make the software increasingly verbose.
|
||||
|
||||
<b>-w</b> When updating a table, do not complain about attempts to update
|
||||
<b>-w</b> When updating a table, do not complain about attempts to update
|
||||
existing entries, and ignore those attempts.
|
||||
|
||||
Arguments:
|
||||
@@ -192,32 +189,32 @@ POSTMAP(1) POSTMAP(1)
|
||||
The <a href="postmap.1.html"><b>postmap</b>(1)</a> command can query any supported file type, but it
|
||||
can create only the following file types:
|
||||
|
||||
<b>btree</b> The output file is a btree file, named <i>file</i><b>_</b><i>name</i><b>.db</b>.
|
||||
This is available on systems with support for <b>db</b> data-
|
||||
<b>btree</b> The output file is a btree file, named <i>file</i><b>_</b><i>name</i><b>.db</b>.
|
||||
This is available on systems with support for <b>db</b> data-
|
||||
bases.
|
||||
|
||||
<b>cdb</b> The output consists of one file, named <i>file</i><b>_</b><i>name</i><b>.cdb</b>.
|
||||
This is available on systems with support for <b>cdb</b> data-
|
||||
<b>cdb</b> The output consists of one file, named <i>file</i><b>_</b><i>name</i><b>.cdb</b>.
|
||||
This is available on systems with support for <b>cdb</b> data-
|
||||
bases.
|
||||
|
||||
<b>dbm</b> The output consists of two files, named <i>file</i><b>_</b><i>name</i><b>.pag</b> and
|
||||
<i>file</i><b>_</b><i>name</i><b>.dir</b>. This is available on systems with support
|
||||
for <b>dbm</b> databases.
|
||||
|
||||
<b>hash</b> The output file is a hashed file, named <i>file</i><b>_</b><i>name</i><b>.db</b>.
|
||||
This is available on systems with support for <b>db</b> data-
|
||||
<b>hash</b> The output file is a hashed file, named <i>file</i><b>_</b><i>name</i><b>.db</b>.
|
||||
This is available on systems with support for <b>db</b> data-
|
||||
bases.
|
||||
|
||||
<b>fail</b> A table that reliably fails all requests. The lookup ta-
|
||||
ble name is used for logging only. This table exists to
|
||||
<b>fail</b> A table that reliably fails all requests. The lookup ta-
|
||||
ble name is used for logging only. This table exists to
|
||||
simplify Postfix error tests.
|
||||
|
||||
<b>sdbm</b> The output consists of two files, named <i>file</i><b>_</b><i>name</i><b>.pag</b> and
|
||||
<i>file</i><b>_</b><i>name</i><b>.dir</b>. This is available on systems with support
|
||||
for <b>sdbm</b> databases.
|
||||
|
||||
When no <i>file</i><b>_</b><i>type</i> is specified, the software uses the database
|
||||
type specified via the <b><a href="postconf.5.html#default_database_type">default_database_type</a></b> configuration
|
||||
When no <i>file</i><b>_</b><i>type</i> is specified, the software uses the database
|
||||
type specified via the <b><a href="postconf.5.html#default_database_type">default_database_type</a></b> configuration
|
||||
parameter.
|
||||
|
||||
<i>file</i><b>_</b><i>name</i>
|
||||
@@ -226,11 +223,11 @@ POSTMAP(1) POSTMAP(1)
|
||||
|
||||
<b>DIAGNOSTICS</b>
|
||||
Problems are logged to the standard error stream and to <b>syslogd</b>(8). No
|
||||
output means that no problems were detected. Duplicate entries are
|
||||
output means that no problems were detected. Duplicate entries are
|
||||
skipped and are flagged with a warning.
|
||||
|
||||
<a href="postmap.1.html"><b>postmap</b>(1)</a> terminates with zero exit status in case of success (includ-
|
||||
ing successful "<b>postmap -q</b>" lookup) and terminates with non-zero exit
|
||||
ing successful "<b>postmap -q</b>" lookup) and terminates with non-zero exit
|
||||
status in case of failure.
|
||||
|
||||
<b>ENVIRONMENT</b>
|
||||
@@ -241,12 +238,12 @@ POSTMAP(1) POSTMAP(1)
|
||||
Enable verbose logging for debugging purposes.
|
||||
|
||||
<b>CONFIGURATION PARAMETERS</b>
|
||||
The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
|
||||
gram. The text below provides only a parameter summary. See <a href="postconf.5.html"><b>post-</b></a>
|
||||
The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
|
||||
gram. The text below provides only a parameter summary. See <a href="postconf.5.html"><b>post-</b></a>
|
||||
<a href="postconf.5.html"><b>conf</b>(5)</a> for more details including examples.
|
||||
|
||||
<b><a href="postconf.5.html#berkeley_db_create_buffer_size">berkeley_db_create_buffer_size</a> (16777216)</b>
|
||||
The per-table I/O buffer size for programs that create Berkeley
|
||||
The per-table I/O buffer size for programs that create Berkeley
|
||||
DB hash or btree tables.
|
||||
|
||||
<b><a href="postconf.5.html#berkeley_db_read_buffer_size">berkeley_db_read_buffer_size</a> (131072)</b>
|
||||
@@ -254,7 +251,7 @@ POSTMAP(1) POSTMAP(1)
|
||||
hash or btree tables.
|
||||
|
||||
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
|
||||
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
|
||||
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
|
||||
figuration files.
|
||||
|
||||
<b><a href="postconf.5.html#default_database_type">default_database_type</a> (see 'postconf -d' output)</b>
|
||||
@@ -262,19 +259,19 @@ POSTMAP(1) POSTMAP(1)
|
||||
and <a href="postmap.1.html"><b>postmap</b>(1)</a> commands.
|
||||
|
||||
<b><a href="postconf.5.html#import_environment">import_environment</a> (see 'postconf -d' output)</b>
|
||||
The list of environment parameters that a privileged Postfix
|
||||
process will import from a non-Postfix parent process, or
|
||||
The list of environment parameters that a privileged Postfix
|
||||
process will import from a non-Postfix parent process, or
|
||||
name=value environment overrides.
|
||||
|
||||
<b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
|
||||
Enable preliminary SMTPUTF8 support for the protocols described
|
||||
Enable preliminary SMTPUTF8 support for the protocols described
|
||||
in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
|
||||
|
||||
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
|
||||
The syslog facility of Postfix logging.
|
||||
|
||||
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
|
||||
A prefix that is prepended to the process name in syslog
|
||||
A prefix that is prepended to the process name in syslog
|
||||
records, so that, for example, "smtpd" becomes "prefix/smtpd".
|
||||
|
||||
<b>SEE ALSO</b>
|
||||
|
@@ -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.
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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.
|
||||
|
@@ -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))",
|
||||
state->tls_context->protocol,
|
||||
state->tls_context->cipher_name,
|
||||
state->tls_context->cipher_usebits,
|
||||
state->tls_context->cipher_algbits);
|
||||
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);
|
||||
|
@@ -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
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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,15 +371,16 @@ 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
|
||||
#endif
|
||||
@@ -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 */
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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,18 +558,19 @@ 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
SSL_CTX_set_num_tickets(server_ctx, 1);
|
||||
}
|
||||
#endif
|
||||
@@ -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();
|
||||
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user