2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-09-01 06:35:27 +00:00

postfix-2.12-20150118

This commit is contained in:
Wietse Venema
2015-01-18 00:00:00 -05:00
committed by Viktor Dukhovni
parent 07c5e9a196
commit 5c187bc356
12 changed files with 194 additions and 120 deletions

View File

@@ -19583,8 +19583,8 @@ Apologies for any names omitted.
smtp/smtp.h, smtp/smtp_rcpt.c. smtp/smtp.h, smtp/smtp_rcpt.c.
Logging: the TLS client logged that an "Untrusted" TLS Logging: the TLS client logged that an "Untrusted" TLS
connection was established instead of "Anonymous". connection was established instead of "Anonymous". Viktor
Viktor Dukhovni. File: tls/tls_client.c. Dukhovni. File: tls/tls_client.c.
Documentation: new self-signed certificate example and Documentation: new self-signed certificate example and
updated private CA example. File: proto/TLS_README.html. updated private CA example. File: proto/TLS_README.html.
@@ -19755,8 +19755,8 @@ Apologies for any names omitted.
20140508 20140508
Cleanup: dynamicmaps.cf is now installed into $daemon_directory Cleanup: dynamicmaps.cf is now installed into $daemon_directory
because the file is shared among Postfix instances just like because the file is shared among Postfix instances just
postfix-files and other files. Files: conf/dynamicmaps.cf, like postfix-files and other files. Files: conf/dynamicmaps.cf,
Makefile.in, conf/postfix-files. Makefile.in, conf/postfix-files.
Cleanup: INSTALL is now plain ASCII instead of README format, Cleanup: INSTALL is now plain ASCII instead of README format,
@@ -19807,11 +19807,11 @@ Apologies for any names omitted.
Support for "make shared=yes" and "make dynamicmaps=yes". Support for "make shared=yes" and "make dynamicmaps=yes".
New plugin_directory parameter for the location of the New plugin_directory parameter for the location of the
dynamicmaps.cf file and for plugins with a relative pathname. dynamicmaps.cf file and for plugins with a relative pathname.
See RELEASE_NOTES and INSTALL for details. Files: See RELEASE_NOTES and INSTALL for details. Files: postfix.c,
postfix.c, mail_params.[hc], dynamicmaps.c, mail_dict.c, mail_params.[hc], dynamicmaps.c, mail_dict.c, makedefs,
makedefs, postfix-files, dynamicmaps.cf, Makefile.in, postfix-files, dynamicmaps.cf, Makefile.in, util/Makefile.in,
util/Makefile.in, global/Makefile.in, postlink, postconf.proto. global/Makefile.in, postlink, postconf.proto. INSTALL.html,
INSTALL.html, RELEASE_NOTES. RELEASE_NOTES.
20140523 20140523
@@ -20243,9 +20243,9 @@ Apologies for any names omitted.
Cleanup: change extract_addr() API to indicate that an Cleanup: change extract_addr() API to indicate that an
address is parsed in SMTPUTF8 context. File: smtpd/smtpd.c. address is parsed in SMTPUTF8 context. File: smtpd/smtpd.c.
Cleanup: shared-library build fixes. Viktor Dukhovni. Cleanup: shared-library build fixes. Viktor Dukhovni. Files:
Files: makedefs, dns/Makefile.in, global/Makefile.in, makedefs, dns/Makefile.in, global/Makefile.in, master/Makefile.in,
master/Makefile.in, tls/Makefile.in, util/Makefile.in. tls/Makefile.in, util/Makefile.in.
First general release with SMTPUTF8 support; see RELEASE_NOTES First general release with SMTPUTF8 support; see RELEASE_NOTES
for an initial writeup. The last pre-SMTPUTF8 release is for an initial writeup. The last pre-SMTPUTF8 release is
@@ -20317,8 +20317,8 @@ Apologies for any names omitted.
20140731 20140731
Feature: the Postfix SMTP server now logs at the end of Feature: the Postfix SMTP server now logs at the end of a
a session how many times each SMTP command was successfully session how many times each SMTP command was successfully
invoked, followed by the total number of invocations if it invoked, followed by the total number of invocations if it
is different. File: smtpd/smtpd.c. is different. File: smtpd/smtpd.c.
@@ -20461,9 +20461,9 @@ Apologies for any names omitted.
20140927 20140927
Cleanup: specify { name = value } in per-Milter settings, to support Cleanup: specify { name = value } in per-Milter settings,
space around the "=" or comma/space within the value. Files: to support space around the "=" or comma/space within the
global/attr_over.[hc]. value. Files: global/attr_over.[hc].
Cleanup: "postconf -n" now only shows config_directory when Cleanup: "postconf -n" now only shows config_directory when
an override is in effect (environment, -c or -o). an override is in effect (environment, -c or -o).
@@ -20504,15 +20504,14 @@ Apologies for any names omitted.
Cleanup: force LANG=C to prevent groff from outputting Cleanup: force LANG=C to prevent groff from outputting
non-ASCII cruft into the HTML-ized manpages. Files: non-ASCII cruft into the HTML-ized manpages. Files:
html/Makefile.in, proto/Makefile.in, many HTML output html/Makefile.in, proto/Makefile.in, many HTML output files.
files.
20140929 20140929
Cleanup: the table-driven code for per-Milter and per-policy Cleanup: the table-driven code for per-Milter and per-policy
overrides now updates arbitrary variables, so that it can also overrides now updates arbitrary variables, so that it can
be used for, say, TLS policies. Files: global/attr_override.[hc], also be used for, say, TLS policies. Files:
smtpd/smtpd_check.c, milter/milter.c. global/attr_override.[hc], smtpd/smtpd_check.c, milter/milter.c.
Documentation: support for "{ argument with whitespace }" Documentation: support for "{ argument with whitespace }"
in master(5) and pipe(8). Files: proto/master, src/pipe/pipe.c. in master(5) and pipe(8). Files: proto/master, src/pipe/pipe.c.
@@ -20524,12 +20523,12 @@ Apologies for any names omitted.
20141001 20141001
Safety: backwards-compatibility safety net that forces Postfix Safety: backwards-compatibility safety net that forces
to run with backwards-compatible default settings after an Postfix to run with backwards-compatible default settings
upgrade to a newer Postfix version. Postfix logs all uses after an upgrade to a newer Postfix version. Postfix logs
of those backwards-compatible default settings so that the all uses of those backwards-compatible default settings so
system administator can determine whether or not some that the system administator can determine whether or not
backwards-compatible default settings need to be made some backwards-compatible default settings need to be made
permanent in main.cf or master.cf. All this is controlled permanent in main.cf or master.cf. All this is controlled
with a new compatibility_level parameter, default value 0. with a new compatibility_level parameter, default value 0.
Files: global/mail_params.[hc], trivial-rewrite/rewrite.c, Files: global/mail_params.[hc], trivial-rewrite/rewrite.c,
@@ -20556,9 +20555,9 @@ Apologies for any names omitted.
20141003 20141003
Workaround: kludge for multiple paragraphs of text in indented Workaround: kludge for multiple paragraphs of text in
paragraphs. Files: mantools/postconf2html, mantools/postconf2man, indented paragraphs. Files: mantools/postconf2html,
proto/Makefile.in, proto/postconf.proto mantools/postconf2man, proto/Makefile.in, proto/postconf.proto
20141005 20141005
@@ -20605,8 +20604,9 @@ Apologies for any names omitted.
a new COMPATIBILITY_README document. Files: proto/postconf.proto, a new COMPATIBILITY_README document. Files: proto/postconf.proto,
proto/COMPATIBILITY_README.html html/index.html. proto/COMPATIBILITY_README.html html/index.html.
Documentation: update the conf/main.cf compatibility_level setting Documentation: update the conf/main.cf compatibility_level
for new Postfix installs, and updated a reminder in mail_params.h. setting for new Postfix installs, and updated a reminder
in mail_params.h.
20141010 20141010
@@ -21011,8 +21011,8 @@ Apologies for any names omitted.
20141208 20141208
Bugfix (introduced: 20141207): in new #ifdef, && should be ||. Bugfix (introduced: 20141207): in new #ifdef, && should be
File: smtpd.c. ||. File: smtpd.c.
20141210 20141210
@@ -21204,11 +21204,11 @@ Apologies for any names omitted.
20141228 20141228
Cleanup: the IDNA conversion routines now accept both Cleanup: the IDNA conversion routines now accept both ASCII
ASCII and UTF8 inputs. The functions als verify that and UTF8 inputs. The functions als verify that either their
either their result is a valid ASCII domain name or that result is a valid ASCII domain name or that it converts
it converts into a valid ASCII domain name. Files: into a valid ASCII domain name. Files: util/midna.c,
util/midna.c, util/midna_test.in, util/midna_test.ref. util/midna_test.in, util/midna_test.ref.
20141230 20141230
@@ -21238,9 +21238,10 @@ Apologies for any names omitted.
byte values, and UTF-8 case folding. As recommended at byte values, and UTF-8 case folding. As recommended at
http://www.w3.org/International/wiki/Case_folding for http://www.w3.org/International/wiki/Case_folding for
caseless string comparison, this uses the en_US locale to caseless string comparison, this uses the en_US locale to
avoid surprises. The implementatin handles avoid surprises. The implementatin handles the entire RFC
the entire RFC 3629 Unicode range (code points U+0000..U+10FFFF 3629 Unicode range (code points U+0000..U+10FFFF including
including surrogates) and is chroot(2) safe. Files: casefold.c, stringops.h. surrogates) and is chroot(2) safe. Files: casefold.c,
stringops.h.
Infrastructure: revised the midna_domain_to_ascii and Infrastructure: revised the midna_domain_to_ascii and
midna_domain_to_utf8 domain name conversion functions after midna_domain_to_utf8 domain name conversion functions after
@@ -21412,3 +21413,16 @@ Apologies for any names omitted.
Cleanup: missing " in \%s\" in postscreen(8) fatal error Cleanup: missing " in \%s\" in postscreen(8) fatal error
messages. Iain Hibbert. File: postconf/postconf_master.c. messages. Iain Hibbert. File: postconf/postconf_master.c.
20150118
Bugfix (introduced: 20140731): when a connection timed out
before any command was received, the Postfix SMTP server
"disconnect from" logging would show the content of the
last SMTP server response (421 4.4.2 $myhostname error:
timeout exceeded) instead of per-command statistics, because
there were no statistics to report. The Postfix SMTP server
now always logs the total number of commands (commands=x/y)
even when the client did not send any. This helps logfile
analyzers to recognize sessions without commands. File:
smtpd/smtpd.c.

