git: 003482675264 - main - mail/exim: fix update to 4.96 by adding missing patches

From: Kurt Jaeger <pi_at_FreeBSD.org>
Date: Fri, 26 May 2023 18:34:21 UTC
The branch main has been updated by pi:

URL: https://cgit.FreeBSD.org/ports/commit/?id=003482675264a732124cbd65b3a76cb67badd49a

commit 003482675264a732124cbd65b3a76cb67badd49a
Author:     Kurt Jaeger <pi@FreeBSD.org>
AuthorDate: 2023-05-26 18:33:29 +0000
Commit:     Kurt Jaeger <pi@FreeBSD.org>
CommitDate: 2023-05-26 18:33:29 +0000

    mail/exim: fix update to 4.96 by adding missing patches
    
    PR:             265098
    Reported by:    David Siebuerger <drs-freebsd@sieborger.nom.za>
---
 ...-attempt-to-rewrite-a-malformed-address.-.patch |  57 +++++
 ...-SPF-fix-memory-accounting-for-error-case.patch |  25 +++
 ...5_08-Fix-regex-n-use-after-free.-Bug-2915.patch | 193 +++++++++++++++++
 .../75_09-Fix-non-WITH_CONTENT_SCAN-build.patch    |  58 ++++++
 .../75_10-Fix-non-WITH_CONTENT_SCAN-build-2.patch  | 135 ++++++++++++
 .../75_11-Fix-non-WITH_CONTENT_SCAN-build-3.patch  |  45 ++++
 ...ix-for-clients-offering-no-TLS-extensions.patch | 114 ++++++++++
 ...-Build-with-libopendmarc-1.4.x-fixes-2728.patch |  88 ++++++++
 ...RC-fix-use-after-free-in-dmarc_dns_lookup.patch |  39 ++++
 .../75_22-Fix-daemon-startup.-Bug-2930.patch       |  68 ++++++
 ..._23-Fix-reccipients-after-run.-.-Bug-2929.patch |  45 ++++
 ...substring-capture-variables-for-null-matc.patch |  79 +++++++
 ...ubstring-capture-variables-for-null-match.patch |  94 +++++++++
 ...ex-substring-capture-commentary.-Bug-2933.patch |  48 +++++
 ...n-preloading-creds-do-the-server-certs-be.patch | 232 +++++++++++++++++++++
 ...-double-expansion-of-tls_verify_certifica.patch | 217 +++++++++++++++++++
 .../75_50-Fix-logging-of-max-size-log-line.patch   |  82 ++++++++
 ...ion-on-dns_again_means_nonexist.-Bug-2911.patch |  76 +++++++
 ...r-smtp-socket-explicitly-on-connect-ACL-d.patch |  50 +++++
 ...-tls_eccurve-setting-explicit-curve-group.patch | 184 ++++++++++++++++
 ...-tls_eccurve-on-earlier-versions-than-3.0.patch |  42 ++++
 ...-conns-rejected-for-bad-ALPN-with-the-off.patch |  99 +++++++++
 ...-check-dns_again_means_nonexist-for-TLSA-.patch |  96 +++++++++
 .../debian/75_66-Fix-crash-in-expansions.patch     |  84 ++++++++
 24 files changed, 2250 insertions(+)

