mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-29 13:18:12 +00:00
postfix-2.3.8-RC1
This commit is contained in:
parent
33178d66c7
commit
145cfd2e62
@ -12928,16 +12928,36 @@ Apologies for any names omitted.
|
||||
|
||||
Workaround: don't insert empty-line header/body separator
|
||||
into malformed MIME attachments, to avoid breaking digital
|
||||
signatures. This change introduces ambiguity. Postfix still
|
||||
treats the remainder of the attachment as body content;
|
||||
header_checks rules will not detect forbidden MIME types
|
||||
inside a message/rfc822 attachment. With the empty-line
|
||||
header/body separator no longer inserted by Postfix, other
|
||||
software may process the malformed attachment differently,
|
||||
and thus may become exposed to forbidden MIME types. This
|
||||
is back-ported from Postfix 2.4. File: global/mime_state.c.
|
||||
signatures. This change introduces ambiguity. As before,
|
||||
Postfix treats the remainder of the attachment as body
|
||||
content, and header_checks rules will not detect forbidden
|
||||
MIME types inside a malformed message/rfc822 attachment.
|
||||
With the empty-line header/body separator no longer inserted
|
||||
by Postfix, other software may process the malformed
|
||||
attachment differently, and thus may now become exposed to
|
||||
forbidden MIME types. This is back-ported from Postfix
|
||||
2.4. File: global/mime_state.c.
|
||||
|
||||
20070118
|
||||
|
||||
Bugfix: match lists didn't implement ![ipv6address]. Problem
|
||||
reported by Paulo Pacheco. File: util/match_list.c.
|
||||
|
||||
20070224
|
||||
|
||||
Workaround: GNU POP3D creates a new mailbox and deletes the
|
||||
old one. Postfix now backs off and retries delivery later,
|
||||
instead of appending mail to a deleted file. File:
|
||||
global/mbox_open.c.
|
||||
|
||||
20070225
|
||||
|
||||
Workaround: Disable SSL/TLS ciphers when the underlying
|
||||
symmetric algorithm is not available in the OpenSSL crypto
|
||||
library at the required bit strength. Problem observed with
|
||||
SunOS 5.10's bundled OpenSSL 0.9.7 and AES 256. Also possible
|
||||
with OpenSSL 0.9.8 and CAMELLIA 256. Root cause fixed in
|
||||
upcoming OpenSSL 0.9.7m, 0.9.8e and 0.9.9 releases. Victor
|
||||
Duchovni, Morgan Stanley. Files: src/smtp/smtp_proto.c,
|
||||
src/smtpd/smtpd.c, src/tls/tls.h, src/tls/tls_client.c,
|
||||
src/tls/tls_misc.c and src/tls/tls_server.c.
|
||||
|
@ -17,13 +17,15 @@ Incompatible changes with Postfix 2.3.7
|
||||
Postfix no longer inserts an empty-line header/body separator into
|
||||
malformed MIME attachments, to avoid breaking digital signatures.
|
||||
|
||||
This change introduces ambiguity. Postfix still treats the remainder
|
||||
of the attachment as body content; header_checks rules will therefore
|
||||
not detect forbidden MIME types inside a message/rfc822 attachment.
|
||||
This change introduces ambiguity. As before, Postfix treats the
|
||||
remainder of the attachment as body content, and header_checks rules
|
||||
will not detect forbidden MIME types inside a malformed message/rfc822
|
||||
attachment.
|
||||
|
||||
With the empty-line header/body separator no longer inserted by
|
||||
Postfix, other software may process the malformed attachment
|
||||
differently, and thus may become exposed to forbidden MIME types.
|
||||
differently, and thus may now become exposed to forbidden MIME types
|
||||
that they would not have been exposed to earlier.
|
||||
|
||||
Incompatible changes with Postfix 2.3.6
|
||||
---------------------------------------
|
||||
|
@ -20,8 +20,8 @@
|
||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||
* patchlevel; they change the release date only.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20070130"
|
||||
#define MAIL_VERSION_NUMBER "2.3.7"
|
||||
#define MAIL_RELEASE_DATE "20070225"
|
||||
#define MAIL_VERSION_NUMBER "2.3.8-RC1"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
|
||||
|
@ -184,6 +184,26 @@ MBOX *mbox_open(const char *path, int flags, mode_t mode, struct stat * st,
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check: reportedly, GNU POP3D creates a new mailbox file and
|
||||
* deletes the old one. This does not play well with software that opens
|
||||
* the mailbox first and then locks it.
|
||||
*
|
||||
* To detect that GNU POP3D deletes the mailbox file we look at the target
|
||||
* file hard-link count. Note that safe_open() guarantees a hard-link
|
||||
* count of 1, so any change in this count is a sign of trouble.
|
||||
*/
|
||||
if (S_ISREG(st->st_mode)
|
||||
&& (fstat(vstream_fileno(fp), st) < 0 || st->st_nlink != 1)) {
|
||||
vstring_sprintf(why->reason, "target file status changed unexpectedly");
|
||||
dsb_status(why, mbox_dsn(EAGAIN, def_dsn));
|
||||
msg_warn("%s: file status changed unexpectedly", path);
|
||||
if (locked & MBOX_DOT_LOCK)
|
||||
dot_unlockfile(path);
|
||||
vstream_fclose(fp);
|
||||
return (0);
|
||||
}
|
||||
mp = (MBOX *) mymalloc(sizeof(*mp));
|
||||
mp->path = mystrdup(path);
|
||||
mp->fp = fp;
|
||||
|
@ -725,7 +725,7 @@ static int smtp_start_tls(SMTP_STATE *state)
|
||||
vstring_sprintf_append(serverid, "&p=%s",
|
||||
tls_protocol_names(VAR_SMTP_TLS_MAND_PROTO,
|
||||
session->tls_protocols));
|
||||
if (session->tls_level >= TLS_LEV_ENCRYPT && session->tls_cipherlist)
|
||||
if (session->tls_level >= TLS_LEV_ENCRYPT)
|
||||
vstring_sprintf_append(serverid, "&c=%s", session->tls_cipherlist);
|
||||
|
||||
tls_props.ctx = smtp_tls_ctx;
|
||||
|
@ -4293,6 +4293,8 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
|
||||
enforce_tls ? var_smtpd_tls_mand_excl :
|
||||
TLS_END_EXCLUDE,
|
||||
TLS_END_EXCLUDE);
|
||||
if (props.cipherlist == 0)
|
||||
msg_panic("NULL export cipherlist");
|
||||
}
|
||||
if (havecert || oknocert)
|
||||
smtpd_tls_ctx = tls_server_init(&props);
|
||||
|
@ -151,6 +151,7 @@ tls_mgr.o: ../../include/vstream.h
|
||||
tls_mgr.o: ../../include/vstring.h
|
||||
tls_mgr.o: tls_mgr.c
|
||||
tls_mgr.o: tls_mgr.h
|
||||
tls_misc.o: ../../include/argv.h
|
||||
tls_misc.o: ../../include/msg.h
|
||||
tls_misc.o: ../../include/mymalloc.h
|
||||
tls_misc.o: ../../include/name_code.h
|
||||
|
@ -130,6 +130,7 @@ extern NAME_CODE tls_cipher_level_table[];
|
||||
|
||||
#define TLS_END_EXCLUDE ((char *)0)
|
||||
extern const char *tls_cipher_list(int,...);
|
||||
extern const char *tls_set_cipher_list(SSL_CTX *, const char *);
|
||||
|
||||
/*
|
||||
* tls_client.c
|
||||
|
@ -626,6 +626,15 @@ TLScontext_t *tls_client_start(const tls_client_start_props *props)
|
||||
if (props->log_level >= 1)
|
||||
msg_info("setting up TLS connection to %s", props->host);
|
||||
|
||||
/*
|
||||
* Before we create an SSL, update the SSL_CTX cipherlist if necessary.
|
||||
*/
|
||||
if (tls_set_cipher_list(props->ctx, props->cipherlist) == 0) {
|
||||
msg_warn("Invalid cipherlist \"%s\": aborting TLS session",
|
||||
props->cipherlist);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new TLScontext for the new connection and get an SSL
|
||||
* structure. Add the location of TLScontext to the SSL to later retrieve
|
||||
@ -710,24 +719,13 @@ TLScontext_t *tls_client_start(const tls_client_start_props *props)
|
||||
}
|
||||
|
||||
/*
|
||||
* Per session cipher selection for sessions with mandatory encryption
|
||||
* Try to load an existing session from the TLS session cache.
|
||||
*
|
||||
* By the time a TLS client is negotiating ciphers it has already offered to
|
||||
* re-use a session, it is too late to renege on the offer. So we must
|
||||
* not attempt to re-use sessions whose ciphers are too weak. We expect
|
||||
* the caller to salt the session lookup key with the cipher list, so
|
||||
* that sessions found in the cache are always acceptable.
|
||||
*/
|
||||
if (props->cipherlist != 0)
|
||||
if (SSL_set_cipher_list(TLScontext->con, props->cipherlist) == 0) {
|
||||
msg_warn("Could not set cipherlist: %s", props->cipherlist);
|
||||
tls_print_errors();
|
||||
tls_free_context(TLScontext);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to load an existing session from the TLS session cache.
|
||||
*
|
||||
* XXX To avoid memory leaks we must always call SSL_SESSION_free() after
|
||||
* calling SSL_set_session(), regardless of whether or not the session
|
||||
|
@ -18,6 +18,10 @@
|
||||
/*
|
||||
/* long tls_bug_bits()
|
||||
/*
|
||||
/* const char *tls_set_cipher_list(ssl_ctx, cipher_list)
|
||||
/* SSL_CTX *ssl_ctx;
|
||||
/* char *cipher_list;
|
||||
/*
|
||||
/* const char *tls_cipher_list(cipher_level, ...)
|
||||
/* int cipher_level;
|
||||
/*
|
||||
@ -53,6 +57,11 @@
|
||||
/* for the run-time library. Some of the bug work-arounds are
|
||||
/* not appropriate for some library versions.
|
||||
/*
|
||||
/* tls_set_cipher_list() updates the cipher list of the specified SSL
|
||||
/* context. Returns the new cipherlist on success, otherwise logs a
|
||||
/* suitable warning and returns 0. The storage for the return value
|
||||
/* is overwritted with each call.
|
||||
/*
|
||||
/* tls_cipher_list() generates a cipher list from the specified
|
||||
/* grade, minus any ciphers specified via a null-terminated
|
||||
/* list of string-valued exclusions. The result is overwritten
|
||||
@ -104,6 +113,7 @@
|
||||
#include <mymalloc.h>
|
||||
#include <vstring.h>
|
||||
#include <stringops.h>
|
||||
#include <argv.h>
|
||||
|
||||
/* TLS library. */
|
||||
|
||||
@ -162,6 +172,134 @@ typedef struct {
|
||||
int status;
|
||||
} TLS_VINFO;
|
||||
|
||||
/*
|
||||
* OpenSSL adopted the cipher selection patch, so we don't expect any more
|
||||
* broken ciphers other than AES and CAMELLIA.
|
||||
*/
|
||||
typedef struct {
|
||||
char *ssl_name;
|
||||
int alg_bits;
|
||||
char *evp_name;
|
||||
} cipher_probe_t;
|
||||
|
||||
static cipher_probe_t cipher_probes[] = {
|
||||
"AES", 256, "AES-256-CBC",
|
||||
"CAMELLIA", 256, "CAMELLIA-256-CBC",
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
/* tls_exclude_missing - Append exclusions for missing ciphers */
|
||||
|
||||
static void tls_exclude_missing(SSL_CTX *ctx, VSTRING *buf)
|
||||
{
|
||||
const char *myname = "tls_exclude_missing";
|
||||
static ARGV *exclude; /* Cached */
|
||||
SSL *s = 0;
|
||||
|
||||
STACK_OF(SSL_CIPHER) * ciphers;
|
||||
SSL_CIPHER *c;
|
||||
cipher_probe_t *probe;
|
||||
int alg_bits;
|
||||
int num;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Process a list of probes which specify:
|
||||
*
|
||||
* An SSL cipher-suite name for a family of ciphers that use the same
|
||||
* symmetric algorithm at two or more key sizes, typically 128/256 bits.
|
||||
*
|
||||
* The key size (typically 256) that OpenSSL fails check, and assumes is
|
||||
* available when another key size (typically 128) is usable.
|
||||
*
|
||||
* The OpenSSL name of the symmetric algorithm associated with the SSL
|
||||
* cipher-suite. Typically, this is MUMBLE-256-CBC, where "MUMBLE" is the
|
||||
* name of the SSL cipher-suite that use the MUMBLE symmetric algorithm.
|
||||
* On systems that support the required encryption algorithm, the name is
|
||||
* listed in the output of "openssl list-cipher-algorithms".
|
||||
*
|
||||
* When an encryption algorithm is not available at the given key size but
|
||||
* the corresponding OpenSSL cipher-suite contains ciphers that have have
|
||||
* this key size, the problem ciphers are explicitly disabled in Postfix.
|
||||
* The list is cached in the static "exclude" array.
|
||||
*/
|
||||
if (exclude == 0) {
|
||||
exclude = argv_alloc(1);
|
||||
|
||||
/*
|
||||
* Iterate over the probe list
|
||||
*/
|
||||
for (probe = cipher_probes; probe->ssl_name; ++probe) {
|
||||
/* No exclusions if evp_name is a valid algorithm */
|
||||
if (EVP_get_cipherbyname(probe->evp_name))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Sadly there is no SSL_CTX_get_ciphers() interface, so we are
|
||||
* forced to allocate and free an SSL object. Fatal error if we
|
||||
* can't allocate the SSL object.
|
||||
*/
|
||||
ERR_clear_error();
|
||||
if (s == 0 && (s = SSL_new(ctx)) == 0) {
|
||||
tls_print_errors();
|
||||
msg_fatal("%s: error allocating SSL object", myname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Cipher is not supported by libcrypto, nothing to do if also
|
||||
* not supported by libssl. Flush the OpenSSL error stack.
|
||||
*
|
||||
* XXX: There may be additional places in pre-existing code where
|
||||
* SSL errors are generated and ignored, that require a similar
|
||||
* "flush". Better yet, is to always flush before calls that run
|
||||
* tls_print_errors() on failure.
|
||||
*
|
||||
* Contrary to documentation, on SunOS 5.10 SSL_set_cipher_list()
|
||||
* returns success with no ciphers selected, when this happens
|
||||
* SSL_get_ciphers() produces a stack with 0 elements!
|
||||
*/
|
||||
if (SSL_set_cipher_list(s, probe->ssl_name) == 0
|
||||
|| (ciphers = SSL_get_ciphers(s)) == 0
|
||||
|| (num = sk_SSL_CIPHER_num(ciphers)) == 0) {
|
||||
ERR_clear_error(); /* flush any generated errors */
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < num; ++i) {
|
||||
c = sk_SSL_CIPHER_value(ciphers, i);
|
||||
(void) SSL_CIPHER_get_bits(c, &alg_bits);
|
||||
if (alg_bits == probe->alg_bits)
|
||||
argv_add(exclude, SSL_CIPHER_get_name(c), ARGV_END);
|
||||
}
|
||||
}
|
||||
if (s != 0)
|
||||
SSL_free(s);
|
||||
}
|
||||
for (i = 0; i < exclude->argc; ++i)
|
||||
vstring_sprintf_append(buf, ":!%s", exclude->argv[i]);
|
||||
}
|
||||
|
||||
/* tls_set_cipher_list - Set SSL_CTX cipher list */
|
||||
|
||||
const char *tls_set_cipher_list(SSL_CTX *ssl_ctx, const char *spec)
|
||||
{
|
||||
static VSTRING *buf;
|
||||
const char *ex_spec;
|
||||
|
||||
if (buf == 0)
|
||||
buf = vstring_alloc(10);
|
||||
|
||||
vstring_strcpy(buf, spec);
|
||||
tls_exclude_missing(ssl_ctx, buf);
|
||||
ex_spec = vstring_str(buf);
|
||||
|
||||
ERR_clear_error();
|
||||
if (SSL_CTX_set_cipher_list(ssl_ctx, ex_spec) != 0)
|
||||
return (ex_spec);
|
||||
|
||||
tls_print_errors();
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* tls_cipher_list - Cipherlist for given grade, less exclusions */
|
||||
|
||||
const char *tls_cipher_list(int cipher_level,...)
|
||||
@ -196,9 +334,16 @@ const char *tls_cipher_list(int cipher_level,...)
|
||||
case TLS_CIPHER_NONE:
|
||||
return 0;
|
||||
default:
|
||||
|
||||
/*
|
||||
* The caller MUST provide a valid cipher grade
|
||||
*/
|
||||
msg_panic("%s: invalid cipher grade: %d", myname, cipher_level);
|
||||
}
|
||||
|
||||
/*
|
||||
* The base lists for each grade can't be empty.
|
||||
*/
|
||||
if (VSTRING_LEN(buf) == 0)
|
||||
msg_panic("%s: empty cipherlist", myname);
|
||||
|
||||
@ -207,22 +352,16 @@ const char *tls_cipher_list(int cipher_level,...)
|
||||
if (*exclude == '\0')
|
||||
continue;
|
||||
save = cp = mystrdup(exclude);
|
||||
while ((tok = mystrtok(&cp, "\t\n\r ,")) != 0) {
|
||||
while ((tok = mystrtok(&cp, "\t\n\r ,:")) != 0) {
|
||||
|
||||
/*
|
||||
* Can't exclude ciphers that start with modifiers, or
|
||||
* multi-element (":" separated) ciphers.
|
||||
* Can't exclude ciphers that start with modifiers.
|
||||
*/
|
||||
if (strchr("!+-@", *tok)) {
|
||||
msg_warn("%s: can't exclude '!+-@' modifiers, '%s' ignored",
|
||||
myname, tok);
|
||||
continue;
|
||||
}
|
||||
if (strchr(tok, ':')) {
|
||||
msg_warn("%s: can't exclude compound ciphers, '%s' ignored",
|
||||
myname, tok);
|
||||
continue;
|
||||
}
|
||||
vstring_sprintf_append(buf, ":!%s", tok);
|
||||
}
|
||||
myfree(save);
|
||||
|
@ -328,12 +328,12 @@ SSL_CTX *tls_server_init(const tls_server_props *props)
|
||||
/*
|
||||
* Override the default cipher list with our own list.
|
||||
*/
|
||||
if (*props->cipherlist != 0)
|
||||
if (SSL_CTX_set_cipher_list(server_ctx, props->cipherlist) == 0) {
|
||||
tls_print_errors();
|
||||
SSL_CTX_free(server_ctx); /* 200411 */
|
||||
return (0);
|
||||
}
|
||||
if (tls_set_cipher_list(server_ctx, props->cipherlist) == 0) {
|
||||
SSL_CTX_free(server_ctx);
|
||||
msg_warn("Invalid cipherlist \"%s\": disabling TLS support",
|
||||
props->cipherlist);
|
||||
return (0); /* Already logged */
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the CA public key certificates for both the server cert and for
|
||||
|
Loading…
x
Reference in New Issue
Block a user