]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.11-20130825
authorWietse Venema <wietse@porcupine.org>
Sun, 25 Aug 2013 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Mon, 26 Aug 2013 01:21:04 +0000 (21:21 -0400)
47 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/LMDB_README
postfix/README_FILES/TLS_README
postfix/html/LMDB_README.html
postfix/html/TLS_README.html
postfix/html/discard.8.html
postfix/html/lmtp.8.html
postfix/html/postconf.5.html
postfix/html/posttls-finger.1.html
postfix/html/smtp.8.html
postfix/html/smtpd.8.html
postfix/html/tlsproxy.8.html
postfix/man/man1/posttls-finger.1
postfix/man/man5/postconf.5
postfix/man/man8/discard.8
postfix/man/man8/smtp.8
postfix/man/man8/smtpd.8
postfix/man/man8/tlsproxy.8
postfix/mantools/postlink
postfix/proto/LMDB_README.html
postfix/proto/TLS_README.html
postfix/proto/postconf.proto
postfix/src/discard/discard.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/posttls-finger/posttls-finger.c
postfix/src/posttls-finger/tlsmgrmem.c
postfix/src/smtp/lmtp_params.c
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp.h
postfix/src/smtp/smtp_addr.c
postfix/src/smtp/smtp_addr.h
postfix/src/smtp/smtp_connect.c
postfix/src/smtp/smtp_params.c
postfix/src/smtp/smtp_tls_policy.c
postfix/src/smtpd/smtpd.c
postfix/src/tls/tls.h
postfix/src/tls/tls_client.c
postfix/src/tls/tls_dane.c
postfix/src/tls/tls_mgr.c
postfix/src/tls/tls_mgr.h
postfix/src/tls/tls_scache.c
postfix/src/tls/tls_scache.h
postfix/src/tls/tls_server.c
postfix/src/tlsmgr/tlsmgr.c
postfix/src/tlsproxy/tlsproxy.c

index 3d53b41ca4a4039830b7d9edb5f9f101ec41f9da..8e82ff87a8b72e8492d9925ec3ff1d1a97986ee3 100644 (file)
 -TTLS_SERVER_INIT_PROPS
 -TTLS_SERVER_START_PROPS
 -TTLS_SESS_STATE
+-TTLS_TICKET_KEY
 -TTLS_TLSA
 -TTLS_VINFO
 -TTLScontext_t
index 347b75ba15cc3a4cfaecf66e32977b92bf920dcf..187107bd414b74630d5632cf75de98c8889c3de4 100644 (file)
@@ -18839,3 +18839,76 @@ Apologies for any names omitted.
        new MDB_MAP_FULL workaround by Howard Chu that ensures that
        postfix will make progress as long as the disk is not full.
        File: util/dict_lmdb.c.
+
+20130822
+
+       The status of LMDB databases is "not recommended".  Unlike
+       other Postfix databases, LMDB does not grow beyond a specified
+       limit even when the file system has room.  This show-stopper
+       bug breaks applications whose requirements grow with load:
+       postscreen(8), greylisting, tlsmgr(8) and verify(8).
+
+20130825
+
+       Bitrot: Arrange for shared keys in SMTP server session
+       tickets.  Otherwise, with clients that enable session
+       tickets, the SMTP session cache is per-process and largely
+       ineffective.  Older releases should add SSL_OP_NO_TICKET
+       to the SSL options bit mask in the SMTP server only.  The
+       session ticket key validity interval (sum of initial issuing
+       and retired key validation intervals) must not exceed the
+       SSL session lifetime.  Otherwise, clients may send valid
+       tickets for expired sessions, which the OpenSSL server code
+       mishandles (does not send a replacement ticket, patch
+       pending...).
+
+       We set the session lifetime to 2 times the configured cache
+       lifetime which is also the ticket issuing and retired
+       validation lifetime, so ticketed sessions last 1 to 2 times
+       the configured session lifetime and never longer than a
+       session's expiration time. 
+
+       Code by Viktor Dukhovni.  Files: .indent.pro, mantools/postlink,
+       proto/TLS_README.html, proto/postconf.proto, global/mail_params.h,
+       posttls-finger/posttls-finger.c, posttls-finger/tlsmgrmem.c,
+       smtpd/smtpd.c, tls/tls.h, tls/tls_client.c, tls/tls_mgr.c,
+       tls/tls_mgr.h, tls/tls_scache.c, tls/tls_scache.h,
+       tls/tls_server.c, tlsmgr/tlsmgr.c, tlsproxy/tlsproxy.c.
+
+       Robustness: Search for TLSA RRs at the resolved server name
+       (rname) and failing that request server name (qname), and
+       use whichever was found as the TLSA base domain for certificate
+       matching.
+
+       When we find a DNSSEC validated MX RRset, and the initial
+       next-hop domain is a CNAME, include both the initial and
+       final (the one with the actual MX RRs) domains in the list
+       of valid server certificate names.
+
+       When we find no MX records, then the initial next-hop domain
+       is obtained securely from the recipient domain or transport
+       next-hop.  Without MX records, this is a destination hostname,
+       so we should generally do a TLSA lookup.  If however the
+       address lookup yields an insecure result, and its rname is
+       equal to its qname (no CNAMEs), we reasonably assume that
+       the its child "_port._tcp" sub-domain is likewise insecure
+       (security here would require DLV just for this sub-domain).
+       This allows us to skip futile TLSA queries for most non-MX
+       destinations (those that are in insecure zones and are not
+       CNAMEs).  This heuristic can be disabled by setting the new
+       main.cf parameter smtp_tls_force_insecure_host_tlsa_lookup
+       to "yes", the default is "no".
+
+       Finally, with MX hostnames, if the MX RRset is secure, we
+       look for TLSA RRs at the qname only when the MX host is an
+       alias with an insecure rname.  If both the qname and the
+       rname are secure, as before we prefer the rname, but when
+       nothing is found there, fall back to the qname.
+
+       Code by Viktor Dukhovni. Files: mantools/postlink,
+       proto/postconf.proto, src/global/mail_params.h,
+       src/posttls-finger/posttls-finger.c, src/smtp/lmtp_params.c,
+       src/smtp/smtp.c, src/smtp/smtp.h, src/smtp/smtp_addr.c,
+       src/smtp/smtp_addr.h, src/smtp/smtp_connect.c,
+       src/smtp/smtp_params.c, src/smtp/smtp_tls_policy.c,
+       src/tls/tls.h, src/tls/tls_dane.c.
index 4d028148179caa45aabebf69c5965f28111be5a1..fa7e80eb1c515d0d8d34007bb9ac38971a542705 100644 (file)
@@ -4,6 +4,14 @@ P\bPo\bos\bst\btf\bfi\bix\bx O\bOp\bpe\ben\bnL\bLD\bDA\bAP\bP L\bLM\bMD\bDB\bB H\bHo\bow\bwt\bto\bo
 
 I\bIn\bnt\btr\bro\bod\bdu\buc\bct\bti\bio\bon\bn
 
+    W\bWa\bar\brn\bni\bin\bng\bg:\b: L\bLM\bMD\bDB\bB d\bda\bat\bta\bab\bba\bas\bse\bes\bs h\bha\bav\bve\be a\ba s\bsh\bho\bow\bw-\b-s\bst\bto\bop\bpp\bpe\ber\br b\bbu\bug\bg:\b: t\bth\bhe\bey\by d\bdo\bo n\bno\bot\bt g\bgr\bro\bow\bw b\bbe\bey\byo\bon\bnd\bd a\ba
+    s\bsp\bpe\bec\bci\bif\bfi\bie\bed\bd l\bli\bim\bmi\bit\bt,\b, a\ban\bnd\bd i\bin\bnt\btr\bro\bod\bdu\buc\bce\be a\ba "\b"d\bda\bat\bta\bab\bba\bas\bse\be f\bfu\bul\bll\bl"\b" h\bha\bar\brd\bd e\ber\brr\bro\bor\br c\bco\bon\bnd\bdi\bit\bti\bio\bon\bn t\bth\bha\bat\bt
+    d\bdo\boe\bes\bs n\bno\bot\bt e\bex\bxi\bis\bst\bt w\bwi\bit\bth\bh a\ban\bny\by o\bot\bth\bhe\ber\br P\bPo\bos\bst\btf\bfi\bix\bx d\bda\bat\bta\bab\bba\bas\bse\be t\bty\byp\bpe\be.\b. T\bTh\bhi\bis\bs i\bis\bs a\ba p\bpr\bro\bob\bbl\ble\bem\bm f\bfo\bor\br
+    p\bpr\bro\bog\bgr\bra\bam\bms\bs w\bwh\bho\bos\bse\be d\bda\bat\bta\bab\bba\bas\bse\be g\bgr\bro\bow\bws\bs w\bwi\bit\bth\bh s\bsy\bys\bst\bte\bem\bm l\blo\boa\bad\bd.\b. E\bEx\bxa\bam\bmp\bpl\ble\bes\bs a\bar\bre\be p\bpo\bos\bst\bts\bsc\bcr\bre\bee\ben\bn(\b(8\b8)\b),\b,
+    g\bgr\bre\bey\byl\bli\bis\bst\bti\bin\bng\bg,\b, v\bve\ber\bri\bif\bfy\by(\b(8\b8)\b) a\ban\bnd\bd t\btl\bls\bsm\bmg\bgr\br(\b(8\b8)\b).\b.
+
+    Y\bYo\bou\bu h\bha\bav\bve\be b\bbe\bee\ben\bn w\bwa\bar\brn\bne\bed\bd.\b.
+
 Postfix uses databases of various kinds to store and look up information.
 Postfix databases are specified as "type:name". OpenLDAP LMDB implements the
 Postfix database type "lmdb". The name of a Postfix OpenLDAP LMDB database is
index 6ec9312148d0cd785829c5f03925c33e3f167443..697d614abe0e5b685facc4674006e0da79da1fcb 100644 (file)
@@ -410,16 +410,40 @@ Example:
 S\bSe\ber\brv\bve\ber\br-\b-s\bsi\bid\bde\be T\bTL\bLS\bS s\bse\bes\bss\bsi\bio\bon\bn c\bca\bac\bch\bhe\be
 
 The Postfix SMTP server and the remote SMTP client negotiate a session, which
-takes some computer time and network bandwidth. By default, this session
-information is cached only in the smtpd(8) process actually using this session
-and is lost when the process terminates. To share the session information
-between multiple smtpd(8) processes, a persistent session cache can be used.
-You can specify any database type that can store objects of several kbytes and
-that supports the sequence operator. DBM databases are not suitable because
-they can only store small objects. The cache is maintained by the tlsmgr(8)
-process, so there is no problem with concurrent access. Session caching is
-highly recommended, because the cost of repeatedly negotiating TLS session keys
-is high.
+takes some computer time and network bandwidth. SSL protocol versions other
+than SSLv2 support resumption of cached sessions. Not only is this more CPU and
+bandwidth efficient, it also reduces latency as only one network round-trip is
+used to resume a session while it takes two round-trips to create a session
+from scratch.
+
+Since Postfix uses multiple smtpd(8) service processes, an in-memory cache is
+not sufficient for session re-use. Clients store at most one cached session per
+server and are very unlikey to repeatedly connect to the same server process.
+Thus session caching in the Postfix SMTP server generally requires a shared
+cache (an alternative available with Postfix >= 2.11 is described below).
+
+To share the session information between multiple smtpd(8) processes, a session
+cache database is used. You can specify any database type that can store
+objects of several kbytes and that supports the sequence operator. DBM
+databases are not suitable because they can only store small objects. The cache
+is maintained by the tlsmgr(8) process, so there is no problem with concurrent
+access. Session caching is highly recommended, because the cost of repeatedly
+negotiating TLS session keys is high.
+
+Starting with Postfix 2.11, linked with a compatible OpenSSL library (at least
+0.9.8h, preferably 1.0.0 or later) the Postfix SMTP server supports RFC 5077
+TLS session resumption without server-side state when the remote SMTP client
+also supports RFC 5077. The session is encrypted by the server in a session
+ticket returned to client for storage. When a client sends a valid session
+ticket, the server decrypts it and resumes the session, provided neither the
+ticket nor the session have expired. This makes it possible to resume cached
+sessions without allocating space for a shared database on the server. This
+feature can be disabled by setting the session cache timeout to zero, otherwise
+the timeout must be at least 2 minutes and at most 100 days.
+
+Note, session tickets can only be negotiated if the client disables SSLv2 and
+does not use the legacy SSLv2 compatible HELLO message. This is true by default
+with the Postfix >= 2.6 SMTP client.
 
 Example:
 
@@ -441,11 +465,15 @@ Example:
     /etc/postfix/main.cf:
         smtpd_tls_session_cache_timeout = 3600s
 
+As of Postfix 2.11 this setting cannot exceed 100 days. If set <= 0, session
+caching is disabled. If set to a positive value less than 2 minutes, the
+minimum value of 2 minutes is used instead.
+
 When the Postfix SMTP server does not save TLS sessions to an external cache
-database, client-side session caching is unlikely to be useful. To prevent such
-wastage, the Postfix SMTP server can be configured to not issue TLS session
-ids. By default the Postfix SMTP server always issues TLS session ids. This
-works around known interoperability issues with some MUAs, and prevents
+database, client-side session caching is unlikely to be useful. To reduce waste
+of client resources, the Postfix SMTP server can be configured to not issue TLS
+session ids. By default the Postfix SMTP server always issues TLS session ids.
+This works around known interoperability issues with some MUAs, and prevents
 possible interoperability issues with other MTAs.
 
 Example:
@@ -1486,6 +1514,10 @@ Example:
     /etc/postfix/main.cf:
         smtp_tls_session_cache_timeout = 3600s
 
+As of Postfix 2.11 this setting cannot exceed 100 days. If set <= 0, session
+caching is disabled. If set to a positive value less than 2 minutes, the
+minimum value of 2 minutes is used instead.
+
 C\bCl\bli\bie\ben\bnt\bt T\bTL\bLS\bS l\bli\bim\bmi\bit\bta\bat\bti\bio\bon\bns\bs
 
 The security properties of TLS communication channels are application specific.
index e9938aa53bc6b76da2a5bf1496c91954af7dde83..81d1484dba2bb26dcb39cf9f9a294e7947e11c5e 100644 (file)
 
 <h2>Introduction</h2>
 
-<!--
-
-<dl> <dt> Note: </dt> <dd> <p> Postfix support for LMDB databases
-is suspended due to the existence of a hard limit (an "out of
-storage" failure mode that cannot be resolved by increasing the
-database size). </p> <p> Postfix may support LMDB again when it no
-longer limits the size of Postfix transactions, whether the limit
-is built into LMDB itself, or implicit by requiring an unbounded
-amount of memory to handle a large transaction. </p> </dd> </dl>
-
--->
+<blockquote> <p> <strong> Warning: LMDB databases have a show-stopper
+bug: they do not grow beyond a specified limit, and introduce a
+"database full" hard error condition that does not exist with any
+other Postfix database type.  This is a problem for programs whose
+database grows with system load. Examples are <a href="postscreen.8.html">postscreen(8)</a>,
+greylisting, <a href="verify.8.html">verify(8)</a> and <a href="tlsmgr.8.html">tlsmgr(8)</a>.  </strong> </p> <p> <strong>
+You have been warned.  </strong> </p> </blockquote>
 
 <p> Postfix uses databases of various kinds to store and look up
 information. Postfix databases are specified as "type:name".
index c89e203dbbf6504b04c43f6fbe05a1043423a06a..c460a195a9fd5f3c75a96c447a97fa173fb01561 100644 (file)
@@ -604,23 +604,20 @@ In order to change this behavior, set
 
 <h3><a name="server_tls_cache">Server-side TLS session cache</a> </h3>
 
-<p> The Postfix SMTP server and the remote SMTP client negotiate
-a session, which takes some computer time and network bandwidth.
-SSLv3, TLSv1 and later support resumption of cached sessions.  Not
-is this more CPU and bandwidth efficient, it also reduces latency
-as it uses only one network round-trip instead of two.  </p>
-
-<p> Since Postfix uses multiple <a href="smtpd.8.html">smtpd(8)</a> service processes, an in
-memory cache is not sufficient for session re-use.  Clients store
+<p> The Postfix SMTP server and the remote SMTP client negotiate a
+session, which takes some computer time and network bandwidth.  SSL
+protocol versions other than SSLv2 support resumption of cached
+sessions.  Not only is this more CPU and bandwidth efficient, it
+also reduces latency as only one network round-trip is used to
+resume a session while it takes two round-trips to create a session
+from scratch.  </p>
+
+<p> Since Postfix uses multiple <a href="smtpd.8.html">smtpd(8)</a> service processes, an
+in-memory cache is not sufficient for session re-use.  Clients store
 at most one cached session per server and are very unlikey to
-repeatedly connect to the same server process.  With a per-process
-server cache, when a client attempts to reuse a session with a
-different process than the one that created it, a new session is
-negotiated and the old forgotten.  Returning to the original server
-process later (except with back to back connections) does not help,
-as that session has most probably been replaced.  Thus session
-caching in the Postfix SMTP server generally requires a shared cache
-(an alternative available with Postfix &ge; 2.11 is described below).
+repeatedly connect to the same server process.  Thus session caching
+in the Postfix SMTP server generally requires a shared cache (an
+alternative available with Postfix &ge; 2.11 is described below).
 </p>
 
 <p> To share the session information between multiple
