]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.12-20141011
authorWietse Venema <wietse@porcupine.org>
Sat, 11 Oct 2014 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sun, 12 Oct 2014 19:29:42 +0000 (15:29 -0400)
39 files changed:
postfix/HISTORY
postfix/README_FILES/COMPATIBILITY_README
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/conf/main.cf
postfix/html/COMPATIBILITY_README.html
postfix/html/postconf.5.html
postfix/makedefs
postfix/man/man5/postconf.5
postfix/mantools/postlink
postfix/proto/COMPATIBILITY_README.html
postfix/proto/TLS_README.html
postfix/proto/postconf.proto
postfix/src/global/attr_override.c
postfix/src/global/bounce.c
postfix/src/global/dsn_filter.c
postfix/src/global/dynamicmaps.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/mkmap_open.c
postfix/src/global/smtputf8.c
postfix/src/smtp/lmtp_params.c
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp.h
postfix/src/smtp/smtp_chat.c
postfix/src/smtp/smtp_connect.c
postfix/src/smtp/smtp_key.c
postfix/src/smtp/smtp_params.c
postfix/src/smtp/smtp_proto.c
postfix/src/smtp/smtp_sasl_glue.c
postfix/src/smtp/smtp_sasl_proto.c
postfix/src/smtp/smtp_tls_policy.c
postfix/src/smtp/smtp_trouble.c
postfix/src/smtpd/smtpd_check.c
postfix/src/util/dict_pipe.c
postfix/src/util/dict_union.c
postfix/src/util/mac_expand.c
postfix/src/util/midna.c
postfix/src/util/valid_utf8_hostname.c

index 885a3562aed6f180892c321c17c89c0cb95eca94..97028e976c3d79407d1ed93d245bf59895741e98 100644 (file)
@@ -20604,3 +20604,39 @@ Apologies for any names omitted.
        Documentation: moved the gory details from postconf(5) to
        a new COMPATIBILITY_README document. Files: proto/postconf.proto,
        proto/COMPATIBILITY_README.html html/index.html.