View File

@@ -151,9 +151,11 @@ provide ETRN service for that domain, then the system administrator should make
the backwards-compatible setting "relay_domains = $mydestination" permanent in the backwards-compatible setting "relay_domains = $mydestination" permanent in
main.cf: main.cf:
# ppoossttccoonnff rreellaayy__ddoommaaiinnss==$$mmyyddeessttiinnaattiioonn # ppoossttccoonnff ''rreellaayy__ddoommaaiinnss==$$mmyyddeessttiinnaattiioonn''
# ppoossttffiixx rreellooaadd # ppoossttffiixx rreellooaadd
Note: quotes are required as indicated above.
Instead of $mydestination, it may be better to specify an explicit list of Instead of $mydestination, it may be better to specify an explicit list of
domain names. domain names.

View File

@@ -8,6 +8,12 @@ Wish list:
Things to do after the stable release: Things to do after the stable release:
postconf -P: emit '{ name = value }' when editing/adding a
parameter whose new value contains whitespace.
In release-notes add commands=x/y logging to the command
statistics.
UTF8 DNS[BW]L domain name. UTF8 DNS[BW]L domain name.
Consolidate maps flags in mail_params.h instead of having Consolidate maps flags in mail_params.h instead of having

View File

@@ -253,11 +253,13 @@ administrator should make the backwards-compatible setting
<blockquote> <blockquote>
<pre> <pre>
# <b>postconf <a href="postconf.5.html#relay_domains">relay_domains</a>=$<a href="postconf.5.html#mydestination">mydestination</a></b> # <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> # <b>postfix reload</b>
</pre> </pre>
</blockquote> </blockquote>
<p> Note: quotes are required as indicated above. </p>
<p> Instead of $<a href="postconf.5.html#mydestination">mydestination</a>, it may be better to specify an <p> Instead of $<a href="postconf.5.html#mydestination">mydestination</a>, it may be better to specify an
explicit list of domain names. </p> explicit list of domain names. </p>

