global/post_mail.h, global/verify.c, oqmgr/qmgr.c, oqmgr/qmgr.h,
oqmgr/qmgr_message.c, qmgr/qmgr.c, qmgr/qmgr.h,
qmgr/qmgr_message.c, verify/verify.c.
+
+20160102
+
+ Workaround: MacOS/X 10.11.x /bin/sh unsets DYLD_LIBRARY_PATH,
+ which breaks the build and install. Viktor Dukhovni and
+ Wietse. Files: makedefs, postfix-install, Makefile.in.
+
+ Bitrot: OpenSSL 1.1.0-dev drops support for EXPORT ciphers
+ and ephemeral RSA. Viktor Dukhovni. Files: tls/tls_client.c,
+ tls/tls_rsa.c, tls/tls_server.c.
+
+ Bugfix: memory leak in tls_set_eecdh_curve(). Viktor Dukhovni.
+ File: tls/tls_dh.c.
+
+ Bugfix (introduced 20150326): when lmtp_fallback_relay
+ support was added, the code that generates lmtp_mumble
+ parameters from smtp_mumble parameters wasn't updated. File:
+ smtp/smtp-only.
+
+ Bugfix (introduced 20151017): the smtpd_client_auth_rate_limit
+ implementation was not guarded with #ifdef USE_SASL_AUTH.
+ File: smtpd/smtpd.c.
+
+20160103
+
+ Feature: enable DANE policies when an MX host has a secure
+ TLSA DNS record, even if the MX DNS record was obtained
+ with insecure lookups. The existence of a secure TLSA record
+ implies that the host wants to talk TLS and not plaintext.
+ This behavior is controlled with smtp_tls_dane_insecure_mx_policy
+ (default: "dane", other settings: "encrypt" and "may"; the
+ latter is backwards-compatible with earlier Postfix releases).
+ Viktor Dukhovni. Files: mantools/postlink, proto/postconf.proto,
+ src/global/mail_params.h, src/posttls-finger/posttls-finger.c,
+ src/smtp/smtp-only, src/smtp/smtp.c, src/smtp/smtp.h,
+ src/smtp/smtp_addr.c, src/smtp/smtp_params.c,
+ src/smtp/smtp_tls_policy.c, src/tls/tls.h, src/tls/tls_client.c.
# shared=yes<->shared=no.
install: update
+ SHLIB_ENV_VAR= SHLIB_ENV_VAL= \
$(SHLIB_ENV) shlib_directory=$(SHLIB_DIR_OVERRIDE) $(SHELL) \
postfix-install
package: update
+ SHLIB_ENV_VAR= SHLIB_ENV_VAL= \
$(SHLIB_ENV) shlib_directory=$(SHLIB_DIR_OVERRIDE) $(SHELL) \
postfix-install -package
upgrade: update
+ SHLIB_ENV_VAR= SHLIB_ENV_VAL= \
$(SHLIB_ENV) shlib_directory=$(SHLIB_DIR_OVERRIDE) $(SHELL) \
postfix-install -non-interactive
non-interactive-package: update
+ SHLIB_ENV_VAR= SHLIB_ENV_VAL= \
$(SHLIB_ENV) shlib_directory=$(SHLIB_DIR_OVERRIDE) $(SHELL) \
postfix-install -non-interactive -package
Request that the Postfix SMTP client connects using the legacy
SMTPS protocol instead of using the STARTTLS command.
+ Available in Postfix version 3.1 and later:
+
+ <b><a href="postconf.5.html#smtp_tls_dane_insecure_mx_policy">smtp_tls_dane_insecure_mx_policy</a> (dane)</b>
+ The TLS policy for MX hosts with "secure" TLSA records when the
+ nexthop destination security level is <b>dane</b>, but the MX record
+ was found via an "insecure" MX lookup.
+
<b>OBSOLETE STARTTLS CONTROLS</b>
The following configuration parameters exist for compatibility with
Postfix versions before 2.3. Support for these will be removed in a
and opportunistic TLS always uses "export" or better (i.e. all) ciphers. </p>
+</DD>
+
+<DT><b><a name="smtp_tls_dane_insecure_mx_policy">smtp_tls_dane_insecure_mx_policy</a>
+(default: dane)</b></DT><DD>
+
+<p> The TLS policy for MX hosts with "secure" TLSA records when the
+nexthop destination security level is <b>dane</b>, but the MX
+record was found via an "insecure" MX lookup. The choices are:
+</p>
+
+<dl>
+<dt><b>may</b></dt>
+<dd> The TLSA records will be ignored and TLS will be optional. If
+the MX host does not appear to support STARTTLS, or the STARTTLS
+handshake fails, mail may be sent in the clear. </dd>
+<dt><b>encrypt</b></dt>
+<dd> The TLSA records will signal a requirement to use TLS. While
+TLS encryption will be required, authentication will not be performed.
+</dd>
+<dt><b>dane</b> (default)</dt>
+<dd>The TLSA records will be used just as with "secure" MX records.
+TLS encryption will be required, and, if at least one of the TLSA
+records is "usable", authentication will be required. When
+authentication succeeds, it will be logged only as "Trusted", not
+"Verified", because the MX host name could have been forged. </dd>
+</dl>
+
+<p> Though with "insecure" MX records an active attacker can
+compromise SMTP transport security by returning forged MX records,
+such attacks are "tamper-evident" since any forged MX hostnames
+will be recorded in the mail logs. Attackers who place a high value
+staying hidden may be deterred from forging MX records. </p>
+
+<p>
+This feature is available in Postfix 3.1 and later. The <b>may</b>
+policy is backwards-compatible with earlier Postfix versions.
+</p>
+
+
</DD>
<DT><b><a name="smtp_tls_dcert_file">smtp_tls_dcert_file</a>
with these servers there will never be more than 1 reconnection
attempt.
+ <b>-M</b> <i>insecure</i><b>_</b><i>mx</i><b>_</b><i>policy</i> (default: <b>dane</b>)
+ The TLS policy for MX hosts with "secure" TLSA records when the
+ nexthop destination security level is <b>dane</b>, but the MX record
+ was found via an "insecure" MX lookup. See the <a href="postconf.5.html">main.cf</a> documen-
+ tation for smtp_tls_insecure_mx_policy for details.
+
<b>-o</b> <i>name=value</i>
- Specify zero or more times to override the value of the <a href="postconf.5.html">main.cf</a>
- parameter <i>name</i> with <i>value</i>. Possible use-cases include overrid-
- ing the values of TLS library parameters, or "<a href="postconf.5.html#myhostname">myhostname</a>" to
+ Specify zero or more times to override the value of the <a href="postconf.5.html">main.cf</a>
+ parameter <i>name</i> with <i>value</i>. Possible use-cases include overrid-
+ ing the values of TLS library parameters, or "<a href="postconf.5.html#myhostname">myhostname</a>" to
configure the SMTP EHLO name sent to the remote server.
<b>-p</b> <i>protocols</i> (default: !SSLv2)
- List of TLS protocols that posttls-finger will exclude or
+ List of TLS protocols that posttls-finger will exclude or
include. See <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> for details.
<b>-P</b> <i>CApath/</i> (default: none)
- The OpenSSL CApath/ directory (indexed via c_rehash(1)) for
+ The OpenSSL CApath/ directory (indexed via c_rehash(1)) for
remote SMTP server certificate verification. By default no CAp-
ath is used and no public CAs are trusted.
<b>-r</b> <i>delay</i>
- With a cacheable TLS session, disconnect and reconnect after
+ With a cacheable TLS session, disconnect and reconnect after
<i>delay</i> seconds. Report whether the session is re-used. Retry if a
- new server is encountered, up to 5 times or as specified with
- the <b>-m</b> option. By default reconnection is disabled, specify a
+ new server is encountered, up to 5 times or as specified with
+ the <b>-m</b> option. By default reconnection is disabled, specify a
positive delay to enable this behavior.
- <b>-S</b> Disable SMTP; that is, connect to an LMTP server. The default
- port for LMTP over TCP is 24. Alternative ports can specified
- by appending "<i>:servicename</i>" or ":<i>portnumber</i>" to the destination
+ <b>-S</b> Disable SMTP; that is, connect to an LMTP server. The default
+ port for LMTP over TCP is 24. Alternative ports can specified
+ by appending "<i>:servicename</i>" or ":<i>portnumber</i>" to the destination
argument.
<b>-t</b> <i>timeout</i> (default: <b>30</b>)
reading the remote server's 220 banner.
<b>-T</b> <i>timeout</i> (default: <b>30</b>)
- The SMTP/LMTP command timeout for EHLO/LHLO, STARTTLS and QUIT.
+ The SMTP/LMTP command timeout for EHLO/LHLO, STARTTLS and QUIT.
- <b>-v</b> Enable verbose Postfix logging. Specify more than once to
+ <b>-v</b> Enable verbose Postfix logging. Specify more than once to
increase the level of verbose logging.
- <b>-w</b> Enable outgoing TLS wrapper mode, or SMTPS support. This is
- typically provided on port 465 by servers that are compatible
- with the ad-hoc SMTP in SSL protocol, rather than the standard
+ <b>-w</b> Enable outgoing TLS wrapper mode, or SMTPS support. This is
+ typically provided on port 465 by servers that are compatible
+ with the ad-hoc SMTP in SSL protocol, rather than the standard
STARTTLS protocol. The destination <i>domain</i>:<i>port</i> should of course
provide such a service.
[<b>inet:</b>]<i>domain</i>[:<i>port</i>]
Connect via TCP to domain <i>domain</i>, port <i>port</i>. The default port is
- <b>smtp</b> (or 24 with LMTP). With SMTP an MX lookup is performed to
- resolve the domain to a host, unless the domain is enclosed in
- <b>[]</b>. If you want to connect to a specific MX host, for instance
- <i>mx1.example.com</i>, specify [<i>mx1.example.com</i>] as the destination
+ <b>smtp</b> (or 24 with LMTP). With SMTP an MX lookup is performed to
+ resolve the domain to a host, unless the domain is enclosed in
+ <b>[]</b>. If you want to connect to a specific MX host, for instance
+ <i>mx1.example.com</i>, specify [<i>mx1.example.com</i>] as the destination
and <i>example.com</i> as a <b>match</b> argument. When using DNS, the desti-
- nation domain is assumed fully qualified and no default domain
- or search suffixes are applied; you must use fully-qualified
- names or also enable <b>native</b> host lookups (these don't support
- <b>dane</b> or <b>dane-only</b> as no DNSSEC validation information is avail-
+ nation domain is assumed fully qualified and no <a href="ADDRESS_CLASS_README.html#default_domain_class">default domain</a>
+ or search suffixes are applied; you must use fully-qualified
+ names or also enable <b>native</b> host lookups (these don't support
+ <b>dane</b> or <b>dane-only</b> as no DNSSEC validation information is avail-
able via <b>native</b> lookups).
<b>unix:</b><i>pathname</i>
<b>match ...</b>
With no match arguments specified, certificate peername matching
uses the compiled-in default strategies for each security level.
- If you specify one or more arguments, these will be used as the
- list of certificate or public-key digests to match for the <b>fin-</b>
+ If you specify one or more arguments, these will be used as the
+ list of certificate or public-key digests to match for the <b>fin-</b>
<b>gerprint</b> level, or as the list of DNS names to match in the cer-
tificate at the <b>verify</b> and <b>secure</b> levels. If the security level
is <b>dane</b>, or <b>dane-only</b> the match names are ignored, and <b>hostname,</b>
Request that the Postfix SMTP client connects using the legacy
SMTPS protocol instead of using the STARTTLS command.
+ Available in Postfix version 3.1 and later:
+
+ <b><a href="postconf.5.html#smtp_tls_dane_insecure_mx_policy">smtp_tls_dane_insecure_mx_policy</a> (dane)</b>
+ The TLS policy for MX hosts with "secure" TLSA records when the
+ nexthop destination security level is <b>dane</b>, but the MX record
+ was found via an "insecure" MX lookup.
+
<b>OBSOLETE STARTTLS CONTROLS</b>
The following configuration parameters exist for compatibility with
Postfix versions before 2.3. Support for these will be removed in a
: ${SHLIB_SUFFIX=.dylib}
: ${SHLIB_LD='cc -shared -Wl,-flat_namespace -Wl,-undefined,dynamic_lookup -Wl,-install_name,@rpath/${LIB}'}
: ${SHLIB_RPATH='-Wl,-rpath,${SHLIB_DIR}'}
- : ${SHLIB_ENV="DYLD_LIBRARY_PATH=`pwd`/lib"}
+ # In MacOS/X 10.11.x /bin/sh unsets DYLD_LIBRARY_PATH, so we
+ # have export it into postfix-install indirectly!
+ : ${SHLIB_ENV="DYLD_LIBRARY_PATH=`pwd`/lib SHLIB_ENV_VAR=DYLD_LIBRARY_PATH SHLIB_ENV_VAL=`pwd`/lib"}
: ${PLUGIN_LD='cc -shared -Wl,-flat_namespace -Wl,-undefined,dynamic_lookup'}
;;
dcosx.1*) SYSTYPE=DCOSX1
don't expose the underlying server identity in their EHLO
response; with these servers there will never be more than
1 reconnection attempt.
+.IP "\fB\-M \fIinsecure_mx_policy\fR (default: \fBdane\fR)"
+The TLS policy for MX hosts with "secure" TLSA records when the
+nexthop destination security level is \fBdane\fR, but the MX
+record was found via an "insecure" MX lookup. See the main.cf
+documentation for smtp_tls_insecure_mx_policy for details.
.IP "\fB\-o \fIname=value\fR"
Specify zero or more times to override the value of the main.cf
parameter \fIname\fR with \fIvalue\fR. Possible use\-cases include
This feature is available in Postfix 2.6 and later. With earlier Postfix
releases only the smtp_tls_mandatory_ciphers parameter is implemented,
and opportunistic TLS always uses "export" or better (i.e. all) ciphers.
+.SH smtp_tls_dane_insecure_mx_policy (default: dane)
+The TLS policy for MX hosts with "secure" TLSA records when the
+nexthop destination security level is \fBdane\fR, but the MX
+record was found via an "insecure" MX lookup. The choices are:
+.IP "\fBmay\fR"
+The TLSA records will be ignored and TLS will be optional. If
+the MX host does not appear to support STARTTLS, or the STARTTLS
+handshake fails, mail may be sent in the clear.
+.br
+.IP "\fBencrypt\fR"
+The TLSA records will signal a requirement to use TLS. While
+TLS encryption will be required, authentication will not be performed.
+.br
+.IP "\fBdane\fR (default)"
+The TLSA records will be used just as with "secure" MX records.
+TLS encryption will be required, and, if at least one of the TLSA
+records is "usable", authentication will be required. When
+authentication succeeds, it will be logged only as "Trusted", not
+"Verified", because the MX host name could have been forged.
+.br
+.br
+Though with "insecure" MX records an active attacker can
+compromise SMTP transport security by returning forged MX records,
+such attacks are "tamper\-evident" since any forged MX hostnames
+will be recorded in the mail logs. Attackers who place a high value
+staying hidden may be deterred from forging MX records.
+.PP
+This feature is available in Postfix 3.1 and later. The \fBmay\fR
+policy is backwards\-compatible with earlier Postfix versions.
.SH smtp_tls_dcert_file (default: empty)
File with the Postfix SMTP client DSA certificate in PEM format.
This file may also contain the Postfix SMTP client private DSA key.
.IP "\fBsmtp_tls_wrappermode (no)\fR"
Request that the Postfix SMTP client connects using the
legacy SMTPS protocol instead of using the STARTTLS command.
+.PP
+Available in Postfix version 3.1 and later:
+.IP "\fBsmtp_tls_dane_insecure_mx_policy (dane)\fR"
+The TLS policy for MX hosts with "secure" TLSA records when the
+nexthop destination security level is \fBdane\fR, but the MX
+record was found via an "insecure" MX lookup.
.SH "OBSOLETE STARTTLS CONTROLS"
.na
.nf
s;\bsmtp_tls_session_cache_database\b;<a href="postconf.5.html#smtp_tls_session_cache_database">$&</a>;g;
s;\bsmtp_tls_session_cache_timeout\b;<a href="postconf.5.html#smtp_tls_session_cache_timeout">$&</a>;g;
s;\bsmtp_tls_block_early_mail_reply\b;<a href="postconf.5.html#smtp_tls_block_early_mail_reply">$&</a>;g;
+ s;\bsmtp_tls_dane_insecure_mx_policy\b;<a href="postconf.5.html#smtp_tls_dane_insecure_mx_policy">$&</a>;g;
s;\bsmtp_tls_force_insecure_host_tlsa_lookup\b;<a href="postconf.5.html#smtp_tls_force_insecure_host_tlsa_lookup">$&</a>;g;
s;\bsmtp_tls_wrappermode\b;<a href="postconf.5.html#smtp_tls_wrappermode">$&</a>;g;
s;\bsmtp_use_tls\b;<a href="postconf.5.html#smtp_use_tls">$&</a>;g;
# Override all LC_* settings and LANG for robustness.
LC_ALL=C; export LC_ALL
+if [ -n "$SHLIB_ENV_VAR" ]; then
+ junk="${SHLIB_ENV_VAL}"
+ eval export "$SHLIB_ENV_VAR=\$junk"
+fi
+
USAGE="Usage: $0 [name=value] [option]
-non-interactive Do not ask for installation parameters.
-package Build a ready-to-install package.
This feature is available in Postfix 3.1 and later.
</p>
+%PARAM smtp_tls_dane_insecure_mx_policy dane
+
+<p> The TLS policy for MX hosts with "secure" TLSA records when the
+nexthop destination security level is <b>dane</b>, but the MX
+record was found via an "insecure" MX lookup. The choices are:
+</p>
+
+<dl>
+<dt><b>may</b></dt>
+<dd> The TLSA records will be ignored and TLS will be optional. If
+the MX host does not appear to support STARTTLS, or the STARTTLS
+handshake fails, mail may be sent in the clear. </dd>
+<dt><b>encrypt</b></dt>
+<dd> The TLSA records will signal a requirement to use TLS. While
+TLS encryption will be required, authentication will not be performed.
+</dd>
+<dt><b>dane</b> (default)</dt>
+<dd>The TLSA records will be used just as with "secure" MX records.
+TLS encryption will be required, and, if at least one of the TLSA
+records is "usable", authentication will be required. When
+authentication succeeds, it will be logged only as "Trusted", not
+"Verified", because the MX host name could have been forged. </dd>
+</dl>
+
+<p> Though with "insecure" MX records an active attacker can
+compromise SMTP transport security by returning forged MX records,
+such attacks are "tamper-evident" since any forged MX hostnames
+will be recorded in the mail logs. Attackers who place a high value
+staying hidden may be deterred from forging MX records. </p>
+
+<p>
+This feature is available in Postfix 3.1 and later. The <b>may</b>
+policy is backwards-compatible with earlier Postfix versions.
+</p>
+
%PARAM address_verify_pending_request_limit see "postconf -d" output
<p> A safety limit that prevents address verification requests from
#define DEF_LMTP_TLS_FORCE_TLSA 0
extern bool var_smtp_tls_force_tlsa;
+ /* SMTP only */
+#define VAR_SMTP_TLS_INSECURE_MX_POLICY "smtp_tls_dane_insecure_mx_policy"
+#define DEF_SMTP_TLS_INSECURE_MX_POLICY "dane"
+extern char *var_smtp_tls_insecure_mx_policy;
+
/*
* SASL authentication support, SMTP server side.
*/
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20151227"
+#define MAIL_RELEASE_DATE "20160103"
#define MAIL_VERSION_NUMBER "3.1"
#ifdef SNAPSHOT
/* don't expose the underlying server identity in their EHLO
/* response; with these servers there will never be more than
/* 1 reconnection attempt.
+/* .IP "\fB-M \fIinsecure_mx_policy\fR (default: \fBdane\fR)"
+/* The TLS policy for MX hosts with "secure" TLSA records when the
+/* nexthop destination security level is \fBdane\fR, but the MX
+/* record was found via an "insecure" MX lookup. See the main.cf
+/* documentation for smtp_tls_insecure_mx_policy for details.
/* .IP "\fB-o \fIname=value\fR"
/* Specify zero or more times to override the value of the main.cf
/* parameter \fIname\fR with \fIvalue\fR. Possible use-cases include
TLS_DANE *ddane; /* DANE TLSA from DNS */
char *grade; /* Minimum cipher grade */
char *protocols; /* Protocol inclusion/exclusion */
+ int mxinsec_level; /* DANE for insecure MX RRs? */
#endif
OPTIONS options; /* JCL */
} STATE;
static const char *myname = "mx_addr_list";
DNS_RR *addr_list = 0;
DNS_RR *rr;
- int res_opt = mx_names->dnssec_valid ? RES_USE_DNSSEC : 0;
+ int res_opt = 0;
+
+ if (mx_names->dnssec_valid)
+ res_opt = RES_USE_DNSSEC;
+#ifdef USE_TLS
+ else if (state->mxinsec_level > TLS_LEV_MAY)
+ res_opt = RES_USE_DNSSEC;
+#endif
for (rr = mx_names; rr; rr = rr->next) {
if (rr->type != T_MX)
#ifdef USE_TLS
if (TLS_DANE_BASED(level)) {
- if (state->mx == 0 || state->mx->dnssec_valid) {
+ if (state->mx == 0 || state->mx->dnssec_valid ||
+ state->mxinsec_level > TLS_LEV_MAY) {
if (state->log_mask & (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE))
tls_dane_verbose(1);
else
} else if (!TLS_DANE_HASTA(state->ddane)
&& !TLS_DANE_HASEE(state->ddane)) {
msg_panic("DANE activated with no TLSA records to match");
+ } else if (state->mx && !state->mx->dnssec_valid &&
+ state->mxinsec_level == TLS_LEV_ENCRYPT) {
+ msg_info("TLSA RRs found, MX RRset insecure: just encrypt");
+ tls_dane_free(state->ddane);
+ state->ddane = 0;
+ level = TLS_LEV_ENCRYPT;
} else {
if (state->match)
argv_free(state->match);
argv_add(state->match = argv_alloc(2),
state->ddane->base_domain, ARGV_END);
if (state->mx) {
+ if (!state->mx->dnssec_valid) {
+ msg_info("MX RRset insecure: log verified as trusted");
+ state->ddane->flags |= TLS_DANE_FLAG_MXINSEC;
+ }
if (strcmp(state->mx->qname, state->mx->rname) == 0)
argv_add(state->match, state->mx->qname, ARGV_END);
else
state->mx->qname, ARGV_END);
}
}
+ } else if (state->mx && !state->mx->dnssec_valid &&
+ state->mxinsec_level == TLS_LEV_MAY) {
+ msg_info("MX RRset is insecure: try to encrypt");
+ level = TLS_LEV_MAY;
} else {
level = TLS_LEV_SECURE;
}
#define OPTS "a:ch:o:St:T:v"
#ifdef USE_TLS
-#define TLSOPTS "A:Cd:fF:g:k:K:l:L:m:p:P:r:w"
+#define TLSOPTS "A:Cd:fF:g:k:K:l:L:m:M:p:P:r:w"
state->mdalg = mystrdup("sha1");
state->CApath = mystrdup("");
state->options.tas = argv_alloc(1);
state->options.logopts = 0;
state->level = TLS_LEV_DANE;
+ state->mxinsec_level = TLS_LEV_DANE;
#else
#define TLSOPTS ""
state->level = TLS_LEV_NONE;
case 'm':
state->max_reconnect = atoi(optarg);
break;
+ case 'M':
+ switch (state->mxinsec_level = tls_level_lookup(optarg)) {
+ case TLS_LEV_MAY:
+ case TLS_LEV_ENCRYPT:
+ case TLS_LEV_DANE:
+ break;
+ default:
+ msg_fatal("bad '-M' option value: %s", optarg);
+ }
+ break;
case 'p':
myfree(state->protocols);
state->protocols = mystrdup(optarg);
_ALWAYS_EHLO
_NEVER_EHLO
-_SMTP_FALLBACK
_IGN_MX_LOOKUP_ERR
+_INSECURE_MX_POLICY
/* .IP "\fBsmtp_tls_wrappermode (no)\fR"
/* Request that the Postfix SMTP client connects using the
/* legacy SMTPS protocol instead of using the STARTTLS command.
+/* .PP
+/* Available in Postfix version 3.1 and later:
+/* .IP "\fBsmtp_tls_dane_insecure_mx_policy (dane)\fR"
+/* The TLS policy for MX hosts with "secure" TLSA records when the
+/* nexthop destination security level is \fBdane\fR, but the MX
+/* record was found via an "insecure" MX lookup.
/* OBSOLETE STARTTLS CONTROLS
/* .ad
/* .fi
char *var_smtp_tls_eckey_file;
bool var_smtp_tls_blk_early_mail_reply;
bool var_smtp_tls_force_tlsa;
+char *var_smtp_tls_insecure_mx_policy;
#endif
* OpenSSL client state (opaque handle)
*/
TLS_APPL_STATE *smtp_tls_ctx;
+int smtp_tls_insecure_mx_policy;
#endif
var_disable_dns = (smtp_dns_support == SMTP_DNS_DISABLED);
}
+#ifdef USE_TLS
+ if (smtp_mode) {
+ smtp_tls_insecure_mx_policy =
+ tls_level_lookup(var_smtp_tls_insecure_mx_policy);
+ switch (smtp_tls_insecure_mx_policy) {
+ case TLS_LEV_MAY:
+ case TLS_LEV_ENCRYPT:
+ case TLS_LEV_DANE:
+ break;
+ default:
+ msg_fatal("invalid %s: \"%s\"", VAR_SMTP_TLS_INSECURE_MX_POLICY,
+ var_smtp_tls_insecure_mx_policy);
+ }
+ }
+#endif
+
/*
* Select hostname lookup mechanisms.
*/
#ifdef USE_TLS
extern TLS_APPL_STATE *smtp_tls_ctx; /* client-side TLS engine */
+extern int smtp_tls_insecure_mx_policy; /* DANE post insecure MX? */
#endif
{
DNS_RR *addr_list = 0;
DNS_RR *rr;
- int res_opt = mx_names->dnssec_valid ? RES_USE_DNSSEC : 0;
+ int res_opt = 0;
+
+ if (mx_names->dnssec_valid)
+ res_opt = RES_USE_DNSSEC;
+#ifdef USE_TLS
+ else if (smtp_tls_insecure_mx_policy > TLS_LEV_MAY)
+ res_opt = RES_USE_DNSSEC;
+#endif
/*
* As long as we are able to look up any host address, we ignore problems
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_INSECURE_MX_POLICY, DEF_SMTP_TLS_INSECURE_MX_POLICY, &var_smtp_tls_insecure_mx_policy, 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,
#define NONDANE_CONFIG 0 /* Administrator's fault */
#define NONDANE_DEST 1 /* Remote server's fault */
-#define DANE_UNUSABLE 2 /* Remote server's fault */
+#define DANE_CANTAUTH 2 /* Remote server's fault */
static void PRINTFLIKE(4, 5) dane_incompat(SMTP_TLS_POLICY *tls,
SMTP_ITERATOR *iter,
va_start(ap, fmt);
if (tls->level == TLS_LEV_DANE) {
- tls->level = (errtype == DANE_UNUSABLE) ? TLS_LEV_ENCRYPT : TLS_LEV_MAY;
+ tls->level = (errtype == DANE_CANTAUTH) ? TLS_LEV_ENCRYPT : TLS_LEV_MAY;
if (errtype == NONDANE_CONFIG)
vmsg_warn(fmt, ap);
else if (msg_verbose)
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) {
+ /* When the MX name is present and insecure, DANE may not apply. */
+ if (iter->mx && !iter->mx->dnssec_valid
+ && smtp_tls_insecure_mx_policy <= TLS_LEV_MAY) {
dane_incompat(tls, iter, NONDANE_DEST, "non DNSSEC destination");
return;
}
* given verifier some of the CAs are surely not trustworthy).
*/
if (tls_dane_unusable(dane)) {
- dane_incompat(tls, iter, DANE_UNUSABLE, "TLSA records unusable");
+ dane_incompat(tls, iter, DANE_CANTAUTH, "TLSA records unusable");
tls_dane_free(dane);
return;
}
+ /*
+ * Perhaps downgrade to "encrypt" if MX is insecure.
+ */
+ if (iter->mx && !iter->mx->dnssec_valid) {
+ if (smtp_tls_insecure_mx_policy == TLS_LEV_ENCRYPT) {
+ dane_incompat(tls, iter, DANE_CANTAUTH,
+ "Verification not possible, MX RRset is insecure");
+ tls_dane_free(dane);
+ return;
+ }
+ /* For correct logging in tls_client_start() */
+ dane->flags |= TLS_DANE_FLAG_MXINSEC;
+ }
+
/*
* With DANE trust anchors, peername matching is not configurable.
*/
}
}
+#ifdef USE_SASL_AUTH
+
/* smtpd_sasl_auth_cmd_wrapper - smtpd_sasl_auth_cmd front-end */
static int smtpd_sasl_auth_cmd_wrapper(SMTPD_STATE *state, int argc,
return (smtpd_sasl_auth_cmd(state, argc, argv));
}
+#endif
+
/* mail_open_stream - open mail queue file or IPC stream */
static int mail_open_stream(SMTPD_STATE *state)
#define TLS_DANE_FLAG_NORRS (1<<0) /* Nothing found in DNS */
#define TLS_DANE_FLAG_EMPTY (1<<1) /* Nothing usable found in DNS */
#define TLS_DANE_FLAG_ERROR (1<<2) /* TLSA record lookup error */
+#define TLS_DANE_FLAG_MXINSEC (1<<3) /* Insecure MX record */
#define tls_dane_unusable(dane) ((dane)->flags & TLS_DANE_FLAG_EMPTY)
#define tls_dane_notfound(dane) ((dane)->flags & TLS_DANE_FLAG_NORRS)
TLS_CERTS *certs; /* Full trust-anchor certificates */
TLS_PKEYS *pkeys; /* Full trust-anchor public keys */
char *base_domain; /* Base domain of TLSA RRset */
- int flags; /* Conflate cert and pkey digests */
+ int flags; /* Lookup status */
time_t expires; /* Expiration time of this record */
int refs; /* Reference count */
} TLS_DANE;
* we want to be as compatible as possible, so we will start off with a
* SSLv2 greeting allowing the best we can offer: TLSv1. We can restrict
* this with the options setting later, anyhow.
- *
+ *
* OpenSSL 1.1.0-dev deprecates SSLv23_client_method() in favour of
* TLS_client_method(), with the change in question signalled via a new
* TLS_ANY_VERSION macro.
return (0);
}
+ /*
+ * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev
+ */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
/*
* According to the OpenSSL documentation, temporary RSA key is needed
* export ciphers are in use. We have to provide one, so well, we just do
* it.
*/
SSL_CTX_set_tmp_rsa_callback(client_ctx, tls_tmp_rsa_cb);
+#endif
/*
* Finally, the setup for the server certificate checking, done "by the
*/
tls_stream_start(props->stream, TLScontext);
+ /*
+ * Can't really be DANE verified if the MX RRset was insecure
+ */
+ if (TLS_DANE_BASED(props->tls_level)
+ && (props->dane->flags & TLS_DANE_FLAG_MXINSEC) != 0) {
+ TLScontext->peer_status &= ~TLS_CERT_FLAG_MATCHED;
+ }
+
/*
* All the key facts in a single log entry.
*/
/*
* Compiled-in DH parameters. Used when no parameters are explicitly loaded
- * from a site-specific file. Using an ASN.1 DER encoding avoids the need to
- * explicitly manipulate the internal represenation of DH parameter objects.
- *
+ * from a site-specific file. Using an ASN.1 DER encoding avoids the need
+ * to explicitly manipulate the internal representation of DH parameter
+ * objects.
+ *
* 512-bit parameters are used for export ciphers, and 2048-bit parameters are
- * used for non-export ciphers. The non-export group is now 2048-bit, as 1024
- * bits is increasingly considered to weak by clients. When greater security
- * is required, use EECDH.
+ * used for non-export ciphers. The non-export group is now 2048-bit, as
+ * 1024 bits is increasingly considered to weak by clients. When greater
+ * security is required, use EECDH.
*/
/*-
}
/*
- * This function is the first to set the DH parameters, but free any prior
- * value just in case the call sequence changes some day.
+ * This function is the first to set the DH parameters, but free any
+ * prior value just in case the call sequence changes some day.
*/
if (*dhPtr) {
DH_free(*dhPtr);
*dhPtr = 0;
}
-
if ((paramfile = fopen(path, "r")) != 0) {
if ((*dhPtr = PEM_read_DHparams(paramfile, 0, 0, 0)) == 0) {
msg_warn("cannot load %d-bit DH parameters from file %s"
ERR_clear_error();
if ((ecdh = EC_KEY_new_by_curve_name(nid)) == 0
|| SSL_CTX_set_tmp_ecdh(server_ctx, ecdh) == 0) {
+ EC_KEY_free(ecdh); /* OK if NULL */
msg_warn("unable to use curve \"%s\": disabling EECDH support", curve);
tls_print_errors();
return (0);
}
+ EC_KEY_free(ecdh);
#endif
return (1);
}
#include <tls.h>
#include <openssl/rsa.h>
+ /*
+ * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev
+ */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
/* tls_tmp_rsa_cb - call-back to generate ephemeral RSA key */
RSA *tls_tmp_rsa_cb(SSL *unused_ssl, int export, int keylength)
return (rsa_tmp);
}
+#endif /* OPENSSL_VERSION_NUMBER */
+
#ifdef TEST
#include <msg_vstream.h>
int main(int unused_argc, char *const argv[])
{
+ int ok = 0;
+
+ /*
+ * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev
+ */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
RSA *rsa;
- int ok;
msg_vstream_init(argv[0], VSTREAM_ERR);
/* Non-export or unexpected bit length should fail */
ok = ok && tls_tmp_rsa_cb(0, 0, 512) == 0;
ok = ok && tls_tmp_rsa_cb(0, 1, 1024) == 0;
+#endif
return ok ? 0 : 1;
}
return (0);
}
+ /*
+ * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev
+ */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
/*
* According to OpenSSL documentation, a temporary RSA key is needed when
* export ciphers are in use, because the certified key cannot be
* directly used.
*/
SSL_CTX_set_tmp_rsa_callback(server_ctx, tls_tmp_rsa_cb);
+#endif
/*
* Diffie-Hellman key generation parameters can either be loaded from