+
+       Documentation: update the conf/main.cf compatibility_level setting 
+       for new Postfix installs, and updated a reminder in mail_params.h.
+
+20141010
+
+       Cleanup: make "const char myname[]" declarations static.
+       global/attr_override.c, global/bounce.c, global/dsn_filter.c,
+       global/dynamicmaps.c, global/mkmap_open.c, global/smtputf8.c,
+       smtp/smtp_key.c, smtpd/smtpd_check.c, util/dict_pipe.c,
+       util/dict_union.c, util/mac_expand.c, util/midna.c,
+       util/valid_utf8_hostname.c.
+
+       Documentation: summarize the user-specified "make makefiles"
+       settings at the top of makedefs.out. This file now has so
+       many internal variables that people would get lost.
+
+20141011
+
+       Cleanup: replaced cryptic macros X_SMTP() and SMTP_X() with
+       more descripive names: LMTP_SMTP_SUFFIX() and VAR_LMTP_SMTP().
+       Files: smtp/smtp.c, smtp/smtp.h, smtp/smtp_chat.c,
+       smtp/smtp_connect.c, smtp/smtp_proto.c, smtp/smtp_sasl_glue.c,
+       smtp/smtp_sasl_proto.c, smtp/smtp_tls_policy.c.
+
+       Feature:  support to fall back to an unauthenticated TLS
+       security level ("may" or "encrypt) when the Postfix SMTP
+       client cannot establish the preferred authenticated TLS
+       security level ("dane", "dane-only", "fingerprint", "verify",
+       or "secure"). The fall-back levels may be specified globally
+       with the smtp_tls_fallback_level parameter or in per-site
+       TLS policies with the "fallback" attribute.  Viktor Dukhovni.
+       Files: mantools/postlink, proto/TLS_README.html,
+       ./proto/postconf.proto, global/mail_params.h, smtp/lmtp_params.c,
+       smtp/smtp.c, smtp/smtp.h, smtp/smtp_connect.c, smtp/smtp_params.c,
+       smtp/smtp_proto.c, smtp/smtp_tls_policy.c, smtp/smtp_trouble.c.
index 79f39424a015e6fcba91a7c811a8f7a655e97e5a..74d7c579f74b5ebb36d9876912f8a8ddab3475a6 100644 (file)
@@ -50,26 +50,30 @@ as the append_dot_mydomain parameter is left at its implicit default value, and
 the backwards-compatible default setting is turned on, Postfix may log one of
 the following messages:
 
-  * postfix/trivial-rewrite[14777]: using backwards-compatible
-        default setting append_dot_mydomain=yes to rewrite
-        "localhost" to "localhost.example.com"; please add
-        "localhost" to mydestination or other address class
+  * Messages about missing "localhost" in mydestination or other address class:
+
+        postfix/trivial-rewrite[14777]: using backwards-compatible
+            default setting append_dot_mydomain=yes to rewrite
+            "localhost" to "localhost.example.com"; please add
+            "localhost" to mydestination or other address class
 
     If Postfix logs the above message, add "localhost" to mydestination (or
     virtual_alias_domains, virtual_mailbox_domains, or relay_domains) and
     execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd".
 
-  * postfix/trivial-rewrite[25835]: using backwards-compatible
-        default setting append_dot_mydomain=yes to rewrite "foo" to
-        "foo.example.com"
+  * Messages about incomplete domains in email addresses:
+
+        postfix/trivial-rewrite[25835]: using backwards-compatible
+            default setting append_dot_mydomain=yes to rewrite "foo" to
+            "foo.example.com"
 
     If Postfix logs the above message for domains different from "localhost",
     and the sender cannot be changed to use complete domain names in email
     addresses, then the system administrator should make the backwards-
     compatible setting "append_dot_mydomain = yes" permanent in main.cf:
 
-    # p\bpo\bos\bst\btc\bco\bon\bnf\bf a\bap\bpp\bpe\ben\bnd\bd_\b_d\bdo\bot\bt_\b_m\bmy\byd\bdo\bom\bma\bai\bin\bn=\b=y\bye\bes\bs
-    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+        # p\bpo\bos\bst\btc\bco\bon\bnf\bf a\bap\bpp\bpe\ben\bnd\bd_\b_d\bdo\bot\bt_\b_m\bmy\byd\bdo\bom\bma\bai\bin\bn=\b=y\bye\bes\bs
+        # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
 
 U\bUs\bsi\bin\bng\bg b\bba\bac\bck\bkw\bwa\bar\brd\bds\bs-\b-c\bco\bom\bmp\bpa\bat\bti\bib\bbl\ble\be d\bde\bef\bfa\bau\bul\blt\bt s\bse\bet\btt\bti\bin\bng\bg c\bch\bhr\bro\boo\bot\bt=\b=y\by
 
@@ -78,15 +82,15 @@ long as a master.cf chroot field is left at its implicit default value, and the
 backwards-compatible default setting is turned on, Postfix may log the
 following message while it reads the master.cf file:
 
-postfix/master[27664]: /etc/postfix/master.cf: line 72: using
-    backwards-compatible default setting chroot=y
+    postfix/master[27664]: /etc/postfix/master.cf: line 72: using
+        backwards-compatible default setting chroot=y
 
 If this service should remain chrooted, then the system administrator should
 make the backwards-compatible setting "chroot = y" permanent in master.cf. For
 example, to update the chroot setting for the "smtp inet" service:
 
-# p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-F\bF s\bsm\bmt\btp\bp/\b/i\bin\bne\bet\bt/\b/c\bch\bhr\bro\boo\bot\bt=\b=y\by
-# p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-F\bF s\bsm\bmt\btp\bp/\b/i\bin\bne\bet\bt/\b/c\bch\bhr\bro\boo\bot\bt=\b=y\by
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
 
 U\bUs\bsi\bin\bng\bg b\bba\bac\bck\bkw\bwa\bar\brd\bds\bs-\b-c\bco\bom\bmp\bpa\bat\bti\bib\bbl\ble\be d\bde\bef\bfa\bau\bul\blt\bt s\bse\bet\btt\bti\bin\bng\bg m\bmy\byn\bne\bet\btw\bwo\bor\brk\bks\bs_\b_s\bst\bty\byl\ble\be=\b=s\bsu\bub\bbn\bne\bet\bt
 
@@ -96,20 +100,20 @@ mynetworks and mynetworks_style parameters are left at their implicit default
 values, and the backwards-compatible default setting is turned on, the Postfix
 SMTP server may log one of the following messages:
 
-postfix/smtpd[17375]: using backwards-compatible default setting
-    mynetworks_style=subnet to permit request from client
-    "foo.example.com[10.1.1.1]"
+    postfix/smtpd[17375]: using backwards-compatible default setting
+        mynetworks_style=subnet to permit request from client
+        "foo.example.com[10.1.1.1]"
 
-postfix/postscreen[24982]: using backwards-compatible default
-    setting mynetworks_style=subnet to permit request from client
-    "10.1.1.1"
+    postfix/postscreen[24982]: using backwards-compatible default
+        setting mynetworks_style=subnet to permit request from client
+        "10.1.1.1"
 
 If the client request should not be rejected, then the system administrator
 should make the backwards-compatible setting "mynetworks_style = subnet"
 permanent in main.cf:
 
-# p\bpo\bos\bst\btc\bco\bon\bnf\bf m\bmy\byn\bne\bet\btw\bwo\bor\brk\bks\bs_\b_s\bst\bty\byl\ble\be=\b=s\bsu\bub\bbn\bne\bet\bt
-# p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf m\bmy\byn\bne\bet\btw\bwo\bor\brk\bks\bs_\b_s\bst\bty\byl\ble\be=\b=s\bsu\bub\bbn\bne\bet\bt
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
 
 U\bUs\bsi\bin\bng\bg b\bba\bac\bck\bkw\bwa\bar\brd\bds\bs-\b-c\bco\bom\bmp\bpa\bat\bti\bib\bbl\ble\be d\bde\bef\bfa\bau\bul\blt\bt s\bse\bet\btt\bti\bin\bng\bg r\bre\bel\bla\bay\by_\b_d\bdo\bom\bma\bai\bin\bns\bs=\b=$\b$m\bmy\byd\bde\bes\bst\bti\bin\bna\bat\bti\bio\bon\bn
 
@@ -118,33 +122,33 @@ value. As long as the relay_domains parameter is left at its implicit default
 value, and the backwards-compatible default setting is turned on, Postfix may
 log one of the following messages.
 
-Messages about accepting mail for a remote domain:
+  * Messages about accepting mail for a remote domain:
 
-postfix/smtpd[19052]: using backwards-compatible default setting
-    relay_domains=$mydestination to accept mail for domain
-    "foo.example.com"
+        postfix/smtpd[19052]: using backwards-compatible default setting
+            relay_domains=$mydestination to accept mail for domain
+            "foo.example.com"
 
-postfix/smtpd[19052]: using backwards-compatible default setting
-    relay_domains=$mydestination to accept mail for address
-    "user@foo.example.com"
+        postfix/smtpd[19052]: using backwards-compatible default setting
+            relay_domains=$mydestination to accept mail for address
+            "user@foo.example.com"
 
-Messages about providing ETRN service for a remote domain:
+  * Messages about providing ETRN service for a remote domain:
 
-postfix/smtpd[19138]: using backwards-compatible default setting
-    relay_domains=$mydestination to flush mail for domain
-    "bar.example.com"
+        postfix/smtpd[19138]: using backwards-compatible default setting
+            relay_domains=$mydestination to flush mail for domain
+            "bar.example.com"
 
-postfix/smtp[13945]: using backwards-compatible default setting
-    relay_domains=$mydestination to update fast-flush logfile for
-    domain "bar.example.com"
+        postfix/smtp[13945]: using backwards-compatible default setting
+            relay_domains=$mydestination to update fast-flush logfile for
+            domain "bar.example.com"
 
 If Postfix should continue to accept mail for that domain or continue to
 provide ETRN service for that domain, then the system administrator should make
 the backwards-compatible setting "relay_domains = $mydestination" permanent in
 main.cf:
 
-# p\bpo\bos\bst\btc\bco\bon\bnf\bf r\bre\bel\bla\bay\by_\b_d\bdo\bom\bma\bai\bin\bns\bs=\b=$\b$m\bmy\byd\bde\bes\bst\bti\bin\bna\bat\bti\bio\bon\bn
-# p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf r\bre\bel\bla\bay\by_\b_d\bdo\bom\bma\bai\bin\bns\bs=\b=$\b$m\bmy\byd\bde\bes\bst\bti\bin\bna\bat\bti\bio\bon\bn
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
 
 Instead of $mydestination, it may be better to specify an explicit list of
 domain names.
@@ -156,18 +160,18 @@ smtputf8_enable parameter is left at its implicit default value, and the
 backwards-compatible default setting is turned on, Postfix logs a warning each
 time an SMTP command uses a non-ASCII address localpart:
 
-postfix/smtpd[27560]: using backwards-compatible default setting
-    smtputf8_enable=no to accept non-ASCII sender address
-    "??@example.org" from localhost[127.0.0.1]
+    postfix/smtpd[27560]: using backwards-compatible default setting
+        smtputf8_enable=no to accept non-ASCII sender address
+        "??@example.org" from localhost[127.0.0.1]
 
-postfix/smtpd[27560]: using backwards-compatible default setting
-    smtputf8_enable=no to accept non-ASCII recipient address
-    "??@example.com" from localhost[127.0.0.1]
+    postfix/smtpd[27560]: using backwards-compatible default setting
+        smtputf8_enable=no to accept non-ASCII recipient address
+        "??@example.com" from localhost[127.0.0.1]
 
 If the address should not be rejected, and the client cannot be updated to use
 SMTPUTF8, then the system administrator should make the backwards-compatible
 setting "smtputf8_enable = no" permanent in main.cf:
 
-# p\bpo\bos\bst\btc\bco\bon\bnf\bf s\bsm\bmt\btp\bpu\but\btf\bf8\b8_\b_e\ben\bna\bab\bbl\ble\be=\b=n\bno\bo
-# p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf s\bsm\bmt\btp\bpu\but\btf\bf8\b8_\b_e\ben\bna\bab\bbl\ble\be=\b=n\bno\bo
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
 
index a5d2e2bf60b6e359f44151d25eb023e1cb4e7d5b..cde2d69a23cfd8a9aa333761ee907608c5086ae1 100644 (file)
@@ -21,18 +21,19 @@ Notes for distribution maintainers
 
 * New backwards-compatibility safety net.
 
+With NEW Postfix installs, you MUST install a main.cf file with
+the setting "compatibility_level = 2". See conf/main.cf for an
+example.
+
+With UPGRADES of existing Postfix systems, you MUST NOT change the
+main.cf compatibility_level setting (if any).
+
 Several Postfix default settings have changed with Postfix 2.12.
 To avoid massive breakage, Postfix comes with a safety net that
 forces Postfix to keep running with backwards-compatible main.cf
-and master.cf default settings.
-
-With NEW Postfix installs, you should install a main.cf file with
-the setting "compatibility_level = 1". See the stock main.cf file
-in the conf subdirectory.
-
-With existing Postfix UPGRADES, the main.cf compatibility_level
-setting (if any) MUST be left alone, to enable the backwards-compatibility
-safety net as discussed below.
+and master.cf default settings. This safety net depends on the
+main.cf compatibility_level setting (if any). Details are in
+COMPATIBILITY_README.
 
 * New Postfix build system.
 
@@ -58,12 +59,44 @@ Maintainers may also benefit from the makedefs documentation
 (mantools/srctoman - makedefs | nroff -man | less) with information
 about build options that are not described in the INSTALL instructions.
 
-Major changes with snapshot 20141001
+Major changes with snapshot 20141011
 ====================================
 
+Support to fall back to an unauthenticated TLS security level ("may"
+or "encrypt) when the Postfix SMTP client cannot establish the
+preferred authenticated TLS security level ("dane", "dane-only",
+"fingerprint", "verify", or "secure"). The fall-back levels may be
+specified globally with the smtp_tls_fallback_level parameter or
+in per-site TLS policies with the "fallback" attribute.
+
+Fallback to unauthenticated TLS is logged, so that downgrade attacks
+are "tamper-evident".  Fallback should be used only when testing,
+or temporarily when working around a known problem at a remote site.
+
+Incompatible changes with snapshot 20141008
+===========================================
+
+The default settings have changed for relay_domains (new: empty,
+old: $mydestination) and mynetworks_style (new: host, old: subnet).
+However the backwards-compatibility safety net will prevent these
+changes from taking effect, giving the system administrator the
+option to make an old default setting permanent in main.cf or to
+adopt the new default setting, before turning off backwards
+compatibility. See COMPATIBILITY_README for details.
+
+With this the built-in compatibility level changes from 1 to 2.
+
+Incompatible changes with snapshot 20141001
+===========================================
+
+The default settings have changed for append_dot_mydomain (new: no.
+old: yes), master.cf chroot (new: n, old: y), and smtputf8 (new:
+yes, old: no).
+
 A new backwards-compatibility safety net forces Postfix to run with
 backwards-compatible main.cf and master.cf default settings after
-an upgrade to a newer but incompatible Postfix version.
+an upgrade to a newer but incompatible Postfix version. See
+COMPATIBILITY_README for details.
 
 While the backwards-compatible default settings are in effect,
 Postfix logs what services or what email would be affected by the
@@ -73,6 +106,8 @@ before turning off backwards compatibility.
 
 See postconf.5.html#compatibility_level for details.
 
+With this the built-in compatibility level changes from 0 to 1.
+
 Major changes with snapshot 20140928
 ====================================
 
index 08b00701f36d28d1f30819d2338b579a9c1d6e99..3bc861825e472ce3366ee6994663e56c8cfb6176 100644 (file)
@@ -10,8 +10,6 @@ Wish list:
 
        Update smtputf8_enable in postconf(5)
 
-       use "static const char myname[] ..."
-
        Add milter_mumble_macros to the list of per-macro features.
 
        The pickup daemon logs warnings only when the cleanup daemon
@@ -28,7 +26,7 @@ Wish list:
        depend on these definitions.
 
        Error reporting: see if pcf_check_master_entry() and children
-       can return error descriptions instread of terminating with
+       can return error descriptions instead of terminating with
        a fatal error.
 
        Make sure that proxy: can handle random:, pipe:, and other
@@ -48,14 +46,15 @@ Wish list:
        filter should be content_filter. Posted Wed, 10 Sep 2014
        09:53:52 -0400 (EDT).
 
-       Clarify that receive_override_options should not be used
-       with smtpd_proxy_filter.
+       Clarify that receive_override_options have no effect with
+       smtpd_proxy_filter.
 
        Document the relative order of header_checks, address
        rewriting, milters.
 
-       Table-driven case folding and case-insensitive string 
-       comparison specifically for UTF-8.
+       NOT: Table-driven case folding and case-insensitive string
+       comparison specifically for UTF-8. Use libicu functions
+       instead.
 
        The postfix-mumble@postfix.org list manager sends list mail
        with ORCPT=rfc822;postfix-mumble-outgoing.  The local
@@ -75,13 +74,16 @@ Wish list:
        Don't accept AUTH or other features that are not announced
        in the EHLO response.
 
-       Per-Milter error action.
-
        Suggested at Mailserver conference: Postscreen RDNS-based
        reputation (but this makes postscreen performance highly
        unpredicable because it introduces a dependency on random
        DNS servers).
 
+       Suggested at Mailserver conference: a way to select a
+       specific field in a table, presumably as the result value.
+       This may be done with a filtermap{i,j,...}: table that propagates
+       only the specified field(s).
+
        Discourage the use of "after 220" tests in POSTSCREEN_README
        and the documentation of individual parameter settings.
 
@@ -126,14 +128,6 @@ Wish list:
        Wietse as the original author, and Lutz Jaenicke's license,
        which is wrong.
 
-       Code clarity: replace obscure macro/function names: for
-       example SMTP_X(XXX) -> VAR_SMTP(XXX), as the purpose is to
-       choose between VAR_SMTP_XXX or VAR_LMTP_XXX; replace
-       digestpl() etc. with names that make clear what operation
-       is being performed (in this case, update a digest with the
-       contents of a buffer with the specified length). Replace r
-       with res_opt, ditto for other 1-letter names.
-
        We have smtp_host_lookup, smtp_dns_resolver_options, and
        now smtp_dns_support_level.  Of these, smtp_dns_resolver_options
        is orthogonal but the rest has overlap.
index 82cb1b6a4b3ba451e37a029ec6b680c272eba02d..1fc886b824e2236b5dfc305686cfedada3feee47 100644 (file)
@@ -27,7 +27,7 @@
 #
 # The level below is what should be used with new (not upgrade) installs.
 #
-compatibility_level = 1
+compatibility_level = 2
 
 # SOFT BOUNCE
 #
index 1ea154f5c60d70be86834586c71e32bbe2d63d4a..56e242ab8d41f3f821009c384ead6243caa93f2f 100644 (file)
@@ -88,24 +88,31 @@ setting is turned on, Postfix may log one of the following messages:</p>
 
 <ul>
 
-<li>
+<li> <p> Messages about missing "localhost" in <a href="postconf.5.html#mydestination">mydestination</a> or
+other address class: </p>
+
+<blockquote>
 <pre>
 postfix/trivial-rewrite[14777]: using backwards-compatible
     default setting <a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a>=yes to rewrite
     "localhost" to "localhost.example.com"; please add
     "localhost" to <a href="postconf.5.html#mydestination">mydestination</a> or other address class
 </pre>
+</blockquote>
 
 <p> If Postfix logs the above message, add "localhost" to
 <a href="postconf.5.html#mydestination">mydestination</a> (or <a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>, <a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>,
 or <a href="postconf.5.html#relay_domains">relay_domains</a>) and execute the command "<b>postfix reload</b>".
 
-<li>
+<li> <p> Messages about incomplete domains in email addresses: </p>
+
+<blockquote>
 <pre>
 postfix/trivial-rewrite[25835]: using backwards-compatible
     default setting <a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a>=yes to rewrite "foo" to
     "foo.example.com"
 </pre>
+</blockquote>
 
 <p> If Postfix logs the above message for domains different from
 "localhost", and the sender cannot be changed to use complete domain
@@ -113,10 +120,12 @@ names in email addresses, then the system administrator should make
 the backwards-compatible setting "<a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a> = yes" permanent
 in <a href="postconf.5.html">main.cf</a>: </p>
 
+<blockquote>
 <pre>
 # <b>postconf <a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a>=yes</b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 </ul>
 
@@ -129,20 +138,24 @@ implicit default value, and the backwards-compatible default setting
 is turned on, Postfix may log the following message while it
 reads the <a href="master.5.html">master.cf</a> file: </p>
 
+<blockquote>
 <pre>
 postfix/master[27664]: /etc/postfix/<a href="master.5.html">master.cf</a>: line 72: using
     backwards-compatible default setting chroot=y
 </pre>
+</blockquote>
 
 <p> If this service should remain chrooted, then the system
 administrator should make the backwards-compatible setting "chroot
 = y" permanent in <a href="master.5.html">master.cf</a>.  For example, to update the chroot
 setting for the "smtp inet" service: </p>
 
+<blockquote>
 <pre>
 # <b>postconf -F smtp/inet/chroot=y</b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 <h2> <a name="mynetworks_style"> Using backwards-compatible default
 setting mynetworks_style=subnet</a> </h2>
@@ -154,26 +167,32 @@ are left at their implicit default values, and the backwards-compatible
 default setting is turned on, the Postfix SMTP server may log one
 of the following messages: </p>
 
+<blockquote>
 <pre>
 postfix/smtpd[17375]: using backwards-compatible default setting
     <a href="postconf.5.html#mynetworks_style">mynetworks_style</a>=subnet to permit request from client
     "foo.example.com[10.1.1.1]"
 </pre>
+</blockquote>
 
+<blockquote>
 <pre>
 postfix/postscreen[24982]: using backwards-compatible default
     setting <a href="postconf.5.html#mynetworks_style">mynetworks_style</a>=subnet to permit request from client
     "10.1.1.1"
 </pre>
+</blockquote>
 
 <p> If the client request should not be rejected, then the system
 administrator should make the backwards-compatible setting
 "<a href="postconf.5.html#mynetworks_style">mynetworks_style</a> = subnet" permanent in <a href="postconf.5.html">main.cf</a>: </p>
 
+<blockquote>
 <pre>
 # <b>postconf <a href="postconf.5.html#mynetworks_style">mynetworks_style</a>=subnet</b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 <h2><a name="relay_domains"> Using backwards-compatible default
 setting relay_domains=$mydestination </a> </h2>
@@ -184,43 +203,57 @@ at its implicit default value, and the backwards-compatible default
 setting is turned on, Postfix may log one of the following messages.
 </p>
 
-<p> Messages about accepting mail for a remote domain:</p>
+<ul>
+
+<li> <p> Messages about accepting mail for a remote domain:</p>
 
+<blockquote>
 <pre>
 postfix/smtpd[19052]: using backwards-compatible default setting
     <a href="postconf.5.html#relay_domains">relay_domains</a>=$<a href="postconf.5.html#mydestination">mydestination</a> to accept mail for domain
     "foo.example.com"
 </pre>
+</blockquote>
 
+<blockquote>
 <pre>
 postfix/smtpd[19052]: using backwards-compatible default setting
     <a href="postconf.5.html#relay_domains">relay_domains</a>=$<a href="postconf.5.html#mydestination">mydestination</a> to accept mail for address
     "user@foo.example.com"
 </pre>
+</blockquote>
 
-<p> Messages about providing ETRN service for a remote domain:</p>
+<li> <p> Messages about providing ETRN service for a remote domain:</p>
 
+<blockquote>
 <pre>
 postfix/smtpd[19138]: using backwards-compatible default setting
     <a href="postconf.5.html#relay_domains">relay_domains</a>=$<a href="postconf.5.html#mydestination">mydestination</a> to flush mail for domain
     "bar.example.com"
 </pre>
+</blockquote>
 
+<blockquote>
 <pre>
 postfix/smtp[13945]: using backwards-compatible default setting
     <a href="postconf.5.html#relay_domains">relay_domains</a>=$<a href="postconf.5.html#mydestination">mydestination</a> to update fast-flush logfile for
     domain "bar.example.com"
 </pre>
+</blockquote>
+
+</ul>
 
 <p> If Postfix should continue to accept mail for that domain or
 continue to provide ETRN service for that domain, then the system
 administrator should make the backwards-compatible setting
 "<a href="postconf.5.html#relay_domains">relay_domains</a> = $<a href="postconf.5.html#mydestination">mydestination</a>" permanent in <a href="postconf.5.html">main.cf</a>: </p>
 
+<blockquote>
 <pre>
 # <b>postconf <a href="postconf.5.html#relay_domains">relay_domains</a>=$<a href="postconf.5.html#mydestination">mydestination</a></b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 <p> Instead of $<a href="postconf.5.html#mydestination">mydestination</a>, it may be better to specify an
 explicit list of domain names. </p>
@@ -234,27 +267,33 @@ default value, and the backwards-compatible default setting is
 turned on, Postfix logs a warning each time an SMTP command uses a
 non-ASCII address localpart: </p>
 
+<blockquote>
 <pre>
 postfix/smtpd[27560]: using backwards-compatible default setting
     <a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a>=no to accept non-ASCII sender address
     "??@example.org" from localhost[127.0.0.1]
 </pre>
+</blockquote>
 
+<blockquote>
 <pre>
 postfix/smtpd[27560]: using backwards-compatible default setting
     <a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a>=no to accept non-ASCII recipient address
     "??@example.com" from localhost[127.0.0.1]
 </pre>
+</blockquote>
 
 <p> If the address should not be rejected, and the client cannot
 be updated to use SMTPUTF8, then the system administrator should
 make the backwards-compatible setting "<a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> = no" permanent
 in <a href="postconf.5.html">main.cf</a>:
 
+<blockquote>
 <pre>
 # <b>postconf <a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a>=no</b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 </body>
 
index db4540db748781a65cef3408ca347ef3efe40560..e4e47d80dd6d898f478237bb36023c04b781c1c7 100644 (file)
@@ -1552,9 +1552,11 @@ message when a backwards-compatible default setting is required.
 
 <blockquote>
 <pre>
-using backwards-compatible default setting <i>name=value</i> to [accept a specific client request]
+using backwards-compatible default setting <i>name=value</i>
+    to [accept a specific client request]
 
-using backwards-compatible default setting <i>name=value</i> to [enable specific Postfix behavior]
+using backwards-compatible default setting <i>name=value</i>
+    to [enable specific Postfix behavior]
 </pre>
 </blockquote>
 
@@ -1586,7 +1588,8 @@ warning message: </p>
 
 <blockquote>
 <pre>
-warning: To disable backwards compatibility use "postconf <a href="postconf.5.html#compatibility_level">compatibility_level</a>=<i>N</i>" and "postfix reload"
+warning: To disable backwards compatibility use "postconf
+    <a href="postconf.5.html#compatibility_level">compatibility_level</a>=<i>N</i>" and "postfix reload"
 </pre>
 </blockquote>
 
index 827e1ff81fc2f71dd2e86b177de1462600f23bc4..1566b955e6bc415137198206ffacb9d8e68385f3 100644 (file)
 
 # Emit system-dependent Makefile macro definitions to standard output.
 
+echo "#----------------------------------------------------------------"
+echo "# Start of summary of user-configurable 'make makefiles' options."
+echo "# CCARGS=$CCARGS"
+echo "# AUXLIBS=$AUXLIBS"
+env | grep '^AUXLIBS_' | sed 's/^/# /'
+echo "# dynamicmaps=$dynamicmaps"
+
 # Defaults for most sane systems
 
 RANLIB=ranlib
@@ -807,6 +814,7 @@ EOF
 
 process_input_parameter()
 {
+    echo "#" $parm_name=$parm_val
     case "$parm_val" in
     *MAIL_VERSION*)
        cparm_val=`echo "$parm_val" | \
@@ -883,6 +891,9 @@ do
     esac
 done
 
+echo "# End of summary of user-configurable 'make makefiles' options."
+echo "#--------------------------------------------------------------"
+
 # The following are for non-shared libsasl and libmilter builds.
 
 _AR=$AR
index b43e11199c54721bcc5d5311cd1d8ff5471e8448..daeebcb9c361cfcc1dbec7d967cb55895f9e98ed 100644 (file)
@@ -904,9 +904,11 @@ message when a backwards-compatible default setting is required.
 .nf
 .na
 .ft C
-using backwards-compatible default setting \fIname=value\fR to [accept a specific client request]
+using backwards-compatible default setting \fIname=value\fR
+    to [accept a specific client request]
 .sp
-using backwards-compatible default setting \fIname=value\fR to [enable specific Postfix behavior]
+using backwards-compatible default setting \fIname=value\fR
+    to [enable specific Postfix behavior]
 .fi
 .ad
 .ft R
@@ -950,7 +952,8 @@ warning message:
 .nf
 .na
 .ft C
-warning: To disable backwards compatibility use "postconf compatibility_level=\fIN\fR" and "postfix reload"
+warning: To disable backwards compatibility use "postconf
+    compatibility_level=\fIN\fR" and "postfix reload"
 .fi
 .ad
 .ft R
index 97ee2364c5ab8dce66371cdd107dce5898422ba5..e285966a4c6071edf673add0156fdedf082a6aee 100755 (executable)
@@ -633,6 +633,8 @@ while (<>) {
     s;\bsmtp_starttls_timeout\b;<a href="postconf.5.html#smtp_starttls_timeout">$&</a>;g;
     s;\bsmtp_tls_CAfile\b;<a href="postconf.5.html#smtp_tls_CAfile">$&</a>;g;
     s;\bsmtp_tls_CApath\b;<a href="postconf.5.html#smtp_tls_CApath">$&</a>;g;
+    s;\bsmtp_tls_fallback_level\b;<a href="postconf.5.html#smtp_tls_fallback_level">$&</a>;g;
+    s;\blmtp_tls_fallback_level\b;<a href="postconf.5.html#lmtp_tls_fallback_level">$&</a>;g;
     s;\bsmtp_tls_cert_file\b;<a href="postconf.5.html#smtp_tls_cert_file">$&</a>;g;
     s;\bsmtp_tls_fingerprint_digest\b;<a href="postconf.5.html#smtp_tls_fingerprint_digest">$&</a>;g;
     s;\bsmtp_tls_protocols\b;<a href="postconf.5.html#smtp_tls_protocols">$&</a>;g;
index 187cc6c021c56bd6d9beae0dc16d7bbac27ced12..46b35537a68a36f6bd07c86d0cb6ffe8887c9cec 100644 (file)
@@ -88,24 +88,31 @@ setting is turned on, Postfix may log one of the following messages:</p>
 
 <ul>
 
-<li>
+<li> <p> Messages about missing "localhost" in mydestination or
+other address class: </p>
+
+<blockquote>
 <pre>
 postfix/trivial-rewrite[14777]: using backwards-compatible
     default setting append_dot_mydomain=yes to rewrite
     "localhost" to "localhost.example.com"; please add
     "localhost" to mydestination or other address class
 </pre>
+</blockquote>
 
 <p> If Postfix logs the above message, add "localhost" to
 mydestination (or virtual_alias_domains, virtual_mailbox_domains,
 or relay_domains) and execute the command "<b>postfix reload</b>".
 
-<li>
+<li> <p> Messages about incomplete domains in email addresses: </p>
+
+<blockquote>
 <pre>
 postfix/trivial-rewrite[25835]: using backwards-compatible
     default setting append_dot_mydomain=yes to rewrite "foo" to
     "foo.example.com"
 </pre>
+</blockquote>
 
 <p> If Postfix logs the above message for domains different from
 "localhost", and the sender cannot be changed to use complete domain
@@ -113,10 +120,12 @@ names in email addresses, then the system administrator should make
 the backwards-compatible setting "append_dot_mydomain = yes" permanent
 in main.cf: </p>
 
+<blockquote>
 <pre>
 # <b>postconf append_dot_mydomain=yes</b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 </ul>
 
@@ -129,20 +138,24 @@ implicit default value, and the backwards-compatible default setting
 is turned on, Postfix may log the following message while it
 reads the master.cf file: </p>
 
+<blockquote>
 <pre>
 postfix/master[27664]: /etc/postfix/master.cf: line 72: using
     backwards-compatible default setting chroot=y
 </pre>
+</blockquote>
 
 <p> If this service should remain chrooted, then the system
 administrator should make the backwards-compatible setting "chroot
 = y" permanent in master.cf.  For example, to update the chroot
 setting for the "smtp inet" service: </p>
 
+<blockquote>
 <pre>
 # <b>postconf -F smtp/inet/chroot=y</b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 <h2> <a name="mynetworks_style"> Using backwards-compatible default
 setting mynetworks_style=subnet</a> </h2>
@@ -154,26 +167,32 @@ are left at their implicit default values, and the backwards-compatible
 default setting is turned on, the Postfix SMTP server may log one
 of the following messages: </p>
 
+<blockquote>
 <pre>
 postfix/smtpd[17375]: using backwards-compatible default setting
     mynetworks_style=subnet to permit request from client
     "foo.example.com[10.1.1.1]"
 </pre>
+</blockquote>
 
+<blockquote>
 <pre>
 postfix/postscreen[24982]: using backwards-compatible default
     setting mynetworks_style=subnet to permit request from client
     "10.1.1.1"
 </pre>
+</blockquote>
 
 <p> If the client request should not be rejected, then the system
 administrator should make the backwards-compatible setting
 "mynetworks_style = subnet" permanent in main.cf: </p>
 
+<blockquote>
 <pre>
 # <b>postconf mynetworks_style=subnet</b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 <h2><a name="relay_domains"> Using backwards-compatible default
 setting relay_domains=$mydestination </a> </h2>
@@ -184,43 +203,57 @@ at its implicit default value, and the backwards-compatible default
 setting is turned on, Postfix may log one of the following messages.
 </p>
 
-<p> Messages about accepting mail for a remote domain:</p>
+<ul>
+
+<li> <p> Messages about accepting mail for a remote domain:</p>
 
+<blockquote>
 <pre>
 postfix/smtpd[19052]: using backwards-compatible default setting
     relay_domains=$mydestination to accept mail for domain
     "foo.example.com"
 </pre>
+</blockquote>
 
+<blockquote>
 <pre>
 postfix/smtpd[19052]: using backwards-compatible default setting
     relay_domains=$mydestination to accept mail for address
     "user@foo.example.com"
 </pre>
+</blockquote>
 
-<p> Messages about providing ETRN service for a remote domain:</p>
+<li> <p> Messages about providing ETRN service for a remote domain:</p>
 
+<blockquote>
 <pre>
 postfix/smtpd[19138]: using backwards-compatible default setting
     relay_domains=$mydestination to flush mail for domain
     "bar.example.com"
 </pre>
+</blockquote>
 
+<blockquote>
 <pre>
 postfix/smtp[13945]: using backwards-compatible default setting
     relay_domains=$mydestination to update fast-flush logfile for
     domain "bar.example.com"
 </pre>
+</blockquote>
+
+</ul>
 
 <p> If Postfix should continue to accept mail for that domain or
 continue to provide ETRN service for that domain, then the system
 administrator should make the backwards-compatible setting
 "relay_domains = $mydestination" permanent in main.cf: </p>
 
+<blockquote>
 <pre>
 # <b>postconf relay_domains=$mydestination</b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 <p> Instead of $mydestination, it may be better to specify an
 explicit list of domain names. </p>
@@ -234,27 +267,33 @@ default value, and the backwards-compatible default setting is
 turned on, Postfix logs a warning each time an SMTP command uses a
 non-ASCII address localpart: </p>
 
+<blockquote>
 <pre>
 postfix/smtpd[27560]: using backwards-compatible default setting
     smtputf8_enable=no to accept non-ASCII sender address
     "??@example.org" from localhost[127.0.0.1]
 </pre>
+</blockquote>
 
+<blockquote>
 <pre>
 postfix/smtpd[27560]: using backwards-compatible default setting
     smtputf8_enable=no to accept non-ASCII recipient address
     "??@example.com" from localhost[127.0.0.1]
 </pre>
+</blockquote>
 
 <p> If the address should not be rejected, and the client cannot
 be updated to use SMTPUTF8, then the system administrator should
 make the backwards-compatible setting "smtputf8_enable = no" permanent
 in main.cf:
 
+<blockquote>
 <pre>
 # <b>postconf smtputf8_enable=no</b>
 # <b>postfix reload</b>
 </pre>
+</blockquote>
 
 </body>
 
index bc492ebd506d2fd8e7dcdbc82aaec3db558af460..c63ab9e5ed4f60f4b74d41a23a2bf382d047a50d 100644 (file)
@@ -1373,8 +1373,12 @@ for early adopters. <p>
 <li> <p> The "example.com" destination uses DANE, but if TLSA records
 are not present or are unusable, mail is deferred. </p>
 
-<li> <p> The "example.org" destination uses DANE if possible, but if no TLSA
-records are found opportunistic TLS is used. </p>
+<li> <p> The "example.org" destination uses DANE if possible, but
+uses opportunistic TLS if no TLSA records are found.  The
+"fallback" attribute (Postfix &ge; 2.12) overrides the global
+main.cf smtp_tls_fallback_level parameter to employ unauthenticated
+mandatory encryption if DANE authentication fails, after logging a
+warning.  </p>
 </ul>
 
 <blockquote>
@@ -1394,26 +1398,16 @@ main.cf:
     # default_transport = smtp, but some destinations are special:
     #
     transport_maps = ${indexed}transport
-</pre>
-</blockquote>
 
-<blockquote>
-<pre>
 transport:
     example.com dane
     example.org dane
-</pre>
-</blockquote>
 
-<blockquote>
-<pre>
 tls_policy:
     example.com dane-only
-</pre>
-</blockquote>
+    # Postfix &ge; 2.12, per-destination smtp_tls_fallback_level override
+    example.org dane fallback=encrypt
 
-<blockquote>
-<pre>
 master.cf:
     dane       unix  -       -       n       -       -       smtp
       -o smtp_dns_support_level=dnssec
@@ -2146,7 +2140,10 @@ href="#client_tls_encrypt">encrypt</a>.  When usable TLSA records
 are obtained for the remote SMTP server, SSLv2 is automatically
 disabled (see smtp_tls_mandatory_protocols), and the server certificate
 must match the TLSA records.  RFC 6698 (DANE) TLS authentication
-and DNSSEC support is available with Postfix 2.11 and later.  </dd>
+and DNSSEC support is available with Postfix 2.11 and later.  
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
+</dd>
 
 <dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
 The TLS policy for the destination is obtained via TLSA records in
@@ -2155,7 +2152,10 @@ connection is made to the server.  When usable TLSA records are
 obtained for the remote SMTP server, SSLv2 is automatically disabled
 (see smtp_tls_mandatory_protocols), and the server certificate must
 match the TLSA records.  RFC 6698 (DANE) TLS authentication and
-DNSSEC support is available with Postfix 2.11 and later.  </dd>
+DNSSEC support is available with Postfix 2.11 and later.  
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
+</dd>
 
 <dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
 fingerprint verification.</a> Available with Postfix 2.5 and
@@ -2164,13 +2164,15 @@ authorities. The certificate trust chain, expiration date, ... are
 not checked. Instead, the optional <b>match</b> attribute, or else
 the main.cf <b>smtp_tls_fingerprint_cert_match</b> parameter, lists
 the server certificate fingerprints or public key fingerprints
-(Postfix 2.9 and later).  The
-digest algorithm used to calculate fingerprints is selected by the
-<b>smtp_tls_fingerprint_digest</b> parameter. Multiple fingerprints can
-be combined with a "|" delimiter in a single match attribute, or multiple
-match attributes can be employed. The ":" character is not used as a
-delimiter as it occurs between each pair of fingerprint (hexadecimal)
-digits. </dd>
+(Postfix 2.9 and later).  The digest algorithm used to calculate
+fingerprints is selected by the <b>smtp_tls_fingerprint_digest</b>
+parameter. Multiple fingerprints can be combined with a "|" delimiter
+in a single match attribute, or multiple match attributes can be
+employed. The ":" character is not used as a delimiter as it occurs
+between each pair of fingerprint (hexadecimal) digits.
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
+</dd>
 
 <dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory
 server certificate verification</a>.  Mail is delivered only if the
@@ -2181,9 +2183,11 @@ the optional "match" attribute (or the main.cf smtp_tls_verify_cert_match
 parameter value when no optional "match" attribute is specified).
 With Postfix &ge; 2.11 the "tafile" attribute optionally modifies
 trust chain verification in the same manner as the
-"smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute
-may be specified multiple times to load multiple trust-anchor
-files.  </dd>
+"smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute may
+be specified multiple times to load multiple trust-anchor files.
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
+</dd>
 
 <dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate
 verification.</a> Mail is delivered only if the TLS handshake succeeds,
@@ -2195,7 +2199,10 @@ main.cf smtp_tls_secure_cert_match parameter value when no optional
 attribute optionally modifies trust chain verification in the same manner
 as the "smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute
 may be specified multiple times to load multiple trust-anchor
-files.  </dd>
+files.  
+The optional "fallback" attribute provides a per-site override of
+the main.cf smtp_tls_fallback_level parameter (Postfix &ge; 2.12).
+</dd>
 
 </dl>
 
@@ -2242,6 +2249,7 @@ Example:
     smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
     # Postfix 2.5 and later
     smtp_tls_fingerprint_digest = md5
+
 /etc/postfix/tls_policy:
     example.edu             none
     example.mil             may
@@ -2256,6 +2264,8 @@ Example:
        match=3D:95:34:51:24:66:33:B9:D2:40:99:C0:C1:17:0B:D1
     # Postfix 2.6 and later
     example.info            may protocols=!SSLv2 ciphers=medium exclude=3DES
+    # Postfix 2.12 and later override of smtp_tls_fallback_level
+    fallback.example        secure fallback=encrypt
 </pre>
 </blockquote>
 
index fe69f342a3e8d9da0ff91cae32548ebea7fbbe17..3d016e68becfd6612f5dda74ac706f51687e0ec3 100644 (file)
@@ -16205,6 +16205,64 @@ mail. </dd>
 
 <p> This feature is available in Postfix 2.12 and later. </p>
 
+%PARAM smtp_tls_fallback_level
+
+<p> Optional fallback levels for authenticated TLS levels.  Specify
+a white-space or comma-separated list of
+<b>policy_level</b>=<b>fallback_level</b> pairs.  The <b>policy_level</b>
+must require authentication (one of dane, dane-only, fingerprint,
+verify, secure).  The <b>fallback_level</b> must be "encrypt" or
+"may".  When an authenticated connection at some desired policy
+level cannot be established, delivery will proceed at the correponding
+fallback level if possible.  A warning will be logged
+indicating the fallback reason. </p>
+
+<p> The TLS <a href="TLS_README.html#client_tls_policy">policy</a> table
+can be used to specify a destination-specific fallback strategy via the
+"fallback" policy attribute.  The value of the "fallback" attribute, if
+specified, must be "may", "encrypt" or "none".  If not "none", this
+specifies the fallback level for the destination in question.  If the
+attribute value is "none", fallback is suppressed for the destination
+even if enabled via a global setting of smtp_tls_fallback_level.  </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+    # When authentication fails, log a warning and deliver anyway
+    # over an unauthenticated TLS connection.
+    #
+    smtp_tls_fallback_level =
+       dane=encrypt,
+       dane-only=encrypt,
+       fingerprint=encrypt,
+       verify=encrypt,
+       secure=encrypt
+    indexed = ${default_database_type}:${config_directory}/
+    smtp_tls_policy_maps = ${indexed}tls-policy
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/tls-policy:
+    # No fallback for example.com
+    example.com secure fallback=none
+    # For example.net tolerate cleartext fallback
+    example.net dane fallback=may
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM lmtp_tls_fallback_level
+
+<p> The LMTP-specific version of the smtp_tls_fallback_level
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
 %PARAM compatibility_level 0
 
 <p> A safety net that causes Postfix to run with backwards-compatible
@@ -16218,9 +16276,11 @@ message when a backwards-compatible default setting is required.
 
 <blockquote>
 <pre>
-using backwards-compatible default setting <i>name=value</i> to [accept a specific client request]
+using backwards-compatible default setting <i>name=value</i>
+    to [accept a specific client request]
 <nroffescape .sp>
-using backwards-compatible default setting <i>name=value</i> to [enable specific Postfix behavior]
+using backwards-compatible default setting <i>name=value</i>
+    to [enable specific Postfix behavior]
 </pre>
 </blockquote>
 
@@ -16252,7 +16312,8 @@ warning message: </p>
 
 <blockquote>
 <pre>
-warning: To disable backwards compatibility use "postconf compatibility_level=<i>N</i>" and "postfix reload"
+warning: To disable backwards compatibility use "postconf
+    compatibility_level=<i>N</i>" and "postfix reload"
 </pre>
 </blockquote>
 
index 8976d2c0320d3bab0ca405fae209fe66482d2784..b3454335f3c824ea4f065f24d0e9b347b042f017 100644 (file)
@@ -90,7 +90,7 @@
 
 void    attr_override(char *cp, const char *sep, const char *parens,...)
 {
-    const char myname[] = "attr_override";
+    static const char myname[] = "attr_override";
     va_list ap;
     int     idx;
     char   *nameval;
index 94e7df75be27c16bed6b173c41c99f34cff23972..e45d9427a15e84b830b1b01b4f86e699d2289da8 100644 (file)
@@ -531,7 +531,7 @@ int     bounce_one_intern(int flags, const char *queue, const char *id,
 
 void    bounce_client_init(const char *title, const char *maps)
 {
-    const char myname[] = "bounce_client_init";
+    static const char myname[] = "bounce_client_init";
 
     if (delivery_status_filter != 0)
        msg_panic("%s: duplicate initialization", myname);
index ed76c29ab69f3f6980d60ffbd391779089c078e8..bc7072c4a41dd2d01235acb667cf47962f6c871b 100644 (file)
@@ -105,7 +105,7 @@ struct DSN_FILTER {
 
 DSN_FILTER *dsn_filter_create(const char *title, const char *map_names)
 {
-    const char myname[] = "dsn_filter_create";
+    static const char myname[] = "dsn_filter_create";
     DSN_FILTER *fp;
 
     if (msg_verbose)
@@ -121,7 +121,7 @@ DSN_FILTER *dsn_filter_create(const char *title, const char *map_names)
 
 DSN    *dsn_filter_lookup(DSN_FILTER *fp, DSN *dsn)
 {
-    const char myname[] = "dsn_filter_lookup";
+    static const char myname[] = "dsn_filter_lookup";
     const char *result;
     int     ndr_dsn = 0;
 
@@ -182,7 +182,7 @@ DSN    *dsn_filter_lookup(DSN_FILTER *fp, DSN *dsn)
 
 void    dsn_filter_free(DSN_FILTER *fp)
 {
-    const char myname[] = "dsn_filter_free";
+    static const char myname[] = "dsn_filter_free";
 
     if (msg_verbose)
        msg_info("%s: %s", myname, fp->maps->title);
index 358aa60779b087b7ae9927b779f42a31c823f135..0a02d75fc92cac8bb40814c49872f6e280b13fd3 100644 (file)
@@ -304,7 +304,7 @@ static void dymap_read_conf(const char *path, const char *path_base)
 
 void    dymap_init(const char *conf_path, const char *plugin_dir)
 {
-    const char myname[] = "dymap_init";
+    static const char myname[] = "dymap_init";
     SCAN_DIR *dir;
     char   *conf_path_d;
     const char *conf_name;
index d4082eb2f87f283431ce7b079a7f24334840628d..2bdf251a015604cbf276bd156b9e9652dc53bb52 100644 (file)
@@ -38,8 +38,9 @@ extern bool var_helpful_warnings;
 extern bool var_show_unk_rcpt_table;
 
  /*
-  * Compatibility level and migration support. Update postconf(5) and
-  * COMPATIBILITY_README when updating the current compatibility level.
+  * Compatibility level and migration support. Update postconf(5),
+  * COMPATIBILITY_README, and conf/main.cf when updating the current
+  * compatibility level.
   */
 #define VAR_COMPAT_LEVEL       "compatibility_level"
 #define DEF_COMPAT_LEVEL       0
@@ -1401,6 +1402,12 @@ extern bool var_smtp_tls_enforce_peername;
 #define DEF_LMTP_TLS_LEVEL     ""
 extern char *var_smtp_tls_level;
 
+#define VAR_SMTP_TLS_FBACK_LEVEL       "smtp_tls_fallback_level"
+#define DEF_SMTP_TLS_FBACK_LEVEL       ""
+#define VAR_LMTP_TLS_FBACK_LEVEL       "lmtp_tls_fallback_level"
+#define DEF_LMTP_TLS_FBACK_LEVEL       ""
+extern char *var_smtp_tls_fback_level;
+
 #define VAR_SMTP_TLS_SCERT_VD  "smtp_tls_scert_verifydepth"
 #define DEF_SMTP_TLS_SCERT_VD  9
 #define VAR_LMTP_TLS_SCERT_VD  "lmtp_tls_scert_verifydepth"
index fbdc6227e17abe5ddaebc80de08df2e784c8daf9..2b7e101ee0049f0cf98276de95aa80d0f7adf9eb 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      "20141009"
+#define MAIL_RELEASE_DATE      "20141011"
 #define MAIL_VERSION_NUMBER    "2.12"
 
 #ifdef SNAPSHOT
index 63f525fd10b74a8a914ea2a61d683a7a1383f9b3..a5daf21ecf2e7aebe51fe3a61faf730cd8791850 100644 (file)
@@ -147,7 +147,7 @@ static MKMAP_OPEN_EXTEND_FN mkmap_open_extend_hook = 0;
 
 static void mkmap_open_init(void)
 {
-    const char myname[] = "mkmap_open_init";
+    static const char myname[] = "mkmap_open_init";
     const MKMAP_OPEN_INFO *mp;
 
     if (mkmap_open_hash != 0)
@@ -162,7 +162,7 @@ static void mkmap_open_init(void)
 
 void    mkmap_open_register(const char *type, MKMAP_OPEN_FN open_fn)
 {
-    const char myname[] = "mkmap_open_register";
+    static const char myname[] = "mkmap_open_register";
     MKMAP_OPEN_INFO *mp;
     HTABLE_INFO *ht;
 
index d86e08421441808efc50556edf5af19d92188469..d361a3b41348c1cff3a7ca55a28bf90e6f55cdbb 100644 (file)
@@ -66,7 +66,7 @@
 
 int     smtputf8_autodetect(int class)
 {
-    const char myname[] = "smtputf8_autodetect";
+    static const char myname[] = "smtputf8_autodetect";
     static const NAME_MASK table[] = {
        MAIL_SRC_NAME_SENDMAIL, MAIL_SRC_MASK_SENDMAIL,
        MAIL_SRC_NAME_SMTPD, MAIL_SRC_MASK_SMTPD,
index 1861e5ba5ee3af14be1f05240478ee854d5cd1b8..b7a68f894bd09a4c6a6a4dae9cae63537456fdac 100644 (file)
@@ -28,6 +28,7 @@
        VAR_LMTP_TLS_ECCERT_FILE, DEF_LMTP_TLS_ECCERT_FILE, &var_smtp_tls_eccert_file, 0, 0,
        VAR_LMTP_TLS_ECKEY_FILE, DEF_LMTP_TLS_ECKEY_FILE, &var_smtp_tls_eckey_file, 0, 0,
        VAR_LMTP_TLS_LOGLEVEL, DEF_LMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0,
+       VAR_LMTP_TLS_FBACK_LEVEL, DEF_LMTP_TLS_FBACK_LEVEL, &var_smtp_tls_fback_level, 0, 0,
 #endif
        VAR_LMTP_SASL_MECHS, DEF_LMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
        VAR_LMTP_SASL_TYPE, DEF_LMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0,
index 99d12085e87cffd4f27046afc9055ac9762c574d..b4e392535d75f4af2252c531edd9bcc37274aa4c 100644 (file)
 /*     RFC 6698 trust-anchor digest support in the Postfix TLS library.
 /* .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
 /*     The name of the \fBtlsmgr\fR(8) service entry in master.cf.
+/* .PP
+/*     Available in Postfix version 2.12 and later:
+/* .IP "\fBsmtp_tls_fallback_level (empty)\fR"
+/*     Optional fallback levels for authenticated TLS levels.
 /* OBSOLETE STARTTLS CONTROLS
 /* .ad
 /* .fi
@@ -856,6 +860,7 @@ char   *var_smtp_tls_mand_excl;
 char   *var_smtp_tls_dcert_file;
 char   *var_smtp_tls_dkey_file;
 bool    var_smtp_tls_enforce_peername;
+char   *var_smtp_tls_fback_level;
 char   *var_smtp_tls_key_file;
 char   *var_smtp_tls_loglevel;
 bool    var_smtp_tls_note_starttls_offer;
@@ -1037,7 +1042,7 @@ static void post_init(char *unused_name, char **unused_argv)
        smtp_dns_support =
            name_code(dns_support, NAME_CODE_FLAG_NONE, var_smtp_dns_support);
        if (smtp_dns_support == SMTP_DNS_INVALID)
-           msg_fatal("invalid %s: \"%s\"", SMTP_X(DNS_SUPPORT),
+           msg_fatal("invalid %s: \"%s\"", VAR_LMTP_SMTP(DNS_SUPPORT),
                      var_smtp_dns_support);
        var_disable_dns = (smtp_dns_support == SMTP_DNS_DISABLED);
     }
@@ -1049,10 +1054,11 @@ static void post_init(char *unused_name, char **unused_argv)
        smtp_host_lookup_mask = SMTP_HOST_FLAG_NATIVE;
     else
        smtp_host_lookup_mask =
-           name_mask(SMTP_X(HOST_LOOKUP), lookup_masks, var_smtp_host_lookup);
+           name_mask(VAR_LMTP_SMTP(HOST_LOOKUP), lookup_masks,
+                     var_smtp_host_lookup);
     if (msg_verbose)
        msg_info("host name lookup methods: %s",
-                str_name_mask(SMTP_X(HOST_LOOKUP), lookup_masks,
+                str_name_mask(VAR_LMTP_SMTP(HOST_LOOKUP), lookup_masks,
                               smtp_host_lookup_mask));
 
     /*
@@ -1071,7 +1077,7 @@ static void post_init(char *unused_name, char **unused_argv)
     /*
      * Select DNS query flags.
      */
-    smtp_dns_res_opt = name_mask(SMTP_X(DNS_RES_OPT), dns_res_opt_masks,
+    smtp_dns_res_opt = name_mask(VAR_LMTP_SMTP(DNS_RES_OPT), dns_res_opt_masks,
                                 var_smtp_dns_res_opt);
 }
 
@@ -1100,7 +1106,7 @@ static void pre_init(char *unused_name, char **unused_argv)
        smtp_sasl_initialize();
 #else
        msg_warn("%s is true, but SASL support is not compiled in",
-                SMTP_X(SASL_ENABLE));
+                VAR_LMTP_SMTP(SASL_ENABLE));
 #endif
 
     if (*var_smtp_tls_level != 0)
@@ -1143,10 +1149,10 @@ static void pre_init(char *unused_name, char **unused_argv)
         */
        smtp_tls_ctx =
            TLS_CLIENT_INIT(&props,
-                           log_param = SMTP_X(TLS_LOGLEVEL),
+                           log_param = VAR_LMTP_SMTP(TLS_LOGLEVEL),
                            log_level = var_smtp_tls_loglevel,
                            verifydepth = var_smtp_tls_scert_vd,
-                           cache_type = X_SMTP(TLS_MGR_SCACHE),
+                           cache_type = LMTP_SMTP_SUFFIX(TLS_MGR_SCACHE),
                            cert_file = var_smtp_tls_cert_file,
                            key_file = var_smtp_tls_key_file,
                            dcert_file = var_smtp_tls_dcert_file,
@@ -1177,7 +1183,7 @@ static void pre_init(char *unused_name, char **unused_argv)
      * EHLO keyword filter.
      */
     if (*var_smtp_ehlo_dis_maps)
-       smtp_ehlo_dis_maps = maps_create(SMTP_X(EHLO_DIS_MAPS),
+       smtp_ehlo_dis_maps = maps_create(VAR_LMTP_SMTP(EHLO_DIS_MAPS),
                                         var_smtp_ehlo_dis_maps,
                                         DICT_FLAG_LOCK);
 
@@ -1185,7 +1191,7 @@ static void pre_init(char *unused_name, char **unused_argv)
      * PIX bug workarounds.
      */
     if (*var_smtp_pix_bug_maps)
-       smtp_pix_bug_maps = maps_create(SMTP_X(PIX_BUG_MAPS),
+       smtp_pix_bug_maps = maps_create(VAR_LMTP_SMTP(PIX_BUG_MAPS),
                                        var_smtp_pix_bug_maps,
                                        DICT_FLAG_LOCK);
 
@@ -1197,19 +1203,19 @@ static void pre_init(char *unused_name, char **unused_argv)
            ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension);
     if (*var_smtp_generic_maps)
        smtp_generic_maps =
-           maps_create(SMTP_X(GENERIC_MAPS), var_smtp_generic_maps,
+           maps_create(VAR_LMTP_SMTP(GENERIC_MAPS), var_smtp_generic_maps,
                        DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
 
     /*
      * Header/body checks.
      */
     smtp_header_checks = hbc_header_checks_create(
-                                     SMTP_X(HEAD_CHKS), var_smtp_head_chks,
-                                     SMTP_X(MIME_CHKS), var_smtp_mime_chks,
-                                     SMTP_X(NEST_CHKS), var_smtp_nest_chks,
+                              VAR_LMTP_SMTP(HEAD_CHKS), var_smtp_head_chks,
+                              VAR_LMTP_SMTP(MIME_CHKS), var_smtp_mime_chks,
+                              VAR_LMTP_SMTP(NEST_CHKS), var_smtp_nest_chks,
                                                  smtp_hbc_callbacks);
     smtp_body_checks = hbc_body_checks_create(
-                                     SMTP_X(BODY_CHKS), var_smtp_body_chks,
+                              VAR_LMTP_SMTP(BODY_CHKS), var_smtp_body_chks,
                                              smtp_hbc_callbacks);
 
     /*
@@ -1227,7 +1233,8 @@ static void pre_init(char *unused_name, char **unused_argv)
        smtp_addr_pref = name_code(addr_pref_map, NAME_CODE_FLAG_NONE,
                                   var_smtp_addr_pref);
        if (smtp_addr_pref < 0)
-           msg_fatal("bad %s value: %s", SMTP_X(ADDR_PREF), var_smtp_addr_pref);
+           msg_fatal("bad %s value: %s", VAR_LMTP_SMTP(ADDR_PREF),
+                     var_smtp_addr_pref);
     }
 }
 
index c21aa65a5b575dbb6ddc0c2faec8987ab803c08e..1b78d469b4700a42c65eed93c53d4e2f2d910a92 100644 (file)
@@ -92,6 +92,8 @@ typedef struct SMTP_ITERATOR {
 
 typedef struct SMTP_TLS_POLICY {
     int     level;                     /* TLS enforcement level */
+    int     policy_level;              /* TLS desired policy level */
+    int     fallback_level;            /* TLS fallback level */
     char   *protocols;                 /* Acceptable SSL protocols */
     char   *grade;                     /* Cipher grade: "export", ... */
     VSTRING *exclusions;               /* Excluded SSL ciphers */
@@ -120,11 +122,13 @@ extern void smtp_tls_policy_cache_flush(void);
        SMTP_TLS_POLICY *_tls_policy_dummy_tmp = (t); \
        smtp_tls_policy_init(_tls_policy_dummy_tmp, (DSN_BUF *) 0); \
        _tls_policy_dummy_tmp->level = TLS_LEV_NONE; \
+       _tls_policy_dummy_tmp->policy_level = TLS_LEV_NONE; \
     } while (0)
 
  /* This macro is not part of the module external interface. */
 #define smtp_tls_policy_init(t, w) do { \
        SMTP_TLS_POLICY *_tls_policy_init_tmp = (t); \
+       _tls_policy_init_tmp->fallback_level = TLS_LEV_NOTFOUND; \
        _tls_policy_init_tmp->protocols = 0; \
        _tls_policy_init_tmp->grade = 0; \
        _tls_policy_init_tmp->exclusions = 0; \
@@ -341,6 +345,7 @@ typedef struct SMTP_SESSION {
     char   *tls_nexthop;               /* Nexthop domain for cert checks */
     int     tls_retry_plain;           /* Try plain when TLS handshake fails */
     SMTP_TLS_POLICY *tls;              /* TEMPORARY */
+    int     tls_level;                 /* Actual tls level */
 #endif
 
     SMTP_STATE *state;                 /* back link */
@@ -469,14 +474,16 @@ extern HBC_CALL_BACKS smtp_hbc_callbacks[];
 
 #define PLAINTEXT_FALLBACK_OK_AFTER_STARTTLS_FAILURE \
        (session->tls_context == 0 \
-           && session->tls->level == TLS_LEV_MAY \
+           && (session->tls->level == TLS_LEV_MAY \
+               || session->tls->fallback_level == TLS_LEV_MAY) \
            && PREACTIVE_DELAY >= var_min_backoff_time \
            && !HAVE_SASL_CREDENTIALS)
 
 #define PLAINTEXT_FALLBACK_OK_AFTER_TLS_SESSION_FAILURE \
        (session->tls_context != 0 \
            && SMTP_RCPT_LEFT(state) > SMTP_RCPT_MARK_COUNT(state) \
-           && session->tls->level == TLS_LEV_MAY \
+           && (session->tls->level == TLS_LEV_MAY \
+               || session->tls->fallback_level == TLS_LEV_MAY) \
            && PREACTIVE_DELAY >= var_min_backoff_time \
            && !HAVE_SASL_CREDENTIALS)
 
@@ -488,8 +495,17 @@ extern HBC_CALL_BACKS smtp_hbc_callbacks[];
 #define RETRY_AS_PLAINTEXT do { \
        session->tls_retry_plain = 1; \
        state->misc_flags &= ~SMTP_MISC_FLAG_FINAL_SERVER; \
+       (void) smtp_tls_trouble(state, session->tls_context ? \
+                               STARTTLS_SESSION_FALLBACK : \
+                               STARTTLS_HANDSHAKE_FALLBACK); \
     } while (0)
 
+#define STARTTLS_FEATURE_FALLBACK      1       /* No STARTTLS feature */
+#define STARTTLS_COMMAND_FALLBACK      2       /* Refused STARTTLS command */
+#define STARTTLS_HANDSHAKE_FALLBACK    3       /* Handshake failed */
+#define STARTTLS_VERIFY_FALLBACK       4       /* Peer verification failed */
+#define STARTTLS_SESSION_FALLBACK      5       /* Data transfer failed */
+
  /*
   * smtp_chat.c
   */
@@ -572,6 +588,11 @@ extern void PRINTFLIKE(5, 6) smtp_rcpt_fail(SMTP_STATE *, RECIPIENT *,
                                                    const char *,...);
 extern int smtp_stream_except(SMTP_STATE *, int, const char *);
 
+#ifdef USE_TLS
+extern int smtp_tls_trouble(SMTP_STATE *, int);
+
+#endif
+
  /*
   * smtp_unalias.c
   */
@@ -657,8 +678,8 @@ char   *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
 
 extern int smtp_mode;
 
-#define SMTP_X(x) (smtp_mode ? VAR_SMTP_##x : VAR_LMTP_##x)
-#define X_SMTP(x) (smtp_mode ? x##_SMTP : x##_LMTP)
+#define VAR_LMTP_SMTP(x) (smtp_mode ? VAR_SMTP_##x : VAR_LMTP_##x)
+#define LMTP_SMTP_SUFFIX(x) (smtp_mode ? x##_SMTP : x##_LMTP)
 
 /* LICENSE
 /* .ad
index 79df24a88de68556d9bab69f943720f901faa9e3..40ee645ee39d0a6ca947c9f0d13406badb6b0668 100644 (file)
@@ -365,7 +365,7 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session)
                msg_warn("to prevent loss of mail, turn off command pipelining "
                         "for %s with the %s parameter",
                         STR(session->iterator->addr),
-                        SMTP_X(EHLO_DIS_MAPS));
+                        VAR_LMTP_SMTP(EHLO_DIS_MAPS));
        }
     }
 
index acff1eba4cf5f9fa60dc1dc08a6dd95ab851d811..7e87c5b6f548631252200cd8fe1222853fdbecd5 100644 (file)
 #include <smtp_addr.h>
 #include <smtp_reuse.h>
 
+ /*
+  * XXX All TLS security level info belongs in session->tls. It should not
+  * pollute the session structure and consequently pollute internal APIs that
+  * don't need access to the session structure. However session->tls is a
+  * pointer into the cache and must therefore not be modified.
+  */
+#ifdef USE_TLS
+#define TLS_SESS_INIT(session, state) do { \
+       session->tls_level = state->tls->level; /* XXX Pre fallback */ \
+       session->tls = state->tls;              /* TEMPORARY */ \
+    } while (0)
+#endif
+
  /*
   * Forward declaration.
   */
@@ -207,12 +220,12 @@ static SMTP_SESSION *smtp_connect_addr(SMTP_ITERATOR *iter, DSN_BUF *why,
 #ifdef HAS_IPV6
     if (sa->sa_family == AF_INET6) {
        bind_addr = var_smtp_bind_addr6;
-       bind_var = SMTP_X(BIND_ADDR6);
+       bind_var = VAR_LMTP_SMTP(BIND_ADDR6);
     } else
 #endif
     if (sa->sa_family == AF_INET) {
        bind_addr = var_smtp_bind_addr;
-       bind_var = SMTP_X(BIND_ADDR);
+       bind_var = VAR_LMTP_SMTP(BIND_ADDR);
     } else
        bind_var = bind_addr = "";
     if (*bind_addr) {
@@ -522,7 +535,7 @@ static void smtp_connect_local(SMTP_STATE *state, const char *path)
     if ((state->session = session) != 0) {
        session->state = state;
 #ifdef USE_TLS
-       session->tls = state->tls;              /* TEMPORARY */
+       TLS_SESS_INIT(session, state);          /* TEMPORARY */
        session->tls_nexthop = var_myhostname;  /* for TLS_LEV_SECURE */
        if (session->tls->level == TLS_LEV_MAY) {
            msg_warn("%s: opportunistic TLS encryption is not appropriate "
@@ -674,7 +687,7 @@ static int smtp_reuse_session(SMTP_STATE *state, DNS_RR **addr_list,
            && *addr_list == 0)
            state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
 #ifdef USE_TLS
-       session->tls = state->tls;              /* TEMPORARY */
+       TLS_SESS_INIT(session, state);          /* TEMPORARY */
 #endif
        smtp_xfer(state);
        smtp_cleanup_session(state);
@@ -734,7 +747,7 @@ static int smtp_reuse_session(SMTP_STATE *state, DNS_RR **addr_list,
                && next == 0)
                state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
 #ifdef USE_TLS
-           session->tls = state->tls;          /* TEMPORARY */
+           TLS_SESS_INIT(session, state);      /* TEMPORARY */
 #endif
            smtp_xfer(state);
            smtp_cleanup_session(state);
@@ -978,7 +991,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
            if ((state->session = session) != 0) {
                session->state = state;
 #ifdef USE_TLS
-               session->tls = state->tls;      /* TEMPORARY */
+               TLS_SESS_INIT(session, state);  /* TEMPORARY */
                /* XXX: EAI: Convert to A-label here or in TLS library */
                session->tls_nexthop = domain;  /* for TLS_LEV_SECURE */
 #endif
index 1eb999638a05b3e54843471dee7e17538204ae60..78d7959234cd1f23b9c0f9bb7c8cc0c5031e9483 100644 (file)
@@ -146,7 +146,7 @@ static void smtp_key_append_uint(VSTRING *buffer, unsigned num,
 char   *smtp_key_prefix(VSTRING *buffer, const char *delim_na,
                                SMTP_ITERATOR *iter, int flags)
 {
-    const char myname[] = "smtp_key_prefix";
+    static const char myname[] = "smtp_key_prefix";
     SMTP_STATE *state = iter->parent;  /* private member */
 
     /*
index 807215dba90d35d07489af0e4c83d1404cfd2034..c22cf0a14259b284aa8e55ee5022e38c12b9ab54 100644 (file)
@@ -29,6 +29,7 @@
        VAR_SMTP_TLS_ECCERT_FILE, DEF_SMTP_TLS_ECCERT_FILE, &var_smtp_tls_eccert_file, 0, 0,
        VAR_SMTP_TLS_ECKEY_FILE, DEF_SMTP_TLS_ECKEY_FILE, &var_smtp_tls_eckey_file, 0, 0,
        VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0,
+       VAR_SMTP_TLS_FBACK_LEVEL, DEF_SMTP_TLS_FBACK_LEVEL, &var_smtp_tls_fback_level, 0, 0,
 #endif
        VAR_SMTP_SASL_MECHS, DEF_SMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
        VAR_SMTP_SASL_TYPE, DEF_SMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0,
index 53e4c14960dbdcc0c859d83af4be4d331e6a25ee..8e897519b156602acc62387f7876320c3f4361cd 100644 (file)
@@ -339,6 +339,9 @@ int     smtp_helo(SMTP_STATE *state)
        /*
         * If the policy table specifies a bogus TLS security level, fail
         * now.
+        * 
+        * XXX: This should be caught in smtp_connect before we even make a
+        * connection to the host.  Change to msg_panic()?
         */
 #ifdef USE_TLS
        if (session->tls->level == TLS_LEV_INVALID)
@@ -359,10 +362,10 @@ int     smtp_helo(SMTP_STATE *state)
                && (pix_bug_words =
                    maps_find(smtp_pix_bug_maps,
                              STR(iter->addr), 0)) != 0) {
-               pix_bug_source = SMTP_X(PIX_BUG_MAPS);
+               pix_bug_source = VAR_LMTP_SMTP(PIX_BUG_MAPS);
            } else {
                pix_bug_words = var_smtp_pix_bug_words;
-               pix_bug_source = SMTP_X(PIX_BUG_WORDS);
+               pix_bug_source = VAR_LMTP_SMTP(PIX_BUG_WORDS);
            }
            if (*pix_bug_words) {
                pix_bug_mask = name_mask_opt(pix_bug_source, pix_bug_table,
@@ -753,37 +756,38 @@ int     smtp_helo(SMTP_STATE *state)
             * although support for it was announced in the EHLO response.
             */
            session->features &= ~SMTP_FEATURE_STARTTLS;
-           if (TLS_REQUIRED(session->tls->level))
+           if (smtp_tls_trouble(state, STARTTLS_COMMAND_FALLBACK))
                return (smtp_site_fail(state, STR(iter->host), resp,
                    "TLS is required, but host %s refused to start TLS: %s",
                                       session->namaddr,
                                       translit(resp->str, "\n", " ")));
            /* Else try to continue in plain-text mode. */
-       }
+       } else {
 
-       /*
-        * Give up if we must use TLS but can't for various reasons.
-        * 
-        * 200412 Be sure to provide the default clause at the bottom of this
-        * block. When TLS is required we must never, ever, end up in
-        * plain-text mode.
-        */
-       if (TLS_REQUIRED(session->tls->level)) {
-           if (!(session->features & SMTP_FEATURE_STARTTLS)) {
-               return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
-                                      SMTP_RESP_FAKE(&fake, "4.7.4"),
+           /*
+            * Give up if we must use TLS but can't for various reasons.
+            
+            * 200412 Be sure to provide the default clause at the bottom of
+            * this block. When TLS is required we must never, ever, end up
+            * in plain-text mode.
+            */
+           if (smtp_tls_trouble(state, STARTTLS_FEATURE_FALLBACK)) {
+               if (!(session->features & SMTP_FEATURE_STARTTLS)) {
+                   return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
+                                          SMTP_RESP_FAKE(&fake, "4.7.4"),
                          "TLS is required, but was not offered by host %s",
-                                      session->namaddr));
-           } else if (smtp_tls_ctx == 0) {
-               return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
-                                      SMTP_RESP_FAKE(&fake, "4.7.5"),
+                                          session->namaddr));
+               } else if (smtp_tls_ctx == 0) {
+                   return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
+                                          SMTP_RESP_FAKE(&fake, "4.7.5"),
                     "TLS is required, but our TLS engine is unavailable"));
-           } else {
-               msg_warn("%s: TLS is required but unavailable, don't know why",
-                        myname);
-               return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
-                                      SMTP_RESP_FAKE(&fake, "4.7.0"),
+               } else {
+                   msg_warn("%s: TLS is required but unavailable, don't know why",
+                            myname);
+                   return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
+                                          SMTP_RESP_FAKE(&fake, "4.7.0"),
                                       "TLS is required, but unavailable"));
+               }
            }
        }
     }
@@ -807,6 +811,7 @@ static int smtp_start_tls(SMTP_STATE *state)
     TLS_CLIENT_START_PROPS tls_props;
     VSTRING *serverid;
     SMTP_RESP fake;
+    int     tls_level;
 
     /*
      * Turn off SMTP connection caching. When the TLS handshake succeeds, we
@@ -856,6 +861,11 @@ static int smtp_start_tls(SMTP_STATE *state)
      * resulting TLScontext. It is now up to the application to abort the TLS
      * connection if it chooses.
      * 
+     * Consequently, the TLS library need not and does not distinguish between
+     * the "dane" and "dane-only" security levels.  By the time we have TLSA
+     * records in hand, both behave identically modulo application-level
+     * fallback.  We collapse these now equivalent security levels.
+     * 
      * XXX When tls_client_start() fails then we don't know what state the SMTP
      * connection is in, so we give up on this connection even if we are not
      * required to use TLS.
@@ -863,12 +873,14 @@ static int smtp_start_tls(SMTP_STATE *state)
      * Large parameter lists are error-prone, so we emulate a language feature
      * that C does not have natively: named parameter lists.
      */
+    if ((tls_level = session->tls->level) == TLS_LEV_DANE_ONLY)
+       tls_level = TLS_LEV_DANE;
     session->tls_context =
        TLS_CLIENT_START(&tls_props,
                         ctx = smtp_tls_ctx,
                         stream = session->stream,
                         timeout = var_smtp_starttls_tmout,
-                        tls_level = session->tls->level,
+                        tls_level = tls_level,
                         nexthop = session->tls_nexthop,
                         host = STR(iter->host),
                         namaddr = session->namaddrport,
@@ -913,25 +925,21 @@ static int smtp_start_tls(SMTP_STATE *state)
      * result, abort the delivery here. We have a usable TLS session with the
      * server, so no need to disable I/O, ... we can even be polite and send
      * "QUIT".
-     * 
-     * See src/tls/tls_level.c and src/tls/tls.h. Levels above "encrypt" require
-     * matching.  Levels >= "dane" require CA or DNSSEC trust.
-     * 
-     * When DANE TLSA records specify an end-entity certificate, the trust and
-     * match bits always coincide, but it is fine to report the wrong
-     * end-entity certificate as untrusted rather than unmatched.
      */
-    if (TLS_MUST_TRUST(session->tls->level))
-       if (!TLS_CERT_IS_TRUSTED(session->tls_context))
+    if (TLS_MUST_TRUST(session->tls_level)
+       && !TLS_CERT_IS_TRUSTED(session->tls_context)) {
+       if (smtp_tls_trouble(state, STARTTLS_VERIFY_FALLBACK))
            return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
                                   SMTP_RESP_FAKE(&fake, "4.7.5"),
                                   "Server certificate not trusted"));
-    if (TLS_MUST_MATCH(session->tls->level))
-       if (!TLS_CERT_IS_MATCHED(session->tls_context))
+    } else if (TLS_MUST_MATCH(session->tls_level)
+              && !TLS_CERT_IS_MATCHED(session->tls_context)) {
+       /* Peer certificate not matched as it should be */
+       if (smtp_tls_trouble(state, STARTTLS_VERIFY_FALLBACK))
            return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
                                   SMTP_RESP_FAKE(&fake, "4.7.5"),
                                   "Server certificate not verified"));
-
+    }
     /* At this point there must not be any pending plaintext. */
     vstream_fpurge(session->stream, VSTREAM_PURGE_BOTH);
 
@@ -1442,8 +1450,8 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
            }
 
            /*
-            * Request SMTPUTF8 when the remote SMTP server supports
-            * SMTPUTF8 and the sender requested SMTPUTF8 support.
+            * Request SMTPUTF8 when the remote SMTP server supports SMTPUTF8
+            * and the sender requested SMTPUTF8 support.
             * 
             * If the sender requested SMTPUTF8 but the remote SMTP server does
             * not support SMTPUTF8, then we have already determined earlier
@@ -1766,7 +1774,7 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
                                       "unexpected server message");
                        msg_warn("server %s violates %s policy",
                                 session->namaddr,
-                                SMTP_X(TLS_BLK_EARLY_MAIL_REPLY));
+                                VAR_LMTP_SMTP(TLS_BLK_EARLY_MAIL_REPLY));
                        mail_from_rejected = 1;
                    }
 #endif
index 5254341d58128a5637c1f4a4d71f863ac77adf96..19f3b9098427bd27a5097179a154dfba42325e08 100644 (file)
@@ -228,7 +228,7 @@ void    smtp_sasl_initialize(void)
        msg_panic("smtp_sasl_initialize: repeated call");
     if (*var_smtp_sasl_passwd == 0)
        msg_fatal("specify a password table via the `%s' configuration parameter",
-                 SMTP_X(SASL_PASSWD));
+                 VAR_LMTP_SMTP(SASL_PASSWD));
 
     /*
      * Open the per-host password table and initialize the SASL library. Use
@@ -258,7 +258,7 @@ void    smtp_sasl_initialize(void)
                                      var_smtp_sasl_auth_cache_time);
 #else
        msg_warn("not compiled with TLS support -- "
-                "ignoring the %s setting", SMTP_X(SASL_AUTH_CACHE_NAME));
+           "ignoring the %s setting", VAR_LMTP_SMTP(SASL_AUTH_CACHE_NAME));
 #endif
     }
 }
index 7676f33340847b96c306f49096460183e977183d..fa636609537a03666211b6fb9bb63ec1c5730ad2 100644 (file)
@@ -177,15 +177,16 @@ int     smtp_sasl_helo_login(SMTP_STATE *state)
        /* Session reuse is disabled. */
     } else {
 #ifndef USE_TLS
-       smtp_sasl_start(session, SMTP_X(SASL_OPTS), var_smtp_sasl_opts);
+       smtp_sasl_start(session, VAR_LMTP_SMTP(SASL_OPTS), var_smtp_sasl_opts);
 #else
        if (session->tls_context == 0)
-           smtp_sasl_start(session, SMTP_X(SASL_OPTS), var_smtp_sasl_opts);
+           smtp_sasl_start(session, VAR_LMTP_SMTP(SASL_OPTS),
+                           var_smtp_sasl_opts);
        else if (TLS_CERT_IS_MATCHED(session->tls_context))
-           smtp_sasl_start(session, SMTP_X(SASL_TLSV_OPTS),
+           smtp_sasl_start(session, VAR_LMTP_SMTP(SASL_TLSV_OPTS),
                            var_smtp_sasl_tlsv_opts);
        else
-           smtp_sasl_start(session, SMTP_X(SASL_TLS_OPTS),
+           smtp_sasl_start(session, VAR_LMTP_SMTP(SASL_TLS_OPTS),
                            var_smtp_sasl_tls_opts);
 #endif
        if (smtp_sasl_authenticate(session, why) <= 0) {
index 59118f2b36f40ceff6427b4147c62c405fe5d14a..a177ecd88b23f429d0c0d3b823ef430a4e7f0a39 100644 (file)
@@ -130,15 +130,16 @@ static MAPS *tls_per_site;                /* lookup table(s) */
 void    smtp_tls_list_init(void)
 {
     if (*var_smtp_tls_policy) {
-       tls_policy = maps_create(SMTP_X(TLS_POLICY), var_smtp_tls_policy,
+       tls_policy = maps_create(VAR_LMTP_SMTP(TLS_POLICY), var_smtp_tls_policy,
                                 DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
        if (*var_smtp_tls_per_site)
            msg_warn("%s ignored when %s is not empty.",
-                    SMTP_X(TLS_PER_SITE), SMTP_X(TLS_POLICY));
+                    VAR_LMTP_SMTP(TLS_PER_SITE), VAR_LMTP_SMTP(TLS_POLICY));
        return;
     }
     if (*var_smtp_tls_per_site) {
-       tls_per_site = maps_create(SMTP_X(TLS_PER_SITE), var_smtp_tls_per_site,
+       tls_per_site = maps_create(VAR_LMTP_SMTP(TLS_PER_SITE),
+                                  var_smtp_tls_per_site,
                                   DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
     }
 }
@@ -155,7 +156,7 @@ static const char *policy_name(int tls_level)
 }
 
 #define MARK_INVALID(why, levelp) do { \
-           dsb_simple((why), "4.7.5", "client TLS configuration problem"); \
+           dsb_simple((why), "4.7.0", "client TLS configuration problem"); \
            *(levelp) = TLS_LEV_INVALID; } while (0)
 
 /* tls_site_lookup - look up per-site TLS security level */
@@ -352,6 +353,37 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
            }
            continue;
        }
+       /* Only one instance per policy. */
+       if (!strcasecmp(name, "fallback")) {
+           int     l;
+
+           if (!TLS_MUST_MATCH(*site_level)) {
+               msg_warn("%s: attribute \"%s\" invalid at security level"
+                        " \"%s\"", WHERE, name, policy_name(*site_level));
+               continue;
+           }
+           if (tls->fallback_level != TLS_LEV_NOTFOUND) {
+               msg_warn("%s: attribute \"%s\" is specified multiple times",
+                        WHERE, name);
+               continue;
+           }
+           if (*val == 0) {
+               msg_warn("%s: attribute \"%s\" has empty value", WHERE, name);
+               continue;
+           }
+           switch (l = tls_level_lookup(val)) {
+           case TLS_LEV_NONE:
+           case TLS_LEV_MAY:
+           case TLS_LEV_ENCRYPT:
+               tls->fallback_level = l;
+               break;
+           default:
+               msg_warn("%s: attribute \"%s\" invalid fallback level: \"%s\"",
+                        WHERE, name, val);
+               break;
+           }
+           continue;
+       }
        msg_warn("%s: invalid attribute name: \"%s\"", WHERE, name);
        INVALID_RETURN(tls->why, site_level);
     }
@@ -433,6 +465,7 @@ static void set_cipher_grade(SMTP_TLS_POLICY *tls)
        break;
 
     case TLS_LEV_DANE:
+    case TLS_LEV_DANE_ONLY:
     case TLS_LEV_FPRINT:
     case TLS_LEV_VERIFY:
     case TLS_LEV_SECURE:
@@ -462,6 +495,49 @@ static void set_cipher_grade(SMTP_TLS_POLICY *tls)
     ADD_EXCLUDE(tls->exclusions, also_exclude);
 }
 
+static int global_fallback(SMTP_TLS_POLICY *tls)
+{
+    static int l = TLS_LEV_NOTFOUND;
+    const char *lname = str_tls_level(tls->level);
+    const char *err;
+    char   *saved;
+    char   *fback;
+    char   *tok;
+    char   *name;
+    char   *val;
+
+    /*
+     * Silently ignore any spurious fallback setting for unauthenticated TLS.
+     */
+    if (!*var_smtp_tls_fback_level || tls->level <= TLS_LEV_ENCRYPT)
+       return l;
+
+    saved = fback = mystrdup(var_smtp_tls_fback_level);
+    while ((tok = mystrtok(&fback, "\t\n\r ,")) != 0) {
+       if ((err = split_nameval(tok, &name, &val)) != 0) {
+           msg_warn("malformed %s: \"%s\": %s", VAR_LMTP_SMTP(TLS_FBACK_LEVEL),
+                    saved, err);
+           l = TLS_LEV_NOTFOUND;
+           break;
+       }
+       if (strcmp(name, lname) == 0) {
+           switch (l = tls_level_lookup(val)) {
+           case TLS_LEV_MAY:
+           case TLS_LEV_ENCRYPT:
+               break;
+           default:
+               msg_warn("%s: bad fallback mapping: %s=%s",
+                        VAR_LMTP_SMTP(TLS_FBACK_LEVEL), name, val);
+               l = TLS_LEV_NOTFOUND;
+               break;
+           }
+           break;
+       }
+    }
+    myfree(saved);
+    return (l);
+}
+
 /* policy_create - create SMTP TLS policy cache object (ctable call-back) */
 
 static void *policy_create(const char *unused_key, void *context)
@@ -522,6 +598,19 @@ static void *policy_create(const char *unused_key, void *context)
        return ((void *) tls);
     }
 