View File

@@ -253,11 +253,13 @@ administrator should make the backwards-compatible setting
<blockquote> <blockquote>
<pre> <pre>
# <b>postconf relay_domains=$mydestination</b> # <b>postconf 'relay_domains=$mydestination'</b>
# <b>postfix reload</b> # <b>postfix reload</b>
</pre> </pre>
</blockquote> </blockquote>
<p> Note: quotes are required as indicated above. </p>
<p> Instead of $mydestination, it may be better to specify an <p> Instead of $mydestination, it may be better to specify an
explicit list of domain names. </p> explicit list of domain names. </p>

View File

@@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20150117" #define MAIL_RELEASE_DATE "20150118"
#define MAIL_VERSION_NUMBER "2.12" #define MAIL_VERSION_NUMBER "2.12"
#ifdef SNAPSHOT #ifdef SNAPSHOT

View File

@@ -228,6 +228,12 @@
/* .IP "\fB-v\fR" /* .IP "\fB-v\fR"
/* Enable verose Postfix logging. Specify more than once to increase /* Enable verose Postfix logging. Specify more than once to increase
/* the level of verbose logging. /* the level of verbose logging.
/* .IP "\fB-w\fR"
/* 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 \fIdomain\fR:\fIport\fR should of course provide such
/* a service.
/* .IP "[\fBinet:\fR]\fIdomain\fR[:\fIport\fR]" /* .IP "[\fBinet:\fR]\fIdomain\fR[:\fIport\fR]"
/* Connect via TCP to domain \fIdomain\fR, port \fIport\fR. The default /* Connect via TCP to domain \fIdomain\fR, port \fIport\fR. The default
/* port is \fBsmtp\fR (or 24 with LMTP). With SMTP an MX lookup is /* port is \fBsmtp\fR (or 24 with LMTP). With SMTP an MX lookup is
@@ -421,6 +427,7 @@ typedef struct STATE {
VSTRING *buffer; /* Response buffer */ VSTRING *buffer; /* Response buffer */
VSTREAM *stream; /* Open connection */ VSTREAM *stream; /* Open connection */
int level; /* TLS security level */ int level; /* TLS security level */
int wrapper_mode; /* SMTPS support */
#ifdef USE_TLS #ifdef USE_TLS
char *mdalg; /* fingerprint digest algorithm */ char *mdalg; /* fingerprint digest algorithm */
char *CAfile; /* Trusted public CAs */ char *CAfile; /* Trusted public CAs */
@@ -547,6 +554,33 @@ static char *exception_text(int except)
} }
} }
/* greeting - read server's 220 greeting */
static int greeting(STATE *state)
{
VSTREAM *stream = state->stream;
int except;
RESPONSE *resp;
/*
* Prepare for disaster.
*/
smtp_stream_setup(stream, conn_tmout, 1);
if ((except = vstream_setjmp(stream)) != 0) {
msg_info("%s while reading server greeting", exception_text(except));
return (1);
}
/*
* Read and parse the server's SMTP greeting banner.
*/
if (((resp = response(state, 1))->code / 100) != 2) {
msg_info("SMTP service not available: %d %s", resp->code, resp->str);
return (1);
}
return (0);
}
/* ehlo - send EHLO/LHLO */ /* ehlo - send EHLO/LHLO */
static RESPONSE *ehlo(STATE *state) static RESPONSE *ehlo(STATE *state)
@@ -647,6 +681,7 @@ static int starttls(STATE *state)
VSTREAM *stream = state->stream; VSTREAM *stream = state->stream;
TLS_CLIENT_START_PROPS tls_props; TLS_CLIENT_START_PROPS tls_props;
if (state->wrapper_mode == 0) {
/* SMTP stream with deadline timeouts */ /* SMTP stream with deadline timeouts */
smtp_stream_setup(stream, smtp_tmout, 1); smtp_stream_setup(stream, smtp_tmout, 1);
if ((except = vstream_setjmp(stream)) != 0) { if ((except = vstream_setjmp(stream)) != 0) {
@@ -662,11 +697,11 @@ static int starttls(STATE *state)
} }
/* /*
* Discard any plain-text data that may be piggybacked after the server's * Discard any plain-text data that may be piggybacked after the
* 220 STARTTLS reply. Should we abort the session instead? * server's 220 STARTTLS reply. Should we abort the session instead?
*/ */
vstream_fpurge(stream, VSTREAM_PURGE_READ); vstream_fpurge(stream, VSTREAM_PURGE_READ);
}
#define ADD_EXCLUDE(vstr, str) \ #define ADD_EXCLUDE(vstr, str) \
do { \ do { \
if (*(str)) \ if (*(str)) \
@@ -718,6 +753,9 @@ static int starttls(STATE *state)
state->stream = 0; state->stream = 0;
return (1); return (1);
} }
if (state->wrapper_mode && greeting(state) != 0)
return (1);
if (state->pass == 1) { if (state->pass == 1) {
ehlo(state); ehlo(state);
if (!TLS_CERT_IS_PRESENT(state->tls_context)) if (!TLS_CERT_IS_PRESENT(state->tls_context))
@@ -743,27 +781,12 @@ static int doproto(STATE *state)
int except; int except;
int n; int n;
char *lines; char *lines;
char *words; char *words = 0;
char *word; char *word;
/* if (!state->wrapper_mode) {
* Prepare for disaster. if (greeting(state) != 0)
*/
smtp_stream_setup(stream, conn_tmout, 1);
if ((except = vstream_setjmp(stream)) != 0)
msg_fatal("%s while reading server greeting", exception_text(except));
/*
* Read and parse the server's SMTP greeting banner.
*/
if (((resp = response(state, 1))->code / 100) != 2) {
msg_info("SMTP service not available: %d %s", resp->code, resp->str);
return (1); return (1);
}
/*
* Send the standard greeting with our hostname
*/
if ((resp = ehlo(state)) == 0) if ((resp = ehlo(state)) == 0)
return (1); return (1);
@@ -776,9 +799,9 @@ static int doproto(STATE *state)
break; break;
} }
} }
}
#ifdef USE_TLS #ifdef USE_TLS
if (words && state->tls_ctx) if ((state->wrapper_mode || words) && state->tls_ctx)
if (starttls(state)) if (starttls(state))
return (1); return (1);
#endif #endif
@@ -793,7 +816,6 @@ static int doproto(STATE *state)
} }
command(state, 1, "QUIT"); command(state, 1, "QUIT");
(void) response(state, 1); (void) response(state, 1);
return (0); return (0);
} }
@@ -1191,7 +1213,7 @@ static int dane_host_level(STATE *state, DNS_RR *addr)
int level = state->level; int level = state->level;
#ifdef USE_TLS #ifdef USE_TLS
if (level == TLS_LEV_DANE) { if (TLS_DANE_BASED(level)) {
if (state->mx == 0 || state->mx->dnssec_valid) { if (state->mx == 0 || state->mx->dnssec_valid) {
if (state->log_mask & (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE)) if (state->log_mask & (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE))
tls_dane_verbose(1); tls_dane_verbose(1);
@@ -1214,7 +1236,8 @@ static int dane_host_level(STATE *state, DNS_RR *addr)
HNAME(addr), ntohs(state->port)); HNAME(addr), ntohs(state->port));
level = TLS_LEV_INVALID; level = TLS_LEV_INVALID;
} else if (tls_dane_notfound(state->ddane) } else if (tls_dane_notfound(state->ddane)
|| tls_dane_unusable(state->ddane)) { || tls_dane_unusable(state->ddane)
|| level == TLS_LEV_DANE_ONLY) {
if (msg_verbose) if (msg_verbose)
msg_info("no %sTLSA records found, " msg_info("no %sTLSA records found, "
"resorting to \"secure\"", "resorting to \"secure\"",
@@ -1223,7 +1246,7 @@ static int dane_host_level(STATE *state, DNS_RR *addr)
level = TLS_LEV_SECURE; level = TLS_LEV_SECURE;
} else if (!TLS_DANE_HASTA(state->ddane) } else if (!TLS_DANE_HASTA(state->ddane)
&& !TLS_DANE_HASEE(state->ddane)) { && !TLS_DANE_HASEE(state->ddane)) {
msg_panic("empty DANE match list"); msg_panic("DANE activated with no TLSA records to match");
} else { } else {
if (state->match) if (state->match)
argv_free(state->match); argv_free(state->match);
@@ -1531,7 +1554,7 @@ static void usage(void)
#ifdef USE_TLS #ifdef USE_TLS
fprintf(stderr, "usage: %s %s \\\n\t%s \\\n\t%s \\\n\t%s" fprintf(stderr, "usage: %s %s \\\n\t%s \\\n\t%s \\\n\t%s"
" destination [match ...]\n", var_procname, " destination [match ...]\n", var_procname,
"[-acCfSv] [-t conn_tmout] [-T cmd_tmout] [-L logopts]", "[-acCfSvw] [-t conn_tmout] [-T cmd_tmout] [-L logopts]",
"[-h host_lookup] [-l level] [-d mdalg] [-g grade] [-p protocols]", "[-h host_lookup] [-l level] [-d mdalg] [-g grade] [-p protocols]",
"[-A tafile] [-F CAfile.pem] [-P CApath/] [-m count] [-r delay]", "[-A tafile] [-F CAfile.pem] [-P CApath/] [-m count] [-r delay]",
"[-o name=value]"); "[-o name=value]");
@@ -1594,6 +1617,7 @@ static void parse_options(STATE *state, int argc, char *argv[])
state->pass = 1; state->pass = 1;
state->reconnect = -1; state->reconnect = -1;
state->max_reconnect = 5; state->max_reconnect = 5;
state->wrapper_mode = 0;
#ifdef USE_TLS #ifdef USE_TLS
state->protocols = mystrdup("!SSLv2"); state->protocols = mystrdup("!SSLv2");
state->grade = mystrdup("medium"); state->grade = mystrdup("medium");
@@ -1603,7 +1627,7 @@ static void parse_options(STATE *state, int argc, char *argv[])
#define OPTS "a:ch:o:St:T:v" #define OPTS "a:ch:o:St:T:v"
#ifdef USE_TLS #ifdef USE_TLS
#define TLSOPTS "A:Cd:fF:g:l:L:m:p:P:r:" #define TLSOPTS "A:Cd:fF:g:l:L:m:p:P:r:w"
state->mdalg = mystrdup("sha1"); state->mdalg = mystrdup("sha1");
state->CApath = mystrdup(""); state->CApath = mystrdup("");
@@ -1692,6 +1716,9 @@ static void parse_options(STATE *state, int argc, char *argv[])
case 'r': case 'r':
state->reconnect = atoi(optarg); state->reconnect = atoi(optarg);
break; break;
case 'w':
state->wrapper_mode = 1;
break;
#endif #endif
} }
} }
@@ -1725,10 +1752,9 @@ static void parse_options(STATE *state, int argc, char *argv[])
state->level = tls_level_lookup(state->options.level); state->level = tls_level_lookup(state->options.level);
switch (state->level) { switch (state->level) {
case TLS_LEV_DANE_ONLY:
state->level = TLS_LEV_DANE;
break;
case TLS_LEV_NONE: case TLS_LEV_NONE:
if (state->wrapper_mode)
msg_fatal("SSL wrapper mode requires that TLS not be disabled");
return; return;
case TLS_LEV_INVALID: case TLS_LEV_INVALID:
msg_fatal("Invalid TLS level \"%s\"", state->options.level); msg_fatal("Invalid TLS level \"%s\"", state->options.level);
@@ -1741,8 +1767,8 @@ static void parse_options(STATE *state, int argc, char *argv[])
* required for DANE support. * required for DANE support.
*/ */
tls_init(state); tls_init(state);
if (state->level == TLS_LEV_DANE && !tls_dane_avail()) { if (TLS_DANE_BASED(state->level) && !tls_dane_avail()) {
msg_warn("The \"dane\" TLS security level is not available"); msg_warn("DANE TLS support is not available, resorting to \"secure\"");
state->level = TLS_LEV_SECURE; state->level = TLS_LEV_SECURE;
} }
state->tls_bio = 0; state->tls_bio = 0;
@@ -1780,6 +1806,7 @@ static void parse_match(STATE *state, int argc, char *argv[])
state->mdalg, *argv++, ""); state->mdalg, *argv++, "");
break; break;
case TLS_LEV_DANE: case TLS_LEV_DANE:
case TLS_LEV_DANE_ONLY:
state->match = argv_alloc(2); state->match = argv_alloc(2);
argv_add(state->match, "nexthop", "hostname", ARGV_END); argv_add(state->match, "nexthop", "hostname", ARGV_END);
break; break;