@@ -633,7 +630,7 @@ concurrent access. Session caching is highly recommended, because
 the cost of repeatedly negotiating TLS session keys is high.</p>
 
 <p> Starting with Postfix 2.11, linked with a compatible OpenSSL
-library (at least 0.9.8h, preferrably 1.0.0 or later) the Postfix
+library (at least 0.9.8h, preferably 1.0.0 or later) the Postfix
 SMTP server supports <a href="http://tools.ietf.org/html/rfc5077">RFC 5077</a> TLS session resumption without
 server-side state when the remote SMTP client also supports <a href="http://tools.ietf.org/html/rfc5077">RFC</a>
 <a href="http://tools.ietf.org/html/rfc5077">5077</a>.  The session is encrypted by the server in a <i>session
@@ -679,6 +676,10 @@ recommends a maximum of 24 hours.  </p>
 </pre>
 </blockquote>
 
+<p> As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+&le; 0, session caching is disabled.  If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead.  </p>
+
 <p> When the Postfix SMTP server does not save TLS sessions to an
 external cache database, client-side session caching is unlikely
 to be useful.  To reduce waste of client resources, the Postfix SMTP server can
@@ -2013,6 +2014,10 @@ recommends a maximum of 24 hours.  </p>
 </pre>
 </blockquote>
 
+<p> As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+&le; 0, session caching is disabled.  If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead.  </p>
+
 <h3><a name="client_tls_limits"> Client TLS limitations </a>
 </h3>
 
index 48c249598df8b0085405c5b7b3b770ac84274fd2..e4b7a15fe9f6af103f41d643c3033a20fee8eee9 100644 (file)
@@ -37,7 +37,7 @@ DISCARD(8)                                                          DISCARD(8)
        low privilege.
 
 <b>STANDARDS</b>
-       None.
+       <a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a> (Enhanced Status Codes)
 
 <b>DIAGNOSTICS</b>
        Problems and transactions are logged to <b>syslogd</b>(8).
index 3b8ba36b6c7ea977486c9e982d01ce4b91e23fd4..4ef7b501f96287ccb7d3303357643d0ba58961c8 100644 (file)
@@ -593,15 +593,10 @@ SMTP(8)                                                                SMTP(8)
               Zero  or  more  PEM-format  files with trust-anchor
               certificates and/or public keys.
 
-       <b>smtp_tls_dane_notfound_tlsa_level (may)</b>
-              The "degraded" security level when the "dane" secu-
-              rity level is specified, but no validated DANE TLSA
-              records are published.
-
-       <b>smtp_tls_dane_unusable_tlsa_level (encrypt)</b>
-              The "degraded" security level when the "dane" secu-
-              rity   level  is  specified,  validated  DANE  TLSA
-              records are present, but none are usable.
+       <b><a href="postconf.5.html#smtp_tls_force_insecure_host_tlsa_lookup">smtp_tls_force_insecure_host_tlsa_lookup</a> (no)</b>
+              Lookup the associated DANE TLSA RRset even  when  a
+              hostname  is  not  an alias and its address records
+              lie in an unsigned zone.
 
        <b><a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a>   (trust-anchor-asser-</b>
        <b>tion)</b>
index 8d83dea6a050089a1dc2388916fe0a65a9194e95..a173c855746c2b101fb679ae94fa9f02362d0974 100644 (file)
@@ -4824,6 +4824,17 @@ configuration parameter.  See there for details. </p>
 <p> This feature is available in Postfix 2.5 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_tls_force_insecure_host_tlsa_lookup">lmtp_tls_force_insecure_host_tlsa_lookup</a>
+(default: no)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_force_insecure_host_tlsa_lookup">smtp_tls_force_insecure_host_tlsa_lookup</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_tls_key_file">lmtp_tls_key_file</a>
@@ -11291,6 +11302,24 @@ to Postfix 2.9.6 or later. </p>
 <p> This feature is available in Postfix 2.5 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="smtp_tls_force_insecure_host_tlsa_lookup">smtp_tls_force_insecure_host_tlsa_lookup</a>
+(default: no)</b></DT><DD>
+
+<p> Lookup the associated DANE TLSA RRset even when a hostname is
+not an alias and its address records lie in an unsigned zone.  This
+is unlikely to ever yield DNSSEC validated results, since child
+zones of unsigned zones are also unsigned in the absense of DLV or
+locally configured non-root trust-anchors.  We anticipate that such
+mechanisms will not be used for just the "_tcp" subdomain of a host.
+Suppressing the TLSA RRset lookup reduces latency and avoids potential
+interoperability problems with nameservers for unsigned zones that
+are not prepared to handle the new TLSA RRset.  </p>
+
+<p> This feature is available in Postfix 2.11. </p>
+
+
 </DD>
 
 <DT><b><a name="smtp_tls_key_file">smtp_tls_key_file</a>
@@ -12081,6 +12110,10 @@ $<a href="postconf.5.html#smtp_tls_session_cache_database">smtp_tls_session_cach
 <a href="tlsmgr.8.html">tlsmgr(8)</a> daemon and therefore per-smtp-instance <a href="master.5.html">master.cf</a> overrides
 are not possible. </p>
 
+<p> As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+&le; 0, session caching is disabled.  If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead.  </p>
+
 <p> This feature is available in Postfix 2.2 and later.  </p>
 
 
@@ -15759,7 +15792,16 @@ $<a href="postconf.5.html#smtpd_tls_session_cache_database">smtpd_tls_session_ca
 <a href="tlsmgr.8.html">tlsmgr(8)</a> daemon and therefore per-smtpd-instance <a href="master.5.html">master.cf</a> overrides
 are not possible. </p>
 
-<p> This feature is available in Postfix 2.2 and later.  </p>
+<p> As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+&le; 0, session caching is disabled, not just via the database, but
+also via <a href="http://tools.ietf.org/html/rfc5077">RFC 5077</a> TLS session tickets, which don't require server-side
+storage.  If set to a positive value less than 2 minutes, the minimum
+value of 2 minutes is used instead.  TLS session tickets require
+an OpenSSL library (at least version 0.9.8h) that provides full
+support for this TLS extension. </p>
+
+<p> This feature is available in Postfix 2.2 and later, and updated
+for TLS session ticket support in Postfix 2.11. </p>
 
 
 </DD>
@@ -16983,10 +17025,10 @@ parameters <a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a> and <a href
 <DT><b><a name="tlsproxy_tls_session_cache_timeout">tlsproxy_tls_session_cache_timeout</a>
 (default: $<a href="postconf.5.html#smtpd_tls_session_cache_timeout">smtpd_tls_session_cache_timeout</a>)</b></DT><DD>
 
-<p> The expiration time of Postfix <a href="tlsproxy.8.html">tlsproxy(8)</a> server TLS session
-cache information. A cache cleanup is performed periodically every
-$<a href="postconf.5.html#smtpd_tls_session_cache_timeout">smtpd_tls_session_cache_timeout</a> seconds. See
-<a href="postconf.5.html#smtpd_tls_session_cache_timeout">smtpd_tls_session_cache_timeout</a> for further details. </p>
+<p> Obsolete expiration time of Postfix <a href="tlsproxy.8.html">tlsproxy(8)</a> server TLS session
+cache information. Since the cache is shared with <a href="smtpd.8.html">smtpd(8)</a> and managed
+by <a href="tlsmgr.8.html">tlsmgr(8)</a>, there is only one expiration time for the SMTP server cache
+shared by all three services, namely <a href="postconf.5.html#smtpd_tls_session_cache_timeout">smtpd_tls_session_cache_timeout</a>. </p>
 
 <p> This feature is available in Postfix 2.8 and later. </p>
 
index 81705a895dd566739dc3ba7f94c1b2815897c9bd..3e449ec61a24333a2f2c610c5bf030254e30feed 100644 (file)
@@ -126,55 +126,60 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
               (with DANE TLSA records the algorithm is  specified
               in the DNS).
 
+       <b>-f</b>     Lookup  the  associated DANE TLSA RRset even when a
+              hostname is not an alias and  its  address  records
+              lie  in an unsigned zone.  See smtp_tls_force_inse-
+              cure_host_tlsa_lookup for details.
+
        <b>-F</b> <i>CAfile.pem</i> (default: none)
-              The  PEM  formatted  CAfile  for remote SMTP server
-              certificate verification.  By default no CAfile  is
+              The PEM formatted CAfile  for  remote  SMTP  server
+              certificate  verification.  By default no CAfile is
               used and no public CAs are trusted.
 
        <b>-g</b> <i>grade</i> (default: medium)
-              The  minimum  TLS cipher grade used by posttls-fin-
+              The minimum TLS cipher grade used  by  posttls-fin-
               ger.  See <a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> for details.
 
        <b>-h</b> <i>host</i><b>_</b><i>lookup</i> (default: <b>dns</b>)
-              The hostname lookup methods used  for  the  connec-
-              tion.   See  the  documentation of <a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a>
+              The  hostname  lookup  methods used for the connec-
+              tion.  See the  documentation  of  <a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a>
               for syntax and semantics.
 
        <b>-l</b> <i>level</i> (default: <b>dane</b> or <b>secure</b>)
               The security level for the connection, default <b>dane</b>
               or <b>secure</b> depending on whether DNSSEC is available.
-              For syntax and semantics, see the documentation  of
+              For  syntax and semantics, see the documentation of
               <a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a>.  When <b>dane</b> or <b>dane-only</b> is
-              supported and selected,  if  no  TLSA  records  are
-              found,  or  all the records found are unusable, the
+              supported  and  selected,  if  no  TLSA records are
+              found, or all the records found are  unusable,  the
               <i>secure</i> level will be used instead.  The <b>fingerprint</b>
-              security  level  allows  you to test certificate or
-              public-key fingerprint matches  before  you  deploy
+              security level allows you to  test  certificate  or
+              public-key  fingerprint  matches  before you deploy
               them in the policy table.
 
-              Note,   since   <b>posttls-finger</b>  does  not  actually
-              deliver any email, the <b>none</b>, <b>may</b> and <b>encrypt</b>  secu-
-              rity  levels  are  not  very useful.  Since <b>may</b> and
-              <b>encrypt</b> don't require peer certificates, they  will
-              often  negotiate anonymous TLS ciphersuites, so you
-              won't learn much about  the  remote  SMTP  server's
-              certificates  at  these  levels if it also supports
+              Note,  since  <b>posttls-finger</b>  does   not   actually
+              deliver  any email, the <b>none</b>, <b>may</b> and <b>encrypt</b> secu-
+              rity levels are not very  useful.   Since  <b>may</b>  and
+              <b>encrypt</b>  don't require peer certificates, they will
+              often negotiate anonymous TLS ciphersuites, so  you
+              won't  learn  much  about  the remote SMTP server's
+              certificates at these levels if  it  also  supports
               anonymous TLS (though you may learn that the server
               supports anonymous TLS).
 
        <b>-L</b> <i>logopts</i> (default: <b>routine,certmatch</b>)
-              Fine-grained  TLS  logging options. To tune the TLS
-              features logged during the TLS  handshake,  specify
+              Fine-grained TLS logging options. To tune  the  TLS
+              features  logged  during the TLS handshake, specify
               one or more of:
 
               <b>0, none</b>
                      These yield no TLS logging; you'll generally
-                     want more, but this is  handy  if  you  just
+                     want  more,  but  this  is handy if you just
                      want the trust chain:
                      $ posttls-finger -cC -L none destination
 
               <b>1, routine, summary</b>
-                     These  synonymous values yield a normal one-
+                     These synonymous values yield a normal  one-
                      line summary of the TLS connection.
 
               <b>2, debug</b>
@@ -182,129 +187,129 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
                      ssl-debug, cache and verbose.
 
               <b>3, ssl-expert</b>
-                     These  synonymous  values combine debug with
-                     ssl-handshake-packet-dump.    For    experts
+                     These synonymous values combine  debug  with
+                     ssl-handshake-packet-dump.     For   experts
                      only.
 
               <b>4, ssl-developer</b>
-                     These  synonymous  values combine ssl-expert
-                     with ssl-session-packet-dump.   For  experts
+                     These synonymous values  combine  ssl-expert
+                     with  ssl-session-packet-dump.   For experts
                      only,  and  in  most  cases,  use  wireshark
                      instead.
 
               <b>ssl-debug</b>
-                     Turn on OpenSSL logging of the  progress  of
+                     Turn  on  OpenSSL logging of the progress of
                      the SSL handshake.
 
               <b>ssl-handshake-packet-dump</b>
-                     Log  hexadecimal  packet  dumps  of  the SSL
+                     Log hexadecimal  packet  dumps  of  the  SSL
                      handshake; for experts only.
 
               <b>ssl-session-packet-dump</b>
-                     Log hexadecimal packet dumps of  the  entire
-                     SSL  session;  only  useful to those who can
-                     debug SSL protocol problems from hex  dumps.
+                     Log  hexadecimal  packet dumps of the entire
+                     SSL session; only useful to  those  who  can
+                     debug  SSL protocol problems from hex dumps.
 
               <b>untrusted</b>
-                     Logs   trust  chain  verification  problems.
-                     This is turned on automatically at  security
-                     levels  that  use  peer names signed by cer-
-                     tificate authorities  to  validate  certifi-
+                     Logs  trust  chain  verification   problems.
+                     This  is turned on automatically at security
+                     levels that use peer names  signed  by  cer-
+                     tificate  authorities  to  validate certifi-
                      cates.  So while this setting is recognized,
-                     you should never need to set it  explicitly.
+                     you  should never need to set it explicitly.
 
               <b>peercert</b>
-                     This  logs  a one line summary of the remote
+                     This logs a one line summary of  the  remote
                      SMTP server certificate subject, issuer, and
                      fingerprints.
 
               <b>certmatch</b>
-                     This  logs  remote  SMTP  server certificate
-                     matching, showing the CN  and  each  subjec-
+                     This logs  remote  SMTP  server  certificate
+                     matching,  showing  the  CN and each subjec-
                      tAltName and which name matched.  With DANE,
-                     logs matching of  TLSA  record  trust-anchor
+                     logs  matching  of  TLSA record trust-anchor
                      and end-entity certificates.
 
-              <b>cache</b>  This  logs session cache operations, showing
-                     whether session caching  is  effective  with
-                     the  remote SMTP server.  Automatically used
+              <b>cache</b>  This logs session cache operations,  showing
+                     whether  session  caching  is effective with
+                     the remote SMTP server.  Automatically  used
                      when reconnecting with the <b>-r</b> option; rarely
                      needs to be set explicitly.
 
               <b>verbose</b>
-                     Enables  verbose  logging in the Postfix TLS
-                     driver; includes all of peercert..cache  and
+                     Enables verbose logging in the  Postfix  TLS
+                     driver;  includes all of peercert..cache and
                      more.
 
-              The  default  is  <b>routine,certmatch</b>. After a recon-
+              The default is <b>routine,certmatch</b>.  After  a  recon-
               nect, <b>peercert</b>, <b>certmatch</b> and <b>verbose</b> are automati-
               cally disabled while <b>cache</b> and <b>summary</b> are enabled.
 
        <b>-m</b> <i>count</i> (default: <b>5</b>)
-              When the <b>-r</b>  <i>delay</i>  option  is  specified,  the  <b>-m</b>
-              option  determines  the maximum number of reconnect
-              attempts to use with a server  behind  a  load-bal-
-              acer,  to  see whether connection caching is likely
-              to be effective for this  destination.   Some  MTAs
-              don't  expose  the  underlying  server  identity in
-              their EHLO response; with these servers there  will
+              When  the  <b>-r</b>  <i>delay</i>  option  is  specified, the <b>-m</b>
+              option determines the maximum number  of  reconnect
+              attempts  to  use  with a server behind a load-bal-
+              acer, to see whether connection caching  is  likely
+              to  be  effective  for this destination.  Some MTAs
+              don't expose  the  underlying  server  identity  in
+              their  EHLO response; with these servers there will
               never be more than 1 reconnection attempt.
 
        <b>-o</b> <i>name=value</i>
               Specify zero or more times to override the value of
-              the <a href="postconf.5.html">main.cf</a> parameter <i>name</i>  with  <i>value</i>.   Possible
-              use-cases  include  overriding  the  values  of TLS
-              library parameters, or  "<a href="postconf.5.html#myhostname">myhostname</a>"  to  configure
+              the  <a href="postconf.5.html">main.cf</a>  parameter  <i>name</i> with <i>value</i>.  Possible
+              use-cases include  overriding  the  values  of  TLS
+              library  parameters,  or  "<a href="postconf.5.html#myhostname">myhostname</a>" to configure
               the SMTP EHLO name sent to the remote server.
 
        <b>-p</b> <i>protocols</i> (default: !SSLv2)
-              List  of  TLS  protocols  that  posttls-finger will
-              exclude or include.  See  smtp_tls_mandatory_proto-
+              List of  TLS  protocols  that  posttls-finger  will
+              exclude  or include.  See smtp_tls_mandatory_proto-
               cols for details.
 
        <b>-P</b> <i>CApath/</i> (default: none)