+    /*
+     * Save level as policy level (may be downgraded by early fallback, and
+     * compute fallback level if not specified per-site.  If site fallback
+     * level is "none", replace with "notfound", otherwise if no site
+     * fallback level, use the global value.
+     */
+    tls->policy_level = tls->level;
+    if (tls->fallback_level == TLS_LEV_NONE)
+       tls->fallback_level = TLS_LEV_NOTFOUND;
+    else if (tls->fallback_level == TLS_LEV_NOTFOUND
+        && (tls->fallback_level = global_fallback(tls)) == TLS_LEV_INVALID)
+       tls->fallback_level = TLS_LEV_NOTFOUND;
+
     /*
      * DANE initialization may change the security level to something else,
      * so do this early, so that we use the right level below.  Note that
@@ -557,6 +646,7 @@ static void *policy_create(const char *unused_key, void *context)
     case TLS_LEV_MAY:
     case TLS_LEV_ENCRYPT:
     case TLS_LEV_DANE:
+    case TLS_LEV_DANE_ONLY:
        break;
     case TLS_LEV_FPRINT:
        if (tls->dane == 0)
@@ -707,29 +797,49 @@ static int global_tls_level(void)
 #define NONDANE_CONFIG 0               /* Administrator's fault */
 #define NONDANE_DEST   1               /* Remote server's fault */
 #define DANE_UNUSABLE  2               /* Remote server's fault */