View File

@@ -437,6 +437,7 @@ static void set_cipher_grade(SMTP_TLS_POLICY *tls)
break; break;
case TLS_LEV_DANE: case TLS_LEV_DANE:
case TLS_LEV_DANE_ONLY:
case TLS_LEV_FPRINT: case TLS_LEV_FPRINT:
case TLS_LEV_VERIFY: case TLS_LEV_VERIFY:
case TLS_LEV_SECURE: case TLS_LEV_SECURE:
@@ -534,7 +535,7 @@ static void *policy_create(const char *unused_key, void *context)
* "dane-only" changes to "dane" once we obtain the requisite TLSA * "dane-only" changes to "dane" once we obtain the requisite TLSA
* records. * records.
*/ */
if (tls->level == TLS_LEV_DANE || tls->level == TLS_LEV_DANE_ONLY) if (TLS_DANE_BASED(tls->level))
dane_init(tls, iter); dane_init(tls, iter);
if (tls->level == TLS_LEV_INVALID) if (tls->level == TLS_LEV_INVALID)
return ((void *) tls); return ((void *) tls);
@@ -563,6 +564,7 @@ static void *policy_create(const char *unused_key, void *context)
case TLS_LEV_MAY: case TLS_LEV_MAY:
case TLS_LEV_ENCRYPT: case TLS_LEV_ENCRYPT:
case TLS_LEV_DANE: case TLS_LEV_DANE:
case TLS_LEV_DANE_ONLY:
break; break;
case TLS_LEV_FPRINT: case TLS_LEV_FPRINT:
if (tls->dane == 0) if (tls->dane == 0)
@@ -844,7 +846,6 @@ static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
} else if (!TLS_DANE_HASEE(dane)) } else if (!TLS_DANE_HASEE(dane))
msg_panic("empty DANE match list"); msg_panic("empty DANE match list");
tls->dane = dane; tls->dane = dane;
tls->level = TLS_LEV_DANE;
return; return;
} }