-              The   OpenSSL   CApath/   directory   (indexed  via
-              c_rehash(1)) for  remote  SMTP  server  certificate
-              verification.   By default no CApath is used and no
+              The  OpenSSL   CApath/   directory   (indexed   via
+              c_rehash(1))  for  remote  SMTP  server certificate
+              verification.  By default no CApath is used and  no
               public CAs are trusted.
 
        <b>-r</b> <i>delay</i>
-              With a cachable TLS session, disconnect and  recon-
-              nect  after  <i>delay</i> seconds. Report whether the ses-
-              sion is re-used. Retry if a new server  is  encoun-
-              tered,  up  to  5 times or as specified with the <b>-m</b>
+              With  a cachable TLS session, disconnect and recon-
+              nect after <i>delay</i> seconds. Report whether  the  ses-
+              sion  is  re-used. Retry if a new server is encoun-
+              tered, up to 5 times or as specified  with  the  <b>-m</b>
               option.  By default reconnection is disabled, spec-
               ify a positive delay to enable this behavior.
 
-       <b>-S</b>     Disable  SMTP;  that is, connect to an LMTP server.
+       <b>-S</b>     Disable SMTP; that is, connect to an  LMTP  server.
               The default port for LMTP over TCP is 24.  Alterna-
-              tive  ports  can  specified by appending "<i>:service-</i>
+              tive ports can specified  by  appending  "<i>:service-</i>
               <i>name</i>" or ":<i>portnumber</i>" to the destination argument.
 
        <b>-t</b> <i>timeout</i> (default: <b>5</b>)
-              The  TCP  connection  timeout to use.  This is also
-              the timeout for reading  the  remote  server's  220
+              The TCP connection timeout to use.   This  is  also
+              the  timeout  for  reading  the remote server's 220
               banner.
 
        <b>-T</b> <i>timeout</i> (default: <b>30</b>)
               The SMTP/LMTP command timeout for EHLO/LHLO, START-
               TLS and QUIT.
 
-       <b>-v</b>     Enable verose Postfix logging.  Specify  more  than
+       <b>-v</b>     Enable  verose  Postfix logging.  Specify more than
               once to increase the level of verbose logging.
 
        [<b>inet:</b>]<i>domain</i>[:<i>port</i>]
-              Connect  via  TCP  to domain <i>domain</i>, port <i>port</i>. The
-              default port is <b>smtp</b> (or 24 with LMTP).  With  SMTP
-              an  MX lookup is performed to resolve the domain to
-              a host, unless the domain is enclosed  in  <b>[]</b>.   If
-              you  want  to  connect  to  a specific MX host, for
+              Connect via TCP to domain <i>domain</i>,  port  <i>port</i>.  The
+              default  port is <b>smtp</b> (or 24 with LMTP).  With SMTP
+              an MX lookup is performed to resolve the domain  to
+              a  host,  unless  the domain is enclosed in <b>[]</b>.  If
+              you want to connect to  a  specific  MX  host,  for
               instance <i>mx1.example.com</i>, specify [<i>mx1.example.com</i>]
               as the destination and <i>example.com</i> as a <b>match</b> argu-
-              ment.  When using DNS, the  destination  domain  is
-              assumed  fully  qualified  and no <a href="ADDRESS_CLASS_README.html#default_domain_class">default domain</a> or
-              search suffixes are applied; you  must  use  fully-
-              qualified  names or also enable <b>native</b> host lookups
+              ment.   When  using  DNS, the destination domain is
+              assumed fully qualified and no  default  domain  or
+              search  suffixes  are  applied; you must use fully-
+              qualified names or also enable <b>native</b> host  lookups
               (these don't support <b>dane</b> or <b>dane-only</b> as no DNSSEC
               validation  information  is  available  via  <b>native</b>
               lookups).
@@ -317,17 +322,17 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
               With  no  match  arguments  specified,  certificate
               peername  matching  uses  the  compiled-in  default
               strategies for each security level.  If you specify
-              one or more arguments, these will be  used  as  the
-              list  of certificate or public-key digests to match
-              for the <b>fingerprint</b> level, or as the  list  of  DNS
+              one  or  more  arguments, these will be used as the
+              list of certificate or public-key digests to  match
+              for  the  <b>fingerprint</b>  level, or as the list of DNS
               names to match in the certificate at the <b>verify</b> and
-              <b>secure</b> levels.  If the security level is  <b>dane</b>,  or
-              <b>dane-only</b>  the  match  names are ignored, and <b>host-</b>
+              <b>secure</b>  levels.   If the security level is <b>dane</b>, or
+              <b>dane-only</b> the match names are  ignored,  and  <b>host-</b>
               <b>name, nexthop</b> strategies are used.
 
 <b>ENVIRONMENT</b>
        <b>MAIL_CONFIG</b>
-              Read configuration parameters  from  a  non-default
+              Read  configuration  parameters  from a non-default
               location.
 
        <b>MAIL_VERBOSE</b>
@@ -341,7 +346,7 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
        <a href="TLS_README.html">TLS_README</a>, Postfix STARTTLS howto
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>AUTHOR(S)</b>
index 3b8ba36b6c7ea977486c9e982d01ce4b91e23fd4..4ef7b501f96287ccb7d3303357643d0ba58961c8 100644 (file)
@@ -593,15 +593,10 @@ SMTP(8)                                                                SMTP(8)
               Zero  or  more  PEM-format  files with trust-anchor
               certificates and/or public keys.
 
-       <b>smtp_tls_dane_notfound_tlsa_level (may)</b>
-              The "degraded" security level when the "dane" secu-
-              rity level is specified, but no validated DANE TLSA
-              records are published.
-
-       <b>smtp_tls_dane_unusable_tlsa_level (encrypt)</b>
-              The "degraded" security level when the "dane" secu-
-              rity   level  is  specified,  validated  DANE  TLSA
-              records are present, but none are usable.
+       <b><a href="postconf.5.html#smtp_tls_force_insecure_host_tlsa_lookup">smtp_tls_force_insecure_host_tlsa_lookup</a> (no)</b>
+              Lookup the associated DANE TLSA RRset even  when  a
+              hostname  is  not  an alias and its address records
+              lie in an unsigned zone.
 
        <b><a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a>   (trust-anchor-asser-</b>
        <b>tion)</b>
index f2bad96c402d1c22203879b5f9ddd5ca7c4e829d..663f03ef8fb6ce2afcf7d3b7b223176d8b8e29cc 100644 (file)
@@ -496,14 +496,6 @@ SMTPD(8)                                                              SMTPD(8)
               remote SMTP client certificate in  order  to  allow
               TLS connections to proceed.
 
-       <b><a href="postconf.5.html#smtpd_tls_session_cache_database">smtpd_tls_session_cache_database</a> (empty)</b>
-              Name  of  the  file containing the optional Postfix
-              SMTP server TLS session cache.
-
-       <b><a href="postconf.5.html#smtpd_tls_session_cache_timeout">smtpd_tls_session_cache_timeout</a> (3600s)</b>
-              The expiration time of Postfix SMTP server TLS ses-
-              sion cache information.
-
        <b><a href="postconf.5.html#smtpd_tls_wrappermode">smtpd_tls_wrappermode</a> (no)</b>
               Run  the  Postfix  SMTP  server in the non-standard
               "wrapper" mode, instead of using the STARTTLS  com-
index 30c9c52e9b334d92cdb7ce4c54cf398231602db5..dfd20d4f79148ff175ea9c03723cb270b907909c 100644 (file)
@@ -178,56 +178,51 @@ TLSPROXY(8)                                                        TLSPROXY(8)
               ified,   this  overrides  the  obsolete  parameters
               <a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a> and <a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a>.
 
-       <b><a href="postconf.5.html#tlsproxy_tls_session_cache_timeout">tlsproxy_tls_session_cache_timeout</a>        ($<a href="postconf.5.html#smtpd_tls_session_cache_timeout">smtpd_tls_ses</a>-</b>
-       <b><a href="postconf.5.html#smtpd_tls_session_cache_timeout">sion_cache_timeout</a>)</b>
-              The expiration time of Postfix  <a href="tlsproxy.8.html"><b>tlsproxy</b>(8)</a>  server
-              TLS session cache information.
-
        Available in Postfix version 2.11 and later:
 
        <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 mas-
+              The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a>  service  entry  in  mas-
               ter.cf.
 
 <b>OBSOLETE STARTTLS SUPPORT CONTROLS</b>
-       These parameters  are  supported  for  compatibility  with
+       These  parameters  are  supported  for  compatibility with
        <a href="smtpd.8.html"><b>smtpd</b>(8)</a> legacy parameters.
 
        <b><a href="postconf.5.html#tlsproxy_use_tls">tlsproxy_use_tls</a> ($<a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a>)</b>
-              Opportunistic  TLS:  announce  STARTTLS  support to
+              Opportunistic TLS:  announce  STARTTLS  support  to
               remote  SMTP  clients,  but  do  not  require  that
               clients use TLS encryption.
 
        <b><a href="postconf.5.html#tlsproxy_enforce_tls">tlsproxy_enforce_tls</a> ($<a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a>)</b>
-              Mandatory  TLS: announce STARTTLS support to remote
-              SMTP clients, and  require  that  clients  use  TLS
+              Mandatory TLS: announce STARTTLS support to  remote
+              SMTP  clients,  and  require  that  clients use TLS
               encryption.
 
 <b>RESOURCE CONTROLS</b>
        <b><a href="postconf.5.html#tlsproxy_watchdog_timeout">tlsproxy_watchdog_timeout</a> (10s)</b>
-              How  much  time  a  <a href="tlsproxy.8.html"><b>tlsproxy</b>(8)</a> process may take to
+              How much time a <a href="tlsproxy.8.html"><b>tlsproxy</b>(8)</a>  process  may  take  to
               process local or remote I/O before it is terminated
               by a built-in watchdog timer.
 
 <b>MISCELLANEOUS CONTROLS</b>
        <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
+              The default location of  the  Postfix  <a href="postconf.5.html">main.cf</a>  and
               <a href="master.5.html">master.cf</a> configuration files.
 
        <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
-              The process ID  of  a  Postfix  command  or  daemon
+              The  process  ID  of  a  Postfix  command or daemon
               process.
 
        <b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
-              The  process  name  of  a Postfix command or daemon
+              The process name of a  Postfix  command  or  daemon
               process.
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              The mail system  name  that  is  prepended  to  the
-              process  name  in  syslog  records, so that "smtpd"
+              The  mail  system  name  that  is  prepended to the
+              process name in syslog  records,  so  that  "smtpd"
               becomes, for example, "postfix/smtpd".
 
 <b>SEE ALSO</b>
@@ -237,7 +232,7 @@ TLSPROXY(8)                                                        TLSPROXY(8)
        syslogd(5), system logging
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>HISTORY</b>
index f418e54c49792ea4384a31c4d5fc32d38049f1d6..3ba4e7b433f1f98a203e9df7a7d91f4346b1df44 100644 (file)
@@ -107,6 +107,10 @@ The message digest algorithm to use for reporting remote SMTP server
 fingerprints and matching against user provided certificate
 fingerprints (with DANE TLSA records the algorithm is specified
 in the DNS).
+.IP "\fB-f\fR"
+Lookup the associated DANE TLSA RRset even when a hostname is not an
+alias and its address records lie in an unsigned zone.  See
+smtp_tls_force_insecure_host_tlsa_lookup for details.
 .IP "\fB-F \fICAfile.pem\fR (default: none)"
 The PEM formatted CAfile for remote SMTP server certificate
 verification.  By default no CAfile is used and no public CAs
index 2a69e1c39792b297886fab3fb396241f0033f2df..02d7d8824404e57cef278a0d39e4f5696ab1b515 100644 (file)
@@ -2757,6 +2757,11 @@ The LMTP-specific version of the smtp_tls_fingerprint_digest
 configuration parameter.  See there for details.
 .PP
 This feature is available in Postfix 2.5 and later.
+.SH lmtp_tls_force_insecure_host_tlsa_lookup (default: no)
+The LMTP-specific version of the smtp_tls_force_insecure_host_tlsa_lookup
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.11 and later.
 .SH lmtp_tls_key_file (default: $lmtp_tls_cert_file)
 The LMTP-specific version of the smtp_tls_key_file
 configuration parameter.  See there for details.
@@ -7069,6 +7074,18 @@ fingerprint incorrectly. To use public-key fingerprints, upgrade
 to Postfix 2.9.6 or later.
 .PP
 This feature is available in Postfix 2.5 and later.
+.SH smtp_tls_force_insecure_host_tlsa_lookup (default: no)
+Lookup the associated DANE TLSA RRset even when a hostname is
+not an alias and its address records lie in an unsigned zone.  This
+is unlikely to ever yield DNSSEC validated results, since child
+zones of unsigned zones are also unsigned in the absense of DLV or
+locally configured non-root trust-anchors.  We anticipate that such
+mechanisms will not be used for just the "_tcp" subdomain of a host.
+Suppressing the TLSA RRset lookup reduces latency and avoids potential
+interoperability problems with nameservers for unsigned zones that
+are not prepared to handle the new TLSA RRset.
+.PP
+This feature is available in Postfix 2.11.
 .SH smtp_tls_key_file (default: $smtp_tls_cert_file)
 File with the Postfix SMTP client RSA private key in PEM format.
 This file may be combined with the Postfix SMTP client RSA certificate
@@ -7818,6 +7835,10 @@ $smtp_tls_session_cache_database, this parameter is implemented in the
 \fBtlsmgr\fR(8) daemon and therefore per-smtp-instance master.cf overrides
 are not possible.
 .PP
+As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+<= 0, session caching is disabled.  If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead.
+.PP
 This feature is available in Postfix 2.2 and later.
 .SH smtp_tls_trust_anchor_file (default: empty)
 Zero or more PEM-format files with trust-anchor certificates
@@ -10731,7 +10752,16 @@ $smtpd_tls_session_cache_database, this parameter is implemented in the
 \fBtlsmgr\fR(8) daemon and therefore per-smtpd-instance master.cf overrides
 are not possible.
 .PP
-This feature is available in Postfix 2.2 and later.
+As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+<= 0, session caching is disabled, not just via the database, but
+also via RFC 5077 TLS session tickets, which don't require server-side
+storage.  If set to a positive value less than 2 minutes, the minimum
+value of 2 minutes is used instead.  TLS session tickets require
+an OpenSSL library (at least version 0.9.8h) that provides full
+support for this TLS extension.
+.PP
+This feature is available in Postfix 2.2 and later, and updated
+for TLS session ticket support in Postfix 2.11.
 .SH smtpd_tls_wrappermode (default: no)
 Run the Postfix SMTP server in the non-standard "wrapper" mode,
 instead of using the STARTTLS command.
@@ -11520,10 +11550,10 @@ smtpd_tls_security_level for further details.
 .PP
 This feature is available in Postfix 2.8 and later.
 .SH tlsproxy_tls_session_cache_timeout (default: $smtpd_tls_session_cache_timeout)
-The expiration time of Postfix \fBtlsproxy\fR(8) server TLS session
-cache information. A cache cleanup is performed periodically every
-$smtpd_tls_session_cache_timeout seconds. See
-smtpd_tls_session_cache_timeout for further details.
+Obsolete expiration time of Postfix \fBtlsproxy\fR(8) server TLS session
+cache information. Since the cache is shared with \fBsmtpd\fR(8) and managed
+by \fBtlsmgr\fR(8), there is only one expiration time for the SMTP server cache
+shared by all three services, namely smtpd_tls_session_cache_timeout.
 .PP
 This feature is available in Postfix 2.8 and later.
 .SH tlsproxy_use_tls (default: $smtpd_use_tls)
index cd603ed3d2392aa8b3bb1294f5b534af316f5dc6..a96cd7d6dbeaf09ef985b91192d8d2eb63850bdf 100644 (file)
@@ -39,7 +39,7 @@ to the network, and can be run chrooted at fixed low privilege.
 .SH "STANDARDS"
 .na
 .nf
-None.
+RFC 3463 (Enhanced Status Codes)
 .SH DIAGNOSTICS
 .ad
 .fi
index e00f5628df7ae746d581d4f7ef24ef91eed3ecff..fcc914029f4ebbbd5205d404b09881d4e0b56bdf 100644 (file)
@@ -476,13 +476,9 @@ Available in Postfix version 2.11 and later:
 .IP "\fBsmtp_tls_trust_anchor_file (empty)\fR"
 Zero or more PEM-format files with trust-anchor certificates
 and/or public keys.
-.IP "\fBsmtp_tls_dane_notfound_tlsa_level (may)\fR"
-The "degraded" security level when the "dane" security level
-is specified, but no validated DANE TLSA records are published.
-.IP "\fBsmtp_tls_dane_unusable_tlsa_level (encrypt)\fR"
-The "degraded" security level when the "dane" security level
-is specified, validated DANE TLSA records are present, but none are
-usable.
+.IP "\fBsmtp_tls_force_insecure_host_tlsa_lookup (no)\fR"
+Lookup the associated DANE TLSA RRset even when a hostname is
+not an alias and its address records lie in an unsigned zone.
 .IP "\fBtls_dane_trust_anchor_digest_enable (trust-anchor-assertion)\fR"
 RFC 6698 trust-anchor digest support in the Postfix TLS library.
 .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
