summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-txt/ChangeLog5
-rw-r--r--src/src/tls-openssl.c50
-rw-r--r--test/confs/21203
3 files changed, 42 insertions, 16 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index e40c11a1d..b155e6b9d 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -58,6 +58,11 @@ JH/12 Bug 2838: Fix for i32lp64 hard-align platforms. Found for SPARC Linux,
debug offset allocations by an int, giving a hard trap in early startup.
Change to using a size_t. Debug and fix by John Paul Adrian Glaubitz.
+JH/13 Bug 2845: Fix handling of tls_require_ciphers for OpenSSL when a value
+ with underbars is given. The write-protection of configuration introduced
+ in 4.95 trapped when normalisation was applied to an option not needing
+ expansion action.
+
Exim version 4.95
-----------------
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index e975eae4d..0d692c79e 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -1642,11 +1642,24 @@ return OK;
* One-time init credentials for server and client *
**************************************************/
+static void
+normalise_ciphers(uschar ** ciphers, const uschar * pre_expansion_ciphers)
+{
+uschar * s = *ciphers;
+
+if (!s || !Ustrchr(s, '_')) return; /* no change needed */
+
+if (s == pre_expansion_ciphers)
+ s = string_copy(s); /* get writable copy */
+
+for (uschar * t = s; *t; t++) if (*t == '_') *t = '-';
+*ciphers = s;
+}
+
static int
server_load_ciphers(SSL_CTX * ctx, exim_openssl_state_st * state,
uschar * ciphers, uschar ** errstr)
{
-for (uschar * s = ciphers; *s; s++ ) if (*s == '_') *s = '-';
DEBUG(D_tls) debug_printf("required ciphers: %s\n", ciphers);
if (!SSL_CTX_set_cipher_list(ctx, CS ciphers))
return tls_error(US"SSL_CTX_set_cipher_list", NULL, NULL, errstr);
@@ -1798,6 +1811,7 @@ else
if (opt_set_and_noexpand(tls_require_ciphers))
{
DEBUG(D_tls) debug_printf("TLS: preloading cipher list for server\n");
+ normalise_ciphers(&tls_require_ciphers, tls_require_ciphers);
if (server_load_ciphers(ctx, &state_server, tls_require_ciphers,
&dummy_errstr) == OK)
state_server.lib_state.pri_string = TRUE;
@@ -3178,9 +3192,12 @@ else
if (!expand_check(tls_require_ciphers, US"tls_require_ciphers", &expciphers, errstr))
return FAIL;
- if ( expciphers
- && (rc = server_load_ciphers(ctx, &state_server, expciphers, errstr)) != OK)
- return rc;
+ if (expciphers)
+ {
+ normalise_ciphers(&expciphers, tls_require_ciphers);
+ if ((rc = server_load_ciphers(ctx, &state_server, expciphers, errstr)) != OK)
+ return rc;
+ }
}
/* If this is a host for which certificate verification is mandatory or
@@ -3881,21 +3898,25 @@ if (conn_args->dane)
return FALSE;
if (expciphers && *expciphers == '\0')
expciphers = NULL;
+
+ normalise_ciphers(&expciphers, ob->dane_require_tls_ciphers);
}
#endif
-if (!expciphers &&
- !expand_check(ob->tls_require_ciphers, US"tls_require_ciphers",
+if (!expciphers)
+ {
+ if (!expand_check(ob->tls_require_ciphers, US"tls_require_ciphers",
&expciphers, errstr))
- return FALSE;
+ return FALSE;
-/* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
-are separated by underscores. So that I can use either form in my tests, and
-also for general convenience, we turn underscores into hyphens here. */
+ /* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
+ are separated by underscores. So that I can use either form in my tests, and
+ also for general convenience, we turn underscores into hyphens here. */
+
+ normalise_ciphers(&expciphers, ob->tls_require_ciphers);
+ }
if (expciphers)
{
- uschar *s = expciphers;
- while (*s) { if (*s == '_') *s = '-'; s++; }
DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
if (!SSL_CTX_set_cipher_list(exim_client_ctx->ctx, CS expciphers))
{
@@ -4558,12 +4579,9 @@ if (!expand_check(tls_require_ciphers, US"tls_require_ciphers", &expciphers,
if (!(expciphers && *expciphers))
return NULL;
-/* normalisation ripped from above */
-s = expciphers;
-while (*s != 0) { if (*s == '_') *s = '-'; s++; }
+normalise_ciphers(&expciphers, tls_require_ciphers);
err = NULL;
-
if (lib_ctx_new(&ctx, NULL, &err) == OK)
{
DEBUG(D_tls)
diff --git a/test/confs/2120 b/test/confs/2120
index ea9111c67..79a2e43f0 100644
--- a/test/confs/2120
+++ b/test/confs/2120
@@ -16,6 +16,9 @@ queue_only
tls_advertise_hosts = *
+# Ciphers string needing normalisation (the underbar)
+tls_require_ciphers = ECDHE_RSA-AES256-SHA
+
# ----- Routers -----