Workaround for broken DANE support after an incompatible
change in GLIBC 2.31. This avoids the need for new options
in /etc/resolv.conf. Files: dns/dns.h, dns/dns_lookup.c.
+
+20200419
+
+ Bugfix: segfault in the tlsproxy client role when the server
+ role was disabled. This typically happens on systems that
+ do not receive mail, after configuring connection reuse for
+ outbound TLS. Found during program maintenance. File:
+ tlsproxy/tlsproxy.c.
+
+20200420
+
+ Noise suppression: shut up a compiler that special-cases
+ string literals. Viktor Dukhovni. File milter/milter.c.
+
+20200422
+
+ Security: disable DANE support on Alpine Linux because
+ libc-musl provides no indication whether DNS responses are
+ authentic. This broke DANE support without a clear explanation.
+ File: makedefs.
+
+20200505
+
+ Noise suppression: shut up a compiler that special-cases
+ string literals. Viktor Dukhovni. File smtpd/smtpd_check.c.
+
+20200509
+
+ Bugfix (introduced: Postfix 3.5): maillog_file_rotate_suffix
+ default value used the minute instead of the month. Reported
+ by Larry Stone. Files: conf/postfix-tls-script,
+ proto/MAILLOG_README.html, proto/postconf.proto.
+ global/mail_params.h, postfix/postfix.c.
+
+20200510
+
+ Bitrot: avoid U_FILE_ACCESS_ERROR after chroot(), by
+ initializing the ICU library before making the chroot()
+ call. Files: util/midna_domain.[hc], global/mail_params.c.
+
+20200511
+
+ Noise suppression: avoid "SSL_Shutdown:shutdown while in
+ init" warnings. File: tls/tls_session.c.
+
+20200515
+
+ Bugfix (introduced: Postfix 2.2): a TLS error for a PostgreSQL
+ client caused a false 'lost connection' error for an SMTP
+ over TLS session in the same Postfix process. Reported by
+ Alexander Vasarab, diagnosed by Viktor Dukhovni. File:
+ tls/tls_bio_ops.c.
+
+ Bugfix (introduced: Postfix 2.8): a TLS error for one TLS
+ session may cause a false 'lost connection' error for a
+ concurrent TLS session in the same tlsproxy process. File:
+ tlsproxy/tlsproxy.c.
* Rename the current logfile by appending a suffix that contains the date and
time. This suffix is configured with the maillog_file_rotate_suffix
- parameter (default: %Y%M%d-%H%M%S).
+ parameter (default: %Y%m%d-%H%M%S).
* Reload Postfix so that postlogd(8) immediately closes the old logfile.
If you upgrade from Postfix 3.2 or earlier, read RELEASE_NOTES-3.3
before proceeding.
+libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12, and 3.5.2
+------------------------------------------------------------------
+
+Security: this release disables DANE support on Linux systems with
+libc-musl, because libc-musl provides no indication whether DNS
+responses are authentic. This broke DANE support without a clear
+explanation.
+
TLS Workaround for Postfix 3.4.6, 3.3.5, 3.2.10 and 3.1.13
-----------------------------------------------------------
<li> <p> Rename the current logfile by appending a suffix that
contains the date and time. This suffix is configured with the
-<a href="postconf.5.html#maillog_file_rotate_suffix">maillog_file_rotate_suffix</a> parameter (default: %Y%M%d-%H%M%S). </p>
+<a href="postconf.5.html#maillog_file_rotate_suffix">maillog_file_rotate_suffix</a> parameter (default: %Y%m%d-%H%M%S). </p>
<li> <p> Reload Postfix so that <a href="postlogd.8.html">postlogd(8)</a> immediately closes the
old logfile. </p>
</DD>
<DT><b><a name="maillog_file_rotate_suffix">maillog_file_rotate_suffix</a>
-(default: %Y%M%d-%H%M%S)</b></DT><DD>
+(default: %Y%m%d-%H%M%S)</b></DT><DD>
<p> The format of the suffix to append to $<a href="postconf.5.html#maillog_file">maillog_file</a> while rotating
the file with "postfix logrotate". See strftime(3) for syntax. The
<b><a href="postconf.5.html#maillog_file_prefixes">maillog_file_prefixes</a> (/var, /dev/stdout)</b>
A list of allowed prefixes for a <a href="postconf.5.html#maillog_file">maillog_file</a> value.
- <b><a href="postconf.5.html#maillog_file_rotate_suffix">maillog_file_rotate_suffix</a> (%Y%M%d-%H%M%S)</b>
+ <b><a href="postconf.5.html#maillog_file_rotate_suffix">maillog_file_rotate_suffix</a> (%Y%m%d-%H%M%S)</b>
The format of the suffix to append to $<a href="postconf.5.html#maillog_file">maillog_file</a> while rotat-
ing the file with "postfix logrotate".
*) echo usage: $0 [system release] 1>&2; exit 1;;
esac
+case "$SYSTEM" in
+ Linux)
+ case "`PATH=/bin:/usr/bin ldd /bin/sh`" in
+ *-musl-*)
+ case "$CCARGS" in
+ *-DNO_DNSSEC*) ;;
+ *) echo Warning: libc-musl breaks DANE/TLSA security. 1>&2
+ echo This build will not support DANE/TLSA. 1>&2
+ CCARGS="$CCARGS -DNO_DNSSEC";;
+ esac;;
+ esac;;
+esac
+
case "$SYSTEM.$RELEASE" in
SCO_SV.3.2) SYSTYPE=SCO5
# Use the native compiler by default
logrotate".
.IP "\fBmaillog_file_prefixes (/var, /dev/stdout)\fR"
A list of allowed prefixes for a maillog_file value.
-.IP "\fBmaillog_file_rotate_suffix (%Y%M%d\-%H%M%S)\fR"
+.IP "\fBmaillog_file_rotate_suffix (%Y%m%d\-%H%M%S)\fR"
The format of the suffix to append to $maillog_file while rotating
the file with "postfix logrotate".
.IP "\fBpostlog_service_name (postlog)\fR"
whitespace.
.PP
This feature is available in Postfix 3.4 and later.
-.SH maillog_file_rotate_suffix (default: %Y%M%d\-%H%M%S)
+.SH maillog_file_rotate_suffix (default: %Y%m%d\-%H%M%S)
The format of the suffix to append to $maillog_file while rotating
the file with "postfix logrotate". See \fBstrftime\fR(3) for syntax. The
default suffix, YYYYMMDD\-HHMMSS, allows logs to be rotated frequently.
<li> <p> Rename the current logfile by appending a suffix that
contains the date and time. This suffix is configured with the
-maillog_file_rotate_suffix parameter (default: %Y%M%d-%H%M%S). </p>
+maillog_file_rotate_suffix parameter (default: %Y%m%d-%H%M%S). </p>
<li> <p> Reload Postfix so that postlogd(8) immediately closes the
old logfile. </p>
<p> This feature is available in Postfix 3.4 and later. </p>
-%PARAM maillog_file_rotate_suffix %Y%M%d-%H%M%S
+%PARAM maillog_file_rotate_suffix %Y%m%d-%H%M%S
<p> The format of the suffix to append to $maillog_file while rotating
the file with "postfix logrotate". See strftime(3) for syntax. The
var_smtputf8_enable = 0;
#else
midna_domain_transitional = var_idna2003_compat;
+ if (var_smtputf8_enable)
+ midna_domain_pre_chroot();
#endif
util_utf8_enable = var_smtputf8_enable;
extern char *var_maillog_file_comp;
#define VAR_MAILLOG_FILE_STAMP "maillog_file_rotate_suffix"
-#define DEF_MAILLOG_FILE_STAMP "%Y%M%d-%H%M%S"
+#define DEF_MAILLOG_FILE_STAMP "%Y%m%d-%H%M%S"
extern char *var_maillog_file_stamp;
#define VAR_POSTLOG_SERVICE "postlog_service_name"
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20200418"
-#define MAIL_VERSION_NUMBER "3.4.11"
+#define MAIL_RELEASE_DATE "20200516"
+#define MAIL_VERSION_NUMBER "3.4.12"
#ifdef SNAPSHOT
#define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
* names by skipping the redundant "milter_" prefix.
*/
static ATTR_OVER_TIME time_table[] = {
- 7 + VAR_MILT_CONN_TIME, DEF_MILT_CONN_TIME, 0, 1, 0,
- 7 + VAR_MILT_CMD_TIME, DEF_MILT_CMD_TIME, 0, 1, 0,
- 7 + VAR_MILT_MSG_TIME, DEF_MILT_MSG_TIME, 0, 1, 0,
+ 7 + (const char *) VAR_MILT_CONN_TIME, DEF_MILT_CONN_TIME, 0, 1, 0,
+ 7 + (const char *) VAR_MILT_CMD_TIME, DEF_MILT_CMD_TIME, 0, 1, 0,
+ 7 + (const char *) VAR_MILT_MSG_TIME, DEF_MILT_MSG_TIME, 0, 1, 0,
0,
};
static ATTR_OVER_STR str_table[] = {
- 7 + VAR_MILT_PROTOCOL, 0, 1, 0,
- 7 + VAR_MILT_DEF_ACTION, 0, 1, 0,
+ 7 + (const char *) VAR_MILT_PROTOCOL, 0, 1, 0,
+ 7 + (const char *) VAR_MILT_DEF_ACTION, 0, 1, 0,
0,
};
/* logrotate".
/* .IP "\fBmaillog_file_prefixes (/var, /dev/stdout)\fR"
/* A list of allowed prefixes for a maillog_file value.
-/* .IP "\fBmaillog_file_rotate_suffix (%Y%M%d-%H%M%S)\fR"
+/* .IP "\fBmaillog_file_rotate_suffix (%Y%m%d-%H%M%S)\fR"
/* The format of the suffix to append to $maillog_file while rotating
/* the file with "postfix logrotate".
/* .IP "\fBpostlog_service_name (postlog)\fR"
* parameter names by skipping the redundant "smtpd_policy_service_" prefix.
*/
static ATTR_OVER_TIME time_table[] = {
- 21 + VAR_SMTPD_POLICY_TMOUT, DEF_SMTPD_POLICY_TMOUT, 0, 1, 0,
- 21 + VAR_SMTPD_POLICY_IDLE, DEF_SMTPD_POLICY_IDLE, 0, 1, 0,
- 21 + VAR_SMTPD_POLICY_TTL, DEF_SMTPD_POLICY_TTL, 0, 1, 0,
- 21 + VAR_SMTPD_POLICY_TRY_DELAY, DEF_SMTPD_POLICY_TRY_DELAY, 0, 1, 0,
+ 21 + (const char *) VAR_SMTPD_POLICY_TMOUT, DEF_SMTPD_POLICY_TMOUT, 0, 1, 0,
+ 21 + (const char *) VAR_SMTPD_POLICY_IDLE, DEF_SMTPD_POLICY_IDLE, 0, 1, 0,
+ 21 + (const char *) VAR_SMTPD_POLICY_TTL, DEF_SMTPD_POLICY_TTL, 0, 1, 0,
+ 21 + (const char *) VAR_SMTPD_POLICY_TRY_DELAY, DEF_SMTPD_POLICY_TRY_DELAY, 0, 1, 0,
0,
};
static ATTR_OVER_INT int_table[] = {
- 21 + VAR_SMTPD_POLICY_REQ_LIMIT, 0, 0, 0,
- 21 + VAR_SMTPD_POLICY_TRY_LIMIT, 0, 1, 0,
+ 21 + (const char *) VAR_SMTPD_POLICY_REQ_LIMIT, 0, 0, 0,
+ 21 + (const char *) VAR_SMTPD_POLICY_TRY_LIMIT, 0, 1, 0,
0,
};
static ATTR_OVER_STR str_table[] = {
- 21 + VAR_SMTPD_POLICY_DEF_ACTION, 0, 1, 0,
- 21 + VAR_SMTPD_POLICY_CONTEXT, 0, 1, 0,
+ 21 + (const char *) VAR_SMTPD_POLICY_DEF_ACTION, 0, 1, 0,
+ 21 + (const char *) VAR_SMTPD_POLICY_CONTEXT, 0, 1, 0,
0,
};
* handling any pending network I/O.
*/
for (;;) {
+
+ /*
+ * Flush the per-thread SSL error queue. Otherwise, errors from other
+ * code that also uses TLS may confuse SSL_get_error(3).
+ */
+ ERR_clear_error();
+
if (hsfunc)
status = hsfunc(TLScontext->con);
else if (rfunc)
* so we will not perform SSL_shutdown() and the session will be removed
* as being bad.
*/
- if (!failure) {
+ if (!failure && !SSL_in_init(TLScontext->con)) {
retval = tls_bio_shutdown(vstream_fileno(stream), timeout, TLScontext);
if (!var_tls_fast_shutdown && retval == 0)
tls_bio_shutdown(vstream_fileno(stream), timeout, TLScontext);
*/
if (state->flags & TLSP_FLAG_DO_HANDSHAKE) {
state->timeout = state->handshake_timeout;
+ ERR_clear_error();
if (state->is_server_role)
ssl_stat = SSL_accept(tls_context->con);
else
if (NBBIO_ERROR_FLAGS(plaintext_buf)) {
if (NBBIO_ACTIVE_FLAGS(plaintext_buf))
nbbio_disable_readwrite(state->plaintext_buf);
+ ERR_clear_error();
if (!SSL_in_init(tls_context->con)
&& (ssl_stat = SSL_shutdown(tls_context->con)) < 0) {
handshake_err = SSL_get_error(tls_context->con, ssl_stat);
*/
ssl_write_err = SSL_ERROR_NONE;
while (NBBIO_READ_PEND(plaintext_buf) > 0) {
+ ERR_clear_error();
ssl_stat = SSL_write(tls_context->con, NBBIO_READ_BUF(plaintext_buf),
NBBIO_READ_PEND(plaintext_buf));
ssl_write_err = SSL_get_error(tls_context->con, ssl_stat);
*/
ssl_read_err = SSL_ERROR_NONE;
while (NBBIO_WRITE_PEND(state->plaintext_buf) < NBBIO_BUFSIZE(plaintext_buf)) {
+ ERR_clear_error();
ssl_stat = SSL_read(tls_context->con,
NBBIO_WRITE_BUF(plaintext_buf)
+ NBBIO_WRITE_PEND(state->plaintext_buf),
TLSP_INIT_TIMEOUT, (void *) state);
}
-/* pre_jail_init - pre-jail initialization */
+/* pre_jail_init_server - pre-jail initialization */
-static void pre_jail_init(char *unused_name, char **unused_argv)
+static void pre_jail_init_server(void)
{
TLS_SERVER_INIT_PROPS props;
const char *cert_file;
int have_server_cert;
int no_server_cert_ok;
int require_server_cert;
- int clnt_use_tls;
/*
* The code in this routine is pasted literally from smtpd(8). I am not
}
var_tlsp_use_tls = var_tlsp_use_tls || var_tlsp_enforce_tls;
if (!var_tlsp_use_tls) {
- msg_warn("TLS service is requested, but disabled with %s or %s",
+ msg_warn("TLS server role is disabled with %s or %s",
VAR_TLSP_TLS_LEVEL, VAR_TLSP_USE_TLS);
return;
}
SSL_CTX_set_mode(tlsp_server_ctx->ssl_ctx,
SSL_MODE_ENABLE_PARTIAL_WRITE
| SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+}
+
+/* pre_jail_init_client - pre-jail initialization */
+
+static void pre_jail_init_client(void)
+{
+ int clnt_use_tls;
/*
* The cache with TLS_APPL_STATE instances for different TLS_CLIENT_INIT
msg_warn("TLS client initialization failed");
}
}
+}
+
+/* pre_jail_init - pre-jail initialization */
+
+static void pre_jail_init(char *unused_name, char **unused_argv)
+{
+
+ /*
+ * Initialize roles separately.
+ */
+ pre_jail_init_server();
+ pre_jail_init_client();
/*
* tlsp_client_init() needs to know if it is called pre-jail or
/*
/* const char *midna_domain_suffix_to_utf8(
/* const char *name)
+/* AUXILIARY FUNCTIONS
+/* void midna_domain_pre_chroot(void)
/* DESCRIPTION
/* The functions in this module transform domain names from/to
/* ASCII and UTF-8 form. The result is cached to avoid repeated
/*
/* midna_domain_transitional enables transitional conversion
/* between UTF8 and ASCII labels.
+/*
+/* midna_domain_pre_chroot() does some pre-chroot initialization.
/* SEE ALSO
/* http://unicode.org/reports/tr46/ Unicode IDNA Compatibility processing
/* msg(3) diagnostics interface
}
}
+/* midna_domain_pre_chroot - pre-chroot initialization */
+
+void midna_domain_pre_chroot(void)
+{
+ UErrorCode error = U_ZERO_ERROR;
+ UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+ UIDNA *idna;
+
+ idna = uidna_openUTS46(midna_domain_transitional ? UIDNA_DEFAULT
+ : UIDNA_NONTRANSITIONAL_TO_ASCII, &error);
+ if (U_FAILURE(error))
+ msg_warn("ICU library initialization failed: %s",
+ midna_domain_strerror(error, info.errors));
+ uidna_close(idna);
+}
+
/* midna_domain_to_ascii_create - convert domain to ASCII */
static void *midna_domain_to_ascii_create(const char *name, void *unused_context)
/*
* Test program - reads names from stdin, reports invalid names to stderr.
*/
+#include <unistd.h>
#include <stdlib.h>
#include <locale.h>
/* msg_verbose = 1; */
util_utf8_enable = 1;
+ if (geteuid() == 0) {
+ midna_domain_pre_chroot();
+ if (chroot(".") != 0)
+ msg_fatal("chroot(\".\"): %m");
+ }
while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
bp = STR(buffer);
msg_info("> %s", bp);
extern const char *midna_domain_to_utf8(const char *);
extern const char *midna_domain_suffix_to_ascii(const char *);
extern const char *midna_domain_suffix_to_utf8(const char *);
+extern void midna_domain_pre_chroot(void);
extern int midna_domain_cache_size;
extern int midna_domain_transitional;