@@ -599,8 +595,9 @@ line, SMTP message content line, or TLS protocol message).
 .PP
 Available in Postfix version 2.11 and later:
 .IP "\fBsmtp_connection_reuse_count_limit (0)\fR"
-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).
+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).
 .SH "TROUBLE SHOOTING CONTROLS"
 .na
 .nf
index 2dad0b546f7e6f47863b6f9b89faf22507590b03..3c4bc859ac55beea341e5264cf45feceff8b2a9b 100644 (file)
@@ -419,12 +419,6 @@ CommonName.
 .IP "\fBsmtpd_tls_req_ccert (no)\fR"
 With mandatory TLS encryption, require a trusted remote SMTP client
 certificate in order to allow TLS connections to proceed.
-.IP "\fBsmtpd_tls_session_cache_database (empty)\fR"
-Name of the file containing the optional Postfix SMTP server
-TLS session cache.
-.IP "\fBsmtpd_tls_session_cache_timeout (3600s)\fR"
-The expiration time of Postfix SMTP server TLS session cache
-information.
 .IP "\fBsmtpd_tls_wrappermode (no)\fR"
 Run the Postfix SMTP server in the non-standard "wrapper" mode,
 instead of using the STARTTLS command.
index caadcdd63738da344522487eee47a4007a88f1c3..61a01065617bd3a79a098581fa8de97562033db2 100644 (file)
@@ -148,9 +148,6 @@ client certificate in order to allow TLS connections to proceed.
 The SMTP TLS security level for the Postfix \fBtlsproxy\fR(8) server;
 when a non-empty value is specified, this overrides the obsolete
 parameters smtpd_use_tls and smtpd_enforce_tls.
-.IP "\fBtlsproxy_tls_session_cache_timeout ($smtpd_tls_session_cache_timeout)\fR"
-The expiration time of Postfix \fBtlsproxy\fR(8) server TLS session
-cache information.
 .PP
 Available in Postfix version 2.11 and later:
 .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
