mail-mta/exim-4.96-r3: move 4.96 patches into tarball

Signed-off-by: Fabian Groffen <grobian@gentoo.org>
This commit is contained in:
Fabian Groffen 2023-05-27 11:24:25 +02:00
parent c753c4ee89
commit 050f88a892
No known key found for this signature in database
GPG Key ID: CE95DA854E444293
16 changed files with 20 additions and 1335 deletions

View File

@ -1,4 +1,5 @@
DIST exim-4.94.2.tar.xz 1838076 BLAKE2B 684e115a7af3efdab15451f8e11f9b53455c9166d8c078216d7a95223d77569cec8a882ed99b9180acbd8a9e747a0bca03d56993d011de15dc35143a989ab046 SHA512 5334c236221ed4e03dbc33e6a79d939b06037fa2f4b71971607a360b67af5c85a89681ee13a5eeaf0184382c55a160cf2e89ed7afb2949f025a54f1e88f9e3fc
DIST exim-4.96-gentoo-patches-r0.tar.xz 13308 BLAKE2B e01cd8b90593329d858cced27bea9da4860e80500c0b0b3f86418931a77616ac1e4a532cfffc551de5844bfcbcd115c1591b28577c234beb551458dc0877e764 SHA512 0a8d7b5903c8cd7c2cc07e4ea3ed62200ee0116fe0b5513ec97ba7f3ab1dd5cd0dc181eb93c3c1c7f767be7df3546ac07b622a8f4352eb883323c3a005a1c7db
DIST exim-4.96.tar.xz 1879152 BLAKE2B 4b424f2ebc661bd0db35d7f6da86300c6d5cb5b9a52cddd24fdd452daa76c84e471d4f8f278cf951d1503b01fd46fc3e6858d6feded09f34253d2cf2ae99b45a SHA512 6b863661465a0b9897c1b71875c5196a1903cf560dd85de45b08242b9731edb2bc10eb56945d62e477e5d15cc7a8d493915bff2ca81689673a8091c66f62c89e
DIST exim-pdf-4.94.2.tar.xz 2092248 BLAKE2B 973ab4f117fdb58afa017bc41b4496fac1277e707a9926d67317c455b0bd617021c17cba6c8d793d8962aacef12c0790d5add7174017512b7b1ea070f8e8533d SHA512 3a661f69d81a992798d4b7e5b7def7cfffa297a7b3c02a6631be426cefff5a6e8783fa322a1bd105d01f7b06968d01e77963e6ab7be3157f63eb62eb6ff172b0
DIST exim-pdf-4.96.tar.xz 2137468 BLAKE2B 7f61767f91864c43a3b7b6ca36ec7f41da6ad7029687a38cfa9307c444c2ffbd3eb61d45645ffd20ec16ba64a37e1ff08c02e7e4e36499c7783679af9a399081 SHA512 05e94579631656330d95d237c58bc9fd52229a067c5846e7c3409b4c83040c9216819bcb0090673d9991fd59e2c2025340592b31b241b557c6775782106854d1

View File