View File

@@ -5132,7 +5132,13 @@ static void smtpd_proto(SMTPD_STATE *state)
static char *smtpd_format_cmd_stats(VSTRING *buf) static char *smtpd_format_cmd_stats(VSTRING *buf)
{ {
SMTPD_CMD *cmdp; SMTPD_CMD *cmdp;
int all_success = 0;
int all_total = 0;
/*
* Log the statistics. Note that this loop produces no output when no
* command was received. We address that after the loop.
*/
VSTRING_RESET(buf); VSTRING_RESET(buf);
for (cmdp = smtpd_cmd_table; /* see below */ ; cmdp++) { for (cmdp = smtpd_cmd_table; /* see below */ ; cmdp++) {
if (cmdp->total_count > 0) { if (cmdp->total_count > 0) {
@@ -5141,10 +5147,22 @@ static char *smtpd_format_cmd_stats(VSTRING *buf)
cmdp->success_count); cmdp->success_count);
if (cmdp->success_count != cmdp->total_count) if (cmdp->success_count != cmdp->total_count)
vstring_sprintf_append(buf, "/%d", cmdp->total_count); vstring_sprintf_append(buf, "/%d", cmdp->total_count);
all_success += cmdp->success_count;
all_total += cmdp->total_count;
} }
if (cmdp->name == 0) if (cmdp->name == 0)
break; break;
} }
/*
* Log total numbers, so that logfile analyzers will see something even
* if the above loop produced no output. When no commands were received
* log "0/0" to simplify the identification of abnormal sessions: any
* statistics with [0-9]/ indicate that there was a problem.
*/
vstring_sprintf_append(buf, " commands=%d", all_success);
if (all_success != all_total || all_total == 0)
vstring_sprintf_append(buf, "/%d", all_total);
return (lowercase(STR(buf))); return (lowercase(STR(buf)));
} }