diff --git a/mail/exim/files/debian/75_01-Fix-exit-on-attempt-to-rewrite-a-malformed-address.-.patch b/mail/exim/files/debian/75_01-Fix-exit-on-attempt-to-rewrite-a-malformed-address.-.patch
new file mode 100644
index 000000000000..bf0f64942d7d
--- /dev/null
+++ b/mail/exim/files/debian/75_01-Fix-exit-on-attempt-to-rewrite-a-malformed-address.-.patch
@@ -0,0 +1,57 @@
+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/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -1,9 +1,14 @@
+ This document describes *changes* to previous versions, that might
+ affect Exim's operation, with an unchanged configuration file.  For new
+ options, and new features, see the NewStuff file next to this ChangeLog.
+ 
++JH/04 Bug 2903: avoid exit on an attempt to rewrite a malformed address.
++      Make the rewrite never match and keep the logging.  Trust the
++      admin to be using verify=header-syntax (to actually reject the message).
++
++
+ Exim version 4.96
+ -----------------
+ 
+ JH/01 Move the wait-for-next-tick (needed for unique messmage IDs) from
+       after reception to before a subsequent reception.  This should
+--- 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,
diff --git a/mail/exim/files/debian/75_05-SPF-fix-memory-accounting-for-error-case.patch b/mail/exim/files/debian/75_05-SPF-fix-memory-accounting-for-error-case.patch
new file mode 100644
index 000000000000..e474acf6f54d
--- /dev/null
+++ b/mail/exim/files/debian/75_05-SPF-fix-memory-accounting-for-error-case.patch
@@ -0,0 +1,25 @@
+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
+
diff --git a/mail/exim/files/debian/75_08-Fix-regex-n-use-after-free.-Bug-2915.patch b/mail/exim/files/debian/75_08-Fix-regex-n-use-after-free.-Bug-2915.patch
new file mode 100644
index 000000000000..2429e9ff55b9
--- /dev/null
+++ b/mail/exim/files/debian/75_08-Fix-regex-n-use-after-free.-Bug-2915.patch
@@ -0,0 +1,193 @@
+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 ++
+ 7 files changed, 55 insertions(+), 17 deletions(-)
+
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -4,15 +4,21 @@
+ 
+ JH/04 Bug 2903: avoid exit on an attempt to rewrite a malformed address.
+       Make the rewrite never match and keep the logging.  Trust the
+       admin to be using verify=header-syntax (to actually reject the message).
+ 
++JH/08 Bug 2915: Fix use-after-free for $regex<n> variables. Previously when
++      more than one message arrived in a single connection a reference from
++      the earlier message could be re-used.  Often a sigsegv resulted.
++      These variables were introduced in Exim 4.87.
++      Debug help from Graeme Fowler.
++
+ 
+ Exim version 4.96
+ -----------------
+ 
+-JH/01 Move the wait-for-next-tick (needed for unique messmage IDs) from
++JH/01 Move the wait-for-next-tick (needed for unique message IDs) from
+       after reception to before a subsequent reception.  This should
+       mean slightly faster delivery, and also confirmation of reception
+       to senders.
+ 
+ JH/02 Move from using the pcre library to pcre2.  The former is no longer
+--- 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 */
diff --git a/mail/exim/files/debian/75_09-Fix-non-WITH_CONTENT_SCAN-build.patch b/mail/exim/files/debian/75_09-Fix-non-WITH_CONTENT_SCAN-build.patch
new file mode 100644
index 000000000000..6071fa7c5bf4
--- /dev/null
+++ b/mail/exim/files/debian/75_09-Fix-non-WITH_CONTENT_SCAN-build.patch
@@ -0,0 +1,58 @@
+From d8ecc7bf97934a1e2244788c610c958cacd740bd Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Wed, 31 Aug 2022 17:03:37 +0100
+Subject: [PATCH 1/3] Fix non-WITH_CONTENT_SCAN build.
+
+Broken-by: 4e9ed49f8f
+---
+ src/exim.c  | 11 +++++++++++
+ src/regex.c | 10 ----------
+ 2 files changed, 11 insertions(+), 10 deletions(-)
+
+--- a/src/exim.c
++++ b/src/exim.c
+@@ -1677,10 +1677,21 @@
+   if ((s = expand_string(big_buffer))) printf("%s\n", CS s);
+   else printf("Failed: %s\n", expand_string_message);
+ }
+ 
+ 
++/* reset regex expansion variables */
++void
++regex_vars_clear(void)
++{
++regex_match_string = NULL;
++for (int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
++}
++
++
++
++
+ 
+ /*************************************************
+ *          Entry point and high-level code       *
+ *************************************************/
+ 
+--- a/src/regex.c
++++ b/src/regex.c
+@@ -95,20 +95,10 @@
+ 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)
+ {
+ unsigned long mbox_size;
+ FILE * mbox_file;
diff --git a/mail/exim/files/debian/75_10-Fix-non-WITH_CONTENT_SCAN-build-2.patch b/mail/exim/files/debian/75_10-Fix-non-WITH_CONTENT_SCAN-build-2.patch
new file mode 100644
index 000000000000..0a8ed514ffe8
--- /dev/null
+++ b/mail/exim/files/debian/75_10-Fix-non-WITH_CONTENT_SCAN-build-2.patch
@@ -0,0 +1,135 @@
+From 158dff9936e36a2d31d037d3988b9353458d6471 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Wed, 31 Aug 2022 17:17:59 +0100
+Subject: [PATCH 2/3] Fix non-WITH_CONTENT_SCAN build (2)
+
+Broken-by: d8ecc7bf97
+---
+ src/exim.c      | 13 +------------
+ src/functions.h |  2 +-
+ src/globals.h   |  2 +-
+ src/regex.c     | 10 ++++++++++
+ src/smtp_in.c   |  2 ++
+ 5 files changed, 15 insertions(+), 14 deletions(-)
+
+--- a/src/exim.c
++++ b/src/exim.c
+@@ -1677,21 +1677,10 @@
+   if ((s = expand_string(big_buffer))) printf("%s\n", CS s);
+   else printf("Failed: %s\n", expand_string_message);
+ }
+ 
+ 
+-/* reset regex expansion variables */
+-void
+-regex_vars_clear(void)
+-{
+-regex_match_string = NULL;
+-for (int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
+-}
+-
+-
+-
+-
+ 
+ /*************************************************
+ *          Entry point and high-level code       *
+ *************************************************/
+ 
+@@ -6085,17 +6074,17 @@
+   deliver_domain_orig = NULL;
+   deliver_host = deliver_host_address = NULL;
+   dnslist_domain = dnslist_matched = NULL;
+ #ifdef WITH_CONTENT_SCAN
+   malware_name = NULL;
++  regex_vars_clear();
+ #endif
+   callout_address = NULL;
+   sending_ip_address = NULL;
+   deliver_localpart_data = deliver_domain_data =
+   recipient_data = sender_data = NULL;
+   acl_var_m = NULL;
+-  regex_vars_clear();
+ 
+   store_reset(reset_point);
+   }
+ 
+ exim_exit(EXIT_SUCCESS);   /* Never returns */
+--- a/src/functions.h
++++ b/src/functions.h
+@@ -432,15 +432,15 @@
+ extern BOOL    receive_msg(BOOL);
+ extern int_eximarith_t receive_statvfs(BOOL, int *);
+ extern void    receive_swallow_smtp(void);
+ #ifdef WITH_CONTENT_SCAN
+ extern int     regex(const uschar **);
++extern void    regex_vars_clear(void);
+ #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.h
++++ b/src/globals.h
+@@ -895,16 +895,16 @@
+ #ifndef DISABLE_PIPE_CONNECT
+ extern const pcre2_code  *regex_EARLY_PIPE;  /* For recognizing PIPE_CONNCT */
+ #endif
+ extern const pcre2_code  *regex_ismsgid;     /* Compiled r.e. for message ID */
+ extern const pcre2_code  *regex_smtp_code;   /* For recognizing SMTP codes */
+-extern const uschar *regex_vars[];           /* $regexN variables */
+ #ifdef WHITELIST_D_MACROS
+ extern const pcre2_code  *regex_whitelisted_macro; /* For -D macro values */
+ #endif
+ #ifdef WITH_CONTENT_SCAN
+ extern uschar *regex_match_string;     /* regex that matched a line (regex ACL condition) */
++extern const uschar *regex_vars[];
+ #endif
+ extern int     remote_delivery_count;  /* Number of remote addresses */
+ extern int     remote_max_parallel;    /* Maximum parallel delivery */
+ extern uschar *remote_sort_domains;    /* Remote domain sorting order */
+ extern retry_config *retries;          /* Chain of retry config information */
+--- a/src/regex.c
++++ b/src/regex.c
+@@ -95,10 +95,20 @@
+ 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)
+ {
+ unsigned long mbox_size;
+ FILE * mbox_file;
+--- a/src/smtp_in.c
++++ b/src/smtp_in.c
+@@ -2155,11 +2155,13 @@
+ prdr_requested = FALSE;
+ #endif
+ #ifdef SUPPORT_I18N
+ message_smtputf8 = FALSE;
+ #endif
++#ifdef WITH_CONTENT_SCAN
+ regex_vars_clear();
++#endif
+ 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 */
diff --git a/mail/exim/files/debian/75_11-Fix-non-WITH_CONTENT_SCAN-build-3.patch b/mail/exim/files/debian/75_11-Fix-non-WITH_CONTENT_SCAN-build-3.patch
new file mode 100644
index 000000000000..b06d89679b7e
--- /dev/null
+++ b/mail/exim/files/debian/75_11-Fix-non-WITH_CONTENT_SCAN-build-3.patch
@@ -0,0 +1,45 @@
+From 32da6327e434e986a18b75a84f2d8c687ba14619 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Thu, 1 Sep 2022 15:54:35 +0100
+Subject: [PATCH 3/3] Fix non-WITH_CONTENT_SCAN build (3)
+
+Broken-by: d8ecc7bf97
+---
+ src/expand.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/expand.c b/src/expand.c
+index 89de56255..831ca2b75 100644
+--- a/src/expand.c
++++ b/src/expand.c
+@@ -1869,6 +1869,7 @@ if (Ustrncmp(name, "auth", 4) == 0)
+   if (!*endptr && n != 0 && n <= AUTH_VARS)
+     return auth_vars[n-1] ? auth_vars[n-1] : US"";
+   }
++#ifdef WITH_CONTENT_SCAN
+ else if (Ustrncmp(name, "regex", 5) == 0)
+   {
+   uschar *endptr;
+@@ -1876,6 +1877,7 @@ else if (Ustrncmp(name, "regex", 5) == 0)
+   if (!*endptr && n != 0 && n <= REGEX_VARS)
+     return regex_vars[n-1] ? regex_vars[n-1] : US"";
+   }
++#endif
+ 
+ /* For all other variables, search the table */
+ 
+@@ -8715,9 +8717,11 @@ assert_variable_notin() treats as const, so deconst is safe. */
+ for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
+   assert_variable_notin(US"auth<n>", US auth_vars[i], &e);
+ 
++#ifdef WITH_CONTENT_SCAN
+ /* check regex<n> variables. assert_variable_notin() treats as const. */
+ for (int i = 0; i < REGEX_VARS; i++) if (regex_vars[i])
+   assert_variable_notin(US"regex<n>", US regex_vars[i], &e);
++#endif
+ 
+ /* check known-name variables */
+ for (var_entry * v = var_table; v < var_table + var_table_size; v++)
+-- 
+2.35.1
+
diff --git a/mail/exim/files/debian/75_16-GnuTLS-fix-for-clients-offering-no-TLS-extensions.patch b/mail/exim/files/debian/75_16-GnuTLS-fix-for-clients-offering-no-TLS-extensions.patch
new file mode 100644
index 000000000000..ae2fa16f51ea
--- /dev/null
+++ b/mail/exim/files/debian/75_16-GnuTLS-fix-for-clients-offering-no-TLS-extensions.patch
@@ -0,0 +1,114 @@
+From ece23f05d6a430a461a75639197271c23f6858ec Mon Sep 17 00:00:00 2001
+From: Jasen Betts <jasen@xnet.co.nz>
+Date: Fri, 30 Sep 2022 13:49:41 +0100
+Subject: [PATCH] GnuTLS: fix for clients offering no TLS extensions
+
+---
+ doc/ChangeLog              |  3 +++
+ src/tls-gnu.c                  |  3 ++-
+ src/tls-openssl.c              | 39 +++++++++++++++---------------
+ test/confs/2091                    |  1 +
+ test/log/2091                      |  3 +++
+ test/scripts/2090-GnuTLS-ALPN/2091 | 19 +++++++++++++++
+ test/stdout/2091                   | 21 ++++++++++++++++
+ 7 files changed, 68 insertions(+), 21 deletions(-)
+ create mode 120000 test/confs/2091
+ create mode 100644 test/log/2091
+ create mode 100644 test/scripts/2090-GnuTLS-ALPN/2091
+ create mode 100644 test/stdout/2091
+
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -10,10 +10,14 @@
+       more than one message arrived in a single connection a reference from
+       the earlier message could be re-used.  Often a sigsegv resulted.
+       These variables were introduced in Exim 4.87.
+       Debug help from Graeme Fowler.
+ 
++JH/10 GnuTLS: fix for (IOT?) clients offering no TLS extensions at all.
++      Find and fix by Jasen Betts.
++
++
+ 
+ Exim version 4.96
+ -----------------
+ 
+ JH/01 Move the wait-for-next-tick (needed for unique message IDs) from
+--- a/src/tls-gnu.c
++++ b/src/tls-gnu.c
+@@ -1130,12 +1130,13 @@
+ static int
+ tls_server_clienthello_cb(gnutls_session_t session, unsigned int htype,
+   unsigned when, unsigned int incoming, const gnutls_datum_t * msg)
+ {
+ /* Call fn for each extension seen.  3.6.3 onwards */
+-return gnutls_ext_raw_parse(NULL, tls_server_clienthello_ext, msg,
++int rc = gnutls_ext_raw_parse(NULL, tls_server_clienthello_ext, msg,
+ 			   GNUTLS_EXT_RAW_FLAG_TLS_CLIENT_HELLO);
++return rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE ? 0 : rc;
+ }
+ 
+ 
+ # ifdef notdef_crashes
+ /* Make a note that we saw a status-response */
+--- a/src/tls-openssl.c
++++ b/src/tls-openssl.c
+@@ -940,40 +940,39 @@
+ 
+ Returns:    nothing
+ */
+ 
+ static void
+-info_callback(SSL *s, int where, int ret)
++info_callback(SSL * s, int where, int ret)
+ {
+ DEBUG(D_tls)
+   {
+-  const uschar * str;
++  gstring * g = NULL;
+ 
+-  if (where & SSL_ST_CONNECT)
+-     str = US"SSL_connect";
+-  else if (where & SSL_ST_ACCEPT)
+-     str = US"SSL_accept";
+-  else
+-     str = US"SSL info (undefined)";
++  if (where & SSL_ST_CONNECT) g = string_append_listele(g, ',', US"SSL_connect");
++  if (where & SSL_ST_ACCEPT)  g = string_append_listele(g, ',', US"SSL_accept");
++  if (where & SSL_CB_LOOP)    g = string_append_listele(g, ',', US"state_chg");
++  if (where & SSL_CB_EXIT)    g = string_append_listele(g, ',', US"hshake_exit");
++  if (where & SSL_CB_READ)    g = string_append_listele(g, ',', US"read");
++  if (where & SSL_CB_WRITE)   g = string_append_listele(g, ',', US"write");
++  if (where & SSL_CB_ALERT)   g = string_append_listele(g, ',', US"alert");
++  if (where & SSL_CB_HANDSHAKE_START) g = string_append_listele(g, ',', US"hshake_start");
++  if (where & SSL_CB_HANDSHAKE_DONE)  g = string_append_listele(g, ',', US"hshake_done");
+ 
+   if (where & SSL_CB_LOOP)
+-     debug_printf("%s: %s\n", str, SSL_state_string_long(s));
++     debug_printf("SSL %s: %s\n", g->s, SSL_state_string_long(s));
+   else if (where & SSL_CB_ALERT)
+-    debug_printf("SSL3 alert %s:%s:%s\n",
+-	  str = where & SSL_CB_READ ? US"read" : US"write",
++    debug_printf("SSL %s %s:%s\n", g->s,
+ 	  SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
+   else if (where & SSL_CB_EXIT)
+     {
+-    if (ret == 0)
+-      debug_printf("%s: failed in %s\n", str, SSL_state_string_long(s));
+-    else if (ret < 0)
+-      debug_printf("%s: error in %s\n", str, SSL_state_string_long(s));
++    if (ret <= 0)
++      debug_printf("SSL %s: %s in %s\n", g->s,
++	ret == 0 ? "failed" : "error", SSL_state_string_long(s));
+     }
+-  else if (where & SSL_CB_HANDSHAKE_START)
+-     debug_printf("%s: hshake start: %s\n", str, SSL_state_string_long(s));
+-  else if (where & SSL_CB_HANDSHAKE_DONE)
+-     debug_printf("%s: hshake done: %s\n", str, SSL_state_string_long(s));
++  else if (where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE))
++     debug_printf("SSL %s: %s\n", g->s, SSL_state_string_long(s));
+   }
+ }
+ 
+ #ifdef OPENSSL_HAVE_KEYLOG_CB
+ static void
diff --git a/mail/exim/files/debian/75_18-Fix-Build-with-libopendmarc-1.4.x-fixes-2728.patch b/mail/exim/files/debian/75_18-Fix-Build-with-libopendmarc-1.4.x-fixes-2728.patch
new file mode 100644
index 000000000000..f261d621d67a
--- /dev/null
+++ b/mail/exim/files/debian/75_18-Fix-Build-with-libopendmarc-1.4.x-fixes-2728.patch
@@ -0,0 +1,88 @@
+From 1561c5d88b3a23a4348d8e3c1ce28554fcbcfe46 Mon Sep 17 00:00:00 2001
+From: "Heiko Schlittermann (HS12-RIPE)" <hs@schlittermann.de>
+Date: Sat, 15 Oct 2022 19:30:58 +0200
+Subject: [PATCH 1/2] Fix: Build with libopendmarc 1.4.x (fixes 2728)
+
+---
+ doc/ChangeLog     | 3 +++
+ src/EDITME            | 7 +++++--
+ src/config.h.defaults | 1 +
+ src/dmarc.c           | 7 ++++++-
+ 4 files changed, 15 insertions(+), 3 deletions(-)
+
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -13,10 +13,13 @@
+       Debug help from Graeme Fowler.
+ 
+ JH/10 GnuTLS: fix for (IOT?) clients offering no TLS extensions at all.
+       Find and fix by Jasen Betts.
+ 
++HS/01 Bug 2728: Introduce EDITME option "DMARC_API" to work around incompatible
++      API changes in libopendmarc.
++
+ 
+ 
+ Exim version 4.96
+ -----------------
+ 
+--- a/src/EDITME
++++ b/src/EDITME
+@@ -600,18 +600,21 @@
+ 
+ # EXPERIMENTAL_DCC=yes
+ 
+ # Uncomment the following line to add DMARC checking capability, implemented
+ # using libopendmarc libraries. You must have SPF and DKIM support enabled also.
+-# Library version libopendmarc-1.4.1-1.fc33.x86_64  (on Fedora 33) is known broken;
+-# 1.3.2-3 works.  I seems that the OpenDMARC project broke their API.
+ # SUPPORT_DMARC=yes
+ # CFLAGS += -I/usr/local/include
+ # LDFLAGS += -lopendmarc
+ # Uncomment the following if you need to change the default. You can
+ # override it at runtime (main config option dmarc_tld_file)
+ # DMARC_TLD_FILE=/etc/exim/opendmarc.tlds
++#
++# Library version libopendmarc-1.4.1-1.fc33.x86_64  (on Fedora 33) is known broken;
++# 1.3.2-3 works.  It seems that the OpenDMARC project broke their API.
++# Use this option if you need to build with an old library (1.3.x)
++# DMARC_API=100300
+ 
+ # Uncomment the following line to add ARC (Authenticated Received Chain)
+ # support.  You must have SPF and DKIM support enabled also.
+ # EXPERIMENTAL_ARC=yes
+ 
+--- a/src/config.h.defaults
++++ b/src/config.h.defaults
+@@ -148,10 +148,11 @@
+ #define STRING_SPRINTF_BUFFER_SIZE (8192 * 4)
+ 
+ #define SUPPORT_CRYPTEQ
+ #define SUPPORT_DANE
+ #define SUPPORT_DMARC
++#define DMARC_API 100400
+ #define DMARC_TLD_FILE "/etc/exim/opendmarc.tlds"
+ #define SUPPORT_I18N
+ #define SUPPORT_I18N_2008
+ #define SUPPORT_MAILDIR
+ #define SUPPORT_MAILSTORE
+--- a/src/dmarc.c
++++ b/src/dmarc.c
+@@ -457,11 +457,16 @@
+     dkim_result = vs == PDKIM_VERIFY_PASS ? DMARC_POLICY_DKIM_OUTCOME_PASS :
+ 		  vs == PDKIM_VERIFY_FAIL ? DMARC_POLICY_DKIM_OUTCOME_FAIL :
+ 		  vs == PDKIM_VERIFY_INVALID ? DMARC_POLICY_DKIM_OUTCOME_TMPFAIL :
+ 		  DMARC_POLICY_DKIM_OUTCOME_NONE;
+     libdm_status = opendmarc_policy_store_dkim(dmarc_pctx, US sig->domain,
+-					       dkim_result, US"");
++/* The opendmarc project broke its API in a way we can't detect * easily.
++ * The EDITME provides a DMARC_API variable */
++#if DMARC_API >= 100400
++                                               sig->selector,
++#endif
++                                               dkim_result, US"");
+     DEBUG(D_receive)
+       debug_printf("DMARC adding DKIM sender domain = %s\n", sig->domain);
+     if (libdm_status != DMARC_PARSE_OKAY)
+       log_write(0, LOG_MAIN|LOG_PANIC,
+ 		"failure to store dkim (%s) for DMARC: %s",
diff --git a/mail/exim/files/debian/75_19-DMARC-fix-use-after-free-in-dmarc_dns_lookup.patch b/mail/exim/files/debian/75_19-DMARC-fix-use-after-free-in-dmarc_dns_lookup.patch
new file mode 100644
index 000000000000..e8bda9e07b35
--- /dev/null
+++ b/mail/exim/files/debian/75_19-DMARC-fix-use-after-free-in-dmarc_dns_lookup.patch
@@ -0,0 +1,39 @@
+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 2/2] 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/dmarc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/dmarc.c b/src/dmarc.c
+index ad0c26c91..53c2752ac 100644
+--- a/src/dmarc.c
++++ b/src/dmarc.c
+@@ -226,16 +226,17 @@ dns_scan dnss;
+ int rc = dns_lookup(dnsa, string_sprintf("_dmarc.%s", dom), T_TXT, NULL);
+ 
+ if (rc == DNS_SUCCEED)
+   for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr;
+        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;
+ }
+ 
+ 
+ static int
+-- 
+2.35.1
+
diff --git a/mail/exim/files/debian/75_22-Fix-daemon-startup.-Bug-2930.patch b/mail/exim/files/debian/75_22-Fix-daemon-startup.-Bug-2930.patch
new file mode 100644
index 000000000000..2a3434f8b0b1
--- /dev/null
+++ b/mail/exim/files/debian/75_22-Fix-daemon-startup.-Bug-2930.patch
@@ -0,0 +1,68 @@
+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/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -16,10 +16,14 @@
+       Find and fix by Jasen Betts.
+ 
+ HS/01 Bug 2728: Introduce EDITME option "DMARC_API" to work around incompatible
+       API changes in libopendmarc.
+ 
++JH/12 Bug 2930: Fix daemon startup.  When started from any process apart from
++      pid 1, in the normal "background daemon" mode, having to drop process-
++      group leadership also lost track of needing to create listener sockets.
++
+ 
+ 
+ Exim version 4.96
+ -----------------
+ 
+--- 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;
diff --git a/mail/exim/files/debian/75_23-Fix-reccipients-after-run.-.-Bug-2929.patch b/mail/exim/files/debian/75_23-Fix-reccipients-after-run.-.-Bug-2929.patch
new file mode 100644
index 000000000000..1c98ef26083b
--- /dev/null
+++ b/mail/exim/files/debian/75_23-Fix-reccipients-after-run.-.-Bug-2929.patch
@@ -0,0 +1,45 @@
+From 6b331d5834d12bdda21857cd6fffac17038ce3c7 Mon Sep 17 00:00:00 2001
+From: Ruben Jenster <r.jenster@drachenfels.de>
+Date: Thu, 3 Nov 2022 21:38:15 +0000
+Subject: [PATCH 2/2] Fix $reccipients after ${run...}.  Bug 2929
+
+Broken-by: cfe6acff2d
+---
+ doc/ChangeLog | 3 +++
+ src/transport.c   | 3 ++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -20,10 +20,13 @@
+ 
+ JH/12 Bug 2930: Fix daemon startup.  When started from any process apart from
+       pid 1, in the normal "background daemon" mode, having to drop process-
+       group leadership also lost track of needing to create listener sockets.
+ 
++JH/13 Bug 2929: Fix using $recipients after ${run...}.  A change made for 4.96
++      resulted in the variable appearing empty.  Find and fix by Ruben Jenster.
++
+ 
+ 
+ Exim version 4.96
+ -----------------
+ 
+--- a/src/transport.c
++++ b/src/transport.c
+@@ -2342,13 +2342,14 @@
+     /* Handle normal expansion string */
+ 
+     else
+       {
+       const uschar *expanded_arg;
++      BOOL enable_dollar_recipients_g = f.enable_dollar_recipients;
+       f.enable_dollar_recipients = allow_dollar_recipients;
+       expanded_arg = expand_cstring(argv[i]);
+-      f.enable_dollar_recipients = FALSE;
++      f.enable_dollar_recipients = enable_dollar_recipients_g;
+ 
+       if (!expanded_arg)
+         {
+         uschar *msg = string_sprintf("Expansion of \"%s\" "
+           "from command \"%s\" in %s failed: %s",
diff --git a/mail/exim/files/debian/75_31-Fix-regext-substring-capture-variables-for-null-matc.patch b/mail/exim/files/debian/75_31-Fix-regext-substring-capture-variables-for-null-matc.patch
new file mode 100644
index 000000000000..bd250f2b7191
--- /dev/null
+++ b/mail/exim/files/debian/75_31-Fix-regext-substring-capture-variables-for-null-matc.patch
@@ -0,0 +1,79 @@
+From e63825824cc406c160ccbf2b154c5d81b168604a Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Fri, 11 Nov 2022 00:05:59 +0000
+Subject: [PATCH 1/2] Fix regext substring capture variables for null matches. 
+ Bug 2933
+
+broken-by: 59d66fdc13f0
*** 1448 LINES SKIPPED ***