@ -34,8 +34,10 @@ SDIR=$([[ ${PV} == *_rc* ]] && echo /test
[[ ${PV} == *.*.*.* ]] && echo /fixes)
COMM_URI="https://downloads.exim.org/exim4${SDIR}"
GPV="r0"
DESCRIPTION="A highly configurable, drop-in replacement for sendmail"
SRC_URI="${COMM_URI}/${P//_rc/-RC}.tar.xz
https://dev.gentoo.org/~grobian/distfiles/${P}-gentoo-patches-${GPV}.tar.xz
mirror://gentoo/system_filter.exim.gz
doc? ( ${COMM_URI}/${PN}-pdf-${PV//_rc/-RC}.tar.xz )"
HOMEPAGE="https://www.exim.org/"
@ -116,20 +118,23 @@ src_prepare() {
eapply -p0 "${FILESDIR}"/exim-4.76-crosscompile.patch # 266591
eapply "${FILESDIR}"/exim-4.69-r1.27021.patch
eapply "${FILESDIR}"/exim-4.95-localscan_dlopen.patch
eapply "${FILESDIR}"/exim-4.96-rewrite-malformed-addr-fix.patch # upstr
eapply "${FILESDIR}"/exim-4.96-spf-memory-error-fix.patch # upstr
eapply "${FILESDIR}"/exim-4.96-regex-use-after-free.patch # upstr
eapply -p2 "${FILESDIR}"/exim-4.96-dmarc_use_after_free.patch # upstr
eapply "${FILESDIR}"/exim-4.96-deamon-startup-fix.patch # upstr
eapply "${FILESDIR}"/exim-4.96-openssl-verify-ocsp.patch # upstr
eapply "${FILESDIR}"/exim-4.96-openssl-double-expansion.patch # upstr
eapply "${FILESDIR}"/exim-4.96-recursion-dns_again.patch # upstr
eapply "${FILESDIR}"/exim-4.96-openssl-tls_eccurve-setting.patch # upstr
eapply "${FILESDIR}"/exim-4.96-openssl-tls_eccurve-lt-3.patch # upstr
eapply "${FILESDIR}"/exim-4.96-openssl-bad-alpn.patch # upstr
eapply "${FILESDIR}"/exim-4.96-dane-dns_again.patch # upstr
eapply "${FILESDIR}"/exim-4.96-expansion-crash.patch # upstr
eapply "${FILESDIR}"/exim-4.96-transport-crash.patch # upstr
# Upstream post-release fixes :(
local GPVDIR=${WORKDIR}/${P}-gentoo-patches-${GPV}
eapply "${GPVDIR}"/exim-4.96-rewrite-malformed-addr-fix.patch # upstr
eapply "${GPVDIR}"/exim-4.96-spf-memory-error-fix.patch # upstr
eapply "${GPVDIR}"/exim-4.96-regex-use-after-free.patch # upstr
eapply -p2 "${GPVDIR}"/exim-4.96-dmarc_use_after_free.patch # upstr
eapply "${GPVDIR}"/exim-4.96-deamon-startup-fix.patch # upstr
eapply "${GPVDIR}"/exim-4.96-openssl-verify-ocsp.patch # upstr
eapply "${GPVDIR}"/exim-4.96-openssl-double-expansion.patch # upstr
eapply "${GPVDIR}"/exim-4.96-recursion-dns_again.patch # upstr
eapply "${GPVDIR}"/exim-4.96-openssl-tls_eccurve-setting.patch # upstr
eapply "${GPVDIR}"/exim-4.96-openssl-tls_eccurve-lt-3.patch # upstr
eapply "${GPVDIR}"/exim-4.96-openssl-bad-alpn.patch # upstr
eapply "${GPVDIR}"/exim-4.96-dane-dns_again.patch # upstr
eapply "${GPVDIR}"/exim-4.96-expansion-crash.patch # upstr
eapply "${GPVDIR}"/exim-4.96-transport-crash.patch # upstr
# oddity, they disable berkdb as hack, and then throw an error when
# berkdb isn't enabled

View File

@ -1,81 +0,0 @@
modified for Gentoo, removed Changelog due to conflicts
From 30520c8f87fcf660ed99a2344cae7f9787f7bc89 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Thu, 5 Jan 2023 18:39:51 +0000
Subject: [PATCH 3/3] DANE: do not check dns_again_means_nonexist for TLSA
results of TRY_AGAIN
---
doc/doc-docbook/spec.xfpt | 7 ++++++-
doc/ChangeLog | 4 ++++
src/dns.c | 35 ++++++++++++++++++++++-------------
3 files changed, 32 insertions(+), 14 deletions(-)
--- a/src/dns.c
+++ b/src/dns.c
@@ -904,25 +904,34 @@ if (dnsa->answerlen < 0) switch (h_errno
DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave TRY_AGAIN\n",
name, dns_text_type(type));
/* Cut this out for various test programs */
#ifndef STAND_ALONE
- if (try_again_recursion)
+ /* Permitting dns_again_means nonexist for TLSA lookups breaks the
+ doewngrade resistance of dane, so avoid for those. */
+
+ if (type == T_TLSA)
+ rc = FAIL;
+ else
{
- log_write(0, LOG_MAIN|LOG_PANIC,
- "dns_again_means_nonexist recursion seen for %s (assuming nonexist)",
- name);
- return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH);
- }
+ if (try_again_recursion)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "dns_again_means_nonexist recursion seen for %s"
+ " (assuming nonexist)", name);
+ return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type),
+ DNS_NOMATCH);
+ }
- try_again_recursion = TRUE;
- save_domain = deliver_domain;
- deliver_domain = string_copy(name); /* set $domain */
- rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0,
- &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
- deliver_domain = save_domain;
- try_again_recursion = FALSE;
+ try_again_recursion = TRUE;
+ save_domain = deliver_domain;
+ deliver_domain = string_copy(name); /* set $domain */
+ rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0,
+ &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
+ deliver_domain = save_domain;
+ try_again_recursion = FALSE;
+ }
if (rc != OK)
{
DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n");
return dns_fail_return(name, type, 0, DNS_AGAIN);
--- a/doc/spec.txt
+++ b/doc/spec.txt
@@ -14246,11 +14246,13 @@ dns_again_means_nonexist, it is treated
should be used with care. You can make it apply to reverse lookups by a setting
such as this:
dns_again_means_nonexist = *.in-addr.arpa
-This option applies to all DNS lookups that Exim does. It also applies when the
+This option applies to all DNS lookups that Exim does, except for TLSA lookups
+(where knowing about such failures +is security-relevant). It also applies
+when the
gethostbyname() or getipnodebyname() functions give temporary errors, since
these are most likely to be caused by DNS lookup problems. The dnslookup router
has some options of its own for controlling what happens when lookups for MX or
SRV records give temporary errors. These more specific options are applied
after this global option.

View File

@ -1,53 +0,0 @@
modified for Gentoo, removed Changelog to avoid conflicts
From 221321d2c51b83d1feced80ecd6c2fe33ec5456c Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Thu, 3 Nov 2022 20:08:25 +0000
Subject: [PATCH 1/2] Fix daemon startup. Bug 2930
Broken-by: 7d5055276a
---
doc/ChangeLog | 4 ++++
src/daemon.c | 8 ++++++--
2 files changed, 10 insertions(+), 2 deletions(-)
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -1744,19 +1744,23 @@
{
/* If the parent process of this one has pid == 1, we are re-initializing the
daemon as the result of a SIGHUP. In this case, there is no need to do
anything, because the controlling terminal has long gone. Otherwise, fork, in
case current process is a process group leader (see 'man setsid' for an
- explanation) before calling setsid(). */
+ explanation) before calling setsid().
+ All other forks want daemon_listen cleared. Rather than blow a register, jsut
+ restore it here. */
if (getppid() != 1)
{
+ BOOL daemon_listen = f.daemon_listen;
pid_t pid = exim_fork(US"daemon");
if (pid < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
"fork() failed when starting daemon: %s", strerror(errno));
if (pid > 0) exit(EXIT_SUCCESS); /* in parent process, just exit */
(void)setsid(); /* release controlling terminal */
+ f.daemon_listen = daemon_listen;
}
}
/* We are now in the disconnected, daemon process (unless debugging). Set up
the listening sockets if required. */
@@ -2090,11 +2094,11 @@
{ /* found; append port to list */
for (p = i2->log; *p; ) p++; /* end of existing string */
if (*--p == '}') *p = '\0'; /* drop EOL */
while (isdigit(*--p)) ; /* char before port */
- i2->log = *p == ':' /* no list yet? */
+ i2->log = *p == ':' /* no list yet? { */
? string_sprintf("%.*s{%s,%d}",
(int)(p - i2->log + 1), i2->log, p+1, ipa->port)
: string_sprintf("%s,%d}", i2->log, ipa->port);
ipa->log = NULL;
break;

View File

@ -1,31 +0,0 @@
From 12fb3842f81bcbd4a4519d5728f2d7e0e3ca1445 Mon Sep 17 00:00:00 2001
From: Lorenz Brun <lorenz@brun.one>
Date: Fri, 14 Oct 2022 21:02:51 +0200
Subject: [PATCH] DMARC: fix use-after-free in dmarc_dns_lookup
This fixes a use-after-free in dmarc_dns_lookup where the result
of dns_lookup in dnsa is freed before the required data is copied out.
Fixes: 9258363 ("DNS: explicit alloc/free of workspace")
---
src/src/dmarc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/src/dmarc.c b/src/src/dmarc.c
index ad0c26c91..53c2752ac 100644
--- a/src/src/dmarc.c
+++ b/src/src/dmarc.c
@@ -230,8 +230,9 @@ if (rc == DNS_SUCCEED)
rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
if (rr->type == T_TXT && rr->size > 3)
{
+ uschar *record = string_copyn_taint(US rr->data, rr->size, GET_TAINTED);
store_free_dns_answer(dnsa);
- return string_copyn_taint(US rr->data, rr->size, GET_TAINTED);
+ return record;
}
store_free_dns_answer(dnsa);
return NULL;
--
2.30.2

View File

@ -1,69 +0,0 @@
modified for Gentoo, removed Changelog and tests
From 70069b65a39a7ba73a36fbd95371ff03cde1eb23 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Thu, 2 Feb 2023 20:00:35 +0000
Subject: [PATCH] Fix crash in expansions
Broken-by: 1058096b8c53
---
doc/ChangeLog | 4 ++++
src/expand.c | 9 +++++----
test/stderr/0630 | 1 +
3 files changed, 10 insertions(+), 4 deletions(-)
--- a/src/expand.c
+++ b/src/expand.c
@@ -4652,11 +4652,11 @@ while (*s)
yield = string_catn(yield, value, len);
continue;
}
- if (isdigit(*s))
+ if (isdigit(*s)) /* A $<n> variable */
{
int n;
s = read_cnumber(&n, s);
if (n >= 0 && n <= expand_nmax)
yield = string_catn(yield, expand_nstring[n], expand_nlength[n]);
@@ -7060,10 +7060,11 @@ NOT_ITEM: ;
if (arg) *arg++ = '_'; /* Put back for error messages */
}
/* Deal specially with operators that might take a certificate variable
as we do not want to do the usual expansion. For most, expand the string.*/
+
switch(c)
{
#ifndef DISABLE_TLS
case EOP_MD5:
case EOP_SHA1:
@@ -7107,11 +7108,11 @@ NOT_ITEM: ;
/* Otherwise, switch on the operator type. After handling go back
to the main loop top. */
{
- int start = yield->ptr;
+ unsigned expansion_start = gstring_length(yield);
switch(c)
{
case EOP_BASE32:
{
uschar *t;
@@ -8168,12 +8169,12 @@ NOT_ITEM: ;
goto EXPAND_FAILED;
} /* EOP_* switch */
DEBUG(D_expand)
{
- const uschar * s = yield->s + start;
- int i = yield->ptr - start;
+ const uschar * s = yield->s + expansion_start;
+ int i = gstring_length(yield) - expansion_start;
BOOL tainted = is_tainted(s);
DEBUG(D_noutf8)
{
debug_printf_indent("|-----op-res: %.*s\n", i, s);

View File

@ -1,101 +0,0 @@
modified for Gentoo, removed tests
From e1aca33756f73c22b00a98d40ce2be8ed94464b1 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Thu, 5 Jan 2023 13:03:37 +0000
Subject: [PATCH 2/3] OpenSSL: log conns rejected for bad ALPN, with the
offered value
Unfortunately, no way to do this under GnuTLS
---
src/match.c | 1 +
src/tls-gnu.c | 9 ++++++++-
src/tls-openssl.c | 13 +++++++++++--
test/log/1190 | 2 ++
test/runtest | 3 +++
5 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/src/match.c b/src/match.c
index 91a49c0f0..07070362d 100644
--- a/src/match.c
+++ b/src/match.c
@@ -968,6 +968,7 @@ Arguments:
s string to search for
listptr ptr to ptr to colon separated list of patterns, or NULL
sep a separator value for the list (see string_nextinlist())
+ or zero for auto
anchorptr ptr to tree for named items, or NULL if no named items
cache_bits ptr to cache_bits for ditto, or NULL if not caching
type MCL_DOMAIN when matching a domain list
diff --git a/src/tls-gnu.c b/src/tls-gnu.c
index 729fb5879..b47fabf1d 100644
--- a/src/tls-gnu.c
+++ b/src/tls-gnu.c
@@ -1119,21 +1119,28 @@ switch (tls_id)
/* The format of "data" here doesn't seem to be documented, but appears
to be a 2-byte field with a (redundant, given the "size" arg) total length
then a sequence of one-byte size then string (not nul-term) names. The
- latter is as described in OpenSSL documentation. */
+ latter is as described in OpenSSL documentation.
+ Note that we do not get called for a match_fail, making it hard to log
+ a single bad ALPN being offered (the common case). */
+ {
+ gstring * g = NULL;
DEBUG(D_tls) debug_printf("Seen ALPN extension from client (s=%u):", size);
for (const uschar * s = data+2; s-data < size-1; s += *s + 1)
{
server_seen_alpn++;
+ g = string_append_listele_n(g, ':', s+1, *s);
DEBUG(D_tls) debug_printf(" '%.*s'", (int)*s, s+1);
}
DEBUG(D_tls) debug_printf("\n");
if (server_seen_alpn > 1)
{
+ log_write(0, LOG_MAIN, "TLS ALPN (%s) rejected", string_from_gstring(g));
DEBUG(D_tls) debug_printf("TLS: too many ALPNs presented in handshake\n");
return GNUTLS_E_NO_APPLICATION_PROTOCOL;
}
break;
+ }
#endif
}
return 0;
diff --git a/src/tls-openssl.c b/src/tls-openssl.c
index e063d29bd..513ba0d3a 100644
--- a/src/tls-openssl.c
+++ b/src/tls-openssl.c
@@ -2324,6 +2324,8 @@ static int
tls_server_alpn_cb(SSL *ssl, const uschar ** out, uschar * outlen,
const uschar * in, unsigned int inlen, void * arg)
{
+gstring * g = NULL;
+
server_seen_alpn = TRUE;
DEBUG(D_tls)
{
@@ -2354,12 +2356,19 @@ if ( inlen > 1 /* at least one name */
}
}
-/* More than one name from clilent, or name did not match our list. */
+/* More than one name from client, or name did not match our list. */
/* This will be fatal to the TLS conn; would be nice to kill TCP also.
Maybe as an option in future; for now leave control to the config (must-tls). */
-DEBUG(D_tls) debug_printf("TLS ALPN rejected\n");
+for (int pos = 0, siz; pos < inlen; pos += siz+1)
+ {
+ siz = in[pos];
+ if (pos + 1 + siz > inlen) siz = inlen - pos - 1;
+ g = string_append_listele_n(g, ':', in + pos + 1, siz);
+ }
+log_write(0, LOG_MAIN, "TLS ALPN (%s) rejected", string_from_gstring(g));
+gstring_release_unused(g);
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
#endif /* EXIM_HAVE_ALPN */
--
2.39.0

View File

@ -1,217 +0,0 @@
From 62b97c2ecf148ee86053d82e5509e4c3a5a20054 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Sat, 29 Oct 2022 22:33:43 +0100
Subject: [PATCH 2/2] OpenSSL: fix double-expansion of tls_verify_certificates
---
src/tls-openssl.c | 66 +++++++++++++++++++++----------------------
1 file changed, 33 insertions(+), 33 deletions(-)
diff --git a/src/tls-openssl.c b/src/tls-openssl.c
index fdf0d92b2..2e09882d2 100644
--- a/src/tls-openssl.c
+++ b/src/tls-openssl.c
@@ -435,15 +435,15 @@ typedef struct exim_openssl_state {
/* should figure out a cleanup of API to handle state preserved per
implementation, for various reasons, which can be void * in the APIs.
For now, we hack around it. */
exim_openssl_state_st *client_static_state = NULL; /*XXX should not use static; multiple concurrent clients! */
exim_openssl_state_st state_server = {.is_server = TRUE};
static int
-setup_certs(SSL_CTX *sctx, uschar *certs, uschar *crl, host_item *host,
+setup_certs(SSL_CTX * sctx, uschar ** certs, uschar * crl, host_item * host,
uschar ** errstr );
/* Callbacks */
#ifndef DISABLE_OCSP
static int tls_server_stapling_cb(SSL *s, void *arg);
static void x509_stack_dump_cert_s_names(const STACK_OF(X509) * sk);
static void x509_store_dump_cert_s_names(X509_STORE * store);
@@ -1762,18 +1762,18 @@ if ( opt_set_and_noexpand(tls_verify_certificates)
{
/* Watch the default dir also as they are always included */
if ( tls_set_watch(CUS X509_get_default_cert_file(), FALSE)
&& tls_set_watch(tls_verify_certificates, FALSE)
&& tls_set_watch(tls_crl, FALSE))
{
+ uschar * v_certs = tls_verify_certificates;
DEBUG(D_tls) debug_printf("TLS: preloading CA bundle for server\n");
- if (setup_certs(ctx, tls_verify_certificates, tls_crl, NULL, &dummy_errstr)
- == OK)
+ if (setup_certs(ctx, &v_certs, tls_crl, NULL, &dummy_errstr) == OK)
state_server.lib_state.cabundle = TRUE;
/* If we can, preload the server-side cert, key and ocsp */
if ( opt_set_and_noexpand(tls_certificate)
# ifndef DISABLE_OCSP
&& opt_unset_or_noexpand(tls_ocsp_file)
@@ -1897,18 +1897,19 @@ if ( opt_set_and_noexpand(ob->tls_verify_certificates)
{
if ( !watch
|| tls_set_watch(CUS X509_get_default_cert_file(), FALSE)
&& tls_set_watch(ob->tls_verify_certificates, FALSE)
&& tls_set_watch(ob->tls_crl, FALSE)
)
{
+ uschar * v_certs = ob->tls_verify_certificates;
DEBUG(D_tls)
debug_printf("TLS: preloading CA bundle for transport '%s'\n", t->name);
- if (setup_certs(ctx, ob->tls_verify_certificates,
+ if (setup_certs(ctx, &v_certs,
ob->tls_crl, dummy_host, &dummy_errstr) == OK)
ob->tls_preload.cabundle = TRUE;
}
}
else
DEBUG(D_tls)
debug_printf("TLS: not preloading CA bundle, for transport '%s'\n", t->name);
@@ -2238,22 +2239,20 @@ if (state->u_ocsp.server.file)
{
SSL_CTX_set_tlsext_status_cb(server_sni, tls_server_stapling_cb);
SSL_CTX_set_tlsext_status_arg(server_sni, state);
}
#endif
{
- uschar * expcerts;
- if ( !expand_check(tls_verify_certificates, US"tls_verify_certificates",
- &expcerts, &dummy_errstr)
- || (rc = setup_certs(server_sni, expcerts, tls_crl, NULL,
+ uschar * v_certs = tls_verify_certificates;
+ if ((rc = setup_certs(server_sni, &v_certs, tls_crl, NULL,
&dummy_errstr)) != OK)
goto bad;
- if (expcerts && *expcerts)
+ if (v_certs && *v_certs)
setup_cert_verify(server_sni, FALSE, verify_callback_server);
}
/* do this after setup_certs, because this can require the certs for verifying
OCSP information. */
if ((rc = tls_expand_session_files(server_sni, state, &dummy_errstr)) != OK)
goto bad;
@@ -3017,32 +3016,33 @@ return TRUE;
/* Called by both client and server startup; on the server possibly
repeated after a Server Name Indication.
Arguments:
sctx SSL_CTX* to initialise
- certs certs file, expanded
+ certs certs file, returned expanded
crl CRL file or NULL
host NULL in a server; the remote host in a client
errstr error string pointer
Returns: OK/DEFER/FAIL
*/
static int
-setup_certs(SSL_CTX *sctx, uschar *certs, uschar *crl, host_item *host,
+setup_certs(SSL_CTX * sctx, uschar ** certsp, uschar * crl, host_item * host,
uschar ** errstr)
{
-uschar *expcerts, *expcrl;
+uschar * expcerts, * expcrl;
-if (!expand_check(certs, US"tls_verify_certificates", &expcerts, errstr))
+if (!expand_check(*certsp, US"tls_verify_certificates", &expcerts, errstr))
return DEFER;
DEBUG(D_tls) debug_printf("tls_verify_certificates: %s\n", expcerts);
+*certsp = expcerts;
if (expcerts && *expcerts)
{
/* Tell the library to use its compiled-in location for the system default
CA bundle. Then add the ones specified in the config, if any. */
if (!SSL_CTX_set_default_verify_paths(sctx))
return tls_error(US"SSL_CTX_set_default_verify_paths", host, NULL, errstr);
@@ -3330,28 +3330,28 @@ if (verify_check_host(&tls_verify_hosts) == OK)
server_verify_optional = FALSE;
else if (verify_check_host(&tls_try_verify_hosts) == OK)
server_verify_optional = TRUE;
else
goto skip_certs;
{
- uschar * expcerts;
- if (!expand_check(tls_verify_certificates, US"tls_verify_certificates",
- &expcerts, errstr))
- return DEFER;
- DEBUG(D_tls) debug_printf("tls_verify_certificates: %s\n", expcerts);
+ uschar * v_certs = tls_verify_certificates;
if (state_server.lib_state.cabundle)
- { DEBUG(D_tls) debug_printf("TLS: CA bundle for server was preloaded\n"); }
+ {
+ DEBUG(D_tls) debug_printf("TLS: CA bundle for server was preloaded\n");
+ setup_cert_verify(ctx, server_verify_optional, verify_callback_server);
+ }
else
- if ((rc = setup_certs(ctx, expcerts, tls_crl, NULL, errstr)) != OK)
+ {
+ if ((rc = setup_certs(ctx, &v_certs, tls_crl, NULL, errstr)) != OK)
return rc;
-
- if (expcerts && *expcerts)
- setup_cert_verify(ctx, server_verify_optional, verify_callback_server);
+ if (v_certs && *v_certs)
+ setup_cert_verify(ctx, server_verify_optional, verify_callback_server);
+ }
}
skip_certs: ;
#ifndef DISABLE_TLS_RESUME
# if OPENSSL_VERSION_NUMBER < 0x30000000L
SSL_CTX_set_tlsext_ticket_key_cb(ctx, ticket_key_callback);
/* despite working, appears to always return failure, so ignoring */
@@ -3606,28 +3606,28 @@ if ( ( ( !ob->tls_verify_hosts || !ob->tls_verify_hosts
client_verify_optional = FALSE;
else if (verify_check_given_host(CUSS &ob->tls_try_verify_hosts, host) == OK)
client_verify_optional = TRUE;
else
return OK;
{
- uschar * expcerts;
- if (!expand_check(ob->tls_verify_certificates, US"tls_verify_certificates",
- &expcerts, errstr))
- return DEFER;
- DEBUG(D_tls) debug_printf("tls_verify_certificates: %s\n", expcerts);
+ uschar * v_certs = ob->tls_verify_certificates;
if (state->lib_state.cabundle)
- { DEBUG(D_tls) debug_printf("TLS: CA bundle was preloaded\n"); }
+ {
+ DEBUG(D_tls) debug_printf("TLS: CA bundle for tpt was preloaded\n");
+ setup_cert_verify(ctx, client_verify_optional, verify_callback_client);
+ }
else
- if ((rc = setup_certs(ctx, expcerts, ob->tls_crl, host, errstr)) != OK)
+ {
+ if ((rc = setup_certs(ctx, &v_certs, ob->tls_crl, host, errstr)) != OK)
return rc;
-
- if (expcerts && *expcerts)
- setup_cert_verify(ctx, client_verify_optional, verify_callback_client);
+ if (v_certs && *v_certs)
+ setup_cert_verify(ctx, client_verify_optional, verify_callback_client);
+ }
}
if (verify_check_given_host(CUSS &ob->tls_verify_cert_hostnames, host) == OK)
{
state->verify_cert_hostnames =
#ifdef SUPPORT_I18N
string_domain_utf8_to_alabel(host->certname, NULL);
--
2.35.1

View File

@ -1,44 +0,0 @@
modified for Gentoo, removed tests due to conflicts
From 7fa5764c203f2f4a900898a79ed02d674075313f Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Mon, 2 Jan 2023 15:04:14 +0000
Subject: [PATCH 1/3] OpenSSL: Fix tls_eccurve on earlier versions than 3.0.0.
Bug 2954
Broken-by: ca4014de81e6
---
src/tls-openssl.c | 7 ++++---
test/log/2149 | 28 ++++++++++++++--------------
test/runtest | 3 +++
test/scripts/2100-OpenSSL/2149 | 22 ++++++++++++----------
4 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/src/tls-openssl.c b/src/tls-openssl.c
index 4d0f99ea9..e063d29bd 100644
--- a/src/tls-openssl.c
+++ b/src/tls-openssl.c
@@ -786,8 +786,9 @@ if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef
# endif
)
{
- tls_error(string_sprintf("Unknown curve name tls_eccurve '%s'", exp_curve),
- NULL, NULL, errstr);
+ uschar * s = string_sprintf("Unknown curve name tls_eccurve '%s'", exp_curve);
+ DEBUG(D_tls) debug_printf("TLS error '%s'\n", s);
+ if (errstr) *errstr = s;
return FALSE;
}
@@ -803,7 +804,7 @@ if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef
/* The "tmp" in the name here refers to setting a temporary key
not to the stability of the interface. */
- if ((rc = SSL_CTX_set_tmp_ecdh(sctx, ecdh) == 0))
+ if ((rc = SSL_CTX_set_tmp_ecdh(sctx, ecdh)) == 0)
tls_error(string_sprintf("Error enabling '%s' curve", exp_curve), NULL, NULL, errstr);
else
DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' curve\n", exp_curve);
--
2.39.0

View File

@ -1,169 +0,0 @@
modified for Gentoo, dropped Changelog and test due to conflicts
From ca4014de81e6aa367aa0a54c49b4c3d4b137814c Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Sun, 1 Jan 2023 12:18:38 +0000
Subject: [PATCH] OpenSSL: fix tls_eccurve setting explicit curve/group. Bug
2954
---
doc/ChangeLog | 4 +++
src/tls-openssl.c | 39 ++++++++++++++----------
test/confs/2148 | 54 ++++++++++++++++++++++++++++++++++
test/confs/2149 | 39 +++++++++++++-----------
test/log/2148 | 48 ++++++++++++++++++++++++++++++
test/log/2149 | 39 ++++++++++++------------
test/paniclog/{2149 => 2148} | 0
test/scripts/2100-OpenSSL/2148 | 50 +++++++++++++++++++++++++++++++
test/scripts/2100-OpenSSL/2149 | 50 ++++++++++++++++---------------
test/stderr/2148 | 5 ++++
test/stderr/2149 | 3 --
11 files changed, 250 insertions(+), 81 deletions(-)
create mode 100644 test/confs/2148
create mode 100644 test/log/2148
rename test/paniclog/{2149 => 2148} (100%)
create mode 100644 test/scripts/2100-OpenSSL/2148
create mode 100644 test/stderr/2148
--- a/src/tls-openssl.c
+++ b/src/tls-openssl.c
@@ -657,16 +657,16 @@ if (dh_bitsize <= tls_dh_max_bits)
/* EVP_PKEY_free(pkey); crashes */
#endif
}
else
DEBUG(D_tls)
- debug_printf("Diffie-Hellman initialized from %s with %d-bit prime\n",
+ debug_printf(" Diffie-Hellman initialized from %s with %d-bit prime\n",
dhexpanded ? dhexpanded : US"default", dh_bitsize);
}
else
DEBUG(D_tls)
- debug_printf("dhparams '%s' %d bits, is > tls_dh_max_bits limit of %d\n",
+ debug_printf(" dhparams '%s' %d bits, is > tls_dh_max_bits limit of %d\n",
dhexpanded ? dhexpanded : US"default", dh_bitsize, tls_dh_max_bits);
#if OPENSSL_VERSION_NUMBER < 0x30000000L
DH_free(dh);
#endif
@@ -712,23 +712,31 @@ init_ecdh(SSL_CTX * sctx, uschar ** errs
#ifdef OPENSSL_NO_ECDH
return TRUE;
#else
uschar * exp_curve;
-int nid;
-BOOL rv;
+int nid, rc;
# ifndef EXIM_HAVE_ECDH
DEBUG(D_tls)
- debug_printf("No OpenSSL API to define ECDH parameters, skipping\n");
+ debug_printf(" No OpenSSL API to define ECDH parameters, skipping\n");
return TRUE;
# else
if (!expand_check(tls_eccurve, US"tls_eccurve", &exp_curve, errstr))
return FALSE;
+
+/* Is the option deliberately empty? */
+
if (!exp_curve || !*exp_curve)
+ {
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ DEBUG(D_tls) debug_printf( " ECDH OpenSSL 1.0.2+: clearing curves list\n");
+ (void) SSL_CTX_set1_curves(sctx, &nid, 0);
+#endif
return TRUE;
+ }
/* "auto" needs to be handled carefully.
* OpenSSL < 1.0.2: we do not select anything, but fallback to prime256v1
* OpenSSL < 1.1.0: we have to call SSL_CTX_set_ecdh_auto
* (openssl/ssl.h defines SSL_CTRL_SET_ECDH_AUTO)
@@ -737,27 +745,26 @@ if (!exp_curve || !*exp_curve)
*/
if (Ustrcmp(exp_curve, "auto") == 0)
{
#if OPENSSL_VERSION_NUMBER < 0x10002000L
DEBUG(D_tls) debug_printf(
- "ECDH OpenSSL < 1.0.2: temp key parameter settings: overriding \"auto\" with \"prime256v1\"\n");
+ " ECDH OpenSSL < 1.0.2: temp key parameter settings: overriding \"auto\" with \"prime256v1\"\n");
exp_curve = US"prime256v1";
#else
# if defined SSL_CTRL_SET_ECDH_AUTO
DEBUG(D_tls) debug_printf(
- "ECDH OpenSSL 1.0.2+: temp key parameter settings: autoselection\n");
+ " ECDH OpenSSL 1.0.2+: temp key parameter settings: autoselection\n");
SSL_CTX_set_ecdh_auto(sctx, 1);
return TRUE;
# else
DEBUG(D_tls) debug_printf(
- "ECDH OpenSSL 1.1.0+: temp key parameter settings: default selection\n");
+ " ECDH OpenSSL 1.1.0+: temp key parameter settings: library default selection\n");
return TRUE;
# endif
#endif
}
-DEBUG(D_tls) debug_printf("ECDH: curve '%s'\n", exp_curve);
if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef
# ifdef EXIM_HAVE_OPENSSL_EC_NIST2NID
&& (nid = EC_curve_nist2nid(CCS exp_curve)) == NID_undef
# endif
)
@@ -777,27 +784,27 @@ if ( (nid = OBJ_sn2nid (CCS exp_c
}
/* The "tmp" in the name here refers to setting a temporary key
not to the stability of the interface. */
- if ((rv = SSL_CTX_set_tmp_ecdh(sctx, ecdh) == 0))
+ if ((rc = SSL_CTX_set_tmp_ecdh(sctx, ecdh) == 0))
tls_error(string_sprintf("Error enabling '%s' curve", exp_curve), NULL, NULL, errstr);
else
- DEBUG(D_tls) debug_printf("ECDH: enabled '%s' curve\n", exp_curve);
+ DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' curve\n", exp_curve);
EC_KEY_free(ecdh);
}
#else /* v 3.0.0 + */
-if ((rv = SSL_CTX_set1_groups(sctx, &nid, 1)) == 0)
+if ((rc = SSL_CTX_set1_groups(sctx, &nid, 1)) == 0)
tls_error(string_sprintf("Error enabling '%s' group", exp_curve), NULL, NULL, errstr);
else
- DEBUG(D_tls) debug_printf("ECDH: enabled '%s' group\n", exp_curve);
+ DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' group\n", exp_curve);
#endif
-return !rv;
+return !!rc;
# endif /*EXIM_HAVE_ECDH*/
#endif /*OPENSSL_NO_ECDH*/
}
@@ -1719,19 +1726,19 @@ state_server.lib_state.lib_ctx = ctx;
/* Preload DH params and EC curve */
if (opt_unset_or_noexpand(tls_dhparam))
{
- DEBUG(D_tls) debug_printf("TLS: preloading DH params for server\n");
+ DEBUG(D_tls) debug_printf("TLS: preloading DH params '%s' for server\n", tls_dhparam);
if (init_dh(ctx, tls_dhparam, &dummy_errstr))
state_server.lib_state.dh = TRUE;
}
else
DEBUG(D_tls) debug_printf("TLS: not preloading DH params for server\n");
if (opt_unset_or_noexpand(tls_eccurve))
{
- DEBUG(D_tls) debug_printf("TLS: preloading ECDH curve for server\n");
+ DEBUG(D_tls) debug_printf("TLS: preloading ECDH curve '%s' for server\n", tls_eccurve);
if (init_ecdh(ctx, &dummy_errstr))
state_server.lib_state.ecdh = TRUE;
}
else
DEBUG(D_tls) debug_printf("TLS: not preloading ECDH curve for server\n");

View File

@ -1,232 +0,0 @@
From 7f65a63b60c6ea86db683ac00e221939f3bb1d47 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Tue, 25 Oct 2022 21:26:30 +0100
Subject: [PATCH 1/2] OpenSSL: when preloading creds do the server certs before
the OCSP proofs so that the latter can ve verified before loading
---
src/tls-openssl.c | 113 ++++++++++++++++++++++--------------------
1 file changed, 58 insertions(+), 55 deletions(-)
diff --git a/src/tls-openssl.c b/src/tls-openssl.c
index 68ad6f15b..fdf0d92b2 100644
--- a/src/tls-openssl.c
+++ b/src/tls-openssl.c
@@ -441,14 +441,16 @@ exim_openssl_state_st state_server = {.is_server = TRUE};
static int
setup_certs(SSL_CTX *sctx, uschar *certs, uschar *crl, host_item *host,
uschar ** errstr );
/* Callbacks */
#ifndef DISABLE_OCSP
static int tls_server_stapling_cb(SSL *s, void *arg);
+static void x509_stack_dump_cert_s_names(const STACK_OF(X509) * sk);
+static void x509_store_dump_cert_s_names(X509_STORE * store);
#endif
/* Daemon-called, before every connection, key create/rotate */
#ifndef DISABLE_TLS_RESUME
static void tk_init(void);
@@ -1307,15 +1309,14 @@ ocsp_load_response(exim_openssl_state_st * state, const uschar * filename,
{
BIO * bio;
OCSP_RESPONSE * resp;
OCSP_BASICRESP * basic_response;
OCSP_SINGLERESP * single_response;
ASN1_GENERALIZEDTIME * rev, * thisupd, * nextupd;
STACK_OF(X509) * sk;
-unsigned long verify_flags;
int status, reason, i;
DEBUG(D_tls)
debug_printf("tls_ocsp_file (%s) '%s'\n", is_pem ? "PEM" : "DER", filename);
if (!filename || !*filename) return;
@@ -1372,28 +1373,28 @@ if ((status = OCSP_response_status(resp)) != OCSP_RESPONSE_STATUS_SUCCESSFUL)
if (!(basic_response = OCSP_response_get1_basic(resp)))
{
DEBUG(D_tls)
debug_printf("OCSP response parse error: unable to extract basic response.\n");
goto bad;
}
-sk = state->verify_stack;
-verify_flags = OCSP_NOVERIFY; /* check sigs, but not purpose */
+sk = state->verify_stack; /* set by setup_certs() / chain_from_pem_file() */
/* May need to expose ability to adjust those flags?
OCSP_NOSIGS OCSP_NOVERIFY OCSP_NOCHAIN OCSP_NOCHECKS OCSP_NOEXPLICIT
OCSP_TRUSTOTHER OCSP_NOINTERN */
-/* This does a full verify on the OCSP proof before we load it for serving
-up; possibly overkill - just date-checks might be nice enough.
+/* This does a partial verify (only the signer link, not the whole chain-to-CA)
+on the OCSP proof before we load it for serving up; possibly overkill -
+just date-checks might be nice enough.
OCSP_basic_verify takes a "store" arg, but does not
-use it for the chain verification, which is all we do
-when OCSP_NOVERIFY is set. The content from the wire
-"basic_response" and a cert-stack "sk" are all that is used.
+use it for the chain verification, when OCSP_NOVERIFY is set.
+The content from the wire "basic_response" and a cert-stack "sk" are all
+that is used.
We have a stack, loaded in setup_certs() if tls_verify_certificates
was a file (not a directory, or "system"). It is unfortunate we
cannot used the connection context store, as that would neatly
handle the "system" case too, but there seems to be no library
function for getting a stack from a store.
[ In OpenSSL 1.1 - ? X509_STORE_CTX_get0_chain(ctx) ? ]
@@ -1402,15 +1403,15 @@ SNI handling.
Separately we might try to replace using OCSP_basic_verify() - which seems to not
be a public interface into the OpenSSL library (there's no manual entry) -
But what with? We also use OCSP_basic_verify in the client stapling callback.
And there we NEED it; we must verify that status... unless the
library does it for us anyway? */
-if ((i = OCSP_basic_verify(basic_response, sk, NULL, verify_flags)) < 0)
+if ((i = OCSP_basic_verify(basic_response, sk, NULL, OCSP_NOVERIFY)) < 0)
{
DEBUG(D_tls)
{
ERR_error_string_n(ERR_get_error(), ssl_errstring, sizeof(ssl_errstring));
debug_printf("OCSP response verify failure: %s\n", US ssl_errstring);
}
goto bad;
@@ -1747,61 +1748,18 @@ if (opt_unset_or_noexpand(tls_eccurve))
if (init_ecdh(ctx, &dummy_errstr))
state_server.lib_state.ecdh = TRUE;
}
else
DEBUG(D_tls) debug_printf("TLS: not preloading ECDH curve for server\n");
#if defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT)
-/* If we can, preload the server-side cert, key and ocsp */
-
-if ( opt_set_and_noexpand(tls_certificate)
-# ifndef DISABLE_OCSP
- && opt_unset_or_noexpand(tls_ocsp_file)
-#endif
- && opt_unset_or_noexpand(tls_privatekey))
- {
- /* Set watches on the filenames. The implementation does de-duplication
- so we can just blindly do them all. */
-
- if ( tls_set_watch(tls_certificate, TRUE)
-# ifndef DISABLE_OCSP
- && tls_set_watch(tls_ocsp_file, TRUE)
-#endif
- && tls_set_watch(tls_privatekey, TRUE))
- {
- state_server.certificate = tls_certificate;
- state_server.privatekey = tls_privatekey;
-#ifndef DISABLE_OCSP
- state_server.u_ocsp.server.file = tls_ocsp_file;
-#endif
-
- DEBUG(D_tls) debug_printf("TLS: preloading server certs\n");
- if (tls_expand_session_files(ctx, &state_server, &dummy_errstr) == OK)
- state_server.lib_state.conn_certs = TRUE;
- }
- }
-else if ( !tls_certificate && !tls_privatekey
-# ifndef DISABLE_OCSP
- && !tls_ocsp_file
-#endif
- )
- { /* Generate & preload a selfsigned cert. No files to watch. */
- if (tls_expand_session_files(ctx, &state_server, &dummy_errstr) == OK)
- {
- state_server.lib_state.conn_certs = TRUE;
- lifetime = f.running_in_test_harness ? 2 : 60 * 60; /* 1 hour */
- }
- }
-else
- DEBUG(D_tls) debug_printf("TLS: not preloading server certs\n");
-
-
/* If we can, preload the Authorities for checking client certs against.
Actual choice to do verify is made (tls_{,try_}verify_hosts)
-at TLS conn startup */
+at TLS conn startup.
+Do this before the server ocsp so that its info can verify the ocsp. */
if ( opt_set_and_noexpand(tls_verify_certificates)
&& opt_unset_or_noexpand(tls_crl))
{
/* Watch the default dir also as they are always included */
if ( tls_set_watch(CUS X509_get_default_cert_file(), FALSE)
@@ -1809,18 +1767,63 @@ if ( opt_set_and_noexpand(tls_verify_certificates)
&& tls_set_watch(tls_crl, FALSE))
{
DEBUG(D_tls) debug_printf("TLS: preloading CA bundle for server\n");
if (setup_certs(ctx, tls_verify_certificates, tls_crl, NULL, &dummy_errstr)
== OK)
state_server.lib_state.cabundle = TRUE;
- }
+
+ /* If we can, preload the server-side cert, key and ocsp */
+
+ if ( opt_set_and_noexpand(tls_certificate)
+# ifndef DISABLE_OCSP
+ && opt_unset_or_noexpand(tls_ocsp_file)
+# endif
+ && opt_unset_or_noexpand(tls_privatekey))
+ {
+ /* Set watches on the filenames. The implementation does de-duplication
+ so we can just blindly do them all. */
+
+ if ( tls_set_watch(tls_certificate, TRUE)
+# ifndef DISABLE_OCSP
+ && tls_set_watch(tls_ocsp_file, TRUE)
+# endif
+ && tls_set_watch(tls_privatekey, TRUE))
+ {
+ state_server.certificate = tls_certificate;
+ state_server.privatekey = tls_privatekey;
+#ifndef DISABLE_OCSP
+ state_server.u_ocsp.server.file = tls_ocsp_file;
+# endif
+
+ DEBUG(D_tls) debug_printf("TLS: preloading server certs\n");
+ if (tls_expand_session_files(ctx, &state_server, &dummy_errstr) == OK)
+ state_server.lib_state.conn_certs = TRUE;
+ }
+ }
+ else if ( !tls_certificate && !tls_privatekey
+# ifndef DISABLE_OCSP
+ && !tls_ocsp_file
+# endif
+ )
+ { /* Generate & preload a selfsigned cert. No files to watch. */
+ if (tls_expand_session_files(ctx, &state_server, &dummy_errstr) == OK)
+ {
+ state_server.lib_state.conn_certs = TRUE;
+ lifetime = f.running_in_test_harness ? 2 : 60 * 60; /* 1 hour */
+ }
+ }
+ else
+ DEBUG(D_tls) debug_printf("TLS: not preloading server certs\n");
+ }
}
else
DEBUG(D_tls) debug_printf("TLS: not preloading CA bundle for server\n");
+
+
#endif /* EXIM_HAVE_INOTIFY */
/* If we can, preload the ciphers control string */
if (opt_set_and_noexpand(tls_require_ciphers))
{
--
2.35.1

View File

@ -1,57 +0,0 @@
modified for Gentoo, removed Changelog due to conflicts
From 1d38781da934809e6ce0b8c3718c4b3bccdfe1d2 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Wed, 28 Dec 2022 19:39:06 +0000
Subject: [PATCH] Fix recursion on dns_again_means_nonexist. Bug 2911
---
doc/ChangeLog | 8 +++++
src/dns.c | 12 ++++++++
test/confs/2202 | 18 +++++++++--
test/scripts/2200-dnsdb/2202 | 8 +++++
test/stderr/2202 | 58 +++++++++++++++++++++++++++++++++++-
test/stdout/2202 | 8 +++++
6 files changed, 108 insertions(+), 4 deletions(-)
--- a/src/dns.c
+++ b/src/dns.c
@@ -799,10 +799,11 @@ int
dns_basic_lookup(dns_answer * dnsa, const uschar * name, int type)
{
int rc;
#ifndef STAND_ALONE
const uschar * save_domain;
+static BOOL try_again_recursion = FALSE;
#endif
/* DNS lookup failures of any kind are cached in a tree. This is mainly so that
a timeout on one domain doesn't happen time and time again for messages that
have many addresses in the same domain. We rely on the resolver and name server
@@ -903,15 +904,26 @@ if (dnsa->answerlen < 0) switch (h_errno
DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave TRY_AGAIN\n",
name, dns_text_type(type));
/* Cut this out for various test programs */
#ifndef STAND_ALONE
+ if (try_again_recursion)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "dns_again_means_nonexist recursion seen for %s (assuming nonexist)",
+ name);
+ return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH);
+ }
+
+ try_again_recursion = TRUE;
save_domain = deliver_domain;
deliver_domain = string_copy(name); /* set $domain */
rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0,
&domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
deliver_domain = save_domain;
+ try_again_recursion = FALSE;
+
if (rc != OK)
{
DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n");
return dns_fail_return(name, type, 0, DNS_AGAIN);
}

View File

@ -1,173 +0,0 @@
modified for Gentoo, removed Changelog due to conflicts
From 4e9ed49f8f12eb331b29bd5b6dc3693c520fddc2 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Wed, 31 Aug 2022 15:37:40 +0100
Subject: [PATCH] Fix $regex<n> use-after-free. Bug 2915
---
doc/ChangeLog | 8 +++++++-
src/exim.c | 4 +---
src/expand.c | 2 +-
src/functions.h | 1 +
src/globals.c | 2 +-
src/regex.c | 29 ++++++++++++++++++-----------
src/smtp_in.c | 2 ++
test/confs/4002 | 10 ++++++++++
test/mail/4002.userx | 7 +++++++
test/scripts/4000-scanning/4002 | 7 +++++++
10 files changed, 55 insertions(+), 17 deletions(-)
--- a/src/exim.c
+++ b/src/exim.c
@@ -1999,12 +1999,10 @@
regex_whitelisted_macro =
regex_must_compile(US"^[A-Za-z0-9_/.-]*$", FALSE, TRUE);
#endif
-for (i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
-
/* If the program is called as "mailq" treat it as equivalent to "exim -bp";
this seems to be a generally accepted convention, since one finds symbolic
links called "mailq" in standard OS configurations. */
if ((namelen == 5 && Ustrcmp(argv[0], "mailq") == 0) ||
@@ -6082,11 +6080,11 @@
callout_address = NULL;
sending_ip_address = NULL;
deliver_localpart_data = deliver_domain_data =
recipient_data = sender_data = NULL;
acl_var_m = NULL;
- for(int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
+ regex_vars_clear();
store_reset(reset_point);
}
exim_exit(EXIT_SUCCESS); /* Never returns */
--- a/src/expand.c
+++ b/src/expand.c
@@ -1871,11 +1871,11 @@
{
tree_node * node = tree_search(router_var, name + 2);
return node ? node->data.ptr : strict_acl_vars ? NULL : US"";
}
-/* Handle $auth<n> variables. */
+/* Handle $auth<n>, $regex<n> variables. */
if (Ustrncmp(name, "auth", 4) == 0)
{
uschar *endptr;
int n = Ustrtoul(name + 4, &endptr, 10);
--- a/src/functions.h
+++ b/src/functions.h
@@ -436,10 +436,11 @@
extern int regex(const uschar **);
#endif
extern BOOL regex_match(const pcre2_code *, const uschar *, int, uschar **);
extern BOOL regex_match_and_setup(const pcre2_code *, const uschar *, int, int);
extern const pcre2_code *regex_must_compile(const uschar *, BOOL, BOOL);
+extern void regex_vars_clear(void);
extern void retry_add_item(address_item *, uschar *, int);
extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL,
uschar **, uschar **);
extern retry_config *retry_find_config(const uschar *, const uschar *, int, int);
extern BOOL retry_ultimate_address_timeout(uschar *, const uschar *,
--- a/src/globals.c
+++ b/src/globals.c
@@ -1313,11 +1313,11 @@
#ifndef DISABLE_PIPE_CONNECT
const pcre2_code *regex_EARLY_PIPE = NULL;
#endif
const pcre2_code *regex_ismsgid = NULL;
const pcre2_code *regex_smtp_code = NULL;
-const uschar *regex_vars[REGEX_VARS];
+const uschar *regex_vars[REGEX_VARS] = { 0 };;
#ifdef WHITELIST_D_MACROS
const pcre2_code *regex_whitelisted_macro = NULL;
#endif
#ifdef WITH_CONTENT_SCAN
uschar *regex_match_string = NULL;
--- a/src/regex.c
+++ b/src/regex.c
@@ -94,22 +94,32 @@
}
pcre2_match_data_free(md);
return FAIL;
}
+
+/* reset expansion variables */
+void
+regex_vars_clear(void)
+{
+regex_match_string = NULL;
+for (int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
+}
+
+
+
int
-regex(const uschar **listptr)
+regex(const uschar ** listptr)
{
unsigned long mbox_size;
-FILE *mbox_file;
-pcre_list *re_list_head;
-uschar *linebuffer;
+FILE * mbox_file;
+pcre_list * re_list_head;
+uschar * linebuffer;
long f_pos = 0;
int ret = FAIL;
-/* reset expansion variable */
-regex_match_string = NULL;
+regex_vars_clear();
if (!mime_stream) /* We are in the DATA ACL */
{
if (!(mbox_file = spool_mbox(&mbox_size, NULL, NULL)))
{ /* error while spooling */
@@ -167,18 +177,17 @@
int
mime_regex(const uschar **listptr)
{
-pcre_list *re_list_head = NULL;
-FILE *f;
-uschar *mime_subject = NULL;
+pcre_list * re_list_head = NULL;
+FILE * f;
+uschar * mime_subject = NULL;
int mime_subject_len = 0;
int ret;
-/* reset expansion variable */
-regex_match_string = NULL;
+regex_vars_clear();
/* precompile our regexes */
if (!(re_list_head = compile(*listptr)))
return FAIL; /* no regexes -> nothing to do */
--- a/src/smtp_in.c
+++ b/src/smtp_in.c
@@ -2155,12 +2155,14 @@
prdr_requested = FALSE;
#endif
#ifdef SUPPORT_I18N
message_smtputf8 = FALSE;
#endif
+regex_vars_clear();
body_linecount = body_zerocount = 0;
+lookup_value = NULL; /* Can be set by ACL */
sender_rate = sender_rate_limit = sender_rate_period = NULL;
ratelimiters_mail = NULL; /* Updated by ratelimit ACL condition */
/* Note that ratelimiters_conn persists across resets. */
/* Reset message ACL variables */

View File

@ -1,42 +0,0 @@
modified for Gentoo, removed Changelog change due to conflicts
From e7ec503729970a03d4509921342bc81313976126 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Tue, 12 Jul 2022 22:14:04 +0100
Subject: [PATCH] Fix exit on attempt to rewrite a malformed address. Bug 2903
---
doc/ChangeLog | 5 +
src/rewrite.c | 9 +-
test/confs/0471 | 7 +
test/log/0471 | 5 +
test/scripts/0000-Basic/0471 | 4 +-
test/stderr/0471 | 245 ++++++++++++++++++++++++++++++++++-
6 files changed, 267 insertions(+), 8 deletions(-)
--- a/src/rewrite.c
+++ b/src/rewrite.c
@@ -493,19 +493,18 @@
empty address, overlong addres. Sometimes the result matters, sometimes not.
It seems this function is called for *any* header we see. */
if (!recipient)
{
- /* Handle unparesable addresses in the header. Slightly ugly because a
+ /* Log unparesable addresses in the header. Slightly ugly because a
null output from the extract can also result from a header without an
- address, "To: undisclosed recpients:;" being the classic case. */
+ address, "To: undisclosed recpients:;" being the classic case. Ignore
+ this one and carry on. */
if ((rewrite_rules || routed_old) && Ustrcmp(errmess, "empty address") != 0)
- {
log_write(0, LOG_MAIN, "rewrite: %s", errmess);
- exim_exit(EXIT_FAILURE);
- }
+
loop_reset_point = store_reset(loop_reset_point);
continue;
}
/* If routed_old is not NULL, this is a rewrite caused by a router,

View File

@ -1,25 +0,0 @@
From 93c722ce0549360af68269f088f4e59ed8fc130e Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Sun, 7 Aug 2022 17:00:27 +0100
Subject: [PATCH] SPF: fix memory accounting for error case
---
src/spf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/spf.c b/src/spf.c
index db6eea3a8..a8c0f75c4 100644
--- a/src/spf.c
+++ b/src/spf.c
@@ -204,7 +204,7 @@ spf_nxdomain = SPF_dns_rr_new_init(spf_dns_server,
"", ns_t_any, 24 * 60 * 60, HOST_NOT_FOUND);
if (!spf_nxdomain)
{
- free(spf_dns_server);
+ store_free(spf_dns_server);
return NULL;
}
--
2.35.1

View File

@ -1,27 +0,0 @@
modified for Gentoo, removed Changelog
From a8786a66feb3c003c74551399b345b1634cc6739 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Thu, 4 May 2023 15:41:46 +0100
Subject: [PATCH 1/3] Fix variable initialisation in smtp transport. Bug 2996
---
doc/ChangeLog | 8 ++++++++
src/transports/smtp.c | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
--- a/src/transports/smtp.c
+++ b/src/transports/smtp.c
@@ -4950,11 +4950,11 @@ Returns: nothing
void
smtp_transport_closedown(transport_instance *tblock)
{
smtp_transport_options_block * ob = SOB tblock->options_block;
client_conn_ctx cctx;
-smtp_context sx;
+smtp_context sx = {0};
uschar buffer[256];
uschar inbuffer[4096];
uschar outbuffer[16];
/*XXX really we need an active-smtp-client ctx, rather than assuming stdout */