View File

@@ -53,6 +53,8 @@
#define TLS_MUST_MATCH(l) ((l) > TLS_LEV_ENCRYPT) #define TLS_MUST_MATCH(l) ((l) > TLS_LEV_ENCRYPT)
#define TLS_MUST_TRUST(l) ((l) >= TLS_LEV_DANE) #define TLS_MUST_TRUST(l) ((l) >= TLS_LEV_DANE)
#define TLS_MUST_PKIX(l) ((l) >= TLS_LEV_VERIFY) #define TLS_MUST_PKIX(l) ((l) >= TLS_LEV_VERIFY)
#define TLS_OPPORTUNISTIC(l) ((l) == TLS_LEV_MAY || (l) == TLS_LEV_DANE)
#define TLS_DANE_BASED(l) ((l) == TLS_LEV_DANE || (l) == TLS_LEV_DANE_ONLY)
extern const NAME_CODE tls_level_table[]; extern const NAME_CODE tls_level_table[];

View File

@@ -827,10 +827,10 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
/* /*
* When certificate verification is required, log trust chain validation * When certificate verification is required, log trust chain validation
* errors even when disabled by default for opportunistic sessions. For * errors even when disabled by default for opportunistic sessions. For
* "dane" this only applies when using trust-anchor associations. * DANE this only applies when using trust-anchor associations.
*/ */
if (TLS_MUST_TRUST(props->tls_level) if (TLS_MUST_TRUST(props->tls_level)
&& (props->tls_level != TLS_LEV_DANE || TLS_DANE_HASTA(props->dane))) && (!TLS_DANE_BASED(props->tls_level) || TLS_DANE_HASTA(props->dane)))
log_mask |= TLS_LOG_UNTRUSTED; log_mask |= TLS_LOG_UNTRUSTED;
if (log_mask & TLS_LOG_VERBOSE) if (log_mask & TLS_LOG_VERBOSE)
@@ -849,8 +849,8 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
props->namaddr, props->protocols); props->namaddr, props->protocols);
return (0); return (0);
} }
/* The DANE level requires SSLv3 or later, not SSLv2. */ /* DANE requires SSLv3 or later, not SSLv2. */
if (props->tls_level == TLS_LEV_DANE) if (TLS_DANE_BASED(props->tls_level))
protomask |= TLS_PROTOCOL_SSLv2; protomask |= TLS_PROTOCOL_SSLv2;
/* /*
@@ -945,7 +945,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
} }
} }
#ifdef TLSEXT_MAXLEN_host_name #ifdef TLSEXT_MAXLEN_host_name
if (props->tls_level == TLS_LEV_DANE if (TLS_DANE_BASED(props->tls_level)
&& strlen(props->host) <= TLSEXT_MAXLEN_host_name) { && strlen(props->host) <= TLSEXT_MAXLEN_host_name) {
/* /*

View File

@@ -227,7 +227,7 @@ char *tls_serverid_digest(const TLS_CLIENT_START_PROPS *props, long protomask,
#if 0 #if 0
digest_dane(props->dane, ee); /* See above */ digest_dane(props->dane, ee); /* See above */
#endif #endif
digest_string(props->tls_level == TLS_LEV_DANE ? props->host : ""); digest_string(TLS_DANE_BASED(props->tls_level) ? props->host : "");
} }
checkok(EVP_DigestFinal_ex(mdctx, md_buf, &md_len)); checkok(EVP_DigestFinal_ex(mdctx, md_buf, &md_len));
EVP_MD_CTX_destroy(mdctx); EVP_MD_CTX_destroy(mdctx);