index 53e810f1bb7ed4058a997987b9c2dbc107035b42..6da58ae745f8f78dd2b7f523a1e210b2c7b41a63 100755 (executable)
@@ -281,6 +281,7 @@ while (<>) {
     s;\blmtp_tls_enforce_peername\b;<a href="postconf.5.html#lmtp_tls_enforce_peername">$&</a>;g;
     s;\blmtp_tls_note_starttls_offer\b;<a href="postconf.5.html#lmtp_tls_note_starttls_offer">$&</a>;g;
     s;\blmtp_tls_block_early_mail_reply\b;<a href="postconf.5.html#lmtp_tls_block_early_mail_reply">$&</a>;g;
+    s;\blmtp_tls_force_insecure_host_tlsa_lookup\b;<a href="postconf.5.html#lmtp_tls_force_insecure_host_tlsa_lookup">$&</a>;g;
     s;\blmtp_sender_dependent_authentication\b;<a href="postconf.5.html#lmtp_sender_dependent_authentication">$&</a>;g;
     s;\blmtp_sasl_path\b;<a href="postconf.5.html#lmtp_sasl_path">$&</a>;g;
     s;\blmtp_lhlo_name\b;<a href="postconf.5.html#lmtp_lhlo_name">$&</a>;g;
@@ -646,6 +647,7 @@ while (<>) {
     s;\bsmtp_tls_session_cache_database\b;<a href="postconf.5.html#smtp_tls_session_cache_database">$&</a>;g;
     s;\bsmtp_tls_session_cache_timeout\b;<a href="postconf.5.html#smtp_tls_session_cache_timeout">$&</a>;g;
     s;\bsmtp_tls_block_early_mail_reply\b;<a href="postconf.5.html#smtp_tls_block_early_mail_reply">$&</a>;g;
+    s;\bsmtp_tls_force_insecure_host_tlsa_lookup\b;<a href="postconf.5.html#smtp_tls_force_insecure_host_tlsa_lookup">$&</a>;g;
     s;\bsmtp_use_tls\b;<a href="postconf.5.html#smtp_use_tls">$&</a>;g;
     s;\bsmtp_header_checks\b;<a href="postconf.5.html#smtp_header_checks">$&</a>;g;
     s;\bsmtp_mime_header_checks\b;<a href="postconf.5.html#smtp_mime_header_checks">$&</a>;g;
@@ -1026,7 +1028,6 @@ while (<>) {
     s;\btlsproxy_tls_protocols\b;<a href="postconf.5.html#tlsproxy_tls_protocols">$&</a>;g;
     s;\btlsproxy_tls_req_ccert\b;<a href="postconf.5.html#tlsproxy_tls_req_ccert">$&</a>;g;
     s;\btlsproxy_tls_security_level\b;<a href="postconf.5.html#tlsproxy_tls_security_level">$&</a>;g;
-    s;\btlsproxy_tls_session_cache_timeout\b;<a href="postconf.5.html#tlsproxy_tls_session_cache_timeout">$&</a>;g;
     s;\btlsproxy_use_tls\b;<a href="postconf.5.html#tlsproxy_use_tls">$&</a>;g;
 
     # Service-defined parameters...
index 292e9920fff216977071b50cf923e3265bf9bb7d..72451281975def8f6ea25b557bf97e2ef8bb7e1b 100644 (file)
 
 <h2>Introduction</h2>
 
-<!--
-
-<dl> <dt> Note: </dt> <dd> <p> Postfix support for LMDB databases
-is suspended due to the existence of a hard limit (an "out of
-storage" failure mode that cannot be resolved by increasing the
-database size). </p> <p> Postfix may support LMDB again when it no
-longer limits the size of Postfix transactions, whether the limit
-is built into LMDB itself, or implicit by requiring an unbounded
-amount of memory to handle a large transaction. </p> </dd> </dl>
-
--->
+<blockquote> <p> <strong> Warning: LMDB databases have a show-stopper
+bug: they do not grow beyond a specified limit, and introduce a
+"database full" hard error condition that does not exist with any
+other Postfix database type.  This is a problem for programs whose
+database grows with system load. Examples are postscreen(8),
+greylisting, verify(8) and tlsmgr(8).  </strong> </p> <p> <strong>
+You have been warned.  </strong> </p> </blockquote>
 
 <p> Postfix uses databases of various kinds to store and look up
 information. Postfix databases are specified as "type:name".
index 28c1f42f821ab7e02f84b6562be23c8e40fffdb5..ad5177224ff70c6c891c4132d18109721045de09 100644 (file)
@@ -604,12 +604,24 @@ In order to change this behavior, set
 
 <h3><a name="server_tls_cache">Server-side TLS session cache</a> </h3>
 
-<p> The Postfix SMTP server and the remote SMTP client negotiate
-a session, which takes some computer time and network bandwidth.
-By default, this session information is cached only in the smtpd(8)
-process actually using this session and is lost when the process
-terminates.  To share the session information between multiple
-smtpd(8) processes, a persistent session cache can be used. You
+<p> The Postfix SMTP server and the remote SMTP client negotiate a
+session, which takes some computer time and network bandwidth.  SSL
+protocol versions other than SSLv2 support resumption of cached
+sessions.  Not only is this more CPU and bandwidth efficient, it
+also reduces latency as only one network round-trip is used to
+resume a session while it takes two round-trips to create a session
+from scratch.  </p>
+
+<p> Since Postfix uses multiple smtpd(8) service processes, an
+in-memory cache is not sufficient for session re-use.  Clients store
+at most one cached session per server and are very unlikey to
+repeatedly connect to the same server process.  Thus session caching
+in the Postfix SMTP server generally requires a shared cache (an
+alternative available with Postfix &ge; 2.11 is described below).
+</p>
+
+<p> To share the session information between multiple
+smtpd(8) processes, a session cache database is used. You
 can specify any database type that can store objects of several
 kbytes and that supports the sequence operator. DBM databases are
 not suitable because they can only store small objects. The cache
@@ -617,6 +629,24 @@ is maintained by the tlsmgr(8) process, so there is no problem with
 concurrent access. Session caching is highly recommended, because
 the cost of repeatedly negotiating TLS session keys is high.</p>
 
+<p> Starting with Postfix 2.11, linked with a compatible OpenSSL
+library (at least 0.9.8h, preferably 1.0.0 or later) the Postfix
+SMTP server supports RFC 5077 TLS session resumption without
+server-side state when the remote SMTP client also supports RFC
+5077.  The session is encrypted by the server in a <i>session
+ticket</i> returned to client for storage.  When a client sends a
+valid session ticket, the server decrypts it and resumes the session,
+provided neither the ticket nor the session have expired.  This
+makes it possible to resume cached sessions without allocating space
+for a shared database on the server.  This feature can be disabled
+by setting the session cache timeout to zero, otherwise the timeout
+must be at least 2 minutes and at most 100 days.  </p>
+
+<p> Note, session tickets can only be negotiated if the client
+disables SSLv2 and does not use the legacy SSLv2 compatible HELLO
+message.  This is true by default with the Postfix &ge; 2.6 SMTP
+client.  </p>
+
 <p> Example: </p>
  
 <blockquote>
@@ -646,9 +676,13 @@ recommends a maximum of 24 hours.  </p>
 </pre>
 </blockquote>
 
+<p> As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+&le; 0, session caching is disabled.  If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead.  </p>
+
 <p> When the Postfix SMTP server does not save TLS sessions to an
 external cache database, client-side session caching is unlikely
-to be useful.  To prevent such wastage, the Postfix SMTP server can
+to be useful.  To reduce waste of client resources, the Postfix SMTP server can
 be configured to not issue TLS session ids. By default the Postfix
 SMTP server always issues TLS session ids. This works around known
 interoperability issues with some MUAs, and prevents possible
@@ -1980,6 +2014,10 @@ recommends a maximum of 24 hours.  </p>
 </pre>
 </blockquote>
 
+<p> As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+&le; 0, session caching is disabled.  If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead.  </p>
+
 <h3><a name="client_tls_limits"> Client TLS limitations </a>
 </h3>
 
index 5a1608c662b5803ebf9e0c9f0555e2bd49cd7645..c4b6c53a187e6585a2f1fb90a9d8411b5f633bbd 100644 (file)
@@ -9272,7 +9272,16 @@ $smtpd_tls_session_cache_database, this parameter is implemented in the
 tlsmgr(8) daemon and therefore per-smtpd-instance master.cf overrides
 are not possible. </p>
 
-<p> This feature is available in Postfix 2.2 and later.  </p>
+<p> As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+&le; 0, session caching is disabled, not just via the database, but
+also via RFC 5077 TLS session tickets, which don't require server-side
+storage.  If set to a positive value less than 2 minutes, the minimum
+value of 2 minutes is used instead.  TLS session tickets require
+an OpenSSL library (at least version 0.9.8h) that provides full
+support for this TLS extension. </p>
+
+<p> This feature is available in Postfix 2.2 and later, and updated
+for TLS session ticket support in Postfix 2.11. </p>
 
 %PARAM relay_clientcerts
 
@@ -9574,6 +9583,10 @@ $smtp_tls_session_cache_database, this parameter is implemented in the
 tlsmgr(8) daemon and therefore per-smtp-instance master.cf overrides
 are not possible. </p>
 
+<p> As of Postfix 2.11 this setting cannot exceed 100 days.  If set
+&le; 0, session caching is disabled.  If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead.  </p>
+
 <p> This feature is available in Postfix 2.2 and later.  </p>
 
 %PARAM smtp_use_tls no
@@ -14602,10 +14615,10 @@ smtpd_tls_security_level for further details. </p>
 
 %PARAM tlsproxy_tls_session_cache_timeout $smtpd_tls_session_cache_timeout
 
-<p> The expiration time of Postfix tlsproxy(8) server TLS session
-cache information. A cache cleanup is performed periodically every
-$smtpd_tls_session_cache_timeout seconds. See
-smtpd_tls_session_cache_timeout for further details. </p>
+<p> Obsolete expiration time of Postfix tlsproxy(8) server TLS session
+cache information. Since the cache is shared with smtpd(8) and managed
+by tlsmgr(8), there is only one expiration time for the SMTP server cache
+shared by all three services, namely smtpd_tls_session_cache_timeout. </p>
 
 <p> This feature is available in Postfix 2.8 and later. </p>
 
@@ -15394,3 +15407,24 @@ the most connections to that destination.  This limitation does not
 exist with the smtp_connection_reuse_time_limit feature. </p>
 
 <p> This feature is available in Postfix 2.11. </p>
+
+%PARAM lmtp_tls_force_insecure_host_tlsa_lookup no
+
+<p> The LMTP-specific version of the smtp_tls_force_insecure_host_tlsa_lookup
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM smtp_tls_force_insecure_host_tlsa_lookup no
+
+<p> Lookup the associated DANE TLSA RRset even when a hostname is
+not an alias and its address records lie in an unsigned zone.  This
+is unlikely to ever yield DNSSEC validated results, since child
+zones of unsigned zones are also unsigned in the absense of DLV or
+locally configured non-root trust-anchors.  We anticipate that such
+mechanisms will not be used for just the "_tcp" subdomain of a host.
+Suppressing the TLSA RRset lookup reduces latency and avoids potential
+interoperability problems with nameservers for unsigned zones that
+are not prepared to handle the new TLSA RRset.  </p>
+
+<p> This feature is available in Postfix 2.11. </p>
index d1d467edb49559e81ef242c305fafd26f46c41e9..4f90926b6d235492247fdb3f516ce00e97c732e8 100644 (file)
@@ -29,7 +29,7 @@
 /*     The \fBdiscard\fR(8) mailer is not security-sensitive. It does not talk
 /*     to the network, and can be run chrooted at fixed low privilege.
 /* STANDARDS
-/*     None.
+/*     RFC 3463 (Enhanced Status Codes)
 /* DIAGNOSTICS
 /*     Problems and transactions are logged to \fBsyslogd\fR(8).
 /*
index 7bd987da64033331403fac7a6fe44d5b2420956b..93d2c356940e4deaaf292cd85ce3f15c277d90c6 100644 (file)
@@ -1327,6 +1327,7 @@ extern bool var_smtpd_tls_received_header;
 #define DEF_SMTPD_TLS_SCACHE_DB        ""
 extern char *var_smtpd_tls_scache_db;
 
+#define MAX_SMTPD_TLS_SCACHETIME       8640000
 #define VAR_SMTPD_TLS_SCACHTIME        "smtpd_tls_session_cache_timeout"
 #define DEF_SMTPD_TLS_SCACHTIME        "3600s"
 extern int var_smtpd_tls_scache_timeout;
@@ -1479,8 +1480,10 @@ extern bool var_smtp_tls_note_starttls_offer;
 extern char *var_smtp_tls_scache_db;
 extern char *var_lmtp_tls_scache_db;
 
+#define MAX_SMTP_TLS_SCACHETIME        8640000
 #define VAR_SMTP_TLS_SCACHTIME "smtp_tls_session_cache_timeout"
 #define DEF_SMTP_TLS_SCACHTIME "3600s"
+#define MAX_LMTP_TLS_SCACHETIME        8640000
 #define VAR_LMTP_TLS_SCACHTIME "lmtp_tls_session_cache_timeout"
 #define DEF_LMTP_TLS_SCACHTIME "3600s"
 extern int var_smtp_tls_scache_timeout;
@@ -1532,6 +1535,12 @@ extern char *var_smtp_tls_fpt_cmatch;
 #define DEF_LMTP_TLS_BLK_EARLY_MAIL_REPLY 0
 extern bool var_smtp_tls_blk_early_mail_reply;
 
+#define VAR_SMTP_TLS_FORCE_TLSA "smtp_tls_force_insecure_host_tlsa_lookup"
+#define DEF_SMTP_TLS_FORCE_TLSA 0
+#define VAR_LMTP_TLS_FORCE_TLSA "lmtp_tls_force_insecure_host_tlsa_lookup"
+#define DEF_LMTP_TLS_FORCE_TLSA 0
+extern bool var_smtp_tls_force_tlsa;
+
  /*
   * SASL authentication support, SMTP server side.
   */
@@ -3653,14 +3662,6 @@ extern char *var_tlsp_tls_loglevel;
 #define DEF_TLSP_TLS_RECHEAD   "$" VAR_SMTPD_TLS_RECHEAD
 extern bool var_tlsp_tls_received_header;
 
-#define VAR_TLSP_TLS_SCACHE_DB "tlsproxy_tls_session_cache_database"
-#define DEF_TLSP_TLS_SCACHE_DB "$" VAR_SMTPD_TLS_SCACHE_DB
-extern char *var_tlsp_tls_scache_db;
-
-#define VAR_TLSP_TLS_SCACHTIME "tlsproxy_tls_session_cache_timeout"
-#define DEF_TLSP_TLS_SCACHTIME "$" VAR_SMTPD_TLS_SCACHTIME
-extern int var_tlsp_tls_scache_timeout;
-
 #define VAR_TLSP_TLS_SET_SESSID        "tlsproxy_tls_always_issue_session_ids"
 #define DEF_TLSP_TLS_SET_SESSID        "$" VAR_SMTPD_TLS_SET_SESSID
 extern bool var_tlsp_tls_set_sessid;
index 7efe5848ce1ef1bf8234aabbbd31c0cad7126916..2dc2e54da233dd3410b4393b29e7de607953833c 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20130818"
+#define MAIL_RELEASE_DATE      "20130825"
 #define MAIL_VERSION_NUMBER    "2.11"
 
 #ifdef SNAPSHOT
index 66edbe9f6a05baccee29cdb533c4c4fe59acbb85..407dfb3dbc0b054ef3e233a11421c88b763de0e6 100644 (file)
 /*     fingerprints and matching against user provided certificate
 /*     fingerprints (with DANE TLSA records the algorithm is specified
 /*     in the DNS).
+/* .IP "\fB-f\fR"
+/*     Lookup the associated DANE TLSA RRset even when a hostname is not an
+/*     alias and its address records lie in an unsigned zone.  See
+/*     smtp_tls_force_insecure_host_tlsa_lookup for details.
 /* .IP "\fB-F \fICAfile.pem\fR (default: none)"
 /*     The PEM formatted CAfile for remote SMTP server certificate
 /*     verification.  By default no CAfile is used and no public CAs
@@ -400,6 +404,7 @@ typedef struct STATE {
     int     log_mask;                  /* via tls_log_mask() */
     int     reconnect;                 /* -r option */
     int     max_reconnect;             /* -m option */
+    int     force_tlsa;                        /* -f option */
     unsigned port;                     /* TCP port */
     char   *dest;                      /* Full destination spec */
     char   *addrport;                  /* [addr]:port */
@@ -407,6 +412,7 @@ typedef struct STATE {
     char   *nexthop;                   /* Nexthop domain for verification */
     char   *hostname;                  /* Hostname for verification */
     DNS_RR *addr;                      /* IPv[46] Address to (re)connect to */
+    DNS_RR *mx;                                /* MX RRset qname, rname, valid */
     int     pass;                      /* Pass number, 2 for reconnect */
     int     nochat;                    /* disable chat logging */
     char   *helo;                      /* Server name from EHLO reply */
@@ -433,7 +439,7 @@ typedef struct STATE {
 
 static DNS_RR *host_addr(STATE *, const char *);
 
-#define HNAME(addr) (addr->dnssec_valid ? addr->rname : addr->qname)
+#define HNAME(addr) (addr->qname)
 
  /*
   * Structure with broken-up SMTP server response.
@@ -1105,6 +1111,7 @@ static DNS_RR *domain_addr(STATE *state, char *domain)
     case DNS_OK:
        mx_names = dns_rr_sort(mx_names, dns_rr_compare_pref_any);
        addr_list = mx_addr_list(state, mx_names);
+       state->mx = dns_rr_copy(mx_names);
        dns_rr_free(mx_names);
        if (addr_list == 0) {
            msg_warn("no MX host for %s has a valid address record", domain);
@@ -1156,10 +1163,26 @@ static DNS_RR *host_addr(STATE *state, const char *host)
 static int dane_host_level(STATE *state, DNS_RR *addr)
 {
     int     level = state->level;
+    int     valid;
+    int     mxvalid;
 
 #ifdef USE_TLS
     if (level == TLS_LEV_DANE) {
-       if (addr->dnssec_valid) {
+
+       /*
+        * Suppress TLSA lookups for non-DNSSEC + non-MX + non-CNAME hosts.
+        * If the host address is not DNSSEC validated, the TLSA RRset is
+        * safely assumed to not be in a DNSSEC Look-aside Validation child
+        * zone.
+        */
+       mxvalid = state->mx == 0 || state->mx->dnssec_valid;
+       valid = addr->dnssec_valid;
+       if (!state->force_tlsa
+           && !valid
+           && state->mx == 0
+           && strcmp(addr->qname, addr->rname) == 0)
+           mxvalid = 0;
+       if (mxvalid) {
            if (state->log_mask & (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE))
                tls_dane_verbose(1);
            else
@@ -1170,7 +1193,9 @@ static int dane_host_level(STATE *state, DNS_RR *addr)
                tls_dane_free(state->ddane);
 
            /* When TLSA lookups fail, next host */
-           state->ddane = tls_dane_resolve(HNAME(addr), "tcp", state->port);
+           state->ddane = tls_dane_resolve(addr->qname,
+                                           valid ? addr->rname : 0,
+                                           "tcp", state->port);
            if (!state->ddane) {
                dsb_simple(state->why, "4.7.5",
                           "TLSA lookup error for %s:%u",
@@ -1193,7 +1218,14 @@ static int dane_host_level(STATE *state, DNS_RR *addr)
                if (state->match)
                    argv_free(state->match);
                argv_add(state->match = argv_alloc(2),
-                        "hostname", "nexthop", ARGV_END);
+                        state->ddane->base_domain, ARGV_END);
+               if (state->mx) {
+                   if (strcmp(state->mx->qname, state->mx->rname) == 0)
+                       argv_add(state->match, state->mx->qname, ARGV_END);
+                   else
+                       argv_add(state->match, state->mx->rname,
+                                state->mx->qname, ARGV_END);
+               }
            }
        } else {
            level = TLS_LEV_SECURE;
@@ -1346,6 +1378,9 @@ static void disconnect_dest(STATE *state)
        if (state->addr)
            dns_rr_free(state->addr);
        state->addr = 0;
+       if (state->mx)
+           dns_rr_free(state->mx);
+       state->mx = 0;
 
        if (state->nexthop)
            myfree(state->nexthop);
@@ -1392,7 +1427,7 @@ static int finger(STATE *state)
        if (cache_enabled && cache_count == 0) {
            msg_info("Server declined session caching. Done reconnecting.");
            state->reconnect = 0;
-       } else if (cache_hits > 0) {
+       } else if (cache_hits > 0 && (state->log_mask & TLS_LOG_SESSTKT) != 0) {
            msg_info("Found a previously used server.  Done reconnecting.");
            state->reconnect = 0;
        } else if (state->max_reconnect-- <= 0) {
@@ -1483,7 +1518,7 @@ static void usage(void)
 #ifdef USE_TLS
     fprintf(stderr, "usage: %s %s \\\n\t%s \\\n\t%s \\\n\t%s"
            " destination [match ...]\n", var_procname,
-           "[-acCSv] [-t conn_tmout] [-T cmd_tmout] [-L logopts]",
+           "[-acCfSv] [-t conn_tmout] [-T cmd_tmout] [-L logopts]",
         "[-h host_lookup] [-l level] [-d mdalg] [-g grade] [-p protocols]",
            "[-A tafile] [-F CAfile.pem] [-P CApath/] [-m count] [-r delay]",
            "[-o name=value]");
@@ -1555,7 +1590,7 @@ static void parse_options(STATE *state, int argc, char *argv[])
 
 #define OPTS "a:ch:o:St:T:v"
 #ifdef USE_TLS
-#define TLSOPTS "A:Cd:F:g:l:L:m:p:P:r:"
+#define TLSOPTS "A:Cd:fF:g:l:L:m:p:P:r:"
 
     state->mdalg = mystrdup("sha1");
     state->CApath = mystrdup("");
@@ -1609,6 +1644,9 @@ static void parse_options(STATE *state, int argc, char *argv[])
            myfree(state->mdalg);
            state->mdalg = mystrdup(optarg);
            break;
+       case 'f':
+           state->force_tlsa = 1;
+           break;
        case 'F':
            myfree(state->CAfile);
            state->CAfile = mystrdup(optarg);
index d6b09d87c854d9a994a29fc9ef7bf2999e7eb075..500932f12f202836ef254c8a809f5d58277604ea 100644 (file)
@@ -82,11 +82,12 @@ int     tls_mgr_seed(VSTRING *buf, int len)
     return (TLS_MGR_STAT_OK);
 }
 
-int     tls_mgr_policy(const char *unused_type, int *cachable)
+int     tls_mgr_policy(const char *unused_type, int *cachable, int *timeout)
 {
     if (cache_enabled && tls_cache == 0)
        tls_cache = htable_create(1);
     *cachable = cache_enabled;
+    *timeout = TLS_SESSION_LIFEMIN;
     return (TLS_MGR_STAT_OK);
 }
 
index faaa6dee152ca6de71694e38875119f0e6f83dd2..68a2739ac2421e4353409b5cdf95d731c3711566 100644 (file)
        VAR_LMTP_TLS_ENFORCE_PN, DEF_LMTP_TLS_ENFORCE_PN, &var_smtp_tls_enforce_peername,
        VAR_LMTP_TLS_NOTEOFFER, DEF_LMTP_TLS_NOTEOFFER, &var_smtp_tls_note_starttls_offer,
        VAR_LMTP_TLS_BLK_EARLY_MAIL_REPLY, DEF_LMTP_TLS_BLK_EARLY_MAIL_REPLY, &var_smtp_tls_blk_early_mail_reply,
+       VAR_LMTP_TLS_FORCE_TLSA, DEF_LMTP_TLS_FORCE_TLSA, &var_smtp_tls_force_tlsa,
 #endif
        VAR_LMTP_SENDER_AUTH, DEF_LMTP_SENDER_AUTH, &var_smtp_sender_auth,
        VAR_LMTP_CNAME_OVERR, DEF_LMTP_CNAME_OVERR, &var_smtp_cname_overr,
index 82684575b064308aa2599149b1f1f7197d8529e9..e11a53746eacac751ab3a8c4f3e79bf30cda3608 100644 (file)
 /* .IP "\fBsmtp_tls_trust_anchor_file (empty)\fR"
 /*     Zero or more PEM-format files with trust-anchor certificates
 /*     and/or public keys.
-/* .IP "\fBsmtp_tls_dane_notfound_tlsa_level (may)\fR"
-/*     The "degraded" security level when the "dane" security level
-/*     is specified, but no validated DANE TLSA records are published.
-/* .IP "\fBsmtp_tls_dane_unusable_tlsa_level (encrypt)\fR"
-/*     The "degraded" security level when the "dane" security level
-/*     is specified, validated DANE TLSA records are present, but none are
-/*     usable.
+/* .IP "\fBsmtp_tls_force_insecure_host_tlsa_lookup (no)\fR"
+/*     Lookup the associated DANE TLSA RRset even when a hostname is
+/*     not an alias and its address records lie in an unsigned zone.
 /* .IP "\fBtls_dane_trust_anchor_digest_enable (trust-anchor-assertion)\fR"
 /*     RFC 6698 trust-anchor digest support in the Postfix TLS library.
 /* .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
 /* .PP
 /*     Available in Postfix version 2.11 and later:
 /* .IP "\fBsmtp_connection_reuse_count_limit (0)\fR"
-/*     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).
+/*     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).
 /* TROUBLE SHOOTING CONTROLS
 /* .ad
 /* .fi
@@ -853,6 +850,7 @@ char   *var_smtp_tls_ciph;
 char   *var_smtp_tls_eccert_file;
 char   *var_smtp_tls_eckey_file;
 bool    var_smtp_tls_blk_early_mail_reply;
+bool    var_smtp_tls_force_tlsa;
 
 #endif
 
index 25530297922cc0778a42b38be6282822d0b798a5..c694708304ee42db0a88aeda552b04362a658f9f 100644 (file)
@@ -55,17 +55,18 @@ typedef struct SMTP_ITERATOR {
     VSTRING *addr;                     /* printable address or empty */
     unsigned port;                     /* network byte order or null */
     struct DNS_RR *rr;                 /* DNS resource record or null */
+    struct DNS_RR *mx;                 /* DNS resource record or null */
     /* Private members. */
     VSTRING *saved_dest;               /* saved current nexthop */
     struct SMTP_STATE *parent;         /* parent linkage */
 } SMTP_ITERATOR;
 
-#define SMTP_ITER_INIT(iter, _dest, _host, _addr, _port, _rr, state) do { \
+#define SMTP_ITER_INIT(iter, _dest, _host, _addr, _port, state) do { \
        vstring_strcpy((iter)->dest, (_dest)); \
        vstring_strcpy((iter)->host, (_host)); \
        vstring_strcpy((iter)->addr, (_addr)); \
        (iter)->port = (_port); \
-       (iter)->rr = (_rr); \
+       (iter)->mx = (iter)->rr = 0; \
        vstring_strcpy((iter)->saved_dest, ""); \
        (iter)->parent = (state); \
     } while (0)
@@ -354,10 +355,9 @@ extern int smtp_session_passivate(SMTP_SESSION *, VSTRING *, VSTRING *);
 extern SMTP_SESSION *smtp_session_activate(int, SMTP_ITERATOR *, VSTRING *, VSTRING *);
 
  /*
-  * What's in a name?  With DANE TLSA we need the rr->rname (if validated).
+  * What's in a name?
   */
-#define SMTP_HNAME(rr) ( (var_smtp_cname_overr || rr->dnssec_valid) ? \
-                        (rr)->rname : (rr)->qname )
+#define SMTP_HNAME(rr) (var_smtp_cname_overr ? (rr)->rname : (rr)->qname)
 
  /*
   * smtp_connect.c
index b4b253e7be1669709371c232e40b2bfa0712c7ec..deba52f7b133c87eb7831f05f20c79e4dfeff4d3 100644 (file)
@@ -6,8 +6,9 @@
 /* SYNOPSIS
 /*     #include "smtp_addr.h"
 /*
-/*     DNS_RR *smtp_domain_addr(name, misc_flags, why, found_myself)
+/*     DNS_RR *smtp_domain_addr(name, mxrr, misc_flags, why, found_myself)
 /*     char    *name;
+/*     DNS_RR  **mxrr;
 /*     int     misc_flags;
 /*     DSN_BUF *why;
 /*     int     *found_myself;
@@ -29,7 +30,9 @@
 /*     so that it contains only hosts that are more preferred than the
 /*     local mail server itself. The found_myself result parameter
 /*     is updated when the local MTA is MX host for the specified
-/*     destination.
+/*     destination.  If MX records were found, the rname, qname,
+/*     and dnssec validation status of the MX RRset are returned
+/*     via mxrr, which the caller must free with dns_rr_free().
 /*
 /*     When no mail exchanger is listed in the DNS for \fIname\fR, the
 /*     request is passed to smtp_host_addr().
@@ -339,8 +342,8 @@ static DNS_RR *smtp_truncate_self(DNS_RR *addr_list, unsigned pref)
 
 /* smtp_domain_addr - mail exchanger address lookup */
 
-DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
-                                int *found_myself)
+DNS_RR *smtp_domain_addr(char *name, DNS_RR **mxrr, int misc_flags,
+                                DSN_BUF *why, int *found_myself)
 {
     DNS_RR *mx_names;
     DNS_RR *addr_list = 0;
@@ -426,6 +429,8 @@ DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
        mx_names = dns_rr_sort(mx_names, dns_rr_compare_pref_any);
        best_pref = (mx_names ? mx_names->pref : IMPOSSIBLE_PREFERENCE);
        addr_list = smtp_addr_list(mx_names, why);
+       if (mxrr)
+           *mxrr = dns_rr_copy(mx_names);      /* copies one record! */
        dns_rr_free(mx_names);
        if (addr_list == 0) {
            /* Text does not change. */
index 67ff5322ada405b6db1b729e953628b75b2152ac..cf0b6898cb74ef2caf59c2be7bd7471f5f7691af 100644 (file)
@@ -17,7 +17,7 @@
   * Internal interfaces.
   */
 extern DNS_RR *smtp_host_addr(const char *, int, DSN_BUF *);
-extern DNS_RR *smtp_domain_addr(char *, int, DSN_BUF *, int *);
+extern DNS_RR *smtp_domain_addr(char *, DNS_RR **, int, DSN_BUF *, int *);
 
 /* LICENSE
 /* .ad
index 337a8371bce1fb0a1baeee239346ff201683522e..70e8dc56db02a5839260fc8d10d9c75d21e096ec 100644 (file)
@@ -488,10 +488,9 @@ static void smtp_connect_local(SMTP_STATE *state, const char *path)
      * 
      * We set dest=path for backwards compatibility.
      */
-#define NO_RR  ((DNS_RR *) 0)
 #define NO_PORT        0
 
-    SMTP_ITER_INIT(iter, path, var_myhostname, path, NO_PORT, NO_RR, state);
+    SMTP_ITER_INIT(iter, path, var_myhostname, path, NO_PORT, state);
 
     /*
      * Opportunistic TLS for unix domain sockets does not make much sense,
@@ -833,9 +832,8 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
        }
 #define NO_HOST        ""                              /* safety */
 #define NO_ADDR        ""                              /* safety */
-#define NO_RR  ((DNS_RR *) 0)                  /* safety */
 
-       SMTP_ITER_INIT(iter, dest, NO_HOST, NO_ADDR, port, NO_RR, state);
+       SMTP_ITER_INIT(iter, dest, NO_HOST, NO_ADDR, port, state);
 
        /*
         * Resolve an SMTP server. Skip mail exchanger lookups when a quoted
@@ -857,7 +855,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
        } else {
            int     i_am_mx = 0;
 
-           addr_list = smtp_domain_addr(domain, state->misc_flags,
+           addr_list = smtp_domain_addr(domain, &iter->mx, state->misc_flags,
                                         why, &i_am_mx);
            /* If we're MX host, don't connect to non-MX backups. */
            if (i_am_mx)
@@ -1026,6 +1024,10 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
            /* XXX Code above assumes there is no code at this loop ending. */
        }
        dns_rr_free(addr_list);
+       if (iter->mx) {
+           dns_rr_free(iter->mx);
+           iter->mx = 0;                       /* Just in case */
+       }
        myfree(dest_buf);
        if (state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
            break;
index 16c51159be374f3e55303f338515ec4407132ac5..c8478b5ef7d23d1a43443524ca6b94bda8a903a6 100644 (file)
        VAR_SMTP_TLS_ENFORCE_PN, DEF_SMTP_TLS_ENFORCE_PN, &var_smtp_tls_enforce_peername,
        VAR_SMTP_TLS_NOTEOFFER, DEF_SMTP_TLS_NOTEOFFER, &var_smtp_tls_note_starttls_offer,
        VAR_SMTP_TLS_BLK_EARLY_MAIL_REPLY, DEF_SMTP_TLS_BLK_EARLY_MAIL_REPLY, &var_smtp_tls_blk_early_mail_reply,
+       VAR_SMTP_TLS_FORCE_TLSA, DEF_SMTP_TLS_FORCE_TLSA, &var_smtp_tls_force_tlsa,
 #endif
        VAR_SMTP_SENDER_AUTH, DEF_SMTP_SENDER_AUTH, &var_smtp_sender_auth,
        VAR_SMTP_CNAME_OVERR, DEF_SMTP_CNAME_OVERR, &var_smtp_cname_overr,
index c41cc99179b6528206b5b4a4a844b57d51e8a98a..9d881903dd6f3ca2d2171bb9e817d7cd1b4da001 100644 (file)
@@ -628,6 +628,7 @@ int     smtp_tls_policy_cache_query(DSN_BUF *why, SMTP_TLS_POLICY *tls,
 {
     VSTRING *key;
     int     valid = iter->rr && iter->rr->dnssec_valid;
+    int     mxvalid = iter->mx == 0 || iter->mx->dnssec_valid;
 
     /*
      * Create an empty TLS Policy cache on the fly.
@@ -644,7 +645,7 @@ int     smtp_tls_policy_cache_query(DSN_BUF *why, SMTP_TLS_POLICY *tls,
     smtp_key_prefix(key, ":", iter, SMTP_KEY_FLAG_NEXTHOP
                    | SMTP_KEY_FLAG_HOSTNAME
                    | SMTP_KEY_FLAG_PORT);
-    vstring_sprintf_append(key, "%d", !!valid);
+    vstring_sprintf_append(key, "%d:%d", !!valid, !!mxvalid);
     ctable_newcontext(policy_cache, (void *) iter);
     *tls = *(SMTP_TLS_POLICY *) ctable_locate(policy_cache, STR(key));
     vstring_free(key);
@@ -711,7 +712,8 @@ static int global_tls_level(void)
 static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
 {
     TLS_DANE *dane;
-    int     valid = iter->rr && iter->rr->dnssec_valid;
+    int     valid;
+    int     mxvalid;
 
     if (!iter->port) {
        msg_warn("%s: the \"dane\" security level is invalid for delivery via"
@@ -756,7 +758,26 @@ static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
        }
        return;
     }
-    if (!valid) {
+
+    /*
+     * If there were no MX records and the destination host is the original
+     * nexthop domain, or if the MX RRset is DNS validated, we can at least
+     * try DANE with the destination host prior to CNAME expansion, but we
+     * prefer CNAME expanded MX hosts if those are also secure.
+     * 
+     * By default suppress TLSA lookups for non-DNSSEC + non-MX + non-CNAME
+     * hosts.  If the host address is not DNSSEC validated, the TLSA RRset is
+     * safely assumed to not be in a DNSSEC Look-aside Validation child zone.
+     */
+    mxvalid = iter->mx == 0 || iter->mx->dnssec_valid;
+    valid = iter->rr && iter->rr->dnssec_valid;
+    if (!var_smtp_tls_force_tlsa
+       && !valid
+       && iter->mx == 0
+       && strcmp(iter->rr->qname, iter->rr->rname) == 0)
+       mxvalid = 0;
+
+    if (!mxvalid) {
        if (tls->level == TLS_LEV_DANE) {
            tls->level = TLS_LEV_MAY;
            if (msg_verbose)
@@ -768,7 +789,8 @@ static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
        return;
     }
     /* When TLSA lookups fail, we defer the message */
-    if ((dane = tls_dane_resolve(STR(iter->host), "tcp", iter->port)) == 0) {
+    if ((dane = tls_dane_resolve(iter->rr->qname, valid ? iter->rr->rname : 0,
+                                "tcp", iter->port)) == 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));
@@ -818,7 +840,14 @@ static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
      */
     if (TLS_DANE_HASTA(dane)) {
        tls->matchargv = argv_alloc(2);
-       argv_add(tls->matchargv, "hostname", "nexthop", ARGV_END);
+       argv_add(tls->matchargv, dane->base_domain, ARGV_END);
+       if (iter->mx) {
+           if (strcmp(iter->mx->qname, iter->mx->rname) == 0)
+               argv_add(tls->matchargv, iter->mx->qname, ARGV_END);
+           else
+               argv_add(tls->matchargv, iter->mx->rname,
+                        iter->mx->qname, ARGV_END);
+       }
     } else if (!TLS_DANE_HASEE(dane))
        msg_panic("empty DANE match list");
     tls->dane = dane;
index 613570f5ecaa00226a6cece90a0083b868a8de27..3ff8959f7abd09054a3564d48f0e575b68adc8fe 100644 (file)
 /* .IP "\fBsmtpd_tls_req_ccert (no)\fR"
 /*     With mandatory TLS encryption, require a trusted remote SMTP client
 /*     certificate in order to allow TLS connections to proceed.
-/* .IP "\fBsmtpd_tls_session_cache_database (empty)\fR"
-/*     Name of the file containing the optional Postfix SMTP server
-/*     TLS session cache.
-/* .IP "\fBsmtpd_tls_session_cache_timeout (3600s)\fR"
-/*     The expiration time of Postfix SMTP server TLS session cache
-/*     information.
 /* .IP "\fBsmtpd_tls_wrappermode (no)\fR"
 /*     Run the Postfix SMTP server in the non-standard "wrapper" mode,
 /*     instead of using the STARTTLS command.
@@ -1264,7 +1258,6 @@ char   *var_smtpd_tls_loglevel;
 char   *var_smtpd_tls_mand_proto;
 bool    var_smtpd_tls_received_header;
 bool    var_smtpd_tls_req_ccert;
-int     var_smtpd_tls_scache_timeout;
 bool    var_smtpd_tls_set_sessid;
 char   *var_smtpd_tls_fpt_dgst;
 char   *var_smtpd_tls_ciph;
@@ -5152,8 +5145,6 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
                                    log_level = var_smtpd_tls_loglevel,
                                    verifydepth = var_smtpd_tls_ccert_vd,
                                    cache_type = TLS_MGR_SCACHE_SMTPD,
-                                   scache_timeout
-                                   = var_smtpd_tls_scache_timeout,
                                    set_sessid = var_smtpd_tls_set_sessid,
                                    cert_file = cert_file,
                                    key_file = var_smtpd_tls_key_file,
@@ -5326,7 +5317,6 @@ int     main(int argc, char **argv)
        VAR_SMTPD_POLICY_TTL, DEF_SMTPD_POLICY_TTL, &var_smtpd_policy_ttl, 1, 0,
 #ifdef USE_TLS
        VAR_SMTPD_STARTTLS_TMOUT, DEF_SMTPD_STARTTLS_TMOUT, &var_smtpd_starttls_tmout, 1, 0,
-       VAR_SMTPD_TLS_SCACHTIME, DEF_SMTPD_TLS_SCACHTIME, &var_smtpd_tls_scache_timeout, 0, 0,
 #endif
        VAR_MILT_CONN_TIME, DEF_MILT_CONN_TIME, &var_milt_conn_time, 1, 0,
        VAR_MILT_CMD_TIME, DEF_MILT_CMD_TIME, &var_milt_cmd_time, 1, 0,
index 47f60e996c5c38b6dcf33866776aef8904edb1cc..9d1fde2f6ae6450f82fabfdae13e2997a839c58e 100644 (file)
@@ -154,6 +154,7 @@ typedef struct TLS_DANE {
     TLS_TLSA *ee;                      /* End-entity cert/pubkey digests */
     TLS_CERTS *certs;                  /* Full trust-anchor certificates */
     TLS_PKEYS *pkeys;                  /* Full trust-anchor public keys */
+    char   *base_domain;               /* Base domain of TLSA RRset */
     int     flags;                     /* Conflate cert and pkey digests */
     time_t  expires;                   /* Expiration time of this record */
     int     refs;                      /* Reference count */
@@ -172,7 +173,8 @@ extern TLS_DANE *tls_dane_alloc(int);
 extern void tls_dane_split(TLS_DANE *, int, int, const char *, const char *,
                                   const char *);
 extern void tls_dane_free(TLS_DANE *);
-extern TLS_DANE *tls_dane_resolve(const char *, const char *, unsigned);
+extern TLS_DANE *tls_dane_resolve(const char *, const char *, const char *,
+                                         unsigned);
 extern int tls_dane_load_trustfile(TLS_DANE *, const char *);
 
  /*
@@ -197,6 +199,7 @@ typedef struct {
     /* Private. */
     SSL    *con;
     char   *cache_type;                        /* tlsmgr(8) cache type if enabled */
+    int     ticketed;                  /* Session ticket issued */
     char   *serverid;                  /* unique server identifier */
     char   *namaddr;                   /* nam[addr] for logging */
     int     log_mask;                  /* What to log */
@@ -254,6 +257,7 @@ extern int tls_log_mask(const char *, const char *);
 #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
@@ -410,7 +414,6 @@ typedef struct {
     const char *log_level;
     int     verifydepth;
     const char *cache_type;
-    long    scache_timeout;
     int     set_sessid;
     const char *cert_file;
     const char *key_file;
@@ -449,13 +452,12 @@ extern TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *);
        tls_session_stop(ctx, (stream), (timeout), (failure), (TLScontext))
 
 #define TLS_SERVER_INIT(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \
-    a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) \
+    a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) \
     tls_server_init((((props)->a1), ((props)->a2), ((props)->a3), \
     ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
     ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
     ((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), \
-    ((props)->a16), ((props)->a17), ((props)->a18), ((props)->a19), \
-    ((props)->a20), (props)))
+    ((props)->a16), ((props)->a17), ((props)->a18), ((props)->a19), (props)))
 
 #define TLS_SERVER_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \
     tls_server_start((((props)->a1), ((props)->a2), ((props)->a3), \
index 321ed6575585a223bb4cfdbd3b881336b7644e7e..f84955e7e601b65afacccdf0438ed60d10398f2e 100644 (file)
@@ -275,6 +275,7 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
 {
     long    off = 0;
     int     cachable;
+    int     scache_timeout;
     SSL_CTX *client_ctx;
     TLS_APPL_STATE *app_ctx;
     int     log_mask;
@@ -445,7 +446,10 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
      * sessions from the external cache, so we must delete them directly (not
      * via a callback).
      */
-    if (tls_mgr_policy(props->cache_type, &cachable) != TLS_MGR_STAT_OK)
+    if (tls_mgr_policy(props->cache_type, &cachable,
+                      &scache_timeout) != TLS_MGR_STAT_OK)
+       scache_timeout = 0;
+    if (scache_timeout <= 0)
        cachable = 0;
 
     /*
@@ -484,6 +488,15 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
                                       SSL_SESS_CACHE_NO_INTERNAL_STORE |
                                       SSL_SESS_CACHE_NO_AUTO_CLEAR);
        SSL_CTX_sess_set_new_cb(client_ctx, new_client_session_cb);
+
+       /*
+        * OpenSSL ignores timed-out sessions. We need to set the internal
+        * cache timeout at least as high as the external cache timeout. This
+        * applies even if no internal cache is used.  We set the session to
+        * twice the cache lifetime.  This way a session always lasts longer
+        * than its lifetime in the cache.
+        */
+       SSL_CTX_set_timeout(client_ctx, 2 * scache_timeout);
     }
     return (app_ctx);
 }
@@ -546,12 +559,12 @@ static int match_servername(const char *certid,
         */
        if (!strcasecmp(certid, domain)
            || (certid[0] == '*' && certid[1] == '.' && certid[2] != 0
-                && (parent = strchr(domain, '.')) != 0
-                && (idlen = strlen(certid + 1)) <= (domlen = strlen(parent))
-                && strcasecmp(var_tls_multi_wildcard == 0 ? parent :
-                              parent + domlen - idlen,
-                              certid + 1) == 0))
-            return (1);
+               && (parent = strchr(domain, '.')) != 0
+               && (idlen = strlen(certid + 1)) <= (domlen = strlen(parent))
+               && strcasecmp(var_tls_multi_wildcard == 0 ? parent :
+                             parent + domlen - idlen,
+                             certid + 1) == 0))
+           return (1);
     }
     return (0);
 }
index cc068af4a8fe216dc5ffa0cb2aeb7eb421baf6d3..8e499832b41b2e86c2192d993e7db409c5f85a91 100644 (file)
@@ -41,8 +41,9 @@
 /*     SSL_CTX *ssl_ctx;
 /*     TLS_SESS_STATE *TLScontext;
 /*
-/*     TLS_DANE *tls_dane_resolve(host, proto, port)
-/*     const char *host;
+/*     TLS_DANE *tls_dane_resolve(qname, rname, proto, port)
+/*     const char *qname;
+/*     const char *rname;
 /*     const char *proto;
 /*     unsigned port;
 /*
@@ -95,7 +96,7 @@
 /*     anchors always override the legacy public CA PKI.  Otherwise, the
 /*     callback MUST be cleared.
 /*
-/*     tls_dane_resolve() maps a (host, protocol, port) triple to a
+/*     tls_dane_resolve() maps a (qname, rname, protocol, port) tuple to a
 /*     a corresponding TLS_DANE policy structure found in the DNS.  The port
 /*     argument is in network byte order.  A null pointer is returned when
 /*     the DNS query for the TLSA record tempfailed.  In all other cases the
 /* .IP dane
 /*     Pointer to a TLS_DANE structure that lists the valid trust-anchor
 /*     and end-entity full-certificate and/or public-key digests.
-/* .IP host
+/* .IP qname
+/*     FQDN of target service (original input form).
+/* .IP rname
 /*     DNSSEC validated (cname resolved) FQDN of target service.
 /* .IP proto
 /*     Almost certainly "tcp".
@@ -366,6 +369,7 @@ TLS_DANE *tls_dane_alloc(int flags)
     dane->ee = 0;
     dane->certs = 0;
     dane->pkeys = 0;
+    dane->base_domain = 0;
     dane->flags = flags;
     dane->expires = 0;
     dane->refs = 1;
@@ -450,6 +454,8 @@ void    tls_dane_free(TLS_DANE *dane)
     /* De-allocate full trust-anchor certs and pkeys */
     free_ta_certs(dane);
     free_ta_pkeys(dane);
+    if (dane->base_domain)
+       myfree(dane->base_domain);
 
     myfree((char *) dane);
 }
@@ -820,14 +826,33 @@ static void *dane_lookup(const char *tlsa_fqdn, void *unused_ctx)
     return (void *) dane;
 }
 
