mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 05:38:06 +00:00
postfix-2.4-20070221
This commit is contained in:
parent
aaed482ca0
commit
761ae533bd
@ -13255,6 +13255,18 @@ Apologies for any names omitted.
|
|||||||
multi-valued macro. Files: util/sys_defs.h, util/events.c,
|
multi-valued macro. Files: util/sys_defs.h, util/events.c,
|
||||||
master/multi_server.c, *qmgr/qmgr_transport.c.
|
master/multi_server.c, *qmgr/qmgr_transport.c.
|
||||||
|
|
||||||
|
20070220
|
||||||
|
|
||||||
|
Work-around: 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.
|
||||||
|
|
||||||
Wish list:
|
Wish list:
|
||||||
|
|
||||||
Update message content length when adding/removing headers.
|
Update message content length when adding/removing headers.
|
||||||
|
@ -11772,7 +11772,7 @@ setting. </p>
|
|||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DT><b><a name="tls_null_cipherlist">tls_null_cipherlist</a>
|
<DT><b><a name="tls_null_cipherlist">tls_null_cipherlist</a>
|
||||||
(default: !aNULL:eNULL+kRSA)</b></DT><DD>
|
(default: eNULL:!aNULL)</b></DT><DD>
|
||||||
|
|
||||||
<p> The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
<p> The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
||||||
authentication without encryption. This defines the meaning of the "null"
|
authentication without encryption. This defines the meaning of the "null"
|
||||||
|
@ -441,7 +441,7 @@ SMTP(8) SMTP(8)
|
|||||||
The OpenSSL cipherlist for "EXPORT" or higher grade
|
The OpenSSL cipherlist for "EXPORT" or higher grade
|
||||||
ciphers.
|
ciphers.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#tls_null_cipherlist">tls_null_cipherlist</a> (!aNULL:eNULL+kRSA)</b>
|
<b><a href="postconf.5.html#tls_null_cipherlist">tls_null_cipherlist</a> (eNULL:!aNULL)</b>
|
||||||
The OpenSSL cipherlist for "NULL" grade ciphers
|
The OpenSSL cipherlist for "NULL" grade ciphers
|
||||||
that provide authentication without encryption.
|
that provide authentication without encryption.
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ SMTPD(8) SMTPD(8)
|
|||||||
The OpenSSL cipherlist for "EXPORT" or higher grade
|
The OpenSSL cipherlist for "EXPORT" or higher grade
|
||||||
ciphers.
|
ciphers.
|
||||||
|
|
||||||
<b><a href="postconf.5.html#tls_null_cipherlist">tls_null_cipherlist</a> (!aNULL:eNULL+kRSA)</b>
|
<b><a href="postconf.5.html#tls_null_cipherlist">tls_null_cipherlist</a> (eNULL:!aNULL)</b>
|
||||||
The OpenSSL cipherlist for "NULL" grade ciphers
|
The OpenSSL cipherlist for "NULL" grade ciphers
|
||||||
that provide authentication without encryption.
|
that provide authentication without encryption.
|
||||||
|
|
||||||
|
@ -7148,7 +7148,7 @@ certificates). You are strongly encouraged to not change this
|
|||||||
setting.
|
setting.
|
||||||
.PP
|
.PP
|
||||||
This feature is available in Postfix 2.3 and later.
|
This feature is available in Postfix 2.3 and later.
|
||||||
.SH tls_null_cipherlist (default: !aNULL:eNULL+kRSA)
|
.SH tls_null_cipherlist (default: eNULL:!aNULL)
|
||||||
The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
||||||
authentication without encryption. This defines the meaning of the "null"
|
authentication without encryption. This defines the meaning of the "null"
|
||||||
setting in smtpd_mandatory_tls_ciphers, smtp_tls_mandatory_ciphers and
|
setting in smtpd_mandatory_tls_ciphers, smtp_tls_mandatory_ciphers and
|
||||||
|
@ -362,7 +362,7 @@ The OpenSSL cipherlist for "MEDIUM" or higher grade ciphers.
|
|||||||
The OpenSSL cipherlist for "LOW" or higher grade ciphers.
|
The OpenSSL cipherlist for "LOW" or higher grade ciphers.
|
||||||
.IP "\fBtls_export_cipherlist (ALL:+RC4:@STRENGTH)\fR"
|
.IP "\fBtls_export_cipherlist (ALL:+RC4:@STRENGTH)\fR"
|
||||||
The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
|
The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
|
||||||
.IP "\fBtls_null_cipherlist (!aNULL:eNULL+kRSA)\fR"
|
.IP "\fBtls_null_cipherlist (eNULL:!aNULL)\fR"
|
||||||
The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
||||||
authentication without encryption.
|
authentication without encryption.
|
||||||
.PP
|
.PP
|
||||||
|
@ -386,7 +386,7 @@ The OpenSSL cipherlist for "MEDIUM" or higher grade ciphers.
|
|||||||
The OpenSSL cipherlist for "LOW" or higher grade ciphers.
|
The OpenSSL cipherlist for "LOW" or higher grade ciphers.
|
||||||
.IP "\fBtls_export_cipherlist (ALL:+RC4:@STRENGTH)\fR"
|
.IP "\fBtls_export_cipherlist (ALL:+RC4:@STRENGTH)\fR"
|
||||||
The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
|
The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
|
||||||
.IP "\fBtls_null_cipherlist (!aNULL:eNULL+kRSA)\fR"
|
.IP "\fBtls_null_cipherlist (eNULL:!aNULL)\fR"
|
||||||
The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
||||||
authentication without encryption.
|
authentication without encryption.
|
||||||
.SH "OBSOLETE STARTTLS CONTROLS"
|
.SH "OBSOLETE STARTTLS CONTROLS"
|
||||||
|
@ -10399,7 +10399,7 @@ strongly encouraged to not change this setting. </p>
|
|||||||
|
|
||||||
<p> This feature is available in Postfix 2.3 and later. </p>
|
<p> This feature is available in Postfix 2.3 and later. </p>
|
||||||
|
|
||||||
%PARAM tls_null_cipherlist !aNULL:eNULL+kRSA
|
%PARAM tls_null_cipherlist eNULL:!aNULL
|
||||||
|
|
||||||
<p> The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
<p> The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
||||||
authentication without encryption. This defines the meaning of the "null"
|
authentication without encryption. This defines the meaning of the "null"
|
||||||
|
@ -2692,7 +2692,7 @@ extern char *var_tls_low_clist;
|
|||||||
extern char *var_tls_export_clist;
|
extern char *var_tls_export_clist;
|
||||||
|
|
||||||
#define VAR_TLS_NULL_CLIST "tls_null_cipherlist"
|
#define VAR_TLS_NULL_CLIST "tls_null_cipherlist"
|
||||||
#define DEF_TLS_NULL_CLIST "!aNULL:eNULL+kRSA"
|
#define DEF_TLS_NULL_CLIST "eNULL:!aNULL"
|
||||||
extern char *var_tls_null_clist;
|
extern char *var_tls_null_clist;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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 "20070218"
|
#define MAIL_RELEASE_DATE "20070221"
|
||||||
#define MAIL_VERSION_NUMBER "2.4"
|
#define MAIL_VERSION_NUMBER "2.4"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -332,7 +332,7 @@
|
|||||||
/* The OpenSSL cipherlist for "LOW" or higher grade ciphers.
|
/* The OpenSSL cipherlist for "LOW" or higher grade ciphers.
|
||||||
/* .IP "\fBtls_export_cipherlist (ALL:+RC4:@STRENGTH)\fR"
|
/* .IP "\fBtls_export_cipherlist (ALL:+RC4:@STRENGTH)\fR"
|
||||||
/* The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
|
/* The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
|
||||||
/* .IP "\fBtls_null_cipherlist (!aNULL:eNULL+kRSA)\fR"
|
/* .IP "\fBtls_null_cipherlist (eNULL:!aNULL)\fR"
|
||||||
/* The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
/* The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
||||||
/* authentication without encryption.
|
/* authentication without encryption.
|
||||||
/* .PP
|
/* .PP
|
||||||
|
@ -753,7 +753,7 @@ static int smtp_start_tls(SMTP_STATE *state)
|
|||||||
vstring_sprintf_append(serverid, "&p=%s",
|
vstring_sprintf_append(serverid, "&p=%s",
|
||||||
tls_protocol_names(VAR_SMTP_TLS_MAND_PROTO,
|
tls_protocol_names(VAR_SMTP_TLS_MAND_PROTO,
|
||||||
session->tls_protocols));
|
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);
|
vstring_sprintf_append(serverid, "&c=%s", session->tls_cipherlist);
|
||||||
|
|
||||||
tls_props.ctx = smtp_tls_ctx;
|
tls_props.ctx = smtp_tls_ctx;
|
||||||
|
@ -354,7 +354,7 @@
|
|||||||
/* The OpenSSL cipherlist for "LOW" or higher grade ciphers.
|
/* The OpenSSL cipherlist for "LOW" or higher grade ciphers.
|
||||||
/* .IP "\fBtls_export_cipherlist (ALL:+RC4:@STRENGTH)\fR"
|
/* .IP "\fBtls_export_cipherlist (ALL:+RC4:@STRENGTH)\fR"
|
||||||
/* The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
|
/* The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
|
||||||
/* .IP "\fBtls_null_cipherlist (!aNULL:eNULL+kRSA)\fR"
|
/* .IP "\fBtls_null_cipherlist (eNULL:!aNULL)\fR"
|
||||||
/* The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
/* The OpenSSL cipherlist for "NULL" grade ciphers that provide
|
||||||
/* authentication without encryption.
|
/* authentication without encryption.
|
||||||
/* OBSOLETE STARTTLS CONTROLS
|
/* OBSOLETE STARTTLS CONTROLS
|
||||||
@ -4311,6 +4311,8 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
|
|||||||
enforce_tls ? var_smtpd_tls_mand_excl :
|
enforce_tls ? var_smtpd_tls_mand_excl :
|
||||||
TLS_END_EXCLUDE,
|
TLS_END_EXCLUDE,
|
||||||
TLS_END_EXCLUDE);
|
TLS_END_EXCLUDE);
|
||||||
|
if (props.cipherlist == 0)
|
||||||
|
msg_panic("NULL export cipherlist");
|
||||||
}
|
}
|
||||||
if (havecert || oknocert)
|
if (havecert || oknocert)
|
||||||
smtpd_tls_ctx = tls_server_init(&props);
|
smtpd_tls_ctx = tls_server_init(&props);
|
||||||
|
@ -130,6 +130,7 @@ extern NAME_CODE tls_cipher_level_table[];
|
|||||||
|
|
||||||
#define TLS_END_EXCLUDE ((char *)0)
|
#define TLS_END_EXCLUDE ((char *)0)
|
||||||
extern const char *tls_cipher_list(int,...);
|
extern const char *tls_cipher_list(int,...);
|
||||||
|
extern const char *tls_set_cipher_list(SSL_CTX *, const char *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tls_client.c
|
* tls_client.c
|
||||||
|
@ -626,6 +626,15 @@ TLScontext_t *tls_client_start(const tls_client_start_props *props)
|
|||||||
if (props->log_level >= 1)
|
if (props->log_level >= 1)
|
||||||
msg_info("setting up TLS connection to %s", props->host);
|
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
|
* Allocate a new TLScontext for the new connection and get an SSL
|
||||||
* structure. Add the location of TLScontext to the SSL to later retrieve
|
* 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
|
* 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
|
* 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
|
* 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
|
* the caller to salt the session lookup key with the cipher list, so
|
||||||
* that sessions found in the cache are always acceptable.
|
* 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
|
* XXX To avoid memory leaks we must always call SSL_SESSION_free() after
|
||||||
* calling SSL_set_session(), regardless of whether or not the session
|
* calling SSL_set_session(), regardless of whether or not the session
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
/*
|
/*
|
||||||
/* long tls_bug_bits()
|
/* 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, ...)
|
/* const char *tls_cipher_list(cipher_level, ...)
|
||||||
/* int cipher_level;
|
/* int cipher_level;
|
||||||
/*
|
/*
|
||||||
@ -53,6 +57,11 @@
|
|||||||
/* for the run-time library. Some of the bug work-arounds are
|
/* for the run-time library. Some of the bug work-arounds are
|
||||||
/* not appropriate for some library versions.
|
/* 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
|
/* tls_cipher_list() generates a cipher list from the specified
|
||||||
/* grade, minus any ciphers specified via a null-terminated
|
/* grade, minus any ciphers specified via a null-terminated
|
||||||
/* list of string-valued exclusions. The result is overwritten
|
/* list of string-valued exclusions. The result is overwritten
|
||||||
@ -152,45 +161,6 @@ NAME_CODE tls_cipher_level_table[] = {
|
|||||||
0, TLS_CIPHER_NONE,
|
0, TLS_CIPHER_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *algorithm;
|
|
||||||
char *exclusion;
|
|
||||||
} cipher_probe;
|
|
||||||
|
|
||||||
static cipher_probe cipher_probe_list[] = {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for missing AES256, OpenSSL only checks for AES128, and then
|
|
||||||
* enables both, because they only have one "is AES" boolean flag in the
|
|
||||||
* cipher property mask. The implementation cannot distinguish between
|
|
||||||
* AES128 and AES256. When some O/S distributions play games with
|
|
||||||
* libcrypto and exclude just the AES256 ciphers, they break the OpenSSL
|
|
||||||
* cipherlist construction code, with clients and servers potentially
|
|
||||||
* negotiating unimplemented ciphers.
|
|
||||||
*
|
|
||||||
* This problem is peculiar to AES, which is not a single cipher, but a
|
|
||||||
* family of related ciphers. The other OpenSSL symmetric ciphers are
|
|
||||||
* atomic, either implemented or not. We expect that future ciphers will
|
|
||||||
* either also be atomic, or will have one property bit per family member
|
|
||||||
* and will be filtered accurately by OpenSSL.
|
|
||||||
*
|
|
||||||
* If all else fails, this table can be expanded :-(
|
|
||||||
*
|
|
||||||
* XXX: the probe for AES256 is enclosed in #ifdef. OpenSSL 0.9.6 and and
|
|
||||||
* earlier don't have AES 256, this requires 0.9.7 or later. We recommend
|
|
||||||
* against use of 0.9.6, it has open issues solved in 0.9.7l and 0.9.8d,
|
|
||||||
* but we are not yet prepared to drop support for 0.9.6.
|
|
||||||
*/
|
|
||||||
#ifdef SN_aes_256_cbc
|
|
||||||
SN_aes_256_cbc, SSL_TXT_AES "+HIGH",
|
|
||||||
#endif
|
|
||||||
0, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parsed OpenSSL version number.
|
* Parsed OpenSSL version number.
|
||||||
*/
|
*/
|
||||||
@ -202,17 +172,140 @@ typedef struct {
|
|||||||
int status;
|
int status;
|
||||||
} TLS_VINFO;
|
} 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 */
|
/* tls_cipher_list - Cipherlist for given grade, less exclusions */
|
||||||
|
|
||||||
const char *tls_cipher_list(int cipher_level,...)
|
const char *tls_cipher_list(int cipher_level,...)
|
||||||
{
|
{
|
||||||
const char *myname = "tls_cipher_list";
|
const char *myname = "tls_cipher_list";
|
||||||
static VSTRING *buf;
|
static VSTRING *buf;
|
||||||
#if 0
|
|
||||||
static ARGV *exclude_unavailable;
|
|
||||||
cipher_probe *probe;
|
|
||||||
int i;
|
|
||||||
#endif
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
const char *exclude;
|
const char *exclude;
|
||||||
char *tok;
|
char *tok;
|
||||||
@ -241,47 +334,34 @@ const char *tls_cipher_list(int cipher_level,...)
|
|||||||
case TLS_CIPHER_NONE:
|
case TLS_CIPHER_NONE:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The caller MUST provide a valid cipher grade
|
||||||
|
*/
|
||||||
msg_panic("%s: invalid cipher grade: %d", myname, cipher_level);
|
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)
|
if (VSTRING_LEN(buf) == 0)
|
||||||
msg_panic("%s: empty cipherlist", myname);
|
msg_panic("%s: empty cipherlist", myname);
|
||||||
|
|
||||||
/*
|
|
||||||
* Exclude ciphers that clueless distributions leave out of libcrypto.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
if (exclude_unavailable == 0) {
|
|
||||||
exclude_unavailable = argv_alloc(1);
|
|
||||||
for (probe = cipher_probe_list; probe->algorithm; ++probe)
|
|
||||||
if (!EVP_get_cipherbyname(probe->algorithm))
|
|
||||||
argv_add(exclude_unavailable, probe->exclusion, (char *) 0);
|
|
||||||
}
|
|
||||||
for (i = 0; i < exclude_unavailable->argc; ++i)
|
|
||||||
vstring_sprintf_append(buf, ":!%s", exclude_unavailable->argv[i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
va_start(ap, cipher_level);
|
va_start(ap, cipher_level);
|
||||||
while ((exclude = va_arg(ap, char *)) != 0) {
|
while ((exclude = va_arg(ap, char *)) != 0) {
|
||||||
if (*exclude == '\0')
|
if (*exclude == '\0')
|
||||||
continue;
|
continue;
|
||||||
save = cp = mystrdup(exclude);
|
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
|
* Can't exclude ciphers that start with modifiers.
|
||||||
* multi-element (":" separated) ciphers.
|
|
||||||
*/
|
*/
|
||||||
if (strchr("!+-@", *tok)) {
|
if (strchr("!+-@", *tok)) {
|
||||||
msg_warn("%s: can't exclude '!+-@' modifiers, '%s' ignored",
|
msg_warn("%s: can't exclude '!+-@' modifiers, '%s' ignored",
|
||||||
myname, tok);
|
myname, tok);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (strchr(tok, ':')) {
|
|
||||||
msg_warn("%s: can't exclude compound ciphers, '%s' ignored",
|
|
||||||
myname, tok);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
vstring_sprintf_append(buf, ":!%s", tok);
|
vstring_sprintf_append(buf, ":!%s", tok);
|
||||||
}
|
}
|
||||||
myfree(save);
|
myfree(save);
|
||||||
|
@ -329,12 +329,12 @@ SSL_CTX *tls_server_init(const tls_server_props *props)
|
|||||||
/*
|
/*
|
||||||
* Override the default cipher list with our own list.
|
* Override the default cipher list with our own list.
|
||||||
*/
|
*/
|
||||||
if (*props->cipherlist != 0)
|
if (tls_set_cipher_list(server_ctx, props->cipherlist) == 0) {
|
||||||
if (SSL_CTX_set_cipher_list(server_ctx, props->cipherlist) == 0) {
|
SSL_CTX_free(server_ctx);
|
||||||
tls_print_errors();
|
msg_warn("Invalid cipherlist \"%s\": disabling TLS support",
|
||||||
SSL_CTX_free(server_ctx); /* 200411 */
|
props->cipherlist);
|
||||||
return (0);
|
return (0); /* Already logged */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the CA public key certificates for both the server cert and for
|
* Load the CA public key certificates for both the server cert and for
|
||||||
|
Loading…
x
Reference in New Issue
Block a user