+#define TLSA_LOOKUP_ERR        3               /* DNS lookup failed */
 
-static void PRINTFLIKE(4, 5) dane_incompat(SMTP_TLS_POLICY *tls,
-                                                  SMTP_ITERATOR *iter,
+static void PRINTFLIKE(3, 4) dane_incompat(SMTP_TLS_POLICY *tls,
                                                   int errtype,
                                                   const char *fmt,...)
 {
     va_list ap;
 
     va_start(ap, fmt);
-    if (tls->level == TLS_LEV_DANE) {
-       tls->level = (errtype == DANE_UNUSABLE) ? TLS_LEV_ENCRYPT : TLS_LEV_MAY;
+
+    /*
+     * TLSA lookup errors are potential downgrade attacks, since they can
+     * hide the presence of usable TLSA RRs, we must fail or fallback, not
+     * downgrade to encryption-only or opportunistic TLS as with unusable or
+     * absent TLSA records.
+     */
+    if (tls->level == TLS_LEV_DANE && errtype != TLSA_LOOKUP_ERR) {
+       if (errtype == DANE_UNUSABLE) {
+
+           /*
+            * When TLSA are present, but none are usable, "dane" clients are
+            * expected to perform mandatory unauthenticated TLS.  If the
+            * "dane" the fallback level is "may", we enable fallback to
+            * cleartext (with the appropriate warnings).
+            */
+           tls->level = TLS_LEV_ENCRYPT;
+           if (tls->fallback_level != TLS_LEV_MAY)
+               tls->fallback_level = TLS_LEV_NOTFOUND;
+       } else {
+           tls->level = TLS_LEV_MAY;
+           tls->fallback_level = TLS_LEV_NOTFOUND;
+       }
        if (errtype == NONDANE_CONFIG)
            vmsg_warn(fmt, ap);
        else if (msg_verbose)
            vmsg_info(fmt, ap);
-    } else {                                   /* dane-only */
-       if (errtype == NONDANE_CONFIG) {
-           vmsg_warn(fmt, ap);
+    } else {
+       vmsg_warn(fmt, ap);
+       if (errtype == NONDANE_CONFIG
+           || tls->fallback_level == TLS_LEV_NOTFOUND)
            MARK_INVALID(tls->why, &tls->level);
-       } else {
-           tls->level = TLS_LEV_INVALID;
-           vdsb_simple(tls->why, "4.7.5", fmt, ap);
-       }
+       else
+           tls->level = tls->fallback_level;
     }
     va_end(ap);
 }
@@ -747,14 +857,14 @@ static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
        return;
     }
     if (!tls_dane_avail()) {
-       dane_incompat(tls, iter, NONDANE_CONFIG,
+       dane_incompat(tls, NONDANE_CONFIG,
                      "%s: %s configured, but no requisite library support",
                      STR(iter->dest), policy_name(tls->level));
        return;
     }
     if (!(smtp_host_lookup_mask & SMTP_HOST_FLAG_DNS)
        || smtp_dns_support != SMTP_DNS_DNSSEC) {
-       dane_incompat(tls, iter, NONDANE_CONFIG,
+       dane_incompat(tls, NONDANE_CONFIG,
                      "%s: %s configured with dnssec lookups disabled",
                      STR(iter->dest), policy_name(tls->level));
        return;
@@ -766,7 +876,7 @@ static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
      * key material.
      */
     if (smtp_mode && var_ign_mx_lookup_err) {
-       dane_incompat(tls, iter, NONDANE_CONFIG,
+       dane_incompat(tls, NONDANE_CONFIG,
                      "%s: %s configured with MX lookup errors ignored",
                      STR(iter->dest), policy_name(tls->level));
        return;
@@ -779,45 +889,48 @@ static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
      * to certificate name checks, ...
      */
     if (smtp_dns_res_opt & (RES_DEFNAMES | RES_DNSRCH)) {
-       dane_incompat(tls, iter, NONDANE_CONFIG,
+       dane_incompat(tls, NONDANE_CONFIG,
                      "%s: dns resolver options incompatible with %s TLS",
                      STR(iter->dest), policy_name(tls->level));
        return;
     }
     /* When the MX name is present and insecure, DANE does not apply. */
     if (iter->mx && !iter->mx->dnssec_valid) {
-       dane_incompat(tls, iter, NONDANE_DEST, "non DNSSEC destination");
+       dane_incompat(tls, NONDANE_DEST, "%s: non-DNSSEC destination",
+                     STR(iter->dest));
        return;
     }
-    /* When TLSA lookups fail, we defer the message */
+
+    /*
+     * When TLSA lookups fail, as with dane-only, we fall back or defer the
+     * message, the level will be set to either the fallback level or
+     * "invalid".
+     */
     if ((dane = tls_dane_resolve(iter->port, "tcp", iter->rr,
                                 var_smtp_tls_force_tlsa)) == 0) {
-       tls->level = TLS_LEV_INVALID;
-       dsb_simple(tls->why, "4.7.5", "TLSA lookup error for %s:%u",
-                  STR(iter->host), ntohs(iter->port));
+       dane_incompat(tls, TLSA_LOOKUP_ERR,
+                     "%s:%u: DANE TLSA lookup error",
+                     STR(iter->host), ntohs(iter->port));
        return;
     }
     if (tls_dane_notfound(dane)) {
-       dane_incompat(tls, iter, NONDANE_DEST, "no TLSA records found");
+       dane_incompat(tls, NONDANE_DEST,
+                     "%s:%u: no DANE TLSA records found",
+                     STR(iter->host), ntohs(iter->port));
        tls_dane_free(dane);
        return;
     }
-
-    /*
-     * Some TLSA records found, but none usable, per
-     * 
-     * https://tools.ietf.org/html/draft-ietf-dane-srv-02#section-4
-     * 
-     * we MUST use TLS, and SHALL use full PKIX certificate checks.  The latter
-     * would be unwise for SMTP: no human present to "click ok" and risk of
-     * non-delivery in most cases exceeds risk of interception.
-     * 
-     * We also have a form of Goedel's incompleteness theorem in play: any list
-     * of public root CA certs is either incomplete or inconsistent (for any
-     * given verifier some of the CAs are surely not trustworthy).
+    /*-
+     * Some TLSA records found, but none usable, per:
+     *
+     *    https://tools.ietf.org/html/draft-ietf-dane-smtp-with-dane
+     *
+     * we MUST use TLS.
      */
     if (tls_dane_unusable(dane)) {
-       dane_incompat(tls, iter, DANE_UNUSABLE, "TLSA records unusable");
+       dane_incompat(tls, DANE_UNUSABLE,
+                     "%s:%u: all DANE TLSA records unusable",
+                     STR(iter->host), ntohs(iter->port));
        tls_dane_free(dane);
        return;
     }
@@ -838,7 +951,6 @@ static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
     } else if (!TLS_DANE_HASEE(dane))
        msg_panic("empty DANE match list");
     tls->dane = dane;
-    tls->level = TLS_LEV_DANE;
     return;
 }
 
index 2262e6cf04cf4298a6483fa1aa1f90585ba4c351..c323a9170034cf9dadbb6b88a3fafa0118ea4b0b 100644 (file)
 /*     SMTP_STATE *state;
 /*     int     exception;
 /*     const char *description;
+/*
+/*     int     smtp_tls_trouble(state, protocol_stage)
+/*     SMTP_STATE *state;
+/*     int protocol_stage;
 /* DESCRIPTION
 /*     This module handles all non-fatal errors that can happen while
 /*     attempting to deliver mail via SMTP, and implements the policy
 /*     The session is marked as "do not cache".
 /*     The result is non-zero.
 /*
+/*     smtp_tls_trouble() handles failure to establish a TLS connection or
+/*     else failure to authenticate the peer.  The protocol_stage argument
+/*     indicates what TLS problem was detected.  The return value is 0 when
+/*     TLS is not required or a fallback strategy allows delivery to continue.
+/*     When a non-zero value is returned delivery must not continue via the
+/*     current SMTP server.  All relevant warnings are logged.
+/*
 /*     Arguments:
 /* .IP state
 /*     SMTP client state per delivery request.
@@ -467,3 +478,74 @@ int     smtp_stream_except(SMTP_STATE *state, int code, const char *description)
      */
     return (smtp_bulk_fail(state, SMTP_THROTTLE));
 }
+
+#ifdef USE_TLS
+
+/* smtp_tls_trouble - Fail or fall back when TLS state is not satisfactory. */
+
+int     smtp_tls_trouble(SMTP_STATE *state, int protocol_stage)
+{
+    SMTP_SESSION *session = state->session;
+    SMTP_TLS_POLICY *tls = session->tls;
+
+    /* Handle non-recoverable cases */
+    switch (protocol_stage) {
+    case STARTTLS_VERIFY_FALLBACK:
+       if (tls->fallback_level == TLS_LEV_NOTFOUND)
+           return (-1);
+       break;
+    case STARTTLS_FEATURE_FALLBACK:
+       /* No recovery when skipping STARTTLS due to local problems */
+       if (session->features & SMTP_FEATURE_STARTTLS)
+           return (-1);
+       /* FALLTHROUGH */
+    case STARTTLS_COMMAND_FALLBACK:
+    case STARTTLS_HANDSHAKE_FALLBACK:
+    case STARTTLS_SESSION_FALLBACK:
+       if (TLS_REQUIRED(session->tls_level)
+           && tls->fallback_level != TLS_LEV_MAY)
+           return (-1);
+       break;
+    default:
+       msg_panic("Unexpected TLS failure stage: %d", protocol_stage);
+    }
+
+    /* Log appropriate warning and perform fallback */
+    switch (protocol_stage) {
+    case STARTTLS_FEATURE_FALLBACK:
+       if (session->tls_level > TLS_LEV_MAY)
+           msg_warn("%s: cleartext fallback, host did not offer STARTTLS",
+                    session->namaddrport);
+       break;
+
+    case STARTTLS_COMMAND_FALLBACK:
+       if (session->tls_level > TLS_LEV_MAY)
+           msg_warn("%s: cleartext fallback, host refused to start TLS",
+                    session->namaddrport);
+       break;
+
+    case STARTTLS_HANDSHAKE_FALLBACK:
+       if (session->tls_level > TLS_LEV_MAY)
+           msg_warn("%s: cleartext fallback, TLS handshake failed",
+                    session->namaddrport);
+       break;
+
+    case STARTTLS_SESSION_FALLBACK:
+       msg_warn("%s: cleartext fallback, post-handshake TLS failure",
+                session->namaddrport);
+       break;
+
+    case STARTTLS_VERIFY_FALLBACK:
+       msg_warn("%s: fallback to unauthenticated TLS: %s",
+                session->namaddrport,
+                TLS_CERT_IS_TRUSTED(session->tls_context) ?
+                "Server certificate failed verification" :
+                "Server certificate not trusted");
+       break;
+    }
+
+    session->tls_level = tls->fallback_level;
+    return (0);
+}
+
+#endif
index 2f05cfb6923b32f297c4ed3ae27005921acc4837..41db103270f50c784efaf1cd0b0428613783aa24 100644 (file)
@@ -505,7 +505,7 @@ static ATTR_OVER_STR str_table[] = {
 
 static void policy_client_register(const char *name)
 {
-    const char myname[] = "policy_client_register";
+    static const char myname[] = "policy_client_register";
     SMTPD_POLICY_CLNT *policy_client;
     char   *saved_name = 0;
     const char *policy_name = 0;
index d2036fae4c10bb39a25fec38e0d1528abdb7755a..135c66d50813d0822b0ec9576926d0c8654b6c47 100644 (file)
@@ -68,7 +68,7 @@ typedef struct {
 
 static const char *dict_pipe_lookup(DICT *dict, const char *query)
 {
-    const char myname[] = "dict_pipe_lookup";
+    static const char myname[] = "dict_pipe_lookup";
     DICT_PIPE *dict_pipe = (DICT_PIPE *) dict;
     DICT   *map;
     char  **cpp;
@@ -105,7 +105,7 @@ static void dict_pipe_close(DICT *dict)
 
 DICT   *dict_pipe_open(const char *name, int open_flags, int dict_flags)
 {
-    const char myname[] = "dict_pipe_open";
+    static const char myname[] = "dict_pipe_open";
     DICT_PIPE *dict_pipe;
     char   *saved_name = 0;
     char   *dict_type_name;
index 88091311b30e419a466004941366e6a73fb7f0ea..ef709ed43dd092302df230f819bae88778b4c3ee 100644 (file)
@@ -67,7 +67,7 @@ typedef struct {
 
 static const char *dict_union_lookup(DICT *dict, const char *query)
 {
-    const char myname[] = "dict_union_lookup";
+    static const char myname[] = "dict_union_lookup";
     DICT_UNION *dict_union = (DICT_UNION *) dict;
     DICT   *map;
     char  **cpp;
@@ -111,7 +111,7 @@ static void dict_union_close(DICT *dict)
 
 DICT   *dict_union_open(const char *name, int open_flags, int dict_flags)
 {
-    const char myname[] = "dict_union_open";
+    static const char myname[] = "dict_union_open";
     DICT_UNION *dict_union;
     char   *saved_name = 0;
     char   *dict_type_name;
index 16b7b6cbf41c451c6594b0a35799e384982c2311..d7e6c1101d06969214b200d6a4a00d71490f62cc 100644 (file)
@@ -397,7 +397,7 @@ static int mac_exp_parse_logical(MAC_EXP_CONTEXT *mc, const char **lookup,
 
 static int mac_expand_callback(int type, VSTRING *buf, char *ptr)
 {
-    const char myname[] = "mac_expand_callback";
+    static const char myname[] = "mac_expand_callback";
     MAC_EXP_CONTEXT *mc = (MAC_EXP_CONTEXT *) ptr;
     int     lookup_mode;
     const char *lookup;
index 446af899190f14b2505d48377ca32fffc5bdcb97..70b393e32bed627cda780ba8952bdfd7cf30f5b0 100644 (file)
@@ -75,7 +75,7 @@ int     midna_cache_size = DEF_MIDNA_CACHE_SIZE;
 
 static void *midna_utf8_to_ascii_create(const char *name, void *unused_context)
 {
-    const char myname[] = "midna_utf8_to_ascii_create";
+    static const char myname[] = "midna_utf8_to_ascii_create";
     char    buf[1024];                 /* XXX */
     UErrorCode error = U_ZERO_ERROR;
     UIDNAInfo info = UIDNA_INFO_INITIALIZER;
@@ -110,7 +110,7 @@ static void *midna_utf8_to_ascii_create(const char *name, void *unused_context)
 
 static void *midna_ascii_to_utf8_create(const char *name, void *unused_context)
 {
-    const char myname[] = "midna_ascii_to_utf8_create";
+    static const char myname[] = "midna_ascii_to_utf8_create";
     char    buf[1024];                 /* XXX */
     UErrorCode error = U_ZERO_ERROR;
     UIDNAInfo info = UIDNA_INFO_INITIALIZER;
index 40bfa2ced8fd9c36500997d9fa0564a9d3c4946f..f1fac55e56a539344feae05b27511edf96d4bb64 100644 (file)
@@ -50,7 +50,7 @@
 
 int     valid_utf8_hostname(int enable_utf8, const char *name, int gripe)
 {
-    const char myname[] = "valid_utf8_hostname";
+    static const char myname[] = "valid_utf8_hostname";
     const char *aname;
     int     ret;