a session how many times each SMTP command was successfully
invoked, followed by the total number of invocations if it
is different. File: smtpd/smtpd.c.
-
+
+20140802
+
+ Workaround: detect mis-configuration where Postfix talks
+ to the Dovecot master socket instead of the Dovecot userdb
+ socket. Timo Sirainen. File: xsasl/xsasl_dovecot_server.c.
+
+20140904
+
+ Logging: the MySQL client now logs a warning when a match
+ against the "domain" list fails due to table lookup error
+ (hte underlying mechanism already logs a warning, but it
+ has less context information). File: global/dict_mysql.c.
+
+20140905
+
+ Feature: support to fall back to an unauthenticated TLS
+ security level ("may" or "encrypt) when the Postfix SMTP
+ client cannot establish the preferred authenticated TLS
+ security level ("dane", "dane-only", "fingerprint", "verify",
+ or "secure"). The fall-back levels may be specified globally
+ with the smtp_tls_fallback_level parameter or in per-site
+ TLS policies with the "fallback" attribute. Viktor Dukhovni.
+ Files: mantools/postlink, proto/TLS_README.html,
+ ./proto/postconf.proto, global/mail_params.h, smtp/lmtp_params.c,
+ smtp/smtp.c, smtp/smtp.h, smtp/smtp_connect.c, smtp/smtp_params.c,
+ smtp/smtp_proto.c, smtp/smtp_tls_policy.c, smtp/smtp_trouble.c.
+
+ Feature TLS audit logging, controlled with the
+ smtp_tls_audit_template parameter. This may be configured
+ to log TLS session properties at the end of each SMTP mail
+ delivery over TLS, for successful and failed deliveries.
+ This logging makes smtp_tls_loglevel=1 handshake logging
+ mostly redundant. Viktor Dukhovni. Files: mantools/postlink,
+ proto/TLS_README.html, ./proto/postconf.proto,
+ global/mail_params.h, smtp/Makefile.in, smtp/lmtp_params.c,
+ smtp/smtp.c, smtp/smtp.h, smtp/smtp_params.c, smtp/smtp_proto.c,
+ smtp_tls_audit.c, tls/tls.h, util/mac_expand.c.
E\bEn\bna\bab\bbl\bli\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bMT\bTP\bPU\bUT\bTF\bF8\b8 s\bsu\bup\bpp\bpo\bor\brt\bt
-By default, Postfix SMTPUTF8 support is disabled. Thus, Postfix should work
-exactly as it has worked before SMTPUTF8 support was implemented.
-
Before turning on SMTPUTF8 support in Postfix, you need to verify that the rest
of your email infrastructure can handle UTF-8 email addresses and message
header values, including SMTPUTF8 protocol support in SMTP-based content
SMTPUTF8 support is enabled by setting the smtputf8_enable parameter in
main.cf:
- # postconf "smtputf8_enable = yes"
- # postfix reload
+ # p\bpo\bos\bst\btc\bco\bon\bnf\bf "\b"s\bsm\bmt\btp\bpu\but\btf\bf8\b8_\b_e\ben\bna\bab\bbl\ble\be =\b= y\bye\bes\bs"\b"
+ # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
With SMTPUTF8 support enabled, Postfix changes behavior as follows:
* The Postfix SMTP server announces SMTPUTF8 support in the EHLO response.
220 server.example.com ESMTP Postfix
- EHLO client.example.com
+ E\bEH\bHL\bLO\bO c\bcl\bli\bie\ben\bnt\bt.\b.e\bex\bxa\bam\bmp\bpl\ble\be.\b.c\bco\bom\bm
250-server.example.com
250-PIPELINING
250-SIZE 10240000
* The Postfix SMTP server accepts the SMTPUTF8 request in MAIL FROM and VRFY
commands.
- MAIL FROM:<address> SMTPUTF8 ...
+ M\bMA\bAI\bIL\bL F\bFR\bRO\bOM\bM:\b:<\b<a\bad\bdd\bdr\bre\bes\bss\bs>\b> S\bSM\bMT\bTP\bPU\bUT\bTF\bF8\b8 .\b..\b..\b.
- VRFY address SMTPUTF8
+ V\bVR\bRF\bFY\bY a\bad\bdd\bdr\bre\bes\bss\bs S\bSM\bMT\bTP\bPU\bUT\bTF\bF8\b8
* The Postfix SMTP client may issue the SMTPUTF8 request in MAIL FROM
commands.
- * Postfix already permitted UTF-8 in message header values and in address
- localparts. This does not change.
-
* The Postfix SMTP server accepts UTF-8 in email address domains, but only
after the remote SMTP client client issues the SMTPUTF8 request in MAIL
FROM or VRFY commands.
+Postfix already permitted UTF-8 in message header values and in address
+localparts. This does not change.
+
U\bUs\bsi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bMT\bTP\bPU\bUT\bTF\bF8\b8 s\bsu\bup\bpp\bpo\bor\brt\bt
After Postfix SMTPUTF8 support is turned on, Postfix behavior will depend on 1)
L\bLi\bim\bmi\bit\bta\bat\bti\bio\bon\bns\bs o\bof\bf t\bth\bhe\be c\bcu\bur\brr\bre\ben\bnt\bt i\bim\bmp\bpl\ble\bem\bme\ben\bnt\bta\bat\bti\bio\bon\bn
"Internationalized" domain names can appear in two forms: the UTF-8 form, and
-the ASCII (xn--mumble) form.
+the ASCII (xn--mumble) form. The initial Postfix SMTPUTF8 implementation
+performs no automatic conversions on UTF8 strings beyond what is needed to
+perform DNS lookups.
N\bNo\bo c\bch\bha\bar\bra\bac\bct\bte\ber\brs\bse\bet\bt c\bca\ban\bno\bon\bni\bic\bca\bal\bli\biz\bza\bat\bti\bio\bon\bn f\bfo\bor\br n\bno\bon\bn-\b-A\bAS\bSC\bCI\bII\bI d\bdo\bom\bma\bai\bin\bn n\bna\bam\bme\bes\bs.\b.
P\bPr\bre\be-\b-e\bex\bxi\bis\bst\bti\bin\bng\bg n\bno\bon\bn-\b-A\bAS\bSC\bCI\bII\bI e\bem\bma\bai\bil\bl f\bfl\blo\bow\bws\bs
In pre-SMTPUTF8 environments, email with UTF-8 in address localparts (and in
-headers) works just fine because the vast majority of email software including
-Postfix is perfectly capable of handling such email, even if pre-SMTPUTF8
-standards do not support this.
+headers) works just fine. The vast majority of email software including Postfix
+is perfectly capable of handling such email, even if pre-SMTPUTF8 standards do
+not support this.
Therefore, when Postfix SMTPUTF8 support is turned on, Postfix must not
suddenly start to break pre-existing email flows with UTF-8 in addres
with SMTPUTF8 support when the library and its header files are installed. To
force Postfix to build without SMTPUTF8, specify:
- $ make makefiles -DNO_EAI ...
+ $ m\bma\bak\bke\be m\bma\bak\bke\bef\bfi\bil\ble\bes\bs -\b-D\bDN\bNO\bO_\b_E\bEA\bAI\bI .\b..\b..\b.
C\bCr\bre\bed\bdi\bit\bts\bs
* The "example.com" destination uses DANE, but if TLSA records are not
present or are unusable, mail is deferred.
- * The "example.org" destination uses DANE if possible, but if no TLSA records
- are found opportunistic TLS is used.
+ * The "example.org" destination uses DANE if possible, but uses opportunistic
+ TLS if no TLSA records are found. The "fallback" attribute (Postfix >=
+ 2.12) overrides the global main.cf smtp_tls_fallback_level parameter to
+ employ unauthenticated mandatory encryption if DANE authentication fails,
+ after logging a warning. See smtp_tls_audit_template for additional control
+ over TLS security logging.
main.cf:
indexed = ${default_database_type}:${config_directory}/
tls_policy:
example.com dane-only
+ # Postfix >= 2.12, per-destination smtp_tls_fallback_level override
+ example.org dane fallback=encrypt
master.cf:
dane unix - - n - - smtp
obtained for the remote SMTP server, SSLv2 is automatically disabled (see
smtp_tls_mandatory_protocols), and the server certificate must match the
TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is
- available with Postfix 2.11 and later.
+ available with Postfix 2.11 and later. The optional "fallback" attribute
+ provides a per-site override of the main.cf smtp_tls_fallback_level
+ parameter (Postfix >= 2.12).
d\bda\ban\bne\be-\b-o\bon\bnl\bly\by
Mandatory DANE TLS. The TLS policy for the destination is obtained via TLSA
records in DNSSEC. If no TLSA records are found, or none are usable, no
the remote SMTP server, SSLv2 is automatically disabled (see
smtp_tls_mandatory_protocols), and the server certificate must match the
TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is
- available with Postfix 2.11 and later.
+ available with Postfix 2.11 and later. The optional "fallback" attribute
+ provides a per-site override of the main.cf smtp_tls_fallback_level
+ parameter (Postfix >= 2.12).
f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt
Certificate fingerprint verification. Available with Postfix 2.5 and later.
At this security level, there are no trusted certificate authorities. The
combined with a "|" delimiter in a single match attribute, or multiple
match attributes can be employed. The ":" character is not used as a
delimiter as it occurs between each pair of fingerprint (hexadecimal)
- digits.
+ digits. The optional "fallback" attribute provides a per-site override of
+ the main.cf smtp_tls_fallback_level parameter (Postfix >= 2.12).
v\bve\ber\bri\bif\bfy\by
Mandatory server certificate verification. Mail is delivered only if the
TLS handshake succeeds, if the remote SMTP server certificate can be
"tafile" attribute optionally modifies trust chain verification in the same
manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile"
attribute may be specified multiple times to load multiple trust-anchor
- files.
+ files. The optional "fallback" attribute provides a per-site override of
+ the main.cf smtp_tls_fallback_level parameter (Postfix >= 2.12).
s\bse\bec\bcu\bur\bre\be
Secure certificate verification. Mail is delivered only if the TLS
handshake succeeds, if the remote SMTP server certificate can be validated
"match" attribute is specified). With Postfix >= 2.11 the "tafile"
attribute optionally modifies trust chain verification in the same manner
as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may
- be specified multiple times to load multiple trust-anchor files.
+ be specified multiple times to load multiple trust-anchor files. The
+ optional "fallback" attribute provides a per-site override of the main.cf
+ smtp_tls_fallback_level parameter (Postfix >= 2.12).
Notes:
* The "match" attribute is especially useful to verify TLS certificates for
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
# Postfix 2.5 and later
smtp_tls_fingerprint_digest = md5
+
/etc/postfix/tls_policy:
example.edu none
example.mil may
# Postfix 2.6 and later
example.info may protocols=!SSLv2 ciphers=medium
exclude=3DES
+ # Postfix 2.12 and later override of smtp_tls_fallback_level
+ fallback.example secure fallback=encrypt
N\bNo\bot\bte\be:\b: The "hostname" strategy if listed in a non-default setting of
smtp_tls_secure_cert_match or in the "match" attribute in the policy table can
(mantools/srctoman - makedefs | nroff -man | less) with information
about build options that are not described in the INSTALL instructions.
+Major changes with snapshot 20140905
+====================================
+
+Support to fall back to an unauthenticated TLS security level ("may"
+or "encrypt) when the Postfix SMTP client cannot establish the
+preferred authenticated TLS security level ("dane", "dane-only",
+"fingerprint", "verify", or "secure"). The fall-back levels may be
+specified globally with the smtp_tls_fallback_level parameter or
+in per-site TLS policies with the "fallback" attribute.
+
+If the above sounds like opportunistic authenticated TLS, than that
+is pretty-much it. Wietse is not fully convinced that this is a
+good idea, because it creates opportunities for downgrade attacks.
+
+SMTP client support to log TLS session properties after each mail
+delivery attempt. The content of this optional logfile record is
+configurable with the smtp_tls_audit_template parameter. The names
+of template properties are not yet final; the names of TLS session
+attributes need to be specific enough so that they will not collide
+with future names of non-TLS session attributes.
+
Major changes with snapshot 20140801
====================================
Things to do after the stable release:
- up-convert myhostname in MIME boundary strings?
+ up-convert myhostname to UTF-8 in MIME boundary strings?
+
+ Clarify that receive_override_options should not be used
+ with smtpd_proxy_filter.
+
+ Send a "relayed" notification upon delivery after a "delayed"
+ notification was sent. This requres that the queue manager
+ notices that the delay warning time has been reset, that
+ the queue manager sets the NOTIFY=SUCCESS' flag on all
+ subsequent delivery attempts for that message where SUCCESS'
+ is like standard SUCCESS except instead of propagating it
+ to a down-stream MTA, the Postfix SMTP client sends a
+ "relayed" notice. Delivery agents will then report a
+ "relayed" or "delivered" status for all successful deliveries.
+
+ Document the relative order of header_checks, address
+ rewriting, milters.
Table-driven case folding and case-insensitive string
comparison specifically for UTF-8.
independent from the DNS and native routines for host
name/address lookup.
- Incorporate 3rd-party code such as dynamic_maps.
-
Make been_here flag BH_FLAG_FOLD configurable for masochists.
Replace some redundant TLS_README sections with pointers
needs to show the unfolded address.
Per SASL account rate limits. This requires new infrastructure
- that maintains stats by SASL account.
+ that maintains stats by SASL account instead of client IP
+ address.
Watchdog timer in postmap/postalias.
End code revision, after DANE support stabilizes.
- It would be nice if the result from one table lookup could
- serve as input for another (e.g. virtual aliases before the
- list of valid recipients). For this to work the magical
- (bare user, domain only, etc.) lookups need to become a
- table property, not a property of the client context.
-
It would be nice if "bare username" lookup is not hard-coded
for domains in the local address class.
Investigate viability of Sendmail dns maps.
- Check if FILTER_README has the "postsuper -r" workaround
-
- Bounces without <> in the plaintext section. Apparently,
- some software renders the text as HTML (and therefore
- does not render addresses and other text inside <> ).
-
Make the rules for how to use close-on-exec more explicit.
Provide separate timeout control for dict_proxy client,
Consistency: in postconf.proto make <dt>..</dt> tags bold.
- postscreen(8): listen on multiple IP addresses and enforce
- that the client contacts the primary MX address first (i.e.
- punish hosts that contact the secondary before the primary).
- The downside with any approach that relies on temporary
- punishment is that it does not scale to configurations
- with multiple equal-preference MX hosts. Such hosts would
- have to share the postscreen cache, causing an unacceptable
- performance bottleneck and a single point of failure.
-
- According to a paper by Ted Unangst at BSDCON09, kqueue
- reports state changes, i.e. kqueue indicates when the socket
- becomes readable. Specifically, he writes when kqueue reports
- a socket becomes readable but no data is read from that
- socket, later kqueue calls won't report the socket as
- readable. That's not what happens on FreeBSD 8.0, where
- kqueue will keep reporting the socket as readable when
- nothing is read. Also, FreeBSD 8.0 kqueue still reports
- the socket as readable after a read operation does not empty
- the kernel buffer. We need a test program for this that
- repeats these tests with OpenBSD and NetBSD (and MacOS X
- once they fix their kqueue implementation).
-
Would it help if there were different cleanup_service
parameter names for different message paths? smtpd(8) uses
the same cleanup_service value for receiving remote mail
into mailer-daemon (current bahavior) or disallow (strict
behavior, currently implemented only in the SMTP server).
- The type of var_message_limit (and other file size/offset
- configuration parameters or internal protocol attributes)
- should be changed from int to off_t. This also requires
- checking all expressions in which var_message_limit etc.
- appears: qmqpd, netstring, deliver_request, ...
-
Add M flag (enable multi-recipient delivery) to pipe daemon.
The usage of TLScontext->cache_type is unclear. It specifies
<h2> <a name="enabling">Enabling Postfix SMTPUTF8 support</a> </h2>
-<p> By default, Postfix SMTPUTF8 support is disabled. Thus, Postfix
-should work exactly as it has worked before SMTPUTF8 support was
-implemented. </p>
-
<p> Before turning on SMTPUTF8 support in Postfix, you need to
verify that the rest of your email infrastructure can handle UTF-8
email addresses and message header values, including SMTPUTF8
<blockquote>
<pre>
-# postconf "<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = yes"
-# postfix reload
+# <b>postconf "<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = yes"</b>
+# <b>postfix reload</b>
</pre>
</blockquote>
<pre>
220 server.example.com ESMTP Postfix
-EHLO client.example.com
+<b>EHLO client.example.com</b>
250-server.example.com
250-PIPELINING
250-SIZE 10240000
MAIL FROM and VRFY commands. </p>
<pre>
-MAIL FROM:<address> SMTPUTF8 ...
+<b>MAIL FROM:<address> SMTPUTF8 ...</b>
-VRFY address SMTPUTF8
+<b>VRFY address SMTPUTF8</b>
</pre>
<li> <p> The Postfix SMTP client may issue the SMTPUTF8 request in
MAIL FROM commands. </p>
-<li> <p> Postfix already permitted UTF-8 in message header values
-and in address localparts. This does not change. </p>
-
<li> <p> The Postfix SMTP server accepts UTF-8 in email address
domains, but only after the remote SMTP client client issues the
SMTPUTF8 request in MAIL FROM or VRFY commands. </p>
</ul>
+<p> Postfix already permitted UTF-8 in message header values
+and in address localparts. This does not change. </p>
+
<h2> <a name="using">Using Postfix SMTPUTF8 support</a> </h2>
<p> After Postfix SMTPUTF8 support is turned on, Postfix behavior
</h2>
<p> "Internationalized" domain names can appear in two forms: the
-UTF-8 form, and the ASCII (xn--mumble) form. </p>
+UTF-8 form, and the ASCII (xn--mumble) form. The initial Postfix
+SMTPUTF8 implementation performs no automatic conversions on UTF8
+strings beyond what is needed to perform DNS lookups. </p>
<h3> No characterset canonicalization for non-ASCII domain names.
</h3>
<h3> Pre-existing non-ASCII email flows </h3>
<p> In pre-SMTPUTF8 environments, email with UTF-8 in address
-localparts (and in headers) works just fine because the vast majority
+localparts (and in headers) works just fine. The vast majority
of email software including Postfix is perfectly capable of handling
such email, even if pre-SMTPUTF8 standards do not support this. </p>
<blockquote>
<pre>
-$ make makefiles -DNO_EAI ...
+$ <b>make makefiles -DNO_EAI ...</b>
</pre>
</blockquote>
<li> <p> The "example.com" destination uses DANE, but if TLSA records
are not present or are unusable, mail is deferred. </p>
-<li> <p> The "example.org" destination uses DANE if possible, but if no TLSA
-records are found opportunistic TLS is used. </p>
+<li> <p> The "example.org" destination uses DANE if possible, but
+uses opportunistic TLS if no TLSA records are found. The
+"fallback" attribute (Postfix ≥ 2.12) overrides the global
+<a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter to employ unauthenticated
+mandatory encryption if DANE authentication fails, after logging a
+warning. See <a href="postconf.5.html#smtp_tls_audit_template">smtp_tls_audit_template</a> for additional control over TLS
+security logging. </p>
</ul>
<blockquote>
# <a href="postconf.5.html#default_transport">default_transport</a> = smtp, but some destinations are special:
#
<a href="postconf.5.html#transport_maps">transport_maps</a> = ${indexed}transport
-</pre>
-</blockquote>
-<blockquote>
-<pre>
transport:
example.com dane
example.org dane
-</pre>
-</blockquote>
-<blockquote>
-<pre>
tls_policy:
example.com dane-only
-</pre>
-</blockquote>
+ # Postfix ≥ 2.12, per-destination <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> override
+ example.org dane fallback=encrypt
-<blockquote>
-<pre>
<a href="master.5.html">master.cf</a>:
dane unix - - n - - smtp
-o <a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a>=dnssec
are obtained for the remote SMTP server, SSLv2 is automatically
disabled (see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the server certificate
must match the TLSA records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS authentication
-and DNSSEC support is available with Postfix 2.11 and later. </dd>
+and DNSSEC support is available with Postfix 2.11 and later.
+The optional "fallback" attribute provides a per-site override of
+the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix ≥ 2.12).
+</dd>
<dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
The TLS policy for the destination is obtained via TLSA records in
obtained for the remote SMTP server, SSLv2 is automatically disabled
(see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the server certificate must
match the TLSA records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS authentication and
-DNSSEC support is available with Postfix 2.11 and later. </dd>
+DNSSEC support is available with Postfix 2.11 and later.
+The optional "fallback" attribute provides a per-site override of
+the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix ≥ 2.12).
+</dd>
<dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
fingerprint verification.</a> Available with Postfix 2.5 and
not checked. Instead, the optional <b>match</b> attribute, or else
the <a href="postconf.5.html">main.cf</a> <b><a href="postconf.5.html#smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a></b> parameter, lists
the server certificate fingerprints or public key fingerprints
-(Postfix 2.9 and later). The
-digest algorithm used to calculate fingerprints is selected by the
-<b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a></b> parameter. Multiple fingerprints can
-be combined with a "|" delimiter in a single match attribute, or multiple
-match attributes can be employed. The ":" character is not used as a
-delimiter as it occurs between each pair of fingerprint (hexadecimal)
-digits. </dd>
+(Postfix 2.9 and later). The digest algorithm used to calculate
+fingerprints is selected by the <b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a></b>
+parameter. Multiple fingerprints can be combined with a "|" delimiter
+in a single match attribute, or multiple match attributes can be
+employed. The ":" character is not used as a delimiter as it occurs
+between each pair of fingerprint (hexadecimal) digits.
+The optional "fallback" attribute provides a per-site override of
+the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix ≥ 2.12).
+</dd>
<dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory
server certificate verification</a>. Mail is delivered only if the
parameter value when no optional "match" attribute is specified).
With Postfix ≥ 2.11 the "tafile" attribute optionally modifies
trust chain verification in the same manner as the
-"<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter. The "tafile" attribute
-may be specified multiple times to load multiple trust-anchor
-files. </dd>
+"<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter. The "tafile" attribute may
+be specified multiple times to load multiple trust-anchor files.
+The optional "fallback" attribute provides a per-site override of
+the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix ≥ 2.12).
+</dd>
<dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate
verification.</a> Mail is delivered only if the TLS handshake succeeds,
attribute optionally modifies trust chain verification in the same manner
as the "<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter. The "tafile" attribute
may be specified multiple times to load multiple trust-anchor
-files. </dd>
+files.
+The optional "fallback" attribute provides a per-site override of
+the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> parameter (Postfix ≥ 2.12).
+</dd>
</dl>
<a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/tls_policy
# Postfix 2.5 and later
<a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> = md5
+
/etc/postfix/tls_policy:
example.edu none
example.mil may
match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
# Postfix 2.6 and later
example.info may protocols=!SSLv2 ciphers=medium exclude=3DES
+ # Postfix 2.12 and later override of <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a>
+ fallback.example secure fallback=encrypt
</pre>
</blockquote>
<b><a href="postconf.5.html#tlsmgr_service_name">tlsmgr_service_name</a> (tlsmgr)</b>
The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in <a href="master.5.html">master.cf</a>.
+ Available in Postfix version 2.12 and later:
+
+ <b><a href="postconf.5.html#smtp_tls_audit_template">smtp_tls_audit_template</a> (empty)</b>
+ Optional template for tls audit logging at the completion of
+ each message data transfer.
+
+ <b><a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> (empty)</b>
+ Optional fallback levels for authenticated TLS levels.
+
<b>OBSOLETE STARTTLS CONTROLS</b>
- The following configuration parameters exist for compatibility with
- Postfix versions before 2.3. Support for these will be removed in a
+ The following configuration parameters exist for compatibility with
+ Postfix versions before 2.3. Support for these will be removed in a
future release.
<b><a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> (no)</b>
- Opportunistic mode: use TLS when a remote SMTP server announces
+ Opportunistic mode: use TLS when a remote SMTP server announces
STARTTLS support, otherwise send the mail in the clear.
<b><a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> (no)</b>
- Enforcement mode: require that remote SMTP servers use TLS
+ Enforcement mode: require that remote SMTP servers use TLS
encryption, and never send mail in the clear.
<b><a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> (yes)</b>
- With mandatory TLS encryption, require that the remote SMTP
- server hostname matches the information in the remote SMTP
+ With mandatory TLS encryption, require that the remote SMTP
+ server hostname matches the information in the remote SMTP
server certificate.
<b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
- Optional lookup tables with the Postfix SMTP client TLS usage
- policy by next-hop destination and by remote SMTP server host‐
+ Optional lookup tables with the Postfix SMTP client TLS usage
+ policy by next-hop destination and by remote SMTP server host‐
name.
<b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
- Obsolete Postfix < 2.3 control for the Postfix SMTP client TLS
+ Obsolete Postfix < 2.3 control for the Postfix SMTP client TLS
cipher list.
<b>RESOURCE AND RATE CONTROLS</b>
<b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a> ($default_destination_concur</b>‐\b‐
<b>rency_limit)</b>
- The maximal number of parallel deliveries to the same destina‐
+ The maximal number of parallel deliveries to the same destina‐
tion via the smtp message delivery transport.
<b><a href="postconf.5.html#smtp_destination_recipient_limit">smtp_destination_recipient_limit</a> ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipient_limit</a>)</b>
- The maximal number of recipients per message for the smtp mes‐
+ The maximal number of recipients per message for the smtp mes‐
sage delivery transport.
<b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
- The Postfix SMTP client time limit for completing a TCP connec‐
+ The Postfix SMTP client time limit for completing a TCP connec‐
tion, or zero (use the operating system built-in time limit).
<b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
- The Postfix SMTP client time limit for sending the HELO or EHLO
- command, and for receiving the initial remote SMTP server
+ The Postfix SMTP client time limit for sending the HELO or EHLO
+ command, and for receiving the initial remote SMTP server
response.
<b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
mand, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
- The Postfix SMTP client time limit for sending the MAIL FROM
+ The Postfix SMTP client time limit for sending the MAIL FROM
command, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
- The Postfix SMTP client time limit for sending the SMTP RCPT TO
+ The Postfix SMTP client time limit for sending the SMTP RCPT TO
command, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
- The Postfix SMTP client time limit for sending the SMTP DATA
+ The Postfix SMTP client time limit for sending the SMTP DATA
command, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
- The Postfix SMTP client time limit for sending the SMTP message
+ The Postfix SMTP client time limit for sending the SMTP message
content.
<b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
Available in Postfix version 2.1 and later:
<b><a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> (5)</b>
- The maximal number of MX (mail exchanger) IP addresses that can
- result from Postfix SMTP client mail exchanger lookups, or zero
+ The maximal number of MX (mail exchanger) IP addresses that can
+ result from Postfix SMTP client mail exchanger lookups, or zero
(no limit).
<b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
- The maximal number of SMTP sessions per delivery request before
- the Postfix SMTP client gives up or delivers to a fall-back
+ The maximal number of SMTP sessions per delivery request before
+ the Postfix SMTP client gives up or delivers to a fall-back
<a href="postconf.5.html#relayhost">relay host</a>, or zero (no limit).
<b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
Available in Postfix version 2.2 and earlier:
<b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
- Keep Postfix LMTP client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
+ Keep Postfix LMTP client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
seconds.
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
- Permanently enable SMTP connection caching for the specified
+ Permanently enable SMTP connection caching for the specified
destinations.
<b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
- Temporarily enable SMTP connection caching while a destination
+ Temporarily enable SMTP connection caching while a destination
has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
<b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
Available in Postfix version 2.3 and later:
<b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
- Time limit for connection cache connect, send or receive opera‐
+ Time limit for connection cache connect, send or receive opera‐
tions.
Available in Postfix version 2.9 and later:
<b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
- Change the behavior of the smtp_*_timeout time limits, from a
- time limit per read or write system call, to a time limit to
- send or receive a complete record (an SMTP command line, SMTP
- response line, SMTP message content line, or TLS protocol mes‐
+ Change the behavior of the smtp_*_timeout time limits, from a
+ time limit per read or write system call, to a time limit to
+ send or receive a complete record (an SMTP command line, SMTP
+ response line, SMTP message content line, or TLS protocol mes‐
sage).
Available in Postfix version 2.11 and later:
<b><a href="postconf.5.html#smtp_connection_reuse_count_limit">smtp_connection_reuse_count_limit</a> (0)</b>
- When SMTP connection caching is enabled, the number of times
- that an SMTP session may be reused before it is closed, or zero
+ When SMTP connection caching is enabled, the number of times
+ that an SMTP session may be reused before it is closed, or zero
(no limit).
<b>SMTPUTF8 CONTROLS</b>
in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
<b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
- Enable SMTPUTF8 autodetection for the specified mail origin
- classes.
+ Detect that a message requires SMTPUTF8 support for the speci‐
+ fied mail origin classes.
<b>TROUBLE SHOOTING CONTROLS</b>
<b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
- The increment in verbose logging level when a remote client or
+ The increment in verbose logging level when a remote client or
server matches a pattern in the <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
<b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
- Optional list of remote client or server hostname or network
+ Optional list of remote client or server hostname or network
address patterns that cause the verbose logging level to
increase by the amount specified in $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
<b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
- The recipient of postmaster notifications about mail delivery
+ The recipient of postmaster notifications about mail delivery
problems that are caused by policy, resource, software or proto‐
col errors.
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
- Where the Postfix SMTP client should deliver mail when it
+ Where the Postfix SMTP client should deliver mail when it
detects a "mail loops back to myself" error condition.
<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#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to handle a
+ How much time a Postfix daemon process may take to handle a
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
- The maximal number of digits after the decimal point when log‐
+ The maximal number of digits after the decimal point when log‐
ging sub-second delay values.
<b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
Disable DNS lookups in the Postfix SMTP and LMTP clients.
<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
- The network interface addresses that this mail system receives
+ The network interface addresses that this mail system receives
mail on.
<b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (all)</b>
- The Internet protocols Postfix will attempt to use when making
+ The Internet protocols Postfix will attempt to use when making
or accepting connections.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
- The time limit for sending or receiving information over an
+ The time limit for sending or receiving information over an
internal communication channel.
<b><a href="postconf.5.html#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
- When a remote LMTP server announces no DSN support, assume that
- the server performs final delivery, and send "delivered" deliv‐
+ When a remote LMTP server announces no DSN support, assume that
+ the server performs final delivery, and send "delivered" deliv‐
ery status notifications instead of "relayed".
<b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
The default TCP port that the Postfix LMTP client connects to.
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
- The maximum amount of time that an idle Postfix daemon process
+ The maximum amount of time that an idle Postfix daemon process
waits for an incoming connection before terminating voluntarily.
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
The process name of a Postfix command or daemon process.
<b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
- The network interface addresses that this mail system receives
+ The network interface addresses that this mail system receives
mail on by way of a proxy or network address translation unit.
<b><a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> (any)</b>
The address type ("ipv6", "ipv4" or "any") that the Postfix SMTP
- client will try first, when a destination has IPv6 and IPv4
+ client will try first, when a destination has IPv6 and IPv4
addresses with equal MX preference.
<b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
- An optional numerical network address that the Postfix SMTP
+ An optional numerical network address that the Postfix SMTP
client should bind to when making an IPv4 connection.
<b><a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> (empty)</b>
- An optional numerical network address that the Postfix SMTP
+ An optional numerical network address that the Postfix SMTP
client should bind to when making an IPv6 connection.
<b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
- The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post‐
+ The mail system name that is prepended to the process name in
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
Available with Postfix 2.2 and earlier:
<p> This feature is available in Postfix 2.3 and later. </p>
+</DD>
+
+<DT><b><a name="lmtp_tls_audit_template">lmtp_tls_audit_template</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_audit_template">smtp_tls_audit_template</a>
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
</DD>
<DT><b><a name="lmtp_tls_block_early_mail_reply">lmtp_tls_block_early_mail_reply</a>
<p> This feature is available in Postfix 2.3 and later. </p>
+</DD>
+
+<DT><b><a name="lmtp_tls_fallback_level">lmtp_tls_fallback_level</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a>
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
</DD>
<DT><b><a name="lmtp_tls_fingerprint_cert_match">lmtp_tls_fingerprint_cert_match</a>
<p> This feature is available in Postfix 2.2 and later. </p>
+</DD>
+
+<DT><b><a name="smtp_tls_audit_template">smtp_tls_audit_template</a>
+(default: empty)</b></DT><DD>
+
+<p> Optional template for tls audit logging at the completion of each
+message data transfer. If empty (the default setting) no TLS audit log
+entries are generated. </p>
+
+<p> The following $name expansions are done on <a href="postconf.5.html#smtp_tls_audit_template">smtp_tls_audit_template</a>: </p>
+
+<dl>
+
+<dt><b>$relay</b></dt>
+<dd>The remote SMTP server <i>name</i>[<i>address</i>]:<i>port</i>.
+</dd>
+
+<dt><b>$level</b></dt>
+<dd>The effective TLS security level after any fallback. </dd>
+
+<dt><b>$policy</b></dt>
+<dd>The desired TLS security level before any fallback, undefined
+if no fallback took place. </dd>
+
+<dt><b>$auth</b></dt>
+<dd>The authentication level of the remote SMTP server. One of
+"Cleartext", "Anonymous", "Untrusted", "Trusted" or "Verified".
+</dd>
+
+<dt><b>$protocol</b></dt>
+<dd>The TLS protocol version, defined only when TLS is used. </dd>
+
+<dt><b>$cipher</b></dt>
+<dd>The TLS cipher name, defined only when TLS is used. </dd>
+
+<dt><b>$cert_digest</b></dt>
+<dd>The digest of the remote SMTP server's certificate, defined
+only when TLS is used and the remote server presented a certificate.
+The digest algorithm is that specified via <a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a>.
+</dd>
+
+<dt><b>$spki_digest</b></dt>
+<dd>The digest of the remote SMTP server's public key (Subject
+Public Key Info or SPKI from X.509), defined only when TLS is used
+and the remote server presented a certificate. The digest algorithm
+is that specified via <a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a>. </dd>
+
+<dt><b>${name?value}</b></dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd>
+
+<dt><b>${name:value}</b></dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd>
+
+</dl>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ <a href="postconf.5.html#smtp_tls_audit_template">smtp_tls_audit_template</a> =
+ tlsaudit: relay=${relay}${auth?, auth=${auth}}${level?, level=${level}}${policy?, policy=${policy}}${protocol?, protocol=${protocol}}${cipher?, cipher=${cipher}}
+</pre>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
</DD>
<DT><b><a name="smtp_tls_block_early_mail_reply">smtp_tls_block_early_mail_reply</a>
<p> This feature is available in Postfix 2.3 and later. </p>
+</DD>
+
+<DT><b><a name="smtp_tls_fallback_level">smtp_tls_fallback_level</a>
+(default: empty)</b></DT><DD>
+
+<p> Optional fallback levels for authenticated TLS levels. Specify
+a white-space or comma-separated list of
+<b>policy_level</b>=<b>fallback_level</b> pairs. The <b>policy_level</b>
+must require authentication (one of dane, dane-only, fingerprint,
+verify, secure). The <b>fallback_level</b> must be "encrypt" or
+"may". When an authenticated connection at some desired policy
+level cannot be established, delivery will proceed at the correponding
+fallback level if possible. A warning will be logged
+indicating the fallback reason. You can use <a href="postconf.5.html#smtp_tls_audit_template">smtp_tls_audit_template</a>
+to record the TLS security status for each delivery. </p>
+
+<p> The TLS <a href="TLS_README.html#client_tls_policy">policy</a> table
+can be used to specify a destination-specific fallback strategy via the
+"fallback" policy attribute. The value of the "fallback" attribute, if
+specified, must be "may", "encrypt" or "none". If not "none", this
+specifies the fallback level for the destination in question. If the
+attribute value is "none", fallback is suppressed for the destination
+even if enabled via a global setting of <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a>. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+ # When authentication fails, log a warning and deliver anyway
+ # over an unauthenticated TLS connection.
+ #
+ <a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> =
+ dane=encrypt,
+ dane-only=encrypt,
+ fingerprint=encrypt,
+ verify=encrypt,
+ secure=encrypt
+ indexed = ${<a href="postconf.5.html#default_database_type">default_database_type</a>}:${<a href="postconf.5.html#config_directory">config_directory</a>}/
+ <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = ${indexed}tls-policy
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/tls-policy:
+ # No fallback for example.com
+ example.com secure fallback=none
+ # For example.net tolerate cleartext fallback
+ example.net dane fallback=may
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
</DD>
<DT><b><a name="smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a>
<b><a href="postconf.5.html#tlsmgr_service_name">tlsmgr_service_name</a> (tlsmgr)</b>
The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in <a href="master.5.html">master.cf</a>.
+ Available in Postfix version 2.12 and later:
+
+ <b><a href="postconf.5.html#smtp_tls_audit_template">smtp_tls_audit_template</a> (empty)</b>
+ Optional template for tls audit logging at the completion of
+ each message data transfer.
+
+ <b><a href="postconf.5.html#smtp_tls_fallback_level">smtp_tls_fallback_level</a> (empty)</b>
+ Optional fallback levels for authenticated TLS levels.
+
<b>OBSOLETE STARTTLS CONTROLS</b>
- The following configuration parameters exist for compatibility with
- Postfix versions before 2.3. Support for these will be removed in a
+ The following configuration parameters exist for compatibility with
+ Postfix versions before 2.3. Support for these will be removed in a
future release.
<b><a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> (no)</b>
- Opportunistic mode: use TLS when a remote SMTP server announces
+ Opportunistic mode: use TLS when a remote SMTP server announces
STARTTLS support, otherwise send the mail in the clear.
<b><a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> (no)</b>
- Enforcement mode: require that remote SMTP servers use TLS
+ Enforcement mode: require that remote SMTP servers use TLS
encryption, and never send mail in the clear.
<b><a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> (yes)</b>
- With mandatory TLS encryption, require that the remote SMTP
- server hostname matches the information in the remote SMTP
+ With mandatory TLS encryption, require that the remote SMTP
+ server hostname matches the information in the remote SMTP
server certificate.
<b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
- Optional lookup tables with the Postfix SMTP client TLS usage
- policy by next-hop destination and by remote SMTP server host‐
+ Optional lookup tables with the Postfix SMTP client TLS usage
+ policy by next-hop destination and by remote SMTP server host‐
name.
<b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
- Obsolete Postfix < 2.3 control for the Postfix SMTP client TLS
+ Obsolete Postfix < 2.3 control for the Postfix SMTP client TLS
cipher list.
<b>RESOURCE AND RATE CONTROLS</b>
<b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a> ($default_destination_concur</b>‐\b‐
<b>rency_limit)</b>
- The maximal number of parallel deliveries to the same destina‐
+ The maximal number of parallel deliveries to the same destina‐
tion via the smtp message delivery transport.
<b><a href="postconf.5.html#smtp_destination_recipient_limit">smtp_destination_recipient_limit</a> ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipient_limit</a>)</b>
- The maximal number of recipients per message for the smtp mes‐
+ The maximal number of recipients per message for the smtp mes‐
sage delivery transport.
<b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
- The Postfix SMTP client time limit for completing a TCP connec‐
+ The Postfix SMTP client time limit for completing a TCP connec‐
tion, or zero (use the operating system built-in time limit).
<b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
- The Postfix SMTP client time limit for sending the HELO or EHLO
- command, and for receiving the initial remote SMTP server
+ The Postfix SMTP client time limit for sending the HELO or EHLO
+ command, and for receiving the initial remote SMTP server
response.
<b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
mand, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
- The Postfix SMTP client time limit for sending the MAIL FROM
+ The Postfix SMTP client time limit for sending the MAIL FROM
command, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
- The Postfix SMTP client time limit for sending the SMTP RCPT TO
+ The Postfix SMTP client time limit for sending the SMTP RCPT TO
command, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
- The Postfix SMTP client time limit for sending the SMTP DATA
+ The Postfix SMTP client time limit for sending the SMTP DATA
command, and for receiving the remote SMTP server response.
<b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
- The Postfix SMTP client time limit for sending the SMTP message
+ The Postfix SMTP client time limit for sending the SMTP message
content.
<b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
Available in Postfix version 2.1 and later:
<b><a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> (5)</b>
- The maximal number of MX (mail exchanger) IP addresses that can
- result from Postfix SMTP client mail exchanger lookups, or zero
+ The maximal number of MX (mail exchanger) IP addresses that can
+ result from Postfix SMTP client mail exchanger lookups, or zero
(no limit).
<b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
- The maximal number of SMTP sessions per delivery request before
- the Postfix SMTP client gives up or delivers to a fall-back
+ The maximal number of SMTP sessions per delivery request before
+ the Postfix SMTP client gives up or delivers to a fall-back
<a href="postconf.5.html#relayhost">relay host</a>, or zero (no limit).
<b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
Available in Postfix version 2.2 and earlier:
<b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
- Keep Postfix LMTP client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
+ Keep Postfix LMTP client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
seconds.
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
- Permanently enable SMTP connection caching for the specified
+ Permanently enable SMTP connection caching for the specified
destinations.
<b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
- Temporarily enable SMTP connection caching while a destination
+ Temporarily enable SMTP connection caching while a destination
has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
<b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
Available in Postfix version 2.3 and later:
<b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
- Time limit for connection cache connect, send or receive opera‐
+ Time limit for connection cache connect, send or receive opera‐
tions.
Available in Postfix version 2.9 and later:
<b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
- Change the behavior of the smtp_*_timeout time limits, from a
- time limit per read or write system call, to a time limit to
- send or receive a complete record (an SMTP command line, SMTP
- response line, SMTP message content line, or TLS protocol mes‐
+ Change the behavior of the smtp_*_timeout time limits, from a
+ time limit per read or write system call, to a time limit to
+ send or receive a complete record (an SMTP command line, SMTP
+ response line, SMTP message content line, or TLS protocol mes‐
sage).
Available in Postfix version 2.11 and later:
<b><a href="postconf.5.html#smtp_connection_reuse_count_limit">smtp_connection_reuse_count_limit</a> (0)</b>
- When SMTP connection caching is enabled, the number of times
- that an SMTP session may be reused before it is closed, or zero
+ When SMTP connection caching is enabled, the number of times
+ that an SMTP session may be reused before it is closed, or zero
(no limit).
<b>SMTPUTF8 CONTROLS</b>
in <a href="http://tools.ietf.org/html/rfc6531">RFC 6531</a>..6533.
<b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
- Enable SMTPUTF8 autodetection for the specified mail origin
- classes.
+ Detect that a message requires SMTPUTF8 support for the speci‐
+ fied mail origin classes.
<b>TROUBLE SHOOTING CONTROLS</b>
<b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
- The increment in verbose logging level when a remote client or
+ The increment in verbose logging level when a remote client or
server matches a pattern in the <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
<b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
- Optional list of remote client or server hostname or network
+ Optional list of remote client or server hostname or network
address patterns that cause the verbose logging level to
increase by the amount specified in $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
<b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
- The recipient of postmaster notifications about mail delivery
+ The recipient of postmaster notifications about mail delivery
problems that are caused by policy, resource, software or proto‐
col errors.
<b>MISCELLANEOUS CONTROLS</b>
<b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
- Where the Postfix SMTP client should deliver mail when it
+ Where the Postfix SMTP client should deliver mail when it
detects a "mail loops back to myself" error condition.
<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#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to handle a
+ How much time a Postfix daemon process may take to handle a
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
- The maximal number of digits after the decimal point when log‐
+ The maximal number of digits after the decimal point when log‐
ging sub-second delay values.
<b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
Disable DNS lookups in the Postfix SMTP and LMTP clients.
<b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
- The network interface addresses that this mail system receives
+ The network interface addresses that this mail system receives
mail on.
<b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (all)</b>
- The Internet protocols Postfix will attempt to use when making
+ The Internet protocols Postfix will attempt to use when making
or accepting connections.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
- The time limit for sending or receiving information over an
+ The time limit for sending or receiving information over an
internal communication channel.
<b><a href="postconf.5.html#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
- When a remote LMTP server announces no DSN support, assume that
- the server performs final delivery, and send "delivered" deliv‐
+ When a remote LMTP server announces no DSN support, assume that
+ the server performs final delivery, and send "delivered" deliv‐
ery status notifications instead of "relayed".
<b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
The default TCP port that the Postfix LMTP client connects to.
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
- The maximum amount of time that an idle Postfix daemon process
+ The maximum amount of time that an idle Postfix daemon process
waits for an incoming connection before terminating voluntarily.
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
The process name of a Postfix command or daemon process.
<b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
- The network interface addresses that this mail system receives
+ The network interface addresses that this mail system receives
mail on by way of a proxy or network address translation unit.
<b><a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> (any)</b>
The address type ("ipv6", "ipv4" or "any") that the Postfix SMTP
- client will try first, when a destination has IPv6 and IPv4
+ client will try first, when a destination has IPv6 and IPv4
addresses with equal MX preference.
<b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
- An optional numerical network address that the Postfix SMTP
+ An optional numerical network address that the Postfix SMTP
client should bind to when making an IPv4 connection.
<b><a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> (empty)</b>
- An optional numerical network address that the Postfix SMTP
+ An optional numerical network address that the Postfix SMTP
client should bind to when making an IPv6 connection.
<b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
- The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post‐
+ The mail system name that is prepended to the process name in
+ syslog records, so that "smtpd" becomes, for example, "post‐
fix/smtpd".
Available with Postfix 2.2 and earlier:
configuration parameter. See there for details.
.PP
This feature is available in Postfix 2.3 and later.
+.SH lmtp_tls_audit_template (default: empty)
+The LMTP-specific version of the smtp_tls_audit_template
+configuration parameter. See there for details.
+.PP
+This feature is available in Postfix 2.12 and later.
.SH lmtp_tls_block_early_mail_reply (default: empty)
The LMTP-specific version of the smtp_tls_block_early_mail_reply
configuration parameter. See there for details.
configuration parameter. See there for details.
.PP
This feature is available in Postfix 2.3 and later.
+.SH lmtp_tls_fallback_level (default: empty)
+The LMTP-specific version of the smtp_tls_fallback_level
+configuration parameter. See there for details.
+.PP
+This feature is available in Postfix 2.12 and later.
.SH lmtp_tls_fingerprint_cert_match (default: empty)
The LMTP-specific version of the smtp_tls_fingerprint_cert_match
configuration parameter. See there for details.
.ft R
.PP
This feature is available in Postfix 2.2 and later.
+.SH smtp_tls_audit_template (default: empty)
+Optional template for tls audit logging at the completion of each
+message data transfer. If empty (the default setting) no TLS audit log
+entries are generated.
+.PP
+The following $name expansions are done on smtp_tls_audit_template:
+.IP "\fB$relay\fR"
+The remote SMTP server \fIname\fR[\fIaddress\fR]:\fIport\fR.
+.br
+.IP "\fB$level\fR"
+The effective TLS security level after any fallback.
+.br
+.IP "\fB$policy\fR"
+The desired TLS security level before any fallback, undefined
+if no fallback took place.
+.br
+.IP "\fB$auth\fR"
+The authentication level of the remote SMTP server. One of
+"Cleartext", "Anonymous", "Untrusted", "Trusted" or "Verified".
+.br
+.IP "\fB$protocol\fR"
+The TLS protocol version, defined only when TLS is used.
+.br
+.IP "\fB$cipher\fR"
+The TLS cipher name, defined only when TLS is used.
+.br
+.IP "\fB$cert_digest\fR"
+The digest of the remote SMTP server's certificate, defined
+only when TLS is used and the remote server presented a certificate.
+The digest algorithm is that specified via smtp_tls_fingerprint_digest.
+.br
+.IP "\fB$spki_digest\fR"
+The digest of the remote SMTP server's public key (Subject
+Public Key Info or SPKI from X.509), defined only when TLS is used
+and the remote server presented a certificate. The digest algorithm
+is that specified via smtp_tls_fingerprint_digest.
+.br
+.IP "\fB${name?value}\fR"
+Expands to \fIvalue\fR when \fI$name\fR is non-empty.
+.br
+.IP "\fB${name:value}\fR"
+Expands to \fIvalue\fR when \fI$name\fR is empty.
+.br
+.br
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+/etc/postfix/main.cf:
+ smtp_tls_audit_template =
+ tlsaudit: relay=${relay}${auth?, auth=${auth}}${level?, level=${level}}${policy?, policy=${policy}}${protocol?, protocol=${protocol}}${cipher?, cipher=${cipher}}
+.fi
+.ad
+.ft R
+.PP
+This feature is available in Postfix 2.12 and later.
.SH smtp_tls_block_early_mail_reply (default: no)
Try to detect a mail hijacking attack based on a TLS protocol
vulnerability (CVE-2009-3555), where an attacker prepends malicious
key exchange with RSA authentication.
.PP
This feature is available in Postfix 2.3 and later.
+.SH smtp_tls_fallback_level (default: empty)
+Optional fallback levels for authenticated TLS levels. Specify
+a white-space or comma-separated list of
+\fBpolicy_level\fR=\fBfallback_level\fR pairs. The \fBpolicy_level\fR
+must require authentication (one of dane, dane-only, fingerprint,
+verify, secure). The \fBfallback_level\fR must be "encrypt" or
+"may". When an authenticated connection at some desired policy
+level cannot be established, delivery will proceed at the correponding
+fallback level if possible. A warning will be logged
+indicating the fallback reason. You can use smtp_tls_audit_template
+to record the TLS security status for each delivery.
+.PP
+The TLS policy table
+can be used to specify a destination-specific fallback strategy via the
+"fallback" policy attribute. The value of the "fallback" attribute, if
+specified, must be "may", "encrypt" or "none". If not "none", this
+specifies the fallback level for the destination in question. If the
+attribute value is "none", fallback is suppressed for the destination
+even if enabled via a global setting of smtp_tls_fallback_level.
+.PP
+Example:
+.sp
+.in +4
+.nf
+.na
+.ft C
+/etc/postfix/main.cf:
+ # When authentication fails, log a warning and deliver anyway
+ # over an unauthenticated TLS connection.
+ #
+ smtp_tls_fallback_level =
+ dane=encrypt,
+ dane-only=encrypt,
+ fingerprint=encrypt,
+ verify=encrypt,
+ secure=encrypt
+ indexed = ${default_database_type}:${config_directory}/
+ smtp_tls_policy_maps = ${indexed}tls-policy
+.fi
+.ad
+.ft R
+.in -4
+.sp
+.in +4
+.nf
+.na
+.ft C
+/etc/postfix/tls-policy:
+ # No fallback for example.com
+ example.com secure fallback=none
+ # For example.net tolerate cleartext fallback
+ example.net dane fallback=may
+.fi
+.ad
+.ft R
+.in -4
+.PP
+This feature is available in Postfix 2.12 and later.
.SH smtp_tls_fingerprint_cert_match (default: empty)
List of acceptable remote SMTP server certificate fingerprints for
the "fingerprint" TLS security level (\fBsmtp_tls_security_level\fR =
RFC 6698 trust-anchor digest support in the Postfix TLS library.
.IP "\fBtlsmgr_service_name (tlsmgr)\fR"
The name of the \fBtlsmgr\fR(8) service entry in master.cf.
+.PP
+Available in Postfix version 2.12 and later:
+.IP "\fBsmtp_tls_audit_template (empty)\fR"
+Optional template for tls audit logging at the completion of each
+message data transfer.
+.IP "\fBsmtp_tls_fallback_level (empty)\fR"
+Optional fallback levels for authenticated TLS levels.
.SH "OBSOLETE STARTTLS CONTROLS"
.na
.nf
Enable experimental SMTPUTF8 support for the protocols described
in RFC 6531..6533.
.IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
-Enable SMTPUTF8 autodetection for the specified mail origin
-classes.
+Detect that a message requires SMTPUTF8 support for the specified
+mail origin classes.
.SH "TROUBLE SHOOTING CONTROLS"
.na
.nf
s;\bsmtp_starttls_timeout\b;<a href="postconf.5.html#smtp_starttls_timeout">$&</a>;g;
s;\bsmtp_tls_CAfile\b;<a href="postconf.5.html#smtp_tls_CAfile">$&</a>;g;
s;\bsmtp_tls_CApath\b;<a href="postconf.5.html#smtp_tls_CApath">$&</a>;g;
+ s;\bsmtp_tls_fallback_level\b;<a href="postconf.5.html#smtp_tls_fallback_level">$&</a>;g;
+ s;\blmtp_tls_fallback_level\b;<a href="postconf.5.html#lmtp_tls_fallback_level">$&</a>;g;
+ s;\bsmtp_tls_audit_template\b;<a href="postconf.5.html#smtp_tls_audit_template">$&</a>;g;
+ s;\blmtp_tls_audit_template\b;<a href="postconf.5.html#lmtp_tls_audit_template">$&</a>;g;
s;\bsmtp_tls_cert_file\b;<a href="postconf.5.html#smtp_tls_cert_file">$&</a>;g;
s;\bsmtp_tls_fingerprint_digest\b;<a href="postconf.5.html#smtp_tls_fingerprint_digest">$&</a>;g;
s;\bsmtp_tls_protocols\b;<a href="postconf.5.html#smtp_tls_protocols">$&</a>;g;
<h2> <a name="enabling">Enabling Postfix SMTPUTF8 support</a> </h2>
-<p> By default, Postfix SMTPUTF8 support is disabled. Thus, Postfix
-should work exactly as it has worked before SMTPUTF8 support was
-implemented. </p>
-
<p> Before turning on SMTPUTF8 support in Postfix, you need to
verify that the rest of your email infrastructure can handle UTF-8
email addresses and message header values, including SMTPUTF8
<blockquote>
<pre>
-# postconf "smtputf8_enable = yes"
-# postfix reload
+# <b>postconf "smtputf8_enable = yes"</b>
+# <b>postfix reload</b>
</pre>
</blockquote>
<pre>
220 server.example.com ESMTP Postfix
-EHLO client.example.com
+<b>EHLO client.example.com</b>
250-server.example.com
250-PIPELINING
250-SIZE 10240000
MAIL FROM and VRFY commands. </p>
<pre>
-MAIL FROM:<address> SMTPUTF8 ...
+<b>MAIL FROM:<address> SMTPUTF8 ...</b>
-VRFY address SMTPUTF8
+<b>VRFY address SMTPUTF8</b>
</pre>
<li> <p> The Postfix SMTP client may issue the SMTPUTF8 request in
MAIL FROM commands. </p>
-<li> <p> Postfix already permitted UTF-8 in message header values
-and in address localparts. This does not change. </p>
-
<li> <p> The Postfix SMTP server accepts UTF-8 in email address
domains, but only after the remote SMTP client client issues the
SMTPUTF8 request in MAIL FROM or VRFY commands. </p>
</ul>
+<p> Postfix already permitted UTF-8 in message header values
+and in address localparts. This does not change. </p>
+
<h2> <a name="using">Using Postfix SMTPUTF8 support</a> </h2>
<p> After Postfix SMTPUTF8 support is turned on, Postfix behavior
</h2>
<p> "Internationalized" domain names can appear in two forms: the
-UTF-8 form, and the ASCII (xn--mumble) form. </p>
+UTF-8 form, and the ASCII (xn--mumble) form. The initial Postfix
+SMTPUTF8 implementation performs no automatic conversions on UTF8
+strings beyond what is needed to perform DNS lookups. </p>
<h3> No characterset canonicalization for non-ASCII domain names.
</h3>
<h3> Pre-existing non-ASCII email flows </h3>
<p> In pre-SMTPUTF8 environments, email with UTF-8 in address
-localparts (and in headers) works just fine because the vast majority
+localparts (and in headers) works just fine. The vast majority
of email software including Postfix is perfectly capable of handling
such email, even if pre-SMTPUTF8 standards do not support this. </p>
<blockquote>
<pre>
-$ make makefiles -DNO_EAI ...
+$ <b>make makefiles -DNO_EAI ...</b>
</pre>
</blockquote>
<li> <p> The "example.com" destination uses DANE, but if TLSA records
are not present or are unusable, mail is deferred. </p>
-<li> <p> The "example.org" destination uses DANE if possible, but if no TLSA
-records are found opportunistic TLS is used. </p>
+<li> <p> The "example.org" destination uses DANE if possible, but
+uses opportunistic TLS if no TLSA records are found. The
+"fallback" attribute (Postfix ≥ 2.12) overrides the global
+main.cf smtp_tls_fallback_level parameter to employ unauthenticated
+mandatory encryption if DANE authentication fails, after logging a
+warning. See smtp_tls_audit_template for additional control over TLS
+security logging. </p>
</ul>
<blockquote>
# default_transport = smtp, but some destinations are special:
#
transport_maps = ${indexed}transport
-</pre>
-</blockquote>
-<blockquote>
-<pre>
transport:
example.com dane
example.org dane
-</pre>
-</blockquote>
-<blockquote>
-<pre>
tls_policy:
example.com dane-only
-</pre>
-</blockquote>
+ # Postfix ≥ 2.12, per-destination smtp_tls_fallback_level override
+ example.org dane fallback=encrypt
-<blockquote>
-<pre>
master.cf:
dane unix - - n - - smtp
-o smtp_dns_support_level=dnssec
are obtained for the remote SMTP server, SSLv2 is automatically
disabled (see smtp_tls_mandatory_protocols), and the server certificate
must match the TLSA records. RFC 6698 (DANE) TLS authentication
-and DNSSEC support is available with Postfix 2.11 and later. </dd>
+and DNSSEC support is available with Postfix 2.11 and later.
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12).
+</dd>
<dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
The TLS policy for the destination is obtained via TLSA records in
obtained for the remote SMTP server, SSLv2 is automatically disabled
(see smtp_tls_mandatory_protocols), and the server certificate must
match the TLSA records. RFC 6698 (DANE) TLS authentication and
-DNSSEC support is available with Postfix 2.11 and later. </dd>
+DNSSEC support is available with Postfix 2.11 and later.
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12).
+</dd>
<dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
fingerprint verification.</a> Available with Postfix 2.5 and
not checked. Instead, the optional <b>match</b> attribute, or else
the main.cf <b>smtp_tls_fingerprint_cert_match</b> parameter, lists
the server certificate fingerprints or public key fingerprints
-(Postfix 2.9 and later). The
-digest algorithm used to calculate fingerprints is selected by the
-<b>smtp_tls_fingerprint_digest</b> parameter. Multiple fingerprints can
-be combined with a "|" delimiter in a single match attribute, or multiple
-match attributes can be employed. The ":" character is not used as a
-delimiter as it occurs between each pair of fingerprint (hexadecimal)
-digits. </dd>
+(Postfix 2.9 and later). The digest algorithm used to calculate
+fingerprints is selected by the <b>smtp_tls_fingerprint_digest</b>
+parameter. Multiple fingerprints can be combined with a "|" delimiter
+in a single match attribute, or multiple match attributes can be
+employed. The ":" character is not used as a delimiter as it occurs
+between each pair of fingerprint (hexadecimal) digits.
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12).
+</dd>
<dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory
server certificate verification</a>. Mail is delivered only if the
parameter value when no optional "match" attribute is specified).
With Postfix ≥ 2.11 the "tafile" attribute optionally modifies
trust chain verification in the same manner as the
-"smtp_tls_trust_anchor_file" parameter. The "tafile" attribute
-may be specified multiple times to load multiple trust-anchor
-files. </dd>
+"smtp_tls_trust_anchor_file" parameter. The "tafile" attribute may
+be specified multiple times to load multiple trust-anchor files.
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12).
+</dd>
<dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate
verification.</a> Mail is delivered only if the TLS handshake succeeds,
attribute optionally modifies trust chain verification in the same manner
as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute
may be specified multiple times to load multiple trust-anchor
-files. </dd>
+files.
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix ≥ 2.12).
+</dd>
</dl>
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
# Postfix 2.5 and later
smtp_tls_fingerprint_digest = md5
+
/etc/postfix/tls_policy:
example.edu none
example.mil may
match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
# Postfix 2.6 and later
example.info may protocols=!SSLv2 ciphers=medium exclude=3DES
+ # Postfix 2.12 and later override of smtp_tls_fallback_level
+ fallback.example secure fallback=encrypt
</pre>
</blockquote>
[mail.example.org]:587 secure match=nexthop
# Postfix 2.5 and later
[thumb.example.org] fingerprint
- match=EC:3B:2D:B0:5B:B1:FB:6D:20:A3:9D:72:F6:8D:12:35
- match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
+ match=EC:3B:2D:B0:5B:B1:FB:6D:20:A3:9D:72:F6:8D:12:35
+ match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
</pre>
<p> <b>Note:</b> The <b>hostname</b> strategy if listed in a non-default
</dl>
<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM smtp_tls_fallback_level
+
+<p> Optional fallback levels for authenticated TLS levels. Specify
+a white-space or comma-separated list of
+<b>policy_level</b>=<b>fallback_level</b> pairs. The <b>policy_level</b>
+must require authentication (one of dane, dane-only, fingerprint,
+verify, secure). The <b>fallback_level</b> must be "encrypt" or
+"may". When an authenticated connection at some desired policy
+level cannot be established, delivery will proceed at the correponding
+fallback level if possible. A warning will be logged
+indicating the fallback reason. You can use smtp_tls_audit_template
+to record the TLS security status for each delivery. </p>
+
+<p> The TLS <a href="TLS_README.html#client_tls_policy">policy</a> table
+can be used to specify a destination-specific fallback strategy via the
+"fallback" policy attribute. The value of the "fallback" attribute, if
+specified, must be "may", "encrypt" or "none". If not "none", this
+specifies the fallback level for the destination in question. If the
+attribute value is "none", fallback is suppressed for the destination
+even if enabled via a global setting of smtp_tls_fallback_level. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # When authentication fails, log a warning and deliver anyway
+ # over an unauthenticated TLS connection.
+ #
+ smtp_tls_fallback_level =
+ dane=encrypt,
+ dane-only=encrypt,
+ fingerprint=encrypt,
+ verify=encrypt,
+ secure=encrypt
+ indexed = ${default_database_type}:${config_directory}/
+ smtp_tls_policy_maps = ${indexed}tls-policy
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/tls-policy:
+ # No fallback for example.com
+ example.com secure fallback=none
+ # For example.net tolerate cleartext fallback
+ example.net dane fallback=may
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM lmtp_tls_fallback_level
+
+<p> The LMTP-specific version of the smtp_tls_fallback_level
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM smtp_tls_audit_template
+
+<p> Optional template for tls audit logging at the completion of each
+message data transfer. If empty (the default setting) no TLS audit log
+entries are generated. </p>
+
+<p> The following $name expansions are done on smtp_tls_audit_template: </p>
+
+<dl>
+
+<dt><b>$relay</b></dt>
+<dd>The remote SMTP server <i>name</i>[<i>address</i>]:<i>port</i>.
+</dd>
+
+<dt><b>$level</b></dt>
+<dd>The effective TLS security level after any fallback. </dd>
+
+<dt><b>$policy</b></dt>
+<dd>The desired TLS security level before any fallback, undefined
+if no fallback took place. </dd>
+
+<dt><b>$auth</b></dt>
+<dd>The authentication level of the remote SMTP server. One of
+"Cleartext", "Anonymous", "Untrusted", "Trusted" or "Verified".
+</dd>
+
+<dt><b>$protocol</b></dt>
+<dd>The TLS protocol version, defined only when TLS is used. </dd>
+
+<dt><b>$cipher</b></dt>
+<dd>The TLS cipher name, defined only when TLS is used. </dd>
+
+<dt><b>$cert_digest</b></dt>
+<dd>The digest of the remote SMTP server's certificate, defined
+only when TLS is used and the remote server presented a certificate.
+The digest algorithm is that specified via smtp_tls_fingerprint_digest.
+</dd>
+
+<dt><b>$spki_digest</b></dt>
+<dd>The digest of the remote SMTP server's public key (Subject
+Public Key Info or SPKI from X.509), defined only when TLS is used
+and the remote server presented a certificate. The digest algorithm
+is that specified via smtp_tls_fingerprint_digest. </dd>
+
+<dt><b>${name?value}</b></dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd>
+
+<dt><b>${name:value}</b></dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd>
+
+</dl>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_audit_template =
+ tlsaudit: relay=${relay}${auth?, auth=${auth}}${level?, level=${level}}${policy?, policy=${policy}}${protocol?, protocol=${protocol}}${cipher?, cipher=${cipher}}
+</pre>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM lmtp_tls_audit_template
+
+<p> The LMTP-specific version of the smtp_tls_audit_template
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
msg_info("%s: Skipping lookup of '%s'", myname, name);
return (0);
}
- if (domain_rc < 0)
+ if (domain_rc < 0) {
+ msg_warn("%s:%s 'domain' pattern match failed for '%s'",
+ dict->type, dict->name, name);
DICT_ERR_VAL_RETURN(dict, domain_rc, (char *) 0);
-
+ }
#define INIT_VSTR(buf, len) do { \
if (buf == 0) \
buf = vstring_alloc(len); \
#define DEF_LMTP_TLS_LEVEL ""
extern char *var_smtp_tls_level;
+#define VAR_SMTP_TLS_FBACK_LEVEL "smtp_tls_fallback_level"
+#define DEF_SMTP_TLS_FBACK_LEVEL ""
+#define VAR_LMTP_TLS_FBACK_LEVEL "lmtp_tls_fallback_level"
+#define DEF_LMTP_TLS_FBACK_LEVEL ""
+extern char *var_smtp_tls_fback_level;
+
#define VAR_SMTP_TLS_SCERT_VD "smtp_tls_scert_verifydepth"
#define DEF_SMTP_TLS_SCERT_VD 9
#define VAR_LMTP_TLS_SCERT_VD "lmtp_tls_scert_verifydepth"
#define DEF_LMTP_TLS_FORCE_TLSA 0
extern bool var_smtp_tls_force_tlsa;
+#define VAR_SMTP_TLS_AUDIT_TEMPLATE "smtp_tls_audit_template"
+#define DEF_SMTP_TLS_AUDIT_TEMPLATE ""
+#define VAR_LMTP_TLS_AUDIT_TEMPLATE "lmtp_tls_audit_template"
+#define DEF_LMTP_TLS_AUDIT_TEMPLATE ""
+extern char *var_smtp_tls_audit_template;
+
/*
* SASL authentication support, SMTP server side.
*/
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20140801"
+#define MAIL_RELEASE_DATE "20140905"
#define MAIL_VERSION_NUMBER "2.12"
#ifdef SNAPSHOT
SRCS = smtp.c smtp_connect.c smtp_proto.c smtp_chat.c smtp_session.c \
smtp_addr.c smtp_trouble.c smtp_state.c smtp_rcpt.c smtp_tls_policy.c \
smtp_sasl_proto.c smtp_sasl_glue.c smtp_reuse.c smtp_map11.c \
- smtp_sasl_auth_cache.c smtp_key.c
+ smtp_sasl_auth_cache.c smtp_key.c smtp_tls_audit.c
OBJS = smtp.o smtp_connect.o smtp_proto.o smtp_chat.o smtp_session.o \
smtp_addr.o smtp_trouble.o smtp_state.o smtp_rcpt.o smtp_tls_policy.o \
smtp_sasl_proto.o smtp_sasl_glue.o smtp_reuse.o smtp_map11.o \
- smtp_sasl_auth_cache.o smtp_key.o
+ smtp_sasl_auth_cache.o smtp_key.o smtp_tls_audit.o
HDRS = smtp.h smtp_sasl.h smtp_addr.h smtp_reuse.h smtp_sasl_auth_cache.h
TESTSRC =
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
smtp_state.o: smtp.h
smtp_state.o: smtp_sasl.h
smtp_state.o: smtp_state.c
+smtp_tls_audit.o: ../../include/argv.h
+smtp_tls_audit.o: ../../include/attr.h
+smtp_tls_audit.o: ../../include/deliver_request.h
+smtp_tls_audit.o: ../../include/dict.h
+smtp_tls_audit.o: ../../include/dns.h
+smtp_tls_audit.o: ../../include/dsn.h
+smtp_tls_audit.o: ../../include/dsn_buf.h
+smtp_tls_audit.o: ../../include/header_body_checks.h
+smtp_tls_audit.o: ../../include/header_opts.h
+smtp_tls_audit.o: ../../include/htable.h
+smtp_tls_audit.o: ../../include/mac_expand.h
+smtp_tls_audit.o: ../../include/mac_parse.h
+smtp_tls_audit.o: ../../include/mail_params.h
+smtp_tls_audit.o: ../../include/maps.h
+smtp_tls_audit.o: ../../include/match_list.h
+smtp_tls_audit.o: ../../include/mime_state.h
+smtp_tls_audit.o: ../../include/msg.h
+smtp_tls_audit.o: ../../include/msg_stats.h
+smtp_tls_audit.o: ../../include/myaddrinfo.h
+smtp_tls_audit.o: ../../include/myflock.h
+smtp_tls_audit.o: ../../include/name_code.h
+smtp_tls_audit.o: ../../include/name_mask.h
+smtp_tls_audit.o: ../../include/recipient_list.h
+smtp_tls_audit.o: ../../include/resolve_clnt.h
+smtp_tls_audit.o: ../../include/scache.h
+smtp_tls_audit.o: ../../include/sock_addr.h
+smtp_tls_audit.o: ../../include/string_list.h
+smtp_tls_audit.o: ../../include/sys_defs.h
+smtp_tls_audit.o: ../../include/tls.h
+smtp_tls_audit.o: ../../include/tok822.h
+smtp_tls_audit.o: ../../include/vbuf.h
+smtp_tls_audit.o: ../../include/vstream.h
+smtp_tls_audit.o: ../../include/vstring.h
+smtp_tls_audit.o: smtp.h
+smtp_tls_audit.o: smtp_tls_audit.c
smtp_tls_policy.o: ../../include/argv.h
smtp_tls_policy.o: ../../include/attr.h
smtp_tls_policy.o: ../../include/ctable.h
VAR_LMTP_TLS_ECCERT_FILE, DEF_LMTP_TLS_ECCERT_FILE, &var_smtp_tls_eccert_file, 0, 0,
VAR_LMTP_TLS_ECKEY_FILE, DEF_LMTP_TLS_ECKEY_FILE, &var_smtp_tls_eckey_file, 0, 0,
VAR_LMTP_TLS_LOGLEVEL, DEF_LMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0,
+ VAR_LMTP_TLS_FBACK_LEVEL, DEF_LMTP_TLS_FBACK_LEVEL, &var_smtp_tls_fback_level, 0, 0,
#endif
VAR_LMTP_SASL_MECHS, DEF_LMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
VAR_LMTP_SASL_TYPE, DEF_LMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0,
VAR_LMTP_DUMMY_MAIL_AUTH, DEF_LMTP_DUMMY_MAIL_AUTH, &var_smtp_dummy_mail_auth,
0,
};
+
+ /* Suppress $name expansion upon loading. */
+ static const CONFIG_RAW_TABLE lmtp_raw_table[] = {
+#ifdef USE_TLS
+ VAR_LMTP_TLS_AUDIT_TEMPLATE, DEF_LMTP_TLS_AUDIT_TEMPLATE, &var_smtp_tls_audit_template, 0, 0,
+#endif
+ 0,
+ };
/* RFC 6698 trust-anchor digest support in the Postfix TLS library.
/* .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
/* The name of the \fBtlsmgr\fR(8) service entry in master.cf.
+/* .PP
+/* Available in Postfix version 2.12 and later:
+/* .IP "\fBsmtp_tls_audit_template (empty)\fR"
+/* Optional template for tls audit logging at the completion of each
+/* message data transfer.
+/* .IP "\fBsmtp_tls_fallback_level (empty)\fR"
+/* Optional fallback levels for authenticated TLS levels.
/* OBSOLETE STARTTLS CONTROLS
/* .ad
/* .fi
/* Enable experimental SMTPUTF8 support for the protocols described
/* in RFC 6531..6533.
/* .IP "\fBsmtputf8_autodetect_classes (sendmail, verify)\fR"
-/* Enable SMTPUTF8 autodetection for the specified mail origin
-/* classes.
+/* Detect that a message requires SMTPUTF8 support for the specified
+/* mail origin classes.
/* TROUBLE SHOOTING CONTROLS
/* .ad
/* .fi
char *var_smtp_tls_dcert_file;
char *var_smtp_tls_dkey_file;
bool var_smtp_tls_enforce_peername;
+char *var_smtp_tls_fback_level;
char *var_smtp_tls_key_file;
char *var_smtp_tls_loglevel;
bool var_smtp_tls_note_starttls_offer;
char *var_smtp_tls_eckey_file;
bool var_smtp_tls_blk_early_mail_reply;
bool var_smtp_tls_force_tlsa;
+char *var_smtp_tls_audit_template;
#endif
smtp_int_table : lmtp_int_table,
MAIL_SERVER_STR_TABLE, smtp_mode ?
smtp_str_table : lmtp_str_table,
+ MAIL_SERVER_RAW_TABLE, smtp_mode ?
+ smtp_raw_table : lmtp_raw_table,
MAIL_SERVER_BOOL_TABLE, smtp_mode ?
smtp_bool_table : lmtp_bool_table,
MAIL_SERVER_PRE_INIT, pre_init,
typedef struct SMTP_TLS_POLICY {
int level; /* TLS enforcement level */
+ int policy_level; /* TLS desired policy level */
+ int fallback_level; /* TLS fallback level */
char *protocols; /* Acceptable SSL protocols */
char *grade; /* Cipher grade: "export", ... */
VSTRING *exclusions; /* Excluded SSL ciphers */
SMTP_TLS_POLICY *_tls_policy_dummy_tmp = (t); \
smtp_tls_policy_init(_tls_policy_dummy_tmp, (DSN_BUF *) 0); \
_tls_policy_dummy_tmp->level = TLS_LEV_NONE; \
+ _tls_policy_dummy_tmp->policy_level = TLS_LEV_NONE; \
} while (0)
/* This macro is not part of the module external interface. */
#define smtp_tls_policy_init(t, w) do { \
SMTP_TLS_POLICY *_tls_policy_init_tmp = (t); \
+ _tls_policy_init_tmp->fallback_level = TLS_LEV_NOTFOUND; \
_tls_policy_init_tmp->protocols = 0; \
_tls_policy_init_tmp->grade = 0; \
_tls_policy_init_tmp->exclusions = 0; \
char *tls_nexthop; /* Nexthop domain for cert checks */
int tls_retry_plain; /* Try plain when TLS handshake fails */
SMTP_TLS_POLICY *tls; /* TEMPORARY */
+ int tls_level; /* Actual tls level */
#endif
SMTP_STATE *state; /* back link */
#define PLAINTEXT_FALLBACK_OK_AFTER_STARTTLS_FAILURE \
(session->tls_context == 0 \
- && session->tls->level == TLS_LEV_MAY \
+ && (session->tls->level == TLS_LEV_MAY \
+ || session->tls->fallback_level == TLS_LEV_MAY) \
&& PREACTIVE_DELAY >= var_min_backoff_time \
&& !HAVE_SASL_CREDENTIALS)
#define PLAINTEXT_FALLBACK_OK_AFTER_TLS_SESSION_FAILURE \
(session->tls_context != 0 \
&& SMTP_RCPT_LEFT(state) > SMTP_RCPT_MARK_COUNT(state) \
- && session->tls->level == TLS_LEV_MAY \
+ && (session->tls->level == TLS_LEV_MAY \
+ || session->tls->fallback_level == TLS_LEV_MAY) \
&& PREACTIVE_DELAY >= var_min_backoff_time \
&& !HAVE_SASL_CREDENTIALS)
#define RETRY_AS_PLAINTEXT do { \
session->tls_retry_plain = 1; \
state->misc_flags &= ~SMTP_MISC_FLAG_FINAL_SERVER; \
+ (void) smtp_tls_trouble(state, session->tls_context ? \
+ STARTTLS_SESSION_FALLBACK : \
+ STARTTLS_HANDSHAKE_FALLBACK); \
} while (0)
+#define STARTTLS_FEATURE_FALLBACK 1 /* No STARTTLS feature */
+#define STARTTLS_COMMAND_FALLBACK 2 /* Refused STARTTLS command */
+#define STARTTLS_HANDSHAKE_FALLBACK 3 /* Handshake failed */
+#define STARTTLS_VERIFY_FALLBACK 4 /* Peer verification failed */
+#define STARTTLS_SESSION_FALLBACK 5 /* Data transfer failed */
+
/*
* smtp_chat.c
*/
const char *,...);
extern int smtp_stream_except(SMTP_STATE *, int, const char *);
+#ifdef USE_TLS
+extern int smtp_tls_trouble(SMTP_STATE *, int);
+
+#endif
+
/*
* smtp_unalias.c
*/
| COND_SASL_SMTP_KEY_FLAG_NEXTHOP | COND_SASL_SMTP_KEY_FLAG_HOSTNAME \
| SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT)
+ /*
+ * smtp_tls_audit.c
+ */
+extern void smtp_tls_audit(const char *, SMTP_SESSION *);
+
/*
* Silly little macros.
*/
#include <smtp_addr.h>
#include <smtp_reuse.h>
+ /*
+ * XXX Unclean: all TLS security level info belongs in session->tls. It
+ * should not pollute the session structure and consequently pollute
+ * internal APIs that don't need access to the session structure.
+ */
+#ifdef USE_TLS
+#define TLS_SESS_INIT(session, state) do { \
+ session->tls_level = state->tls->level; /* XXX Pre fallback */ \
+ session->tls = state->tls; /* TEMPORARY */ \
+ } while (0)
+#endif
+
/*
* Forward declaration.
*/
if ((state->session = session) != 0) {
session->state = state;
#ifdef USE_TLS
- session->tls = state->tls; /* TEMPORARY */
+ TLS_SESS_INIT(session, state); /* TEMPORARY */
session->tls_nexthop = var_myhostname; /* for TLS_LEV_SECURE */
if (session->tls->level == TLS_LEV_MAY) {
msg_warn("%s: opportunistic TLS encryption is not appropriate "
&& *addr_list == 0)
state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
#ifdef USE_TLS
- session->tls = state->tls; /* TEMPORARY */
+ TLS_SESS_INIT(session, state); /* TEMPORARY */
#endif
smtp_xfer(state);
smtp_cleanup_session(state);
&& next == 0)
state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
#ifdef USE_TLS
- session->tls = state->tls; /* TEMPORARY */
+ TLS_SESS_INIT(session, state); /* TEMPORARY */
#endif
smtp_xfer(state);
smtp_cleanup_session(state);
if ((state->session = session) != 0) {
session->state = state;
#ifdef USE_TLS
- session->tls = state->tls; /* TEMPORARY */
+ TLS_SESS_INIT(session, state); /* TEMPORARY */
/* XXX: EAI: Convert to A-label here or in TLS library */
session->tls_nexthop = domain; /* for TLS_LEV_SECURE */
#endif
VAR_SMTP_TLS_ECCERT_FILE, DEF_SMTP_TLS_ECCERT_FILE, &var_smtp_tls_eccert_file, 0, 0,
VAR_SMTP_TLS_ECKEY_FILE, DEF_SMTP_TLS_ECKEY_FILE, &var_smtp_tls_eckey_file, 0, 0,
VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0,
+ VAR_SMTP_TLS_FBACK_LEVEL, DEF_SMTP_TLS_FBACK_LEVEL, &var_smtp_tls_fback_level, 0, 0,
#endif
VAR_SMTP_SASL_MECHS, DEF_SMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
VAR_SMTP_SASL_TYPE, DEF_SMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0,
VAR_SMTP_DUMMY_MAIL_AUTH, DEF_SMTP_DUMMY_MAIL_AUTH, &var_smtp_dummy_mail_auth,
0,
};
+
+ /* Suppress $name expansion upon loading. */
+ static const CONFIG_RAW_TABLE smtp_raw_table[] = {
+#ifdef USE_TLS
+ VAR_SMTP_TLS_AUDIT_TEMPLATE, DEF_SMTP_TLS_AUDIT_TEMPLATE, &var_smtp_tls_audit_template, 0, 0,
+#endif
+ 0,
+ };
/*
* If the policy table specifies a bogus TLS security level, fail
* now.
+ *
+ * XXX: This should be caught in smtp_connect before we even make a
+ * connection to the host. Change to msg_panic()?
*/
#ifdef USE_TLS
if (session->tls->level == TLS_LEV_INVALID)
* although support for it was announced in the EHLO response.
*/
session->features &= ~SMTP_FEATURE_STARTTLS;
- if (TLS_REQUIRED(session->tls->level))
+ if (smtp_tls_trouble(state, STARTTLS_COMMAND_FALLBACK))
return (smtp_site_fail(state, STR(iter->host), resp,
"TLS is required, but host %s refused to start TLS: %s",
session->namaddr,
translit(resp->str, "\n", " ")));
/* Else try to continue in plain-text mode. */
- }
+ } else {
- /*
- * Give up if we must use TLS but can't for various reasons.
- *
- * 200412 Be sure to provide the default clause at the bottom of this
- * block. When TLS is required we must never, ever, end up in
- * plain-text mode.
- */
- if (TLS_REQUIRED(session->tls->level)) {
- if (!(session->features & SMTP_FEATURE_STARTTLS)) {
- return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
- SMTP_RESP_FAKE(&fake, "4.7.4"),
+ /*
+ * Give up if we must use TLS but can't for various reasons.
+ *
+ * 200412 Be sure to provide the default clause at the bottom of
+ * this block. When TLS is required we must never, ever, end up
+ * in plain-text mode.
+ */
+ if (smtp_tls_trouble(state, STARTTLS_FEATURE_FALLBACK)) {
+ if (!(session->features & SMTP_FEATURE_STARTTLS)) {
+ return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
+ SMTP_RESP_FAKE(&fake, "4.7.4"),
"TLS is required, but was not offered by host %s",
- session->namaddr));
- } else if (smtp_tls_ctx == 0) {
- return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
- SMTP_RESP_FAKE(&fake, "4.7.5"),
+ session->namaddr));
+ } else if (smtp_tls_ctx == 0) {
+ return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
+ SMTP_RESP_FAKE(&fake, "4.7.5"),
"TLS is required, but our TLS engine is unavailable"));
- } else {
- msg_warn("%s: TLS is required but unavailable, don't know why",
- myname);
- return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
- SMTP_RESP_FAKE(&fake, "4.7.0"),
+ } else {
+ msg_warn("%s: TLS is required but unavailable, don't know why",
+ myname);
+ return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
+ SMTP_RESP_FAKE(&fake, "4.7.0"),
"TLS is required, but unavailable"));
+ }
}
}
}
TLS_CLIENT_START_PROPS tls_props;
VSTRING *serverid;
SMTP_RESP fake;
+ int tls_level;
/*
* Turn off SMTP connection caching. When the TLS handshake succeeds, we
* resulting TLScontext. It is now up to the application to abort the TLS
* connection if it chooses.
*
+ * Consequently, the TLS library need not and does not distinguish between
+ * the "dane" and "dane-only" security levels. By the time we have TLSA
+ * records in hand, both behave identically modulo application-level
+ * fallback. We collapse these now equivalent security levels.
+ *
* XXX When tls_client_start() fails then we don't know what state the SMTP
* connection is in, so we give up on this connection even if we are not
* required to use TLS.
* Large parameter lists are error-prone, so we emulate a language feature
* that C does not have natively: named parameter lists.
*/
+ if ((tls_level = session->tls->level) == TLS_LEV_DANE_ONLY)
+ tls_level = TLS_LEV_DANE;
session->tls_context =
TLS_CLIENT_START(&tls_props,
ctx = smtp_tls_ctx,
stream = session->stream,
timeout = var_smtp_starttls_tmout,
- tls_level = session->tls->level,
+ tls_level = tls_level,
nexthop = session->tls_nexthop,
host = STR(iter->host),
namaddr = session->namaddrport,
* result, abort the delivery here. We have a usable TLS session with the
* server, so no need to disable I/O, ... we can even be polite and send
* "QUIT".
- *
- * See src/tls/tls_level.c and src/tls/tls.h. Levels above "encrypt" require
- * matching. Levels >= "dane" require CA or DNSSEC trust.
- *
- * When DANE TLSA records specify an end-entity certificate, the trust and
- * match bits always coincide, but it is fine to report the wrong
- * end-entity certificate as untrusted rather than unmatched.
*/
- if (TLS_MUST_TRUST(session->tls->level))
- if (!TLS_CERT_IS_TRUSTED(session->tls_context))
+ if (TLS_MUST_TRUST(session->tls_level)
+ && !TLS_CERT_IS_TRUSTED(session->tls_context)) {
+ if (smtp_tls_trouble(state, STARTTLS_VERIFY_FALLBACK))
return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
SMTP_RESP_FAKE(&fake, "4.7.5"),
"Server certificate not trusted"));
- if (TLS_MUST_MATCH(session->tls->level))
- if (!TLS_CERT_IS_MATCHED(session->tls_context))
+ } else if (TLS_MUST_MATCH(session->tls_level)
+ && !TLS_CERT_IS_MATCHED(session->tls_context)) {
+ /* Peer certificate not matched as it should be */
+ if (smtp_tls_trouble(state, STARTTLS_VERIFY_FALLBACK))
return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
SMTP_RESP_FAKE(&fake, "4.7.5"),
"Server certificate not verified"));
-
+ }
/* At this point there must not be any pending plaintext. */
vstream_fpurge(session->stream, VSTREAM_PURGE_BOTH);
}
/*
- * Request SMTPUTF8 when the remote SMTP server supports
- * SMTPUTF8 and the sender requested SMTPUTF8 support.
+ * Request SMTPUTF8 when the remote SMTP server supports SMTPUTF8
+ * and the sender requested SMTPUTF8 support.
*
* If the sender requested SMTPUTF8 but the remote SMTP server does
* not support SMTPUTF8, then we have already determined earlier
*/
result = smtp_loop(state, send_state, recv_state);
+ /*
+ * Optionally log the TLS session status. This provides an audit trail
+ * for both successful and failed deliveries. Failed deliveries should
+ * not escape auditing: they may in fact be successful deliveries to an
+ * impostor who steals copies of email by posing as a high-preference MX
+ * server that fakes a temporary error after end-of-data.
+ */
+#ifdef USE_TLS
+ smtp_tls_audit(request->queue_id, session);
+#endif
+
if (result == 0
/* Just in case */
&& vstream_ferror(session->stream) == 0
--- /dev/null
+/*++
+/* NAME
+/* smtp_tls_audit 3
+/* SUMMARY
+/* report effective TLS policy
+/* SYNOPSIS
+/* #include "smtp.h"
+/*
+/* smtp_tls_audit(
+/* const char *queue_id,
+/* SMTP_SESSION *session)
+/* DESCRIPTION
+/* smtp_tls_audit() logs a record with TLS session properties
+/* as specified with the smtp_tls_audit_template configuration
+/* parameter.
+/*
+/* Arguments:
+/* .IP queue_id
+/* Mail delivery transaction identifier.
+/* .IP session
+/* Client-side SMTP/TLS session state.
+/* DIAGNOSTICS
+/* Unrecognized macro name in audit template.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Viktor Dukhovni
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstring.h>
+#include <dict.h>
+#include <mac_expand.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+
+/* Application-specific. */
+
+#include "smtp.h"
+
+ /*
+ * The mini symbol table name and keys used for expanding macros in smtp tls
+ * audit log entries.
+ */
+#define TLS_AUDIT_DICT_TABLE "tls_audit_template" /* table name */
+#define TLS_AUDIT_DICT_RELAY "relay" /* key */
+#define TLS_AUDIT_DICT_ALEVEL "level" /* key */
+#define TLS_AUDIT_DICT_PLEVEL "policy"/* key */
+#define TLS_AUDIT_DICT_STATUS "auth" /* key */
+#define TLS_AUDIT_DICT_PROTOCOL "protocol" /* key */
+#define TLS_AUDIT_DICT_CIPHER "cipher"/* key */
+#define TLS_AUDIT_DICT_CERT "cert_digest" /* key */
+#define TLS_AUDIT_DICT_SPKI "spki_digest" /* key */
+
+/* audit_lookup - macro parser call-back routine */
+
+static const char *audit_lookup(const char *key, int unused_mode, char *dict)
+{
+ const char *value = dict_lookup(dict, key);
+
+ if (value == 0)
+ msg_warn("%s: unknown TLS audit template macro name: \"%s\"",
+ SMTP_X(TLS_AUDIT_TEMPLATE), key);
+ return value;
+}
+
+/* expand_template - expand macros in the audit template */
+
+static int expand_template(char *template, VSTRING *result)
+{
+
+#define NO_SCAN_FILTER ((const char *) 0)
+ return mac_expand(result, template, MAC_EXP_FLAG_NONE, NO_SCAN_FILTER,
+ audit_lookup, TLS_AUDIT_DICT_TABLE);
+}
+
+/* smtp_tls_audit - log TLS audit trail */
+
+void smtp_tls_audit(const char *queue_id, SMTP_SESSION *session)
+{
+ SMTP_TLS_POLICY *tls = session->tls;
+ TLS_SESS_STATE *TLScontext = session->tls_context;
+ const char *policy_level;
+ const char *actual_level;
+ VSTRING *result = vstring_alloc(100);
+ int status;
+
+ if (!*var_smtp_tls_audit_template)
+ return;
+
+#ifndef TLS_AUDIT_NONE_POLICY
+ /* Do we log policy "none" and cleartext status when TLS is disabled? */
+ if (tls->policy_level <= TLS_LEV_NONE)
+ return;
+#endif
+
+ dict_update(TLS_AUDIT_DICT_TABLE, TLS_AUDIT_DICT_RELAY,
+ session->namaddrport);
+
+ actual_level = str_tls_level(session->tls_level);
+ policy_level = (session->tls_level == tls->policy_level) ? "" :
+ str_tls_level(tls->policy_level);
+ dict_update(TLS_AUDIT_DICT_TABLE, TLS_AUDIT_DICT_ALEVEL,
+ actual_level ? actual_level : "");
+ dict_update(TLS_AUDIT_DICT_TABLE, TLS_AUDIT_DICT_PLEVEL,
+ policy_level ? policy_level : "");
+
+ dict_update(TLS_AUDIT_DICT_TABLE, TLS_AUDIT_DICT_STATUS,
+ TLScontext == 0 ? "Cleartext" :
+ !TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous" :
+ TLS_CERT_IS_MATCHED(TLScontext) ? "Verified" :
+ TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" :
+ "Untrusted");
+ dict_update(TLS_AUDIT_DICT_TABLE, TLS_AUDIT_DICT_PROTOCOL,
+ TLScontext == 0 ? "" : TLScontext->protocol);
+ dict_update(TLS_AUDIT_DICT_TABLE, TLS_AUDIT_DICT_CIPHER,
+ TLScontext == 0 ? "" : TLScontext->cipher_name);
+ dict_update(TLS_AUDIT_DICT_TABLE, TLS_AUDIT_DICT_CERT,
+ TLScontext == 0 ? "" : TLScontext->peer_cert_fprint);
+ dict_update(TLS_AUDIT_DICT_TABLE, TLS_AUDIT_DICT_SPKI,
+ TLScontext == 0 ? "" : TLScontext->peer_pkey_fprint);
+
+ status = expand_template(var_smtp_tls_audit_template, result);
+ if (status == 0)
+ msg_info("%s: %s", queue_id, STR(result));
+ vstring_free(result);
+}
+
+#endif /* USE_TLS */
}
#define MARK_INVALID(why, levelp) do { \
- dsb_simple((why), "4.7.5", "client TLS configuration problem"); \
+ dsb_simple((why), "4.7.0", "client TLS configuration problem"); \
*(levelp) = TLS_LEV_INVALID; } while (0)
/* tls_site_lookup - look up per-site TLS security level */
}
continue;
}
+ /* Only one instance per policy. */
+ if (!strcasecmp(name, "fallback")) {
+ int l;
+
+ if (!TLS_MUST_MATCH(*site_level)) {
+ msg_warn("%s: attribute \"%s\" invalid at security level"
+ " \"%s\"", WHERE, name, policy_name(*site_level));
+ continue;
+ }
+ if (tls->fallback_level != TLS_LEV_NOTFOUND) {
+ msg_warn("%s: attribute \"%s\" is specified multiple times",
+ WHERE, name);
+ continue;
+ }
+ if (*val == 0) {
+ msg_warn("%s: attribute \"%s\" has empty value", WHERE, name);
+ continue;
+ }
+ switch (l = tls_level_lookup(val)) {
+ case TLS_LEV_NONE:
+ case TLS_LEV_MAY:
+ case TLS_LEV_ENCRYPT:
+ tls->fallback_level = l;
+ break;
+ default:
+ msg_warn("%s: attribute \"%s\" invalid fallback level: \"%s\"",
+ WHERE, name, val);
+ break;
+ }
+ continue;
+ }
msg_warn("%s: invalid attribute name: \"%s\"", WHERE, name);
INVALID_RETURN(tls->why, site_level);
}
break;
case TLS_LEV_DANE:
+ case TLS_LEV_DANE_ONLY:
case TLS_LEV_FPRINT:
case TLS_LEV_VERIFY:
case TLS_LEV_SECURE:
ADD_EXCLUDE(tls->exclusions, also_exclude);
}
+static int global_fallback(SMTP_TLS_POLICY *tls)
+{
+ static int l = TLS_LEV_NOTFOUND;
+ const char *lname = str_tls_level(tls->level);
+ const char *err;
+ char *saved;
+ char *fback;
+ char *tok;
+ char *name;
+ char *val;
+
+ /*
+ * Silently ignore any spurious fallback setting for unauthenticated TLS.
+ */
+ if (!*var_smtp_tls_fback_level || tls->level <= TLS_LEV_ENCRYPT)
+ return l;
+
+ saved = fback = mystrdup(var_smtp_tls_fback_level);
+ while ((tok = mystrtok(&fback, "\t\n\r ,")) != 0) {
+ if ((err = split_nameval(tok, &name, &val)) != 0) {
+ msg_warn("malformed %s: \"%s\": %s", SMTP_X(TLS_FBACK_LEVEL),
+ saved, err);
+ l = TLS_LEV_NOTFOUND;
+ break;
+ }
+ if (strcmp(name, lname) == 0) {
+ switch (l = tls_level_lookup(val)) {
+ case TLS_LEV_MAY:
+ case TLS_LEV_ENCRYPT:
+ break;
+ default:
+ msg_warn("%s: bad fallback mapping: %s=%s",
+ SMTP_X(TLS_FBACK_LEVEL), name, val);
+ l = TLS_LEV_NOTFOUND;
+ break;
+ }
+ break;
+ }
+ }
+ myfree(saved);
+ return (l);
+}
+
/* policy_create - create SMTP TLS policy cache object (ctable call-back) */
static void *policy_create(const char *unused_key, void *context)
return ((void *) tls);
}
+ /*
+ * Save level as policy level (may be downgraded by early fallback, and
+ * compute fallback level if not specified per-site. If site fallback
+ * level is "none", replace with "notfound", otherwise if no site
+ * fallback level, use the global value.
+ */
+ tls->policy_level = tls->level;
+ if (tls->fallback_level == TLS_LEV_NONE)
+ tls->fallback_level = TLS_LEV_NOTFOUND;
+ else if (tls->fallback_level == TLS_LEV_NOTFOUND
+ && (tls->fallback_level = global_fallback(tls)) == TLS_LEV_INVALID)
+ tls->fallback_level = TLS_LEV_NOTFOUND;
+
/*
* DANE initialization may change the security level to something else,
* so do this early, so that we use the right level below. Note that
case TLS_LEV_MAY:
case TLS_LEV_ENCRYPT:
case TLS_LEV_DANE:
+ case TLS_LEV_DANE_ONLY:
break;
case TLS_LEV_FPRINT:
if (tls->dane == 0)
#define NONDANE_CONFIG 0 /* Administrator's fault */
#define NONDANE_DEST 1 /* Remote server's fault */
#define DANE_UNUSABLE 2 /* Remote server's fault */
+#define TLSA_LOOKUP_ERR 3 /* DNS lookup failed */
-static void PRINTFLIKE(4, 5) dane_incompat(SMTP_TLS_POLICY *tls,
- SMTP_ITERATOR *iter,
+static void PRINTFLIKE(3, 4) dane_incompat(SMTP_TLS_POLICY *tls,
int errtype,
const char *fmt,...)
{
va_list ap;
va_start(ap, fmt);
- if (tls->level == TLS_LEV_DANE) {
- tls->level = (errtype == DANE_UNUSABLE) ? TLS_LEV_ENCRYPT : TLS_LEV_MAY;
+
+ /*
+ * TLSA lookup errors are potential downgrade attacks, since they can
+ * hide the presence of usable TLSA RRs, we must fail or fallback, not
+ * downgrade to encryption-only or opportunistic TLS as with unusable or
+ * absent TLSA records.
+ */
+ if (tls->level == TLS_LEV_DANE && errtype != TLSA_LOOKUP_ERR) {
+ if (errtype == DANE_UNUSABLE) {
+
+ /*
+ * When TLSA are present, but none are usable, "dane" clients are
+ * expected to perform mandatory unauthenticated TLS. If the
+ * "dane" the fallback level is "may", we enable fallback to
+ * cleartext (with the appropriate warnings).
+ */
+ tls->level = TLS_LEV_ENCRYPT;
+ if (tls->fallback_level != TLS_LEV_MAY)
+ tls->fallback_level = TLS_LEV_NOTFOUND;
+ } else {
+ tls->level = TLS_LEV_MAY;
+ tls->fallback_level = TLS_LEV_NOTFOUND;
+ }
if (errtype == NONDANE_CONFIG)
vmsg_warn(fmt, ap);
else if (msg_verbose)
vmsg_info(fmt, ap);
- } else { /* dane-only */
- if (errtype == NONDANE_CONFIG) {
- vmsg_warn(fmt, ap);
+ } else {
+ vmsg_warn(fmt, ap);
+ if (errtype == NONDANE_CONFIG
+ || tls->fallback_level == TLS_LEV_NOTFOUND)
MARK_INVALID(tls->why, &tls->level);
- } else {
- tls->level = TLS_LEV_INVALID;
- vdsb_simple(tls->why, "4.7.5", fmt, ap);
- }
+ else
+ tls->level = tls->fallback_level;
}
va_end(ap);
}
return;
}
if (!tls_dane_avail()) {
- dane_incompat(tls, iter, NONDANE_CONFIG,
+ dane_incompat(tls, NONDANE_CONFIG,
"%s: %s configured, but no requisite library support",
STR(iter->dest), policy_name(tls->level));
return;
}
if (!(smtp_host_lookup_mask & SMTP_HOST_FLAG_DNS)
|| smtp_dns_support != SMTP_DNS_DNSSEC) {
- dane_incompat(tls, iter, NONDANE_CONFIG,
+ dane_incompat(tls, NONDANE_CONFIG,
"%s: %s configured with dnssec lookups disabled",
STR(iter->dest), policy_name(tls->level));
return;
* key material.
*/
if (smtp_mode && var_ign_mx_lookup_err) {
- dane_incompat(tls, iter, NONDANE_CONFIG,
+ dane_incompat(tls, NONDANE_CONFIG,
"%s: %s configured with MX lookup errors ignored",
STR(iter->dest), policy_name(tls->level));
return;
* to certificate name checks, ...
*/
if (smtp_dns_res_opt & (RES_DEFNAMES | RES_DNSRCH)) {
- dane_incompat(tls, iter, NONDANE_CONFIG,
+ dane_incompat(tls, NONDANE_CONFIG,
"%s: dns resolver options incompatible with %s TLS",
STR(iter->dest), policy_name(tls->level));
return;
}
/* When the MX name is present and insecure, DANE does not apply. */
if (iter->mx && !iter->mx->dnssec_valid) {
- dane_incompat(tls, iter, NONDANE_DEST, "non DNSSEC destination");
+ dane_incompat(tls, NONDANE_DEST, "%s: non-DNSSEC destination",
+ STR(iter->dest));
return;
}
- /* When TLSA lookups fail, we defer the message */
+
+ /*
+ * When TLSA lookups fail, as with dane-only, we fall back or defer the
+ * message, the level will be set to either the fallback level or
+ * "invalid".
+ */
if ((dane = tls_dane_resolve(iter->port, "tcp", iter->rr,
var_smtp_tls_force_tlsa)) == 0) {
- tls->level = TLS_LEV_INVALID;
- dsb_simple(tls->why, "4.7.5", "TLSA lookup error for %s:%u",
- STR(iter->host), ntohs(iter->port));
+ dane_incompat(tls, TLSA_LOOKUP_ERR,
+ "%s:%u: DANE TLSA lookup error",
+ STR(iter->host), ntohs(iter->port));
return;
}
if (tls_dane_notfound(dane)) {
- dane_incompat(tls, iter, NONDANE_DEST, "no TLSA records found");
+ dane_incompat(tls, NONDANE_DEST,
+ "%s:%u: no DANE TLSA records found",
+ STR(iter->host), ntohs(iter->port));
tls_dane_free(dane);
return;
}
-
- /*
- * Some TLSA records found, but none usable, per
- *
- * https://tools.ietf.org/html/draft-ietf-dane-srv-02#section-4
- *
- * we MUST use TLS, and SHALL use full PKIX certificate checks. The latter
- * would be unwise for SMTP: no human present to "click ok" and risk of
- * non-delivery in most cases exceeds risk of interception.
- *
- * We also have a form of Goedel's incompleteness theorem in play: any list
- * of public root CA certs is either incomplete or inconsistent (for any
- * given verifier some of the CAs are surely not trustworthy).
+ /*-
+ * Some TLSA records found, but none usable, per:
+ *
+ * https://tools.ietf.org/html/draft-ietf-dane-smtp-with-dane
+ *
+ * we MUST use TLS.
*/
if (tls_dane_unusable(dane)) {
- dane_incompat(tls, iter, DANE_UNUSABLE, "TLSA records unusable");
+ dane_incompat(tls, DANE_UNUSABLE,
+ "%s:%u: all DANE TLSA records unusable",
+ STR(iter->host), ntohs(iter->port));
tls_dane_free(dane);
return;
}
} else if (!TLS_DANE_HASEE(dane))
msg_panic("empty DANE match list");
tls->dane = dane;
- tls->level = TLS_LEV_DANE;
return;
}
/* SMTP_STATE *state;
/* int exception;
/* const char *description;
+/*
+/* int smtp_tls_trouble(state, protocol_stage)
+/* SMTP_STATE *state;
+/* int protocol_stage;
/* DESCRIPTION
/* This module handles all non-fatal errors that can happen while
/* attempting to deliver mail via SMTP, and implements the policy
/* The session is marked as "do not cache".
/* The result is non-zero.
/*
+/* smtp_tls_trouble() handles failure to establish a TLS connection or
+/* else failure to authenticate the peer. The protocol_stage argument
+/* indicates what TLS problem was detected. The return value is 0 when
+/* TLS is not required or a fallback strategy allows delivery to continue.
+/* When a non-zero value is returned delivery must not continue via the
+/* current SMTP server. All relevant warnings are logged.
+/*
/* Arguments:
/* .IP state
/* SMTP client state per delivery request.
*/
return (smtp_bulk_fail(state, SMTP_THROTTLE));
}
+
+#ifdef USE_TLS
+
+/* smtp_tls_trouble - Fail or fall back when TLS state is not satisfactory. */
+
+int smtp_tls_trouble(SMTP_STATE *state, int protocol_stage)
+{
+ SMTP_SESSION *session = state->session;
+ SMTP_TLS_POLICY *tls = session->tls;
+
+ /* Handle non-recoverable cases */
+ switch (protocol_stage) {
+ case STARTTLS_VERIFY_FALLBACK:
+ if (tls->fallback_level == TLS_LEV_NOTFOUND)
+ return (-1);
+ break;
+ case STARTTLS_FEATURE_FALLBACK:
+ /* No recovery when skipping STARTTLS due to local problems */
+ if (session->features & SMTP_FEATURE_STARTTLS)
+ return (-1);
+ /* FALLTHROUGH */
+ case STARTTLS_COMMAND_FALLBACK:
+ case STARTTLS_HANDSHAKE_FALLBACK:
+ case STARTTLS_SESSION_FALLBACK:
+ if (TLS_REQUIRED(session->tls_level)
+ && tls->fallback_level != TLS_LEV_MAY)
+ return (-1);
+ break;
+ default:
+ msg_panic("Unexpected TLS failure stage: %d", protocol_stage);
+ }
+
+ /* Log appropriate warning and perform fallback */
+ switch (protocol_stage) {
+ case STARTTLS_FEATURE_FALLBACK:
+ msg_warn("%s: cleartext fallback, host did not offer STARTTLS",
+ session->namaddrport);
+ break;
+
+ case STARTTLS_COMMAND_FALLBACK:
+ msg_warn("%s: cleartext fallback, host refused to start TLS",
+ session->namaddrport);
+ break;
+
+ case STARTTLS_HANDSHAKE_FALLBACK:
+ msg_warn("%s: cleartext fallback, TLS handshake failed",
+ session->namaddrport);
+ break;
+
+ case STARTTLS_SESSION_FALLBACK:
+ msg_warn("%s: cleartext fallback, post-handshake TLS failure",
+ session->namaddrport);
+ break;
+
+ case STARTTLS_VERIFY_FALLBACK:
+ msg_warn("%s: fallback to unathenticated TLS: %s",
+ session->namaddrport,
+ TLS_CERT_IS_TRUSTED(session->tls_context) ?
+ "Server certificate failed verification" :
+ "Server certificate not trusted");
+ break;
+ }
+
+ session->tls_level = tls->fallback_level;
+ return (0);
+}
+
+#endif
#define TLS_LOG_DEBUG (1<<7)
#define TLS_LOG_TLSPKTS (1<<8)
#define TLS_LOG_ALLPKTS (1<<9)
-#define TLS_LOG_SESSTKT (1<<10)
/*
* Client and Server application contexts
/* .IP MAC_EXP_FLAG_APPEND
/* Append text to the result buffer without truncating it.
/* .IP MAC_EXP_FLAG_SCAN
-/* Invoke the call-back function each macro name in the input
+/* Invoke the call-back function for each macro name in the input
/* string, including macro names in the values of conditional
/* expressions. Do not expand macros, and do not write to the
/* result argument.
else if ((mc->flags & MAC_EXP_FLAG_SCAN) == 0) {
vstring_strcat(mc->result, vstring_str(buf));
}
-
mc->level--;
return (mc->status);
VSTREAM *sasl_stream;
char *line, *cmd, *mech_name;
unsigned int major_version, minor_version;
- int fd, success;
+ int fd, success, have_mech_line;
int sec_props;
const char *path;
return (-1);
}
success = 0;
+ have_mech_line = 0;
line_str = vstring_alloc(256);
/* XXX Encapsulate for logging. */
while (vstring_get_nonl(line_str, sasl_stream) != VSTREAM_EOF) {
}
} else if (strcmp(cmd, "MECH") == 0 && line != NULL) {
mech_name = line;
+ have_mech_line = 1;
line = split_at(line, '\t');
if (line != 0) {
sec_props =
sec_props = 0;
xsasl_dovecot_server_mech_append(&xp->mechanism_list, mech_name,
sec_props);
+ } else if (strcmp(cmd, "SPID") == 0) {
+
+ /*
+ * Unfortunately the auth protocol handshake wasn't designed well
+ * to differentiate between auth-client/userdb/master.
+ * auth-userdb and auth-master send VERSION + SPID lines only and
+ * nothing afterwards, while auth-client sends VERSION + MECH +
+ * SPID + CUID + more. The simplest way that we can determine if
+ * we've connected to the correct socket is to see if MECH line
+ * exists or not (alternatively we'd have to have a small timeout
+ * after SPID to see if CUID is sent or not).
+ */
+ if (!have_mech_line) {
+ msg_warn("SASL: Connected to wrong auth socket (auth-master instead of auth-client)");
+ break;
+ }
} else if (strcmp(cmd, "DONE") == 0) {
/* Handshake finished. */
success = 1;
const char *myname = "xsasl_dovecot_server_create";
XSASL_DOVECOT_SERVER *server;
struct sockaddr_storage ss;
- struct sockaddr *sa = (struct sockaddr *) & ss;
+ struct sockaddr *sa = (struct sockaddr *) &ss;
SOCKADDR_SIZE salen;
MAI_HOSTADDR_STR server_addr;