+/* resolve_host - resolve TLSA RRs for hostname (rname or qname) */
+
+static TLS_DANE *resolve_host(const char *host, const char *proto,
+                                     unsigned port)
+{
+    static VSTRING *query_domain;
+    TLS_DANE *dane;
+
+    if (query_domain == 0)
+       query_domain = vstring_alloc(64);
+
+    vstring_sprintf(query_domain, "_%u._%s.%s", ntohs(port), proto, host);
+    dane = (TLS_DANE *) ctable_locate(dane_cache, STR(query_domain));
+    if (timecmp(event_time(), dane->expires) > 0)
+       dane = (TLS_DANE *) ctable_refresh(dane_cache, STR(query_domain));
+    if (dane->base_domain == 0)
+       dane->base_domain = mystrdup(host);
+    return (dane);
+}
+
 #endif
 
-/* tls_dane_resolve - cached map: (host, proto, port) -> TLS_DANE */
+/* tls_dane_resolve - cached map: (name, proto, port) -> TLS_DANE */
 
-TLS_DANE *tls_dane_resolve(const char *host, const char *proto,
-                                  unsigned port)
+TLS_DANE *tls_dane_resolve(const char *qname, const char *rname,
+                                  const char *proto, unsigned port)
 {
-    static VSTRING *qname;
     TLS_DANE *dane = 0;
 
 #ifdef DANE_TLSA_SUPPORT
@@ -837,13 +862,16 @@ TLS_DANE *tls_dane_resolve(const char *host, const char *proto,
     if (!dane_cache)
        dane_cache = ctable_create(CACHE_SIZE, dane_lookup, dane_free, 0);
 
-    if (qname == 0)
-       qname = vstring_alloc(64);
-    vstring_sprintf(qname, "_%u._%s.%s", ntohs(port), proto, host);
-    dane = (TLS_DANE *) ctable_locate(dane_cache, STR(qname));
-    if (timecmp(event_time(), dane->expires) > 0)
-       dane = (TLS_DANE *) ctable_refresh(dane_cache, STR(qname));
-
+    /*
+     * Try the rname first, if nothing there, try the qname.  Note, lookup
+     * errors are distinct from success with nothing found.  If the rname
+     * lookup fails we don't try the qname.  The rname may be null when only
+     * the qname is in a secure zone.
+     */
+    if (rname)
+       dane = resolve_host(rname, proto, port);
+    if (!rname || (tls_dane_notfound(dane) && strcmp(qname, rname) != 0))
+       dane = resolve_host(qname, proto, port);
     if (dane->flags & TLS_DANE_FLAG_ERROR)
        return (0);
 
@@ -1193,7 +1221,7 @@ static int wrap_key(TLS_SESS_STATE *TLScontext, EVP_PKEY *key, X509 *subject,
        || !add_skid(cert, akid)
        || (wrap_signed
            && (!X509_sign(cert, danekey, signmd)
-               || (key && !wrap_key(TLScontext, 0, cert, depth + 1))))) {
+               || (key && !wrap_key(TLScontext, 0, cert, depth + 1))))) {
        msg_warn("error generating DANE wrapper certificate");
        tls_print_errors();
        ret = 0;
@@ -1391,4 +1419,3 @@ void    tls_dane_set_callback(SSL_CTX *ctx, TLS_SESS_STATE *TLScontext)
 }
 
 #endif                                 /* USE_TLS */
-
index ef40143700e7e663e4f34d8a9ae216d7e8896a34..683f3673445fc7ba007c14c13e483293363b88d3 100644 (file)
 /*     int     tls_mgr_delete(cache_type, cache_id)
 /*     const char *cache_type;
 /*     const char *cache_id;
+/*
+/*     TLS_TICKET_KEY *tls_mgr_key(keyname, timeout)
+/*     unsigned char *keyname;
+/*     int     timeout;
 /* DESCRIPTION
 /*     These routines communicate with the tlsmgr(8) server for
 /*     entropy and session cache management. Since these are
 /*     tls_mgr_delete() removes specified session from
 /*     the specified session cache.
 /*
-/*     Arguments
+/*     tls_mgr_key() is used to retrieve the current TLS session ticket
+/*     encryption or decryption keys.
+/*
+/*     Arguments:
 /* .IP cache_type
 /*     One of TLS_MGR_SCACHE_SMTPD, TLS_MGR_SCACHE_SMTP or
 /*     TLS_MGR_SCACHE_LMTP.
 /*     The result or input buffer.
 /* .IP len
 /*     The length of the input buffer, or the amount of data requested.
+/* .IP keyname
+/*     Is null when requesting the current encryption keys.  Otherwise,
+/*     keyname is a pointer to an array of TLS_TICKET_NAMELEN unsigned
+/*     chars (not NUL terminated) that is an identifier for a key
+/*     previously used to encrypt a session ticket.  When encrypting
+/*     a null result indicates that session tickets are not supported, when
+/*     decrypting it indicates that no matching keys were found.
+/* .IP timeout
+/*     The encryption key timeout.  Once a key has been active for this many
+/*     seconds it is retired and used only for decrypting previously issued
+/*     session tickets for another timeout seconds, and is then destroyed.
+/*     The timeout must not be longer than half the SSL session lifetime.
 /* DIAGNOSTICS
 /*     All client functions return one of the following status codes:
 /* .IP TLS_MGR_STAT_OK
 
 #include <mail_params.h>
 #include <mail_proto.h>
+
+/* TLS library. */
 #include <tls_mgr.h>
 
 /* Application-specific. */
 
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
 static ATTR_CLNT *tls_mgr;
 
 /* tls_mgr_open - create client handle */
@@ -174,7 +198,7 @@ int     tls_mgr_seed(VSTRING *buf, int len)
 
 /* tls_mgr_policy - request caching policy */
 
-int     tls_mgr_policy(const char *cache_type, int *cachable)
+int     tls_mgr_policy(const char *cache_type, int *cachable, int *timeout)
 {
     int     status;
 
@@ -195,7 +219,8 @@ int     tls_mgr_policy(const char *cache_type, int *cachable)
                          ATTR_FLAG_MISSING,    /* Reply attributes */
                          ATTR_TYPE_INT, TLS_MGR_ATTR_STATUS, &status,
                          ATTR_TYPE_INT, TLS_MGR_ATTR_CACHABLE, cachable,
-                         ATTR_TYPE_END) != 2)
+                         ATTR_TYPE_INT, TLS_MGR_ATTR_SESSTOUT, timeout,
+                         ATTR_TYPE_END) != 3)
        status = TLS_MGR_STAT_FAIL;
     return (status);
 }
@@ -288,6 +313,65 @@ int     tls_mgr_delete(const char *cache_type, const char *cache_id)
     return (status);
 }
 
+/* request_scache_key - ask tlsmgr(8) for matching key */
+
+static TLS_TICKET_KEY *request_scache_key(unsigned char *keyname)
+{
+    TLS_TICKET_KEY tmp;
+    static VSTRING *keybuf;
+    char   *name;
+    size_t  len;
+    int     status;
+
+    /*
+     * Create the tlsmgr client handle.
+     */
+    if (tls_mgr == 0)
+       tls_mgr_open();
+
+    if (keybuf == 0)
+       keybuf = vstring_alloc(sizeof(tmp));
+
+    /* In tlsmgr requests we encode null key names as empty strings. */
+    name = keyname ? (char *) keyname : "";
+    len = keyname ? TLS_TICKET_NAMELEN : 0;
+
+    /*
+     * Send the request and receive the reply.
+     */
+    if (attr_clnt_request(tls_mgr,
+                         ATTR_FLAG_NONE,       /* Request */
+                       ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_TKTKEY,
+                         ATTR_TYPE_DATA, TLS_MGR_ATTR_KEYNAME, len, name,
+                         ATTR_TYPE_END,
+                         ATTR_FLAG_MISSING,    /* Reply */
+                         ATTR_TYPE_INT, TLS_MGR_ATTR_STATUS, &status,
+                         ATTR_TYPE_DATA, TLS_MGR_ATTR_KEYBUF, keybuf,
+                         ATTR_TYPE_END) != 2
+       || status != TLS_MGR_STAT_OK
+       || LEN(keybuf) != sizeof(tmp))
+       return (0);
+
+    memcpy((char *) &tmp, STR(keybuf), sizeof(tmp));
+    return (tls_scache_key_rotate(&tmp));
+}
+
+/* tls_mgr_key - session ticket key lookup, local cache, then tlsmgr(8) */
+
+TLS_TICKET_KEY *tls_mgr_key(unsigned char *keyname, int timeout)
+{
+    TLS_TICKET_KEY *key = 0;
+    time_t  now = time((time_t *) 0);
+
+    /* A zero timeout disables session tickets. */
+    if (timeout <= 0)
+       return (0);
+
+    if ((key = tls_scache_key(keyname, now, timeout)) == 0)
+       key = request_scache_key(keyname);
+    return (key);
+}
+
 #ifdef TEST
 
 /* System library. */
@@ -307,9 +391,6 @@ int     tls_mgr_delete(const char *cache_type, const char *cache_id)
 
 /* Application-specific. */
 
-#define STR(x) vstring_str(x)
-#define LEN(x) VSTRING_LEN(x)
-
 int     main(int unused_ac, char **av)
 {
     VSTRING *inbuf = vstring_alloc(10);
@@ -332,7 +413,6 @@ int     main(int unused_ac, char **av)
            argv_free(argv);
            continue;
        }
-
 #define COMMAND(argv, str, len) \
     (strcasecmp(argv->argv[0], str) == 0 && argv->argc == len)
 
index bc9effffc6a073516abb3d5c3c49323dc27a5e55..c58417524892f5c3fddd38975c199ec92341c2a3 100644 (file)
 /* DESCRIPTION
 /* .nf
 
+ /*
+  * TLS library
+  */
+#include <tls_scache.h>                        /* Session ticket keys */
+
  /*
   * TLS manager protocol.
   */
@@ -23,6 +28,7 @@
 #define TLS_MGR_REQ_LOOKUP     "lookup"
 #define TLS_MGR_REQ_UPDATE     "update"
 #define TLS_MGR_REQ_DELETE     "delete"
+#define TLS_MGR_REQ_TKTKEY     "tktkey"
 #define TLS_MGR_ATTR_CACHABLE  "cachable"
 #define TLS_MGR_ATTR_CACHE_TYPE        "cache_type"
 #define TLS_MGR_ATTR_SEED      "seed"
@@ -30,6 +36,9 @@
 #define TLS_MGR_ATTR_SESSION   "session"
 #define TLS_MGR_ATTR_SIZE      "size"
 #define TLS_MGR_ATTR_STATUS    "status"
+#define TLS_MGR_ATTR_KEYNAME   "keyname"
+#define TLS_MGR_ATTR_KEYBUF    "keybuf"
+#define TLS_MGR_ATTR_SESSTOUT  "timeout"
 
  /*
   * TLS manager request status codes.
   * Functional interface.
   */
 extern int tls_mgr_seed(VSTRING *, int);
-extern int tls_mgr_policy(const char *, int *);
+extern int tls_mgr_policy(const char *, int *, int *);
 extern int tls_mgr_lookup(const char *, const char *, VSTRING *);
 extern int tls_mgr_update(const char *, const char *, const char *, ssize_t);
 extern int tls_mgr_delete(const char *, const char *);
+extern TLS_TICKET_KEY *tls_mgr_key(unsigned char *, int);
 
 /* LICENSE
 /* .ad
index 3fd8b5313b39e385e24bf2400c6f5d397e5c8c95..9eadfc410669a67085895f0dc9f2c6eddd75068b 100644 (file)
 /*     int     tls_scache_delete(cache, cache_id)
 /*     TLS_SCACHE *cache;
 /*     const char *cache_id;
+/*
+/*     TLS_TICKET_KEY *tls_scache_key(keyname, now, timeout)
+/*     unsigned char *keyname;
+/*     time_t  now;
+/*     int     timeout;
+/*
+/*     TLS_TICKET_KEY *tls_scache_key_rotate(newkey)
+/*     TLS_TICKET_KEY *newkey;
 /* DESCRIPTION
 /*     This module maintains Postfix TLS session cache files.
 /*     each session is stored under a lookup key (hostname or
 /*     tls_scache_delete() removes the specified cache entry from
 /*     the specified TLS session cache.
 /*
+/*     tls_scache_key() locates a TLS session ticket key in a 2-element
+/*     in-memory cache.  A null result is returned if no unexpired matching
+/*     key is found.
+/*
+/*     tls_scache_key_rotate() saves a TLS session tickets key in the
+/*     in-memory cache.
+/*
 /*     Arguments:
 /* .IP dbname
 /*     The base name of the session cache file.
 /*
 /*     Specify TLS_SCACHE_DONT_NEED_SESSION to avoid
 /*     saving the session information in the cache entry.
+/* .IP keyname
+/*     Is null when requesting the current encryption keys.  Otherwise,
+/*     keyname is a pointer to an array of TLS_TICKET_NAMELEN unsigned
+/*     chars (not NUL terminated) that is an identifier for a key
+/*     previously used to encrypt a session ticket.
+/* .IP now
+/*     Current epoch time passed by caller.
+/* .IP timeout
+/*     TLS session ticket encryption lifetime.
+/* .IP newkey
+/*     TLS session ticket key obtained from tlsmgr(8) to be added to
+ *     internal cache.
 /* DIAGNOSTICS
 /*     These routines terminate with a fatal run-time error
 /*     for unrecoverable database errors. This allows the
 #include <hex_code.h>
 #include <myflock.h>
 #include <vstring.h>
+#include <timecmp.h>
 
 /* Global library. */
 
@@ -150,6 +178,8 @@ typedef struct {
     char    session[1];                        /* actually a bunch of bytes */
 } TLS_SCACHE_ENTRY;
 
+static TLS_TICKET_KEY *keys[2];
+
  /*
   * SLMs.
   */
@@ -504,4 +534,60 @@ void    tls_scache_close(TLS_SCACHE *cp)
     myfree((char *) cp);
 }
 
+/* tls_scache_key - find session ticket key for given key name */
+
+TLS_TICKET_KEY *tls_scache_key(unsigned char *keyname, time_t now, int timeout)
+{
+    int     i;
+
+    /*
+     * The keys array contains 2 elements, the current signing key and the
+     * previous key.
+     * 
+     * When name == 0 we are issuing a ticket, otherwise decrypting an existing
+     * ticket with the given key name.  For new tickets we always use the
+     * current key if unexpired.  For existing tickets, we use either the
+     * current or previous key with a validation expiration that is timeout
+     * longer than the signing expiration.
+     */
+    if (keyname) {
+       for (i = 0; i < 2 && keys[i]; ++i) {
+           if (memcmp(keyname, keys[i]->name, TLS_TICKET_NAMELEN) == 0) {
+               if (timecmp(keys[i]->tout + timeout, now) > 0)
+                   return (keys[i]);
+               break;
+           }
+       }
+    } else if (keys[0]) {
+       if (timecmp(keys[0]->tout, now) > 0)
+           return (keys[0]);
+    }
+    return (0);
+}
+
+/* tls_scache_key_rotate - rotate session ticket keys */
+
+TLS_TICKET_KEY *tls_scache_key_rotate(TLS_TICKET_KEY *newkey)
+{
+
+    /*
+     * Allocate or re-use storage of retired key, then overwrite it, since
+     * caller's key data is ephemeral.
+     */
+    if (keys[1] == 0)
+       keys[1] = (TLS_TICKET_KEY *) mymalloc(sizeof(*newkey));
+    *keys[1] = *newkey;
+    newkey = keys[1];
+
+    /*
+     * Rotate if required, ensuring that the keys are sorted by expiration
+     * time with keys[0] expiring last.
+     */
+    if (keys[0] == 0 || keys[0]->tout < keys[1]->tout) {
+       keys[1] = keys[0];
+       keys[0] = newkey;
+    }
+    return (newkey);
+}
+
 #endif
index 78903416db0f6413c7cd3fb3b271ad8daae981e0..fe6b40f85acd64299bc511dca2e74b31cdec3737 100644 (file)
@@ -29,6 +29,19 @@ typedef struct {
     char   *saved_cursor;              /* cursor cache ID */
 } TLS_SCACHE;
 
+#define TLS_TICKET_NAMELEN     16      /* RFC 5077 ticket key name length */
+#define TLS_TICKET_IVLEN       16      /* RFC 5077 ticket IV length */
+#define TLS_TICKET_KEYLEN      16      /* AES-128-CBC key size */
+#define TLS_TICKET_MACLEN      16      /* SHA-256 collision strength */
+#define TLS_SESSION_LIFEMIN    120     /* May you live to 120! */
+
+typedef struct TLS_TICKET_KEY {
+    unsigned char name[TLS_TICKET_NAMELEN];
+    unsigned char bits[TLS_TICKET_KEYLEN];
+    unsigned char hmac[TLS_TICKET_MACLEN];
+    time_t  tout;
+} TLS_TICKET_KEY;
+
 #define TLS_SCACHE_FLAG_DEL_SAVED_CURSOR       (1<<0)
 
 extern TLS_SCACHE *tls_scache_open(const char *, const char *, int, int);
@@ -37,6 +50,8 @@ extern int tls_scache_lookup(TLS_SCACHE *, const char *, VSTRING *);
 extern int tls_scache_update(TLS_SCACHE *, const char *, const char *, ssize_t);
 extern int tls_scache_delete(TLS_SCACHE *, const char *);
 extern int tls_scache_sequence(TLS_SCACHE *, int, char **, VSTRING *);
+extern TLS_TICKET_KEY *tls_scache_key(unsigned char *, time_t, int);
+extern TLS_TICKET_KEY *tls_scache_key_rotate(TLS_TICKET_KEY *);
 
 #define TLS_SCACHE_DONT_NEED_CACHE_ID          ((char **) 0)
 #define TLS_SCACHE_DONT_NEED_SESSION           ((VSTRING *) 0)
index d31c772c1469f5feafae23437cbaf976fa4d845c..680046fb1e5725b9292ec2eda2dbc05e6233a7cf 100644 (file)
@@ -276,6 +276,47 @@ static int new_server_session_cb(SSL *ssl, SSL_SESSION *session)
     return (1);
 }
 
+#define NOENGINE       ((ENGINE *) 0)
+#define TLS_TKT_NOKEYS -1              /* No keys for encryption */
+#define TLS_TKT_STALE  0               /* No matching keys for decryption */
+#define TLS_TKT_ACCEPT 1               /* Ticket decryptable and re-usable */
+#define TLS_TKT_REISSUE        2               /* Ticket decryptable, not re-usable */
+
+/* ticket_cb - configure tls session ticket encrypt/decrypt context */
+
+static int ticket_cb(SSL *con, unsigned char name[], unsigned char iv[],
+                         EVP_CIPHER_CTX * ctx, HMAC_CTX * hctx, int create)
+{
+    static const EVP_MD *sha256;
+    static const EVP_CIPHER *aes128;
+    TLS_TICKET_KEY *key;
+    TLS_SESS_STATE *TLScontext = SSL_get_ex_data(con, TLScontext_index);
+    int     timeout = ((int) SSL_CTX_get_timeout(SSL_get_SSL_CTX(con))) / 2;
+
+    if ((!sha256 && (sha256 = EVP_sha256()) == 0)
+       || (!aes128 && (aes128 = EVP_aes_128_cbc()) == 0)
+       || (key = tls_mgr_key(create ? 0 : name, timeout)) == 0
+       || (create && RAND_bytes(iv, TLS_TICKET_IVLEN) <= 0))
+       return (create ? TLS_TKT_NOKEYS : TLS_TKT_STALE);
+
+    HMAC_Init_ex(hctx, key->hmac, TLS_TICKET_MACLEN, sha256, NOENGINE);
+
+    if (create) {
+       EVP_EncryptInit_ex(ctx, aes128, NOENGINE, key->bits, iv);
+       memcpy((char *) name, (char *) key->name, TLS_TICKET_NAMELEN);
+       if (TLScontext->log_mask & TLS_LOG_CACHE)
+           msg_info("%s: Issuing session ticket, key expiration: %ld",
+                    TLScontext->namaddr, (long) key->tout);
+    } else {
+       EVP_DecryptInit_ex(ctx, aes128, NOENGINE, key->bits, iv);
+       if (TLScontext->log_mask & TLS_LOG_CACHE)
+           msg_info("%s: Decrypting session ticket, key expiration: %ld",
+                    TLScontext->namaddr, (long) key->tout);
+    }
+    TLScontext->ticketed = 1;
+    return (TLS_TKT_ACCEPT);
+}
+
 /* tls_server_init - initialize the server-side TLS engine */
 
 TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
@@ -284,6 +325,8 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
     long    off = 0;
     int     verify_flags = SSL_VERIFY_NONE;
     int     cachable;
+    int     scache_timeout;
+    int     ticketable = 0;
     int     protomask;
     TLS_APPL_STATE *app_ctx;
     int     log_mask;
@@ -380,13 +423,42 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
      */
     SSL_CTX_set_verify_depth(server_ctx, props->verifydepth + 1);
 
+    /*
+     * The session cache is implemented by the tlsmgr(8) server.
+     * 
+     * XXX 200502 Surprise: when OpenSSL purges an entry from the in-memory
+     * cache, it also attempts to purge the entry from the on-disk cache.
+     * This is undesirable, especially when we set the in-memory cache size
+     * to 1. For this reason we don't allow OpenSSL to purge on-disk cache
+     * entries, and leave it up to the tlsmgr process instead. Found by
+     * Victor Duchovni.
+     */
+    if (tls_mgr_policy(props->cache_type, &cachable,
+                      &scache_timeout) != TLS_MGR_STAT_OK)
+       scache_timeout = 0;
+    if (scache_timeout <= 0)
+       cachable = 0;
+
     /*
      * Protocol work-arounds, OpenSSL version dependent.
      */
+    off |= tls_bug_bits();
+
+    /*
+     * Add SSL_OP_NO_TICKET when the timeout is zero or library support is
+     * incomplete.  The SSL_CTX_set_tlsext_ticket_key_cb feature was added in
+     * OpenSSL 0.9.8h, while SSL_NO_TICKET was added in 0.9.8f.
+     */
 #ifdef SSL_OP_NO_TICKET
-    off |= SSL_OP_NO_TICKET;
+#if !defined(OPENSSL_NO_TLSEXT) && OPENSSL_VERSION_NUMBER >= 0x0090808fL
+    ticketable = (scache_timeout > 0 && !(off & SSL_OP_NO_TICKET));
+    if (ticketable)
+       SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, ticket_cb);
 #endif
-    off |= tls_bug_bits();
+    if (!ticketable)
+       off |= SSL_OP_NO_TICKET;
+#endif
+
     SSL_CTX_set_options(server_ctx, off);
 
     /*
@@ -521,21 +593,7 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
      */
     app_ctx = tls_alloc_app_context(server_ctx, log_mask);
 
-    /*
-     * The session cache is implemented by the tlsmgr(8) server.
-     * 
-     * XXX 200502 Surprise: when OpenSSL purges an entry from the in-memory
-     * cache, it also attempts to purge the entry from the on-disk cache.
-     * This is undesirable, especially when we set the in-memory cache size
-     * to 1. For this reason we don't allow OpenSSL to purge on-disk cache
-     * entries, and leave it up to the tlsmgr process instead. Found by
-     * Victor Duchovni.
-     */
-
-    if (tls_mgr_policy(props->cache_type, &cachable) != TLS_MGR_STAT_OK)
-       cachable = 0;
-
-    if (cachable || props->set_sessid) {
+    if (cachable || ticketable || props->set_sessid) {
 
        /*
         * Initialize the session cache.
@@ -572,9 +630,14 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
        /*
         * OpenSSL ignores timed-out sessions. We need to set the internal
         * cache timeout at least as high as the external cache timeout. This
-        * applies even if no internal cache is used.
+        * applies even if no internal cache is used.  We set the session
+        * lifetime to twice the cache lifetime, which is also the issuing
+        * and retired key validation lifetime of session tickets keys. This
+        * way a session always lasts longer than the server's ability to
+        * decrypt its session ticket.  Otherwise, a bug in OpenSSL may fail
+        * to re-issue tickets when sessions decrypt, but are expired.
         */
-       SSL_CTX_set_timeout(server_ctx, props->scache_timeout);
+       SSL_CTX_set_timeout(server_ctx, 2 * scache_timeout);
     } else {
 
        /*
@@ -742,7 +805,8 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
      */
     TLScontext->session_reused = SSL_session_reused(TLScontext->con);
     if ((TLScontext->log_mask & TLS_LOG_CACHE) && TLScontext->session_reused)
-       msg_info("%s: Reusing old session", TLScontext->namaddr);
+       msg_info("%s: Reusing old session%s", TLScontext->namaddr,
+                TLScontext->ticketed ? " (RFC 5077 session ticket)" : "");
 
     /*
      * Let's see whether a peer certificate is available and what is the
index cab6caff200504bed54654d74d04d96c50409f16..83fd8eda88157a03f2597becb36f36647ec3facc 100644 (file)
 #include <mail_conf.h>
 #include <mail_params.h>
 #include <mail_version.h>
-#include <tls_mgr.h>
 #include <mail_proto.h>
 #include <data_redirect.h>
 
 /* TLS library. */
 
 #ifdef USE_TLS
+#include <tls_mgr.h>
 #define TLS_INTERNAL
 #include <tls.h>                       /* TLS_MGR_SCACHE_<type> */
 #include <tls_prng.h>
@@ -289,7 +289,7 @@ typedef struct {
     int    *cache_timeout;             /* main.cf parameter value */
 } TLSMGR_SCACHE;
 
-TLSMGR_SCACHE cache_table[] = {
+static TLSMGR_SCACHE cache_table[] = {
     TLS_MGR_SCACHE_SMTPD, 0, 0, &var_smtpd_tls_scache_db,
     VAR_SMTPD_TLS_LOGLEVEL,
     &var_smtpd_tls_loglevel, &var_smtpd_tls_scache_timeout,
@@ -302,6 +302,8 @@ TLSMGR_SCACHE cache_table[] = {
     0,
 };
 
+#define        smtpd_cache     (cache_table[0])
+
  /*
   * SLMs.
   */
@@ -455,6 +457,44 @@ static void tlsmgr_cache_run_event(int unused_event, char *ctx)
                        cache->cache_info->timeout);
 }
 
+/* tlsmgr_key - return matching or current RFC 5077 session ticket keys */
+
+static int tlsmgr_key(VSTRING *buffer, int timeout)
+{
+    TLS_TICKET_KEY *key;
+    TLS_TICKET_KEY tmp;
+    unsigned char *name;
+    time_t  now = time((time_t *) 0);
+
+    /* In tlsmgr requests we encode null key names as empty strings. */
+    name = LEN(buffer) ? (unsigned char *) STR(buffer) : 0;
+
+    /*
+     * Each key's encrypt and subsequent decrypt-only timeout is half of the
+     * total session timeout.
+     */
+    timeout /= 2;
+
+    /* Attempt to locate existing key */
+    if ((key = tls_scache_key(name, now, timeout)) == 0) {
+       if (name == 0) {
+           /* Create new encryption key */
+           if (RAND_bytes(tmp.name, TLS_TICKET_NAMELEN) <= 0
+               || RAND_bytes(tmp.bits, TLS_TICKET_KEYLEN) <= 0
+               || RAND_bytes(tmp.hmac, TLS_TICKET_MACLEN) <= 0)
+               return (TLS_MGR_STAT_ERR);
+           tmp.tout = now + timeout - 1;
+           key = tls_scache_key_rotate(&tmp);
+       } else {
+           /* No matching decryption key found */
+           return (TLS_MGR_STAT_ERR);
+       }
+    }
+    /* Return value overrites name buffer */
+    vstring_memcpy(buffer, (char *) key, sizeof(*key));
+    return (TLS_MGR_STAT_OK);
+}
+
 /* tlsmgr_loop - TLS manager main loop */
 
 static int tlsmgr_loop(char *unused_name, char **unused_argv)
@@ -667,6 +707,31 @@ static void tlsmgr_service(VSTREAM *client_stream, char *unused_service,
                       ATTR_TYPE_END);
        }
 
+       /*
+        * RFC 5077 TLS session ticket keys
+        */
+       else if (STREQ(STR(request), TLS_MGR_REQ_TKTKEY)) {
+           if (attr_scan(client_stream, ATTR_FLAG_STRICT,
+                         ATTR_TYPE_DATA, TLS_MGR_ATTR_KEYNAME, buffer,
+                         ATTR_TYPE_END) == 1) {
+               if (LEN(buffer) != 0 && LEN(buffer) != TLS_TICKET_NAMELEN) {
+                   msg_warn("invalid session ticket key name length: %ld",
+                            (long) LEN(buffer));
+                   VSTRING_RESET(buffer);
+               } else if (*smtpd_cache.cache_timeout <= 0) {
+                   status = TLS_MGR_STAT_ERR;
+                   VSTRING_RESET(buffer);
+               } else {
+                   status = tlsmgr_key(buffer, *smtpd_cache.cache_timeout);
+               }
+           }
+           attr_print(client_stream, ATTR_FLAG_NONE,
+                      ATTR_TYPE_INT, MAIL_ATTR_STATUS, status,
+                      ATTR_TYPE_DATA, TLS_MGR_ATTR_KEYBUF,
+                      LEN(buffer), STR(buffer),
+                      ATTR_TYPE_END);
+       }
+
        /*
         * Entropy request.
         */
@@ -698,6 +763,7 @@ static void tlsmgr_service(VSTREAM *client_stream, char *unused_service,
         */
        else if (STREQ(STR(request), TLS_MGR_REQ_POLICY)) {
            int     cachable = 0;
+           int     timeout = 0;
 
            if (attr_scan(client_stream, ATTR_FLAG_STRICT,
                          ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_TYPE, cache_type,
@@ -710,12 +776,14 @@ static void tlsmgr_service(VSTREAM *client_stream, char *unused_service,
                             STR(cache_type), TLS_MGR_REQ_POLICY);
                } else {
                    cachable = (ent->cache_info != 0) ? 1 : 0;
+                   timeout = *ent->cache_timeout;
                    status = TLS_MGR_STAT_OK;
                }
            }
            attr_print(client_stream, ATTR_FLAG_NONE,
                       ATTR_TYPE_INT, MAIL_ATTR_STATUS, status,
                       ATTR_TYPE_INT, TLS_MGR_ATTR_CACHABLE, cachable,
+                      ATTR_TYPE_INT, TLS_MGR_ATTR_SESSTOUT, timeout,
                       ATTR_TYPE_END);
        }
 
@@ -847,7 +915,15 @@ static void tlsmgr_pre_init(char *unused_name, char **unused_argv)
      */
     dup_filter = htable_create(sizeof(cache_table) / sizeof(cache_table[0]));
     for (ent = cache_table; ent->cache_label; ++ent) {
-       if (**ent->cache_db) {
+       /* Sanitize session timeout */
+       if (*ent->cache_timeout > 0) {
+           if (*ent->cache_timeout < TLS_SESSION_LIFEMIN)
+               *ent->cache_timeout = TLS_SESSION_LIFEMIN;
+       } else {
+           *ent->cache_timeout = 0;
+       }
+       /* External cache database disabled if timeout is non-positive */
+       if (*ent->cache_timeout > 0 && **ent->cache_db) {
            if ((dup_label = htable_find(dup_filter, *ent->cache_db)) != 0)
                msg_fatal("do not use the same TLS cache file %s for %s and %s",
                          *ent->cache_db, dup_label, ent->cache_label);
@@ -948,9 +1024,9 @@ int     main(int argc, char **argv)
     static const CONFIG_TIME_TABLE time_table[] = {
        VAR_TLS_RESEED_PERIOD, DEF_TLS_RESEED_PERIOD, &var_tls_reseed_period, 1, 0,
        VAR_TLS_PRNG_UPD_PERIOD, DEF_TLS_PRNG_UPD_PERIOD, &var_tls_prng_exch_period, 1, 0,
-       VAR_SMTPD_TLS_SCACHTIME, DEF_SMTPD_TLS_SCACHTIME, &var_smtpd_tls_scache_timeout, 0, 0,
-       VAR_SMTP_TLS_SCACHTIME, DEF_SMTP_TLS_SCACHTIME, &var_smtp_tls_scache_timeout, 0, 0,
-       VAR_LMTP_TLS_SCACHTIME, DEF_LMTP_TLS_SCACHTIME, &var_lmtp_tls_scache_timeout, 0, 0,
+       VAR_SMTPD_TLS_SCACHTIME, DEF_SMTPD_TLS_SCACHTIME, &var_smtpd_tls_scache_timeout, 0, MAX_SMTPD_TLS_SCACHETIME,
+       VAR_SMTP_TLS_SCACHTIME, DEF_SMTP_TLS_SCACHTIME, &var_smtp_tls_scache_timeout, 0, MAX_SMTP_TLS_SCACHETIME,
+       VAR_LMTP_TLS_SCACHTIME, DEF_LMTP_TLS_SCACHTIME, &var_lmtp_tls_scache_timeout, 0, MAX_LMTP_TLS_SCACHETIME,
        0,
     };
     static const CONFIG_INT_TABLE int_table[] = {
index eff987a6e14ef89a969b08e36bcf114cd6beaf35..eb826b00c0feb0f40356b38d040b94e59d64d789 100644 (file)
 /*     The SMTP TLS security level for the Postfix \fBtlsproxy\fR(8) server;
 /*     when a non-empty value is specified, this overrides the obsolete
 /*     parameters smtpd_use_tls and smtpd_enforce_tls.
-/* .IP "\fBtlsproxy_tls_session_cache_timeout ($smtpd_tls_session_cache_timeout)\fR"
-/*     The expiration time of Postfix \fBtlsproxy\fR(8) server TLS session
-/*     cache information.
 /* .PP
 /*     Available in Postfix version 2.11 and later:
 /* .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
   */
 int     var_smtpd_tls_ccert_vd;
 char   *var_smtpd_tls_loglevel;
-int     var_smtpd_tls_scache_timeout;
 bool    var_smtpd_use_tls;
 bool    var_smtpd_enforce_tls;
 bool    var_smtpd_tls_ask_ccert;
@@ -266,7 +262,6 @@ char   *var_smtpd_tls_level;
 
 int     var_tlsp_tls_ccert_vd;
 char   *var_tlsp_tls_loglevel;
-int     var_tlsp_tls_scache_timeout;
 bool    var_tlsp_use_tls;
 bool    var_tlsp_enforce_tls;
 bool    var_tlsp_tls_ask_ccert;
@@ -978,7 +973,6 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
                            log_level = var_tlsp_tls_loglevel,
                            verifydepth = var_tlsp_tls_ccert_vd,
                            cache_type = TLS_MGR_SCACHE_SMTPD,
-                           scache_timeout = var_tlsp_tls_scache_timeout,
                            set_sessid = var_tlsp_tls_set_sessid,
                            cert_file = cert_file,
                            key_file = var_tlsp_tls_key_file,
@@ -1036,9 +1030,7 @@ int     main(int argc, char **argv)
        0,
     };
     static const CONFIG_TIME_TABLE time_table[] = {
-       VAR_SMTPD_TLS_SCACHTIME, DEF_SMTPD_TLS_SCACHTIME, &var_smtpd_tls_scache_timeout, 0, 0,
        VAR_TLSP_WATCHDOG, DEF_TLSP_WATCHDOG, &var_tlsp_watchdog, 10, 0,
-       VAR_TLSP_TLS_SCACHTIME, DEF_TLSP_TLS_SCACHTIME, &var_tlsp_tls_scache_timeout, 0, 0,
        0,
     };
     static const CONFIG_BOOL_TABLE bool_table[] = {