aboutsummaryrefslogtreecommitdiff
path: root/mail/exim
diff options
context:
space:
mode:
authorDima Panov <fluffy@FreeBSD.org>2020-07-17 09:46:00 +0000
committerDima Panov <fluffy@FreeBSD.org>2020-07-17 09:46:00 +0000
commit704f6e9e4f84b9c89c73a7acefb02f2563384c54 (patch)
tree196cfba530003054a8c0d976d4d56d279042ba67 /mail/exim
parent2b4c62b4f925d10219a0ac3d3ca20707b149b2d8 (diff)
downloadports-704f6e9e4f84b9c89c73a7acefb02f2563384c54.tar.gz
ports-704f6e9e4f84b9c89c73a7acefb02f2563384c54.zip
mail/exim: import exim-4.94+fixes branch as state of 2020.07.17
Used git diffs: [02/26] Taint: fix pam expansion condition. Bug 2587 [03/26] Taint: fix listcount expansion operator. Bug 2586 [04/26] Docs: fix mistaken variable name [06/26] Docs: typoes [07/26] Taint: fix multiple ACL actions to properly manage tainted argument data [08/26] Fix -bi. Bug 2590 [09/26] Filters: fix "vacation" in Exim filter. Bug 2593 [10/26] TLS: use RFC 6125 rules for certifucate name checks when CNAMES are present. Bug 2594 [11/26] Taint: fix radius expansion condition [13/26] Taint: fix verify. Bug 2598 [14/26] Fix string_copy() macro to not multiple-eval args. Bug 2603 [15/26] Cutthrough: handle request when a callout-hold is active. Bug 2604 [16/26] Lookups: Fix "subdir" filter on a dsearch. [18/26] Sqlite: fix segfault on bad/missing sqlite_dbfile. Bug 2606 [19/26] Taint: fix ACL "spam" condition, to permit tainted name arguments. [20/26] Fix message-reception clock usage. Bug 2615 [21/26] typoes [22/26] Fix DKIM signing to always ;-terminate. Bug 2295 [23/26] Fix taint trap in parse_fix_phrase(). Bug 2617 [24/26] Taint: fix ACL "spam" condition, to permit tainted name arguments [25/26] Fix debug_print_socket() [26/26] debug_print_socket(): output formatting MFH: 2020Q3
Notes
Notes: svn path=/head/; revision=542419
Diffstat (limited to 'mail/exim')
-rw-r--r--mail/exim/Makefile2
-rw-r--r--mail/exim/files/patch-z0002-Taint-fix-pam-expansion-condition.-Bug-258756
-rw-r--r--mail/exim/files/patch-z0003-Taint-fix-listcount-expansion-operator.-Bug-258643
-rw-r--r--mail/exim/files/patch-z0004-Docs-fix-mistaken-variable-name28
-rw-r--r--mail/exim/files/patch-z0006-Docs-typoes25
-rw-r--r--mail/exim/files/patch-z0007-Taint-fix-multiple-ACL-actions-to-properly-manage-tainted-79
-rw-r--r--mail/exim/files/patch-z0008-Fix-bi.-Bug-259044
-rw-r--r--mail/exim/files/patch-z0009-Filters-fix-vacation-in-Exim-filter.-Bug-259348
-rw-r--r--mail/exim/files/patch-z0010-TLS-use-RFC-6125-rules-for-certifucate-name-checks-when-CN180
-rw-r--r--mail/exim/files/patch-z0011-Taint-fix-radius-expansion-condition40
-rw-r--r--mail/exim/files/patch-z0012-smtp_accept_map_per_host-call-search_tidyup-in-fail-path.-42
-rw-r--r--mail/exim/files/patch-z0013-Taint-fix-verify.-Bug-259850
-rw-r--r--mail/exim/files/patch-z0014-Fix-string_copy-macro-to-not-multiple-eval-args.-Bug-260348
-rw-r--r--mail/exim/files/patch-z0015-Cutthrough-handle-request-when-a-callout-hold-is-active.-B118
-rw-r--r--mail/exim/files/patch-z0016-Lookups-Fix-subdir-filter-on-a-dsearch53
-rw-r--r--mail/exim/files/patch-z0018-Sqlite-fix-segfault-on-bad-missing-sqlite_dbfile.-Bug-260659
-rw-r--r--mail/exim/files/patch-z0019-Taint-fix-ACL-spam-condition-to-permit-tainted-name-argume52
-rw-r--r--mail/exim/files/patch-z0020-Fix-message-reception-clock-usage.-Bug-2615158
-rw-r--r--mail/exim/files/patch-z0021-typoes24
-rw-r--r--mail/exim/files/patch-z0022-Fix-DKIM-signing-to-always-terminate.-Bug-2295193
-rw-r--r--mail/exim/files/patch-z0023-Fix-taint-trap-in-parse_fix_phrase-.-Bug-2617366
-rw-r--r--mail/exim/files/patch-z0024-Taint-fix-ACL-spam-condition-to-permit-tainted-name-argume74
-rw-r--r--mail/exim/files/patch-z0025-Fix-debug_print_socket79
-rw-r--r--mail/exim/files/patch-z0026-debug_print_socket-output-formatting51
24 files changed, 1911 insertions, 1 deletions
diff --git a/mail/exim/Makefile b/mail/exim/Makefile
index 5129a5fa08b0..ae03a638ace0 100644
--- a/mail/exim/Makefile
+++ b/mail/exim/Makefile
@@ -3,7 +3,7 @@
PORTNAME= exim
PORTVERSION?= ${EXIM_VERSION}
-PORTREVISION?= 0
+PORTREVISION?= 1
CATEGORIES= mail
MASTER_SITES= EXIM:exim
MASTER_SITE_SUBDIR= /exim4/:exim \
diff --git a/mail/exim/files/patch-z0002-Taint-fix-pam-expansion-condition.-Bug-2587 b/mail/exim/files/patch-z0002-Taint-fix-pam-expansion-condition.-Bug-2587
new file mode 100644
index 000000000000..cdc7ccda8ed5
--- /dev/null
+++ b/mail/exim/files/patch-z0002-Taint-fix-pam-expansion-condition.-Bug-2587
@@ -0,0 +1,56 @@
+From 173bd1c8f9cf83ad8c0e61a9e32678e7e371d41d Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Tue, 2 Jun 2020 14:50:31 +0100
+Subject: [PATCH 02/26] Taint: fix pam expansion condition. Bug 2587
+
+(cherry picked from commit f7f933a199be8bb7362c715e0040545b514cddca)
+---
+ doc/ChangeLog | 9 +++++++++
+ src/auths/call_pam.c | 5 ++---
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 585deb042..dbdc22117 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -3,6 +3,15 @@ affect Exim's operation, with an unchanged configuration file. For new
+ options, and new features, see the NewStuff file next to this ChangeLog.
+
+
++Since Exim version 4.94
++-----------------------
++
++JH/02 Bug 2587: Fix pam expansion condition. Tainted values are commonly used
++ as arguments, so an implementation trying to copy these into a local
++ buffer was taking a taint-enformance trap. Fix by using dynamically
++ created buffers.
++
++
+ Exim version 4.94
+ -----------------
+
+diff --git src/auths/call_pam.c src/auths/call_pam.c
+index 2959cbbf3..80bb23ec3 100644
+--- src/auths/call_pam.c
++++ src/auths/call_pam.c
+@@ -83,8 +83,7 @@ for (int i = 0; i < num_msg; i++)
+ {
+ case PAM_PROMPT_ECHO_ON:
+ case PAM_PROMPT_ECHO_OFF:
+- arg = string_nextinlist(&pam_args, &sep, big_buffer, big_buffer_size);
+- if (!arg)
++ if (!(arg = string_nextinlist(&pam_args, &sep, NULL, 0)))
+ {
+ arg = US"";
+ pam_arg_ended = TRUE;
+@@ -155,7 +154,7 @@ pam_arg_ended = FALSE;
+ fail. PAM doesn't support authentication with an empty user (it prompts for it,
+ causing a potential mis-interpretation). */
+
+-user = string_nextinlist(&pam_args, &sep, big_buffer, big_buffer_size);
++user = string_nextinlist(&pam_args, &sep, NULL, 0);
+ if (user == NULL || user[0] == 0) return FAIL;
+
+ /* Start off PAM interaction */
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0003-Taint-fix-listcount-expansion-operator.-Bug-2586 b/mail/exim/files/patch-z0003-Taint-fix-listcount-expansion-operator.-Bug-2586
new file mode 100644
index 000000000000..42f01d070507
--- /dev/null
+++ b/mail/exim/files/patch-z0003-Taint-fix-listcount-expansion-operator.-Bug-2586
@@ -0,0 +1,43 @@
+From 63652bbaf66c4bdb388b08fdf3eb8ab1e4d91475 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Tue, 2 Jun 2020 15:03:36 +0100
+Subject: [PATCH 03/26] Taint: fix listcount expansion operator. Bug 2586
+
+(cherry picked from commit 44644c2e404a3ea0191db0b0458e86924fb240bb)
+---
+ doc/ChangeLog | 4 ++++
+ src/expand.c | 3 +--
+
+diff --git doc/ChangeLog doc/ChangeLog
+index dbdc22117..94bcea29b 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -11,6 +11,10 @@ JH/02 Bug 2587: Fix pam expansion condition. Tainted values are commonly used
+ buffer was taking a taint-enformance trap. Fix by using dynamically
+ created buffers.
+
++JH/03 Bug 2586: Fix listcount expansion operator. Using tainted arguments is
++ reasonable, eg. to count headers. Fix by using dynamically created
++ buffers rather than a local,
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/expand.c src/expand.c
+index 26f7f10ac..6ed22c14d 100644
+--- src/expand.c
++++ src/expand.c
+@@ -7208,9 +7208,8 @@ while (*s != 0)
+ {
+ int cnt = 0;
+ int sep = 0;
+- uschar buffer[256];
+
+- while (string_nextinlist(CUSS &sub, &sep, buffer, sizeof(buffer))) cnt++;
++ while (string_nextinlist(CUSS &sub, &sep, NULL, 0)) cnt++;
+ yield = string_fmt_append(yield, "%d", cnt);
+ continue;
+ }
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0004-Docs-fix-mistaken-variable-name b/mail/exim/files/patch-z0004-Docs-fix-mistaken-variable-name
new file mode 100644
index 000000000000..bcf4909ce0fb
--- /dev/null
+++ b/mail/exim/files/patch-z0004-Docs-fix-mistaken-variable-name
@@ -0,0 +1,28 @@
+From aabe0ebe82297d7dec3abdfff9c3b1edc34fd8ab Mon Sep 17 00:00:00 2001
+From: Patrick Boutilier <boutilpj@ednet.ns.ca>
+Date: Tue, 2 Jun 2020 15:16:10 +0100
+Subject: [PATCH 04/26] Docs: fix mistaken variable name
+
+(cherry picked from commit eb55cb1d2c5552209e24345e9d21f83ec1eaccf6)
+---
+ README.UPDATING | 4 ++--
+
+diff --git README.UPDATING README.UPDATING
+index a0afa8df0..708027f2c 100644
+--- README.UPDATING
++++ README.UPDATING
+@@ -31,9 +31,9 @@ Exim version 4.94
+
+ Some Transports now refuse to use tainted data in constructing their delivery
+ location; this WILL BREAK configurations which are not updated accordingly.
+-In particular: any Transport use of $local_user which has been relying upon
++In particular: any Transport use of $local_part which has been relying upon
+ check_local_user far away in the Router to make it safe, should be updated to
+-replace $local_user with $local_part_data.
++replace $local_part with $local_part_data.
+
+ Attempting to remove, in router or transport, a header name that ends with
+ an asterisk (which is a standards-legal name) will now result in all headers
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0006-Docs-typoes b/mail/exim/files/patch-z0006-Docs-typoes
new file mode 100644
index 000000000000..16ec41fe911f
--- /dev/null
+++ b/mail/exim/files/patch-z0006-Docs-typoes
@@ -0,0 +1,25 @@
+From de498d230862bcc49acbc6d5e76c71b1e15596c3 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Tue, 2 Jun 2020 16:34:42 +0100
+Subject: [PATCH 06/26] Docs: typoes
+
+Cherry-picked from: 1195f8f2a4
+---
+ doc/ChangeLog | 2 +-
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 94bcea29b..f858c9121 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -8,7 +8,7 @@ Since Exim version 4.94
+
+ JH/02 Bug 2587: Fix pam expansion condition. Tainted values are commonly used
+ as arguments, so an implementation trying to copy these into a local
+- buffer was taking a taint-enformance trap. Fix by using dynamically
++ buffer was taking a taint-enforcement trap. Fix by using dynamically
+ created buffers.
+
+ JH/03 Bug 2586: Fix listcount expansion operator. Using tainted arguments is
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0007-Taint-fix-multiple-ACL-actions-to-properly-manage-tainted- b/mail/exim/files/patch-z0007-Taint-fix-multiple-ACL-actions-to-properly-manage-tainted-
new file mode 100644
index 000000000000..44cc46634e77
--- /dev/null
+++ b/mail/exim/files/patch-z0007-Taint-fix-multiple-ACL-actions-to-properly-manage-tainted-
@@ -0,0 +1,79 @@
+From 623f07cfdcaca96274ca765d0fcf0761bdf7151b Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Wed, 3 Jun 2020 11:40:17 +0100
+Subject: [PATCH 07/26] Taint: fix multiple ACL actions to properly manage
+ tainted argument data
+
+(cherry picked from commit 12b7f811de4a540d0724585aecfa33b5881e2a30)
+---
+ doc/ChangeLog | 4 +++-
+ src/acl.c | 12 ++++++------
+
+diff --git doc/ChangeLog doc/ChangeLog
+index f858c9121..015959cb6 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -13,7 +13,9 @@ JH/02 Bug 2587: Fix pam expansion condition. Tainted values are commonly used
+
+ JH/03 Bug 2586: Fix listcount expansion operator. Using tainted arguments is
+ reasonable, eg. to count headers. Fix by using dynamically created
+- buffers rather than a local,
++ buffers rather than a local. Do similar fixes for ACL actions "dcc",
++ "log_reject_target", "malware" and "spam"; the arguments are expanded
++ so could be handling tainted values.
+
+
+ Exim version 4.94
+diff --git src/acl.c src/acl.c
+index c1d60bbd9..8619cd5ef 100644
+--- src/acl.c
++++ src/acl.c
+@@ -3349,11 +3349,11 @@ for (; cb; cb = cb->next)
+ {
+ /* Separate the regular expression and any optional parameters. */
+ const uschar * list = arg;
+- uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
++ uschar *ss = string_nextinlist(&list, &sep, NULL, 0);
+ /* Run the dcc backend. */
+ rc = dcc_process(&ss);
+ /* Modify return code based upon the existence of options. */
+- while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
++ while ((ss = string_nextinlist(&list, &sep, NULL, 0)))
+ if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER)
+ rc = FAIL; /* FAIL so that the message is passed to the next ACL */
+ }
+@@ -3514,7 +3514,7 @@ for (; cb; cb = cb->next)
+ int sep = 0;
+ const uschar *s = arg;
+ uschar * ss;
+- while ((ss = string_nextinlist(&s, &sep, big_buffer, big_buffer_size)))
++ while ((ss = string_nextinlist(&s, &sep, NULL, 0)))
+ {
+ if (Ustrcmp(ss, "main") == 0) logbits |= LOG_MAIN;
+ else if (Ustrcmp(ss, "panic") == 0) logbits |= LOG_PANIC;
+@@ -3567,7 +3567,7 @@ for (; cb; cb = cb->next)
+ {
+ /* Separate the regular expression and any optional parameters. */
+ const uschar * list = arg;
+- uschar * ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
++ uschar * ss = string_nextinlist(&list, &sep, NULL, 0);
+ uschar * opt;
+ BOOL defer_ok = FALSE;
+ int timeout = 0;
+@@ -3672,11 +3672,11 @@ for (; cb; cb = cb->next)
+ {
+ /* Separate the regular expression and any optional parameters. */
+ const uschar * list = arg;
+- uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
++ uschar *ss = string_nextinlist(&list, &sep, NULL, 0);
+
+ rc = spam(CUSS &ss);
+ /* Modify return code based upon the existence of options. */
+- while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
++ while ((ss = string_nextinlist(&list, &sep, NULL, 0)))
+ if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER)
+ rc = FAIL; /* FAIL so that the message is passed to the next ACL */
+ }
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0008-Fix-bi.-Bug-2590 b/mail/exim/files/patch-z0008-Fix-bi.-Bug-2590
new file mode 100644
index 000000000000..6c42ea45d7fc
--- /dev/null
+++ b/mail/exim/files/patch-z0008-Fix-bi.-Bug-2590
@@ -0,0 +1,44 @@
+From 0e8319c3edebfec2158fbaa4898af27cb3225c99 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Thu, 4 Jun 2020 15:28:15 +0100
+Subject: [PATCH 08/26] Fix -bi. Bug 2590
+
+ Actual fix from pierre.labastie@neuf.fr ; additional coding and testcase bu jgh
+ Broken-by: bdcc6f2bd5
+
+ (Cherry-picked from: 0e0e171628)
+---
+ doc/ChangeLog | 4 ++++
+ src/exim.c | 2 +-
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 015959cb6..621d5b1b5 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -17,6 +17,10 @@ JH/03 Bug 2586: Fix listcount expansion operator. Using tainted arguments is
+ "log_reject_target", "malware" and "spam"; the arguments are expanded
+ so could be handling tainted values.
+
++JH/04 Bug 2590: Fix -bi (newaliases). A previous code rearrangement had
++ broken the (no-op) support for this sendmail command. Restore it
++ to doing nothing, silently, and returning good status.
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/exim.c src/exim.c
+index a60488e95..6143fe989 100644
+--- src/exim.c
++++ src/exim.c
+@@ -2148,7 +2148,7 @@ on the second character (the one after '-'), to save some effort. */
+ concept of *the* alias file, but since Sun's YP make script calls
+ sendmail this way, some support must be provided. */
+ case 'i':
+- if (!*++argrest) bi_option = TRUE;
++ if (!*argrest) bi_option = TRUE;
+ else badarg = TRUE;
+ break;
+
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0009-Filters-fix-vacation-in-Exim-filter.-Bug-2593 b/mail/exim/files/patch-z0009-Filters-fix-vacation-in-Exim-filter.-Bug-2593
new file mode 100644
index 000000000000..cb3f2c113cd5
--- /dev/null
+++ b/mail/exim/files/patch-z0009-Filters-fix-vacation-in-Exim-filter.-Bug-2593
@@ -0,0 +1,48 @@
+From 701af1005a6effaac5ce249f1c2086dc6c0c2a7f Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Mon, 8 Jun 2020 13:00:55 +0100
+Subject: [PATCH 09/26] Filters: fix "vacation" in Exim filter. Bug 2593
+
+Broken-by: cfb9cf20cb (4.90)
+(cherry picked from commit 59eee1bc902f106d20f507ba16f37cb8ab5a5e8d)
+---
+ doc/ChangeLog | 5 ++
+ src/transports/autoreply.c | 6 +--
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 621d5b1b5..b9c1ec29e 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -21,6 +21,11 @@ JH/04 Bug 2590: Fix -bi (newaliases). A previous code rearrangement had
+ broken the (no-op) support for this sendmail command. Restore it
+ to doing nothing, silently, and returning good status.
+
++JH/05 Bug 2593: Fix "vacation" in Exim filter. Previously, when a "once"
++ record path was given (or the default used) without a leading directory
++ path, an error occurred on trying to open it. Use the transport's working
++ directory.
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/transports/autoreply.c src/transports/autoreply.c
+index 4c2c08b70..865abbf4f 100644
+--- src/transports/autoreply.c
++++ src/transports/autoreply.c
+@@ -474,10 +474,10 @@ if (oncelog && *oncelog && to)
+ else
+ {
+ EXIM_DATUM key_datum, result_datum;
+- uschar * dirname = string_copy(oncelog);
+- uschar * s;
++ uschar * dirname, * s;
+
+- if ((s = Ustrrchr(dirname, '/'))) *s = '\0';
++ dirname = (s = Ustrrchr(oncelog, '/'))
++ ? string_copyn(oncelog, s - oncelog) : NULL;
+ EXIM_DBOPEN(oncelog, dirname, O_RDWR|O_CREAT, ob->mode, &dbm_file);
+ if (!dbm_file)
+ {
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0010-TLS-use-RFC-6125-rules-for-certifucate-name-checks-when-CN b/mail/exim/files/patch-z0010-TLS-use-RFC-6125-rules-for-certifucate-name-checks-when-CN
new file mode 100644
index 000000000000..626d11609e1b
--- /dev/null
+++ b/mail/exim/files/patch-z0010-TLS-use-RFC-6125-rules-for-certifucate-name-checks-when-CN
@@ -0,0 +1,180 @@
+From 3fe5ec41e81831028c992f77a15292872fbbac75 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Thu, 11 Jun 2020 20:45:05 +0100
+Subject: [PATCH 10/26] TLS: use RFC 6125 rules for certifucate name
+ checks when CNAMES are present. Bug 2594
+
+ (cherry picked from commit 0851a3bbf4667081d47f5d85b6b3a5cb33cbdba6)
+---
+ doc/ChangeLog | 7 ++-
+ src/host.c | 17 +++++++
+ src/structs.h | 19 ++++----
+ src/tls-gnu.c | 4 +-
+ src/tls-openssl.c | 20 ++++-----
+
+diff --git doc/ChangeLog doc/ChangeLog
+index b9c1ec29e..612005803 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -26,6 +26,11 @@ JH/05 Bug 2593: Fix "vacation" in Exim filter. Previously, when a "once"
+ path, an error occurred on trying to open it. Use the transport's working
+ directory.
+
++JH/06 Bug 2594: Change the name used for certificate name checks in the smtp
++ transport. Previously it was the name on the DNS A-record; use instead
++ the head of the CNAME chain leading there (if there is one). This seems
++ to align better with RFC 6125.
++
+
+ Exim version 4.94
+ -----------------
+@@ -331,7 +336,7 @@ JH/20 Bug 2389: fix server advertising of usable certificates, under GnuTLS in
+
+ JH/21 The smtp transport option "hosts_noproxy_tls" is now unset by default.
+ A single TCP connection by a client will now hold a TLS connection open
+- for multiple message deliveries, by default. Previoud the default was to
++ for multiple message deliveries, by default. Previously the default was to
+ not do so.
+
+ JH/22 The smtp transport option "hosts_try_dane" now enables all hosts by
+diff --git src/host.c src/host.c
+index 0e0e0130b..817d4446c 100644
+--- src/host.c
++++ src/host.c
+@@ -1950,6 +1950,13 @@ BOOL temp_error = FALSE;
+ int af;
+ #endif
+
++#ifndef DISABLE_TLS
++/* Copy the host name at this point to the value which is used for
++TLS certificate name checking, before anything modifies it. */
++
++host->certname = host->name;
++#endif
++
+ /* Make sure DNS options are set as required. This appears to be necessary in
+ some circumstances when the get..byname() function actually calls the DNS. */
+
+@@ -2117,6 +2124,9 @@ for (int i = 1; i <= times;
+ {
+ host_item *next = store_get(sizeof(host_item), FALSE);
+ next->name = host->name;
++#ifndef DISABLE_TLS
++ next->certname = host->certname;
++#endif
+ next->mx = host->mx;
+ next->address = text_address;
+ next->port = PORT_NONE;
+@@ -2260,6 +2270,13 @@ BOOL v6_find_again = FALSE;
+ BOOL dnssec_fail = FALSE;
+ int i;
+
++#ifndef DISABLE_TLS
++/* Copy the host name at this point to the value which is used for
++TLS certificate name checking, before any CNAME-following modifies it. */
++
++host->certname = host->name;
++#endif
++
+ /* If allow_ip is set, a name which is an IP address returns that value
+ as its address. This is used for MX records when allow_mx_to_ip is set, for
+ those sites that feel they have to flaunt the RFC rules. */
+diff --git src/structs.h src/structs.h
+index c6700d513..206237f04 100644
+--- src/structs.h
++++ src/structs.h
+@@ -80,14 +80,17 @@ typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t;
+
+ typedef struct host_item {
+ struct host_item *next;
+- const uschar *name; /* Host name */
+- const uschar *address; /* IP address in text form */
+- int port; /* port value in host order (if SRV lookup) */
+- int mx; /* MX value if found via MX records */
+- int sort_key; /* MX*1000 plus random "fraction" */
+- int status; /* Usable, unusable, or unknown */
+- int why; /* Why host is unusable */
+- int last_try; /* Time of last try if known */
++ const uschar *name; /* Host name */
++#ifndef DISABLE_TLS
++ const uschar *certname; /* Name used for certificate checks */
++#endif
++ const uschar *address; /* IP address in text form */
++ int port; /* port value in host order (if SRV lookup) */
++ int mx; /* MX value if found via MX records */
++ int sort_key; /* MX*1000 plus random "fraction" */
++ int status; /* Usable, unusable, or unknown */
++ int why; /* Why host is unusable */
++ int last_try; /* Time of last try if known */
+ dnssec_status_t dnssec;
+ } host_item;
+
+diff --git src/tls-gnu.c src/tls-gnu.c
+index 24114f05e..875c82efa 100644
+--- src/tls-gnu.c
++++ src/tls-gnu.c
+@@ -2601,9 +2601,9 @@ if (verify_check_given_host(CUSS &ob->tls_verify_cert_hostnames, host) == OK)
+ {
+ state->exp_tls_verify_cert_hostnames =
+ #ifdef SUPPORT_I18N
+- string_domain_utf8_to_alabel(host->name, NULL);
++ string_domain_utf8_to_alabel(host->certname, NULL);
+ #else
+- host->name;
++ host->certname;
+ #endif
+ DEBUG(D_tls)
+ debug_printf("TLS: server cert verification includes hostname: \"%s\".\n",
+diff --git src/tls-openssl.c src/tls-openssl.c
+index 8c9d8aa69..a62322928 100644
+--- src/tls-openssl.c
++++ src/tls-openssl.c
+@@ -372,10 +372,10 @@ typedef struct ocsp_resp {
+ } ocsp_resplist;
+
+ typedef struct tls_ext_ctx_cb {
+- tls_support * tlsp;
+- uschar *certificate;
+- uschar *privatekey;
+- BOOL is_server;
++ tls_support * tlsp;
++ uschar * certificate;
++ uschar * privatekey;
++ BOOL is_server;
+ #ifndef DISABLE_OCSP
+ STACK_OF(X509) *verify_stack; /* chain for verifying the proof */
+ union {
+@@ -390,14 +390,14 @@ typedef struct tls_ext_ctx_cb {
+ } client;
+ } u_ocsp;
+ #endif
+- uschar *dhparam;
++ uschar * dhparam;
+ /* these are cached from first expand */
+- uschar *server_cipher_list;
++ uschar * server_cipher_list;
+ /* only passed down to tls_error: */
+- host_item *host;
++ host_item * host;
+ const uschar * verify_cert_hostnames;
+ #ifndef DISABLE_EVENT
+- uschar * event_action;
++ uschar * event_action;
+ #endif
+ } tls_ext_ctx_cb;
+
+@@ -2915,9 +2915,9 @@ if (verify_check_given_host(CUSS &ob->tls_verify_cert_hostnames, host) == OK)
+ {
+ cbinfo->verify_cert_hostnames =
+ #ifdef SUPPORT_I18N
+- string_domain_utf8_to_alabel(host->name, NULL);
++ string_domain_utf8_to_alabel(host->certname, NULL);
+ #else
+- host->name;
++ host->certname;
+ #endif
+ DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n",
+ cbinfo->verify_cert_hostnames);
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0011-Taint-fix-radius-expansion-condition b/mail/exim/files/patch-z0011-Taint-fix-radius-expansion-condition
new file mode 100644
index 000000000000..04cb3acd08a3
--- /dev/null
+++ b/mail/exim/files/patch-z0011-Taint-fix-radius-expansion-condition
@@ -0,0 +1,40 @@
+From 94d719d803caf2c0c902dceeb787795eac11a63b Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Fri, 12 Jun 2020 00:46:34 +0100
+Subject: [PATCH 11/26] Taint: fix radius expansion condition
+
+(cherry picked from commit f91219c114a3d95792d052555664a5a7a3984a8d)
+---
+ doc/ChangeLog | 2 +-
+ src/auths/call_radius.c | 3 +--
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 612005803..41d8c6276 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -9,7 +9,7 @@ Since Exim version 4.94
+ JH/02 Bug 2587: Fix pam expansion condition. Tainted values are commonly used
+ as arguments, so an implementation trying to copy these into a local
+ buffer was taking a taint-enforcement trap. Fix by using dynamically
+- created buffers.
++ created buffers. Similar fix for radius expansion condition.
+
+ JH/03 Bug 2586: Fix listcount expansion operator. Using tainted arguments is
+ reasonable, eg. to count headers. Fix by using dynamically created
+diff --git src/auths/call_radius.c src/auths/call_radius.c
+index cc269dcd5..9d10b34c6 100644
+--- src/auths/call_radius.c
++++ src/auths/call_radius.c
+@@ -96,8 +96,7 @@ int sep = 0;
+ #endif
+
+
+-user = string_nextinlist(&radius_args, &sep, big_buffer, big_buffer_size);
+-if (!user) user = US"";
++if (!(user = string_nextinlist(&radius_args, &sep, NULL, 0))) user = US"";
+
+ DEBUG(D_auth) debug_printf("Running RADIUS authentication for user \"%s\" "
+ "and \"%s\"\n", user, radius_args);
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0012-smtp_accept_map_per_host-call-search_tidyup-in-fail-path.- b/mail/exim/files/patch-z0012-smtp_accept_map_per_host-call-search_tidyup-in-fail-path.-
new file mode 100644
index 000000000000..35d0e48879a1
--- /dev/null
+++ b/mail/exim/files/patch-z0012-smtp_accept_map_per_host-call-search_tidyup-in-fail-path.-
@@ -0,0 +1,42 @@
+From c165e95889471bc1a644104dd9a6129c47c56c09 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Fri, 12 Jun 2020 20:43:43 +0100
+Subject: [PATCH 12/26] smtp_accept_map_per_host: call search_tidyup in fail
+ path. Bug 2597
+
+(cherry-picked from: d3a538c8fe)
+---
+ doc/ChangeLog | 5 +++++
+ src/daemon.c | 1 +
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 41d8c6276..92298e7fc 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -31,6 +31,11 @@ JH/06 Bug 2594: Change the name used for certificate name checks in the smtp
+ the head of the CNAME chain leading there (if there is one). This seems
+ to align better with RFC 6125.
+
++JH/07 Bug 2597: Fix a resource leak. Using a lookup in obtaining a value for
++ smtp_accept_max_per_host allocated resources which were not released
++ when the limit was exceeded. This eventually crashed the daemon. Fix
++ by adding a relase action in that path.
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/daemon.c src/daemon.c
+index 2bed143a1..9d491593f 100644
+--- src/daemon.c
++++ src/daemon.c
+@@ -336,6 +336,7 @@ if ((max_for_this_host > 0) &&
+ log_write(L_connection_reject,
+ LOG_MAIN, "Connection from %s refused: too many connections "
+ "from that IP address", whofrom->s);
++ search_tidyup();
+ goto ERROR_RETURN;
+ }
+ }
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0013-Taint-fix-verify.-Bug-2598 b/mail/exim/files/patch-z0013-Taint-fix-verify.-Bug-2598
new file mode 100644
index 000000000000..de23801152f7
--- /dev/null
+++ b/mail/exim/files/patch-z0013-Taint-fix-verify.-Bug-2598
@@ -0,0 +1,50 @@
+From ecf1e77accda6355ebb745a0a03e97ba7eb298b2 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Sun, 14 Jun 2020 22:14:11 +0100
+Subject: [PATCH 13/26] Taint: fix verify. Bug 2598
+
+(cherry-picked from 2b60ac1021 and 9eed571fd7)
+---
+ doc/ChangeLog | 4 +++
+ src/acl.c | 4 +--
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 92298e7fc..859e87b00 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -36,6 +36,10 @@ JH/07 Bug 2597: Fix a resource leak. Using a lookup in obtaining a value for
+ when the limit was exceeded. This eventually crashed the daemon. Fix
+ by adding a relase action in that path.
+
++JH/08 Bug 2598: Fix verify ACL condition. The options for the condition are
++ expanded; previously using tainted values was rejected. Fix by using
++ dynamically-created buffers.
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/acl.c src/acl.c
+index 8619cd5ef..11d1fd028 100644
+--- src/acl.c
++++ src/acl.c
+@@ -1767,7 +1767,7 @@ switch(vp->value)
+ /* Remaining items are optional; they apply to sender and recipient
+ verification, including "header sender" verification. */
+
+-while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
++while ((ss = string_nextinlist(&list, &sep, NULL, 0)))
+ {
+ if (strcmpic(ss, US"defer_ok") == 0) defer_ok = TRUE;
+ else if (strcmpic(ss, US"no_details") == 0) no_details = TRUE;
+@@ -1804,7 +1804,7 @@ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
+ uschar * opt;
+
+ while (isspace(*sublist)) sublist++;
+- while ((opt = string_nextinlist(&sublist, &optsep, buffer, sizeof(buffer))))
++ while ((opt = string_nextinlist(&sublist, &optsep, NULL, 0)))
+ {
+ callout_opt_t * op;
+ double period = 1.0F;
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0014-Fix-string_copy-macro-to-not-multiple-eval-args.-Bug-2603 b/mail/exim/files/patch-z0014-Fix-string_copy-macro-to-not-multiple-eval-args.-Bug-2603
new file mode 100644
index 000000000000..a8420ba00deb
--- /dev/null
+++ b/mail/exim/files/patch-z0014-Fix-string_copy-macro-to-not-multiple-eval-args.-Bug-2603
@@ -0,0 +1,48 @@
+From 5c608b75d5bd734ddca41e4468fb22544ef96265 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Sat, 20 Jun 2020 00:54:05 +0100
+Subject: [PATCH 14/26] Fix string_copy() macro to not multiple-eval args. Bug
+ 2603
+
+Broken-by: a76d120aed
+(cherry picked from commit 80c2ec2e47c556daff00c79ee068ce68f25fd264)
+---
+ doc/ChangeLog | 6 ++++++
+ src/functions.h | 4 ++--
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 859e87b00..1173b3651 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -40,6 +40,12 @@ JH/08 Bug 2598: Fix verify ACL condition. The options for the condition are
+ expanded; previously using tainted values was rejected. Fix by using
+ dynamically-created buffers.
+
++JH/10 Bug 2603: Fix coding of string copying to only evaluate arguments once.
++ Previously a macro used one argument twice; when called with the
++ argument as an expression having side-effects, incorrect operation
++ resulted. Use an inlineable function.
++
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/functions.h src/functions.h
+index 0028deb0d..0050cdeeb 100644
+--- src/functions.h
++++ src/functions.h
+@@ -767,9 +767,9 @@ string_copy_trc(const uschar * s, const char * func, int line)
+ /* Simple string-copy functions maintaining the taint */
+
+ #define string_copyn(s, len) \
+- string_copyn_taint_trc((s), (len), is_tainted(s), __FUNCTION__, __LINE__)
++ string_copyn_trc((s), (len), __FUNCTION__, __LINE__)
+ #define string_copy(s) \
+- string_copy_taint_trc((s), is_tainted(s), __FUNCTION__, __LINE__)
++ string_copy_trc((s), __FUNCTION__, __LINE__)
+
+
+ /*************************************************
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0015-Cutthrough-handle-request-when-a-callout-hold-is-active.-B b/mail/exim/files/patch-z0015-Cutthrough-handle-request-when-a-callout-hold-is-active.-B
new file mode 100644
index 000000000000..50e65bd87024
--- /dev/null
+++ b/mail/exim/files/patch-z0015-Cutthrough-handle-request-when-a-callout-hold-is-active.-B
@@ -0,0 +1,118 @@
+From cdee8a5f76cc013de5622112cd04e42d0dcf333b Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Mon, 22 Jun 2020 17:27:18 +0100
+Subject: [PATCH 15/26] Cutthrough: handle request when a callout-hold is
+ active. Bug 2604
+
+(cherry picked from commit 99bfcf2b678e7bd8125a7eb44409e46549bfc111)
+---
+ doc/ChangeLog | 4 +++
+ src/acl.c | 50 +++++++++++++++++--------------
+ src/verify.c | 4 +--
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 1173b3651..de11b4f09 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -45,6 +45,10 @@ JH/10 Bug 2603: Fix coding of string copying to only evaluate arguments once.
+ argument as an expression having side-effects, incorrect operation
+ resulted. Use an inlineable function.
+
++JH/11 Bug 2604: Fix request to cutthrough-deliver when a connection is already
++ held open for a verify callout. Previously this wan not accounted for
++ and a corrupt onward SMTP conversation resulted.
++
+
+
+ Exim version 4.94
+diff --git src/acl.c src/acl.c
+index 11d1fd028..62cb68561 100644
+--- src/acl.c
++++ src/acl.c
+@@ -3264,37 +3264,41 @@ for (; cb; cb = cb->next)
+ the case where both sides handle prdr and this-node prdr acl
+ is "accept" */
+ ignored = US"PRDR active";
++ else if (f.deliver_freeze)
++ ignored = US"frozen";
++ else if (f.queue_only_policy)
++ ignored = US"queue-only";
++ else if (fake_response == FAIL)
++ ignored = US"fakereject";
++ else if (rcpt_count != 1)
++ ignored = US"nonfirst rcpt";
++ else if (cutthrough.delivery)
++ ignored = US"repeated";
++ else if (cutthrough.callout_hold_only)
++ {
++ DEBUG(D_acl)
++ debug_printf_indent(" cutthrough request upgrades callout hold\n");
++ cutthrough.callout_hold_only = FALSE;
++ cutthrough.delivery = TRUE; /* control accepted */
++ }
+ else
+ {
+- if (f.deliver_freeze)
+- ignored = US"frozen";
+- else if (f.queue_only_policy)
+- ignored = US"queue-only";
+- else if (fake_response == FAIL)
+- ignored = US"fakereject";
+- else
++ cutthrough.delivery = TRUE; /* control accepted */
++ while (*p == '/')
+ {
+- if (rcpt_count == 1)
++ const uschar * pp = p+1;
++ if (Ustrncmp(pp, "defer=", 6) == 0)
+ {
+- cutthrough.delivery = TRUE; /* control accepted */
+- while (*p == '/')
+- {
+- const uschar * pp = p+1;
+- if (Ustrncmp(pp, "defer=", 6) == 0)
+- {
+- pp += 6;
+- if (Ustrncmp(pp, "pass", 4) == 0) cutthrough.defer_pass = TRUE;
+- /* else if (Ustrncmp(pp, "spool") == 0) ; default */
+- }
+- else
+- while (*pp && *pp != '/') pp++;
+- p = pp;
+- }
++ pp += 6;
++ if (Ustrncmp(pp, "pass", 4) == 0) cutthrough.defer_pass = TRUE;
++ /* else if (Ustrncmp(pp, "spool") == 0) ; default */
+ }
+ else
+- ignored = US"nonfirst rcpt";
++ while (*pp && *pp != '/') pp++;
++ p = pp;
+ }
+ }
++
+ DEBUG(D_acl) if (ignored)
+ debug_printf(" cutthrough request ignored on %s item\n", ignored);
+ }
+diff --git src/verify.c src/verify.c
+index fba1f6e9e..5f4181de9 100644
+--- src/verify.c
++++ src/verify.c
+@@ -875,12 +875,12 @@ tls_retry_connection:
+ case PENDING_OK: done = TRUE;
+ new_address_record.result = ccache_accept;
+ break;
+- case FAIL: done = TRUE;
++ case FAIL: done = TRUE;
+ yield = FAIL;
+ *failure_ptr = US"recipient";
+ new_address_record.result = ccache_reject;
+ break;
+- default: break;
++ default: break;
+ }
+ break;
+
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0016-Lookups-Fix-subdir-filter-on-a-dsearch b/mail/exim/files/patch-z0016-Lookups-Fix-subdir-filter-on-a-dsearch
new file mode 100644
index 000000000000..f2e46b49a370
--- /dev/null
+++ b/mail/exim/files/patch-z0016-Lookups-Fix-subdir-filter-on-a-dsearch
@@ -0,0 +1,53 @@
+From 777ee8ae75277c05fb72cc94f568ba4d2bfe15a6 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Thu, 25 Jun 2020 11:16:54 +0100
+Subject: [PATCH 16/26] Lookups: Fix "subdir" filter on a dsearch.
+
+(cherry picked from commit e0e21929b7426b9b5bbf5e3747797043801b1151)
+---
+ doc/ChangeLog | 2 ++
+ src/lookups/dsearch.c | 7 +++----
+
+diff --git doc/ChangeLog doc/ChangeLog
+index de11b4f09..bae9abb85 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -49,6 +49,8 @@ JH/11 Bug 2604: Fix request to cutthrough-deliver when a connection is already
+ held open for a verify callout. Previously this wan not accounted for
+ and a corrupt onward SMTP conversation resulted.
+
++JH/13 Fix dsearch "subdir" filter to ignore ".". Previously only ".." was
++ excluded, not matching the documentation.
+
+
+ Exim version 4.94
+diff --git src/lookups/dsearch.c src/lookups/dsearch.c
+index 455273fb1..501293ac0 100644
+--- src/lookups/dsearch.c
++++ src/lookups/dsearch.c
+@@ -125,8 +125,7 @@ if ( Ulstat(filename, &statbuf) >= 0
+ && S_ISDIR(statbuf.st_mode)
+ && ( flags & FILTER_DIR
+ || keystring[0] != '.'
+- || keystring[1] != '.'
+- || keystring[1] && keystring[2]
++ || keystring[1] && keystring[1] != '.'
+ ) ) ) )
+ {
+ /* Since the filename exists in the filesystem, we can return a
+@@ -135,10 +134,10 @@ if ( Ulstat(filename, &statbuf) >= 0
+ return OK;
+ }
+
+-if (errno == ENOENT) return FAIL;
++if (errno == ENOENT || errno == 0) return FAIL;
+
+ save_errno = errno;
+-*errmsg = string_sprintf("%s: lstat failed", filename);
++*errmsg = string_sprintf("%s: lstat: %s", filename, strerror(errno));
+ errno = save_errno;
+ return DEFER;
+ }
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0018-Sqlite-fix-segfault-on-bad-missing-sqlite_dbfile.-Bug-2606 b/mail/exim/files/patch-z0018-Sqlite-fix-segfault-on-bad-missing-sqlite_dbfile.-Bug-2606
new file mode 100644
index 000000000000..61d4d4a6af65
--- /dev/null
+++ b/mail/exim/files/patch-z0018-Sqlite-fix-segfault-on-bad-missing-sqlite_dbfile.-Bug-2606
@@ -0,0 +1,59 @@
+From 2be77199fc9009ab796ad2d67eed20d8da4773c7 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Sun, 28 Jun 2020 15:24:21 +0100
+Subject: [PATCH 18/26] Sqlite: fix segfault on bad/missing sqlite_dbfile.
+ Bug 2606
+
+(cherry picked from commit 3d0472791a0928963a3f8184fe28479e80d1a47d)
+---
+ doc/ChangeLog | 3 +++
+ src/lookups/sqlite.c | 13 ++++++++++---
+
+diff --git doc/ChangeLog doc/ChangeLog
+index bae9abb85..8a13bda87 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -52,6 +52,9 @@ JH/11 Bug 2604: Fix request to cutthrough-deliver when a connection is already
+ JH/13 Fix dsearch "subdir" filter to ignore ".". Previously only ".." was
+ excluded, not matching the documentation.
+
++JH/14 Bug 2606: Fix a segfault in sqlite lookups. When no, or a bad, filename
++ was given for the sqlite_dbfile a trap resulted.
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/lookups/sqlite.c src/lookups/sqlite.c
+index dc4439153..1638ea401 100644
+--- src/lookups/sqlite.c
++++ src/lookups/sqlite.c
+@@ -24,16 +24,23 @@ sqlite_open(const uschar * filename, uschar ** errmsg)
+ sqlite3 *db = NULL;
+ int ret;
+
+-if (!filename || !*filename) filename = sqlite_dbfile;
+-if (*filename != '/')
++if (!filename || !*filename)
++ {
++ DEBUG(D_lookup) debug_printf_indent("Using sqlite_dbfile: %s\n", sqlite_dbfile);
++ filename = sqlite_dbfile;
++ }
++if (!filename || *filename != '/')
+ *errmsg = US"absolute file name expected for \"sqlite\" lookup";
+ else if ((ret = sqlite3_open(CCS filename, &db)) != 0)
+ {
+ *errmsg = (void *)sqlite3_errmsg(db);
++ sqlite3_close(db);
++ db = NULL;
+ DEBUG(D_lookup) debug_printf_indent("Error opening database: %s\n", *errmsg);
+ }
+
+-sqlite3_busy_timeout(db, 1000 * sqlite_lock_timeout);
++if (db)
++ sqlite3_busy_timeout(db, 1000 * sqlite_lock_timeout);
+ return db;
+ }
+
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0019-Taint-fix-ACL-spam-condition-to-permit-tainted-name-argume b/mail/exim/files/patch-z0019-Taint-fix-ACL-spam-condition-to-permit-tainted-name-argume
new file mode 100644
index 000000000000..e9b93e263ad8
--- /dev/null
+++ b/mail/exim/files/patch-z0019-Taint-fix-ACL-spam-condition-to-permit-tainted-name-argume
@@ -0,0 +1,52 @@
+From 5f3e2ac9f39db5c8ef5a408929c8a5aba957b20f Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Mon, 29 Jun 2020 17:26:36 +0100
+Subject: [PATCH 19/26] Taint: fix ACL "spam" condition, to permit tainted
+ name arguments.
+
+Cherry-picked from: 62b2ccce05
+---
+ doc/ChangeLog | 4 ++++
+ src/spam.c | 5 +----
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 8a13bda87..6a867c716 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -55,6 +55,10 @@ JH/13 Fix dsearch "subdir" filter to ignore ".". Previously only ".." was
+ JH/14 Bug 2606: Fix a segfault in sqlite lookups. When no, or a bad, filename
+ was given for the sqlite_dbfile a trap resulted.
+
++JH/15 Fix "spam" ACL condition. Previously, tainted values for the "name"
++ argument resulted in a trap. There is no reason to disallow such; this
++ was a coding error.
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/spam.c src/spam.c
+index 5eff1ad5c..63ced4f65 100644
+--- src/spam.c
++++ src/spam.c
+@@ -190,7 +190,6 @@ spam(const uschar **listptr)
+ int sep = 0;
+ const uschar *list = *listptr;
+ uschar *user_name;
+-uschar user_name_buffer[128];
+ unsigned long mbox_size;
+ FILE *mbox_file;
+ client_conn_ctx spamd_cctx = {.sock = -1};
+@@ -218,9 +217,7 @@ spamd_address_container * sd;
+ result = 0;
+
+ /* find the username from the option list */
+-if ((user_name = string_nextinlist(&list, &sep,
+- user_name_buffer,
+- sizeof(user_name_buffer))) == NULL)
++if (!(user_name = string_nextinlist(&list, &sep, NULL, 0)))
+ {
+ /* no username given, this means no scanning should be done */
+ return FAIL;
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0020-Fix-message-reception-clock-usage.-Bug-2615 b/mail/exim/files/patch-z0020-Fix-message-reception-clock-usage.-Bug-2615
new file mode 100644
index 000000000000..68dbd8d23d0d
--- /dev/null
+++ b/mail/exim/files/patch-z0020-Fix-message-reception-clock-usage.-Bug-2615
@@ -0,0 +1,158 @@
+From cafcab0848e35047a93a8920b5105baf55f8e702 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Tue, 30 Jun 2020 21:16:42 +0100
+Subject: [PATCH 20/26] Fix message-reception clock usage. Bug 2615
+
+Broken-by: 6906c131d1 (4.94)
+(cherry picked from commit c9bce82e3064126be34d85280d0a7fbf65b3abec)
+---
+ doc/ChangeLog | 8 ++++++
+ src/exim.c | 60 +++++++++++++++++++++++++------------------
+ src/functions.h | 1 +
+ src/receive.c | 2 +-
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 6a867c716..80277f979 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -59,6 +59,14 @@ JH/15 Fix "spam" ACL condition. Previously, tainted values for the "name"
+ argument resulted in a trap. There is no reason to disallow such; this
+ was a coding error.
+
++JH/16 Bug 2615: Fix pause during message reception, on systems that have been
++ suspended/resumed. The Linux CLOCK_MONOTONIC does not account for time
++ spent suspended, ignoring the Posix definition. Previously we assumed
++ it did and a constant offset from real time could be used as a correction.
++ Change to using the same clock source for the start-of-message and the
++ post-message next-tick-wait. Also change to using CLOCK_BOOTTIME if it
++ exists, just to get a clock slightly more aligned to reality.
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/exim.c src/exim.c
+index 6143fe989..dde991065 100644
+--- src/exim.c
++++ src/exim.c
+@@ -384,14 +384,20 @@ return 0;
+ *************************************************/
+
+ #ifdef _POSIX_MONOTONIC_CLOCK
+-/* Amount CLOCK_MONOTONIC is behind realtime, at startup. */
++# ifdef CLOCK_BOOTTIME
++# define EXIM_CLOCKTYPE CLOCK_BOOTTIME
++# else
++# define EXIM_CLOCKTYPE CLOCK_MONOTONIC
++# endif
++
++/* Amount EXIM_CLOCK is behind realtime, at startup. */
+ static struct timespec offset_ts;
+
+ static void
+ exim_clock_init(void)
+ {
+ struct timeval tv;
+-if (clock_gettime(CLOCK_MONOTONIC, &offset_ts) != 0) return;
++if (clock_gettime(EXIM_CLOCKTYPE, &offset_ts) != 0) return;
+ (void)gettimeofday(&tv, NULL);
+ offset_ts.tv_sec = tv.tv_sec - offset_ts.tv_sec;
+ offset_ts.tv_nsec = tv.tv_usec * 1000 - offset_ts.tv_nsec;
+@@ -402,6 +408,29 @@ offset_ts.tv_nsec += 1000*1000*1000;
+ #endif
+
+
++void
++exim_gettime(struct timeval * tv)
++{
++#ifdef _POSIX_MONOTONIC_CLOCK
++struct timespec now_ts;
++
++if (clock_gettime(EXIM_CLOCKTYPE, &now_ts) == 0)
++ {
++ now_ts.tv_sec += offset_ts.tv_sec;
++ if ((now_ts.tv_nsec += offset_ts.tv_nsec) >= 1000*1000*1000)
++ {
++ now_ts.tv_sec++;
++ now_ts.tv_nsec -= 1000*1000*1000;
++ }
++ tv->tv_sec = now_ts.tv_sec;
++ tv->tv_usec = now_ts.tv_nsec / 1000;
++ }
++else
++#endif
++ (void)gettimeofday(tv, NULL);
++}
++
++
+ /* Exim uses a time + a pid to generate a unique identifier in two places: its
+ message IDs, and in file names for maildir deliveries. Because some OS now
+ re-use pids within the same second, sub-second times are now being used.
+@@ -428,28 +457,9 @@ exim_wait_tick(struct timeval * tgt_tv, int resolution)
+ struct timeval now_tv;
+ long int now_true_usec;
+
+-#ifdef _POSIX_MONOTONIC_CLOCK
+-struct timespec now_ts;
+-
+-if (clock_gettime(CLOCK_MONOTONIC, &now_ts) == 0)
+- {
+- now_ts.tv_sec += offset_ts.tv_sec;
+- if ((now_ts.tv_nsec += offset_ts.tv_nsec) >= 1000*1000*1000)
+- {
+- now_ts.tv_sec++;
+- now_ts.tv_nsec -= 1000*1000*1000;
+- }
+- now_tv.tv_sec = now_ts.tv_sec;
+- now_true_usec = (now_ts.tv_nsec / (resolution * 1000)) * resolution;
+- now_tv.tv_usec = now_true_usec;
+- }
+-else
+-#endif
+- {
+- (void)gettimeofday(&now_tv, NULL);
+- now_true_usec = now_tv.tv_usec;
+- now_tv.tv_usec = (now_true_usec/resolution) * resolution;
+- }
++exim_gettime(&now_tv);
++now_true_usec = now_tv.tv_usec;
++now_tv.tv_usec = (now_true_usec/resolution) * resolution;
+
+ while (exim_tvcmp(&now_tv, tgt_tv) <= 0)
+ {
+@@ -1728,7 +1738,7 @@ make quite sure. */
+
+ setlocale(LC_ALL, "C");
+
+-/* Get the offset between CLOCK_MONOTONIC and wallclock */
++/* Get the offset between CLOCK_MONOTONIC/CLOCK_BOOTTIME and wallclock */
+
+ #ifdef _POSIX_MONOTONIC_CLOCK
+ exim_clock_init();
+diff --git src/functions.h src/functions.h
+index 0050cdeeb..8b17531ed 100644
+--- src/functions.h
++++ src/functions.h
+@@ -234,6 +234,7 @@ extern void msg_event_raise(const uschar *, const address_item *);
+ extern int exim_chown_failure(int, const uschar*, uid_t, gid_t);
+ extern const uschar * exim_errstr(int);
+ extern void exim_exit(int) NORETURN;
++extern void exim_gettimg(struct timeval *);
+ extern void exim_nullstd(void);
+ extern void exim_setugid(uid_t, gid_t, BOOL, uschar *);
+ extern void exim_underbar_exit(int) NORETURN;
+diff --git src/receive.c src/receive.c
+index 0fbd35f82..0db897e9e 100644
+--- src/receive.c
++++ src/receive.c
+@@ -1784,7 +1784,7 @@ if (sender_host_address) dmarc_init(); /* initialize libopendmarc */
+ ids, and fractions of a second are required. See the comments that precede the
+ message id creation below. */
+
+-(void)gettimeofday(&message_id_tv, NULL);
++exim_gettime(&message_id_tv);
+
+ /* For other uses of the received time we can operate with granularity of one
+ second, and for that we use the global variable received_time. This is for
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0021-typoes b/mail/exim/files/patch-z0021-typoes
new file mode 100644
index 000000000000..d7de1be5a89f
--- /dev/null
+++ b/mail/exim/files/patch-z0021-typoes
@@ -0,0 +1,24 @@
+From 436c0d208b49421d3d126f7c284bc3130b50ff14 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Fri, 3 Jul 2020 20:35:58 +0100
+Subject: [PATCH 21/26] typoes
+
+---
+ src/functions.h | 2 +-
+
+diff --git src/functions.h src/functions.h
+index 8b17531ed..afe9f1bf4 100644
+--- src/functions.h
++++ src/functions.h
+@@ -234,7 +234,7 @@ extern void msg_event_raise(const uschar *, const address_item *);
+ extern int exim_chown_failure(int, const uschar*, uid_t, gid_t);
+ extern const uschar * exim_errstr(int);
+ extern void exim_exit(int) NORETURN;
+-extern void exim_gettimg(struct timeval *);
++extern void exim_gettime(struct timeval *);
+ extern void exim_nullstd(void);
+ extern void exim_setugid(uid_t, gid_t, BOOL, uschar *);
+ extern void exim_underbar_exit(int) NORETURN;
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0022-Fix-DKIM-signing-to-always-terminate.-Bug-2295 b/mail/exim/files/patch-z0022-Fix-DKIM-signing-to-always-terminate.-Bug-2295
new file mode 100644
index 000000000000..7525937433ae
--- /dev/null
+++ b/mail/exim/files/patch-z0022-Fix-DKIM-signing-to-always-terminate.-Bug-2295
@@ -0,0 +1,193 @@
+From de99158d2927863a6826c9f5f2c6fa4547326e75 Mon Sep 17 00:00:00 2001
+From: Guillaume Outters <guillaume-exim@outters.eu>
+Date: Mon, 6 Jul 2020 22:31:51 +0100
+Subject: [PATCH 22/26] Fix DKIM signing to always ;-terminate. Bug 2295
+
+(cherry picked from commit 65fe780259d0009354b5dfc9a4f1b48ad6513db2)
+---
+ doc/ChangeLog | 5 ++
+ src/pdkim/pdkim.c | 116 ++++++++++++++++--------------------------
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 80277f979..08c6638a9 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -67,6 +67,11 @@ JH/16 Bug 2615: Fix pause during message reception, on systems that have been
+ post-message next-tick-wait. Also change to using CLOCK_BOOTTIME if it
+ exists, just to get a clock slightly more aligned to reality.
+
++JH/17 Bug 2295: Fix DKIM signing to always semicolon-terminate. Although the
++ RFC says it is optional some validators care. The missing char was not
++ intended but triggered by a line-wrap alignement. Discovery and fix by
++ Guillaume Outters, hacked on by JH.
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/pdkim/pdkim.c src/pdkim/pdkim.c
+index 7712409b5..3a6ca4e91 100644
+--- src/pdkim/pdkim.c
++++ src/pdkim/pdkim.c
+@@ -1111,14 +1111,14 @@ return string_catn(str, US"\r\n\t", 3);
+
+ /*
+ * RFC 5322 specifies that header line length SHOULD be no more than 78
+- * lets make it so!
+ * pdkim_headcat
+ *
+- * returns uschar * (not nul-terminated)
++ * Returns gstring (not nul-terminated) appending to one supplied
+ *
+ * col: this int holds and receives column number (octets since last '\n')
+ * str: partial string to append to
+- * pad: padding, split line or space after before or after eg: ";"
++ * pad: padding, split line or space after before or after eg: ";".
++ * Only the initial charater is used.
+ * intro: - must join to payload eg "h=", usually the tag name
+ * payload: eg base64 data - long data can be split arbitrarily.
+ *
+@@ -1127,7 +1127,7 @@ return string_catn(str, US"\r\n\t", 3);
+ * pairs and inside long values. it also always spaces or breaks after the
+ * "pad"
+ *
+- * no guarantees are made for output given out-of range input. like tag
++ * No guarantees are made for output given out-of range input. like tag
+ * names longer than 78, or bogus col. Input is assumed to be free of line breaks.
+ */
+
+@@ -1135,92 +1135,64 @@ static gstring *
+ pdkim_headcat(int * col, gstring * str,
+ const uschar * pad, const uschar * intro, const uschar * payload)
+ {
+-size_t l;
++int len, chomp, padded = 0;
+
+-if (pad)
+- {
+- l = Ustrlen(pad);
+- if (*col + l > 78)
+- str = pdkim_hdr_cont(str, col);
+- str = string_catn(str, pad, l);
+- *col += l;
+- }
+-
+-l = (pad?1:0) + (intro?Ustrlen(intro):0);
++/* If we can fit at least the pad at the end of current line, do it now.
++Otherwise, wrap if there is a pad. */
+
+-if (*col + l > 78)
+- { /*can't fit intro - start a new line to make room.*/
+- str = pdkim_hdr_cont(str, col);
+- l = intro?Ustrlen(intro):0;
+- }
+-
+-l += payload ? Ustrlen(payload):0 ;
+-
+-while (l>77)
+- { /* this fragment will not fit on a single line */
+- if (pad)
+- {
+- str = string_catn(str, US" ", 1);
+- *col += 1;
+- pad = NULL; /* only want this once */
+- l--;
+- }
+-
+- if (intro)
+- {
+- size_t sl = Ustrlen(intro);
+-
+- str = string_catn(str, intro, sl);
+- *col += sl;
+- l -= sl;
+- intro = NULL; /* only want this once */
+- }
+-
+- if (payload)
++if (pad)
++ if (*col + 1 <= 78)
+ {
+- size_t sl = Ustrlen(payload);
+- size_t chomp = *col+sl < 77 ? sl : 78-*col;
+-
+- str = string_catn(str, payload, chomp);
+- *col += chomp;
+- payload += chomp;
+- l -= chomp-1;
++ str = string_catn(str, pad, 1);
++ (*col)++;
++ pad = NULL;
++ padded = 1;
+ }
++ else
++ str = pdkim_hdr_cont(str, col);
+
+- /* the while precondition tells us it didn't fit. */
+- str = pdkim_hdr_cont(str, col);
+- }
++/* Special case: if the whole addition does not fit at the end of the current
++line, but could fit on a new line, wrap to give it its full, dedicated line. */
+
+-if (*col + l > 78)
++len = (pad ? 2 : padded)
++ + (intro ? Ustrlen(intro) : 0)
++ + (payload ? Ustrlen(payload) : 0);
++if (len <= 77 && *col+len > 78)
+ {
+ str = pdkim_hdr_cont(str, col);
+- pad = NULL;
++ padded = 0;
+ }
+
++/* Either we already dealt with the pad or we know there is room */
++
+ if (pad)
+ {
++ str = string_catn(str, pad, 1);
+ str = string_catn(str, US" ", 1);
+- *col += 1;
+- pad = NULL;
++ *col += 2;
+ }
+-
+-if (intro)
++else if (padded && *col < 78)
+ {
+- size_t sl = Ustrlen(intro);
+-
+- str = string_catn(str, intro, sl);
+- *col += sl;
+- l -= sl;
+- intro = NULL;
++ str = string_catn(str, US" ", 1);
++ (*col)++;
+ }
+
+-if (payload)
+- {
+- size_t sl = Ustrlen(payload);
++/* Call recursively with intro as payload: it gets the same, special treatment
++(that is, not split if < 78). */
+
+- str = string_catn(str, payload, sl);
+- *col += sl;
+- }
++if (intro)
++ str = pdkim_headcat(col, str, NULL, NULL, intro);
++
++if (payload)
++ for (len = Ustrlen(payload); len; len -= chomp)
++ {
++ if (*col >= 78)
++ str = pdkim_hdr_cont(str, col);
++ chomp = *col+len > 78 ? 78 - *col : len;
++ str = string_catn(str, payload, chomp);
++ *col += chomp;
++ payload += chomp;
++ }
+
+ return str;
+ }
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0023-Fix-taint-trap-in-parse_fix_phrase-.-Bug-2617 b/mail/exim/files/patch-z0023-Fix-taint-trap-in-parse_fix_phrase-.-Bug-2617
new file mode 100644
index 000000000000..ae3f4de35602
--- /dev/null
+++ b/mail/exim/files/patch-z0023-Fix-taint-trap-in-parse_fix_phrase-.-Bug-2617
@@ -0,0 +1,366 @@
+From 86ba540670517109809d93cd73716d320a6a0923 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Thu, 9 Jul 2020 15:30:55 +0100
+Subject: [PATCH 23/26] Fix taint trap in parse_fix_phrase(). Bug 2617
+
+(cherry picked from commit 3c90bbcdc7cf73298156f7bcd5f5e750e7814e72)
+---
+ doc/ChangeLog | 6 +++
+ src/acl.c | 3 +-
+ src/exim.c | 3 +-
+ src/expand.c | 5 +--
+ src/functions.h | 4 +-
+ src/parse.c | 89 +++++++++++++++----------------------------
+ src/rewrite.c | 9 +----
+ src/sieve.c | 17 ++-------
+
+diff --git doc/ChangeLog doc/ChangeLog
+index 08c6638a9..a1f39459e 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -72,6 +72,12 @@ JH/17 Bug 2295: Fix DKIM signing to always semicolon-terminate. Although the
+ intended but triggered by a line-wrap alignement. Discovery and fix by
+ Guillaume Outters, hacked on by JH.
+
++JH/18 Bug 2617: Fix a taint trap in parse_fix_phrase(). Previously when the
++ name being quoted was tainted a trap would be taken. Fix by using
++ dynamicaly created buffers. The routine could have been called by a
++ rewrite with the "h" flag, by using the "-F" command-line option, or
++ by using a "name=" option on a control=submission ACL modifier.
++
+
+ Exim version 4.94
+ -----------------
+diff --git src/acl.c src/acl.c
+index 62cb68561..105b1b473 100644
+--- src/acl.c
++++ src/acl.c
+@@ -3199,8 +3199,7 @@ for (; cb; cb = cb->next)
+ {
+ const uschar *pp = p + 6;
+ while (*pp) pp++;
+- submission_name = string_copy(parse_fix_phrase(p+6, pp-p-6,
+- big_buffer, big_buffer_size));
++ submission_name = parse_fix_phrase(p+6, pp-p-6);
+ p = pp;
+ }
+ else break;
+diff --git src/exim.c src/exim.c
+index dde991065..ac0ff5523 100644
+--- src/exim.c
++++ src/exim.c
+@@ -4769,8 +4769,7 @@ if (originator_login == NULL || f.running_in_test_harness)
+ /* Ensure that the user name is in a suitable form for use as a "phrase" in an
+ RFC822 address.*/
+
+-originator_name = string_copy(parse_fix_phrase(originator_name,
+- Ustrlen(originator_name), big_buffer, big_buffer_size));
++originator_name = parse_fix_phrase(originator_name, Ustrlen(originator_name));
+
+ /* If a message is created by this call of Exim, the uid/gid of its originator
+ are those of the caller. These values are overridden if an existing message is
+diff --git src/expand.c src/expand.c
+index 6ed22c14d..791222324 100644
+--- src/expand.c
++++ src/expand.c
+@@ -7571,13 +7571,10 @@ while (*s != 0)
+ prescribed by the RFC, if there are characters that need to be encoded */
+
+ case EOP_RFC2047:
+- {
+- uschar buffer[2048];
+ yield = string_cat(yield,
+ parse_quote_2047(sub, Ustrlen(sub), headers_charset,
+- buffer, sizeof(buffer), FALSE));
++ FALSE));
+ continue;
+- }
+
+ /* RFC 2047 decode */
+
+diff --git src/functions.h src/functions.h
+index afe9f1bf4..f4d1622dc 100644
+--- src/functions.h
++++ src/functions.h
+@@ -366,9 +366,9 @@ extern int parse_forward_list(uschar *, int, address_item **, uschar **,
+ const uschar *, uschar *, error_block **);
+ extern uschar *parse_find_address_end(uschar *, BOOL);
+ extern uschar *parse_find_at(uschar *);
+-extern const uschar *parse_fix_phrase(const uschar *, int, uschar *, int);
++extern const uschar *parse_fix_phrase(const uschar *, int);
+ extern uschar *parse_message_id(uschar *, uschar **, uschar **);
+-extern const uschar *parse_quote_2047(const uschar *, int, uschar *, uschar *, int, BOOL);
++extern const uschar *parse_quote_2047(const uschar *, int, uschar *, BOOL);
+ extern uschar *parse_date_time(uschar *str, time_t *t);
+ extern int vaguely_random_number(int);
+ #ifndef DISABLE_TLS
+diff --git src/parse.c src/parse.c
+index e3b471f1a..3ea758ac9 100644
+--- src/parse.c
++++ src/parse.c
+@@ -843,8 +843,7 @@ return NULL;
+
+ /* This function is used for quoting text in headers according to RFC 2047.
+ If the only characters that strictly need quoting are spaces, we return the
+-original string, unmodified. If a quoted string is too long for the buffer, it
+-is truncated. (This shouldn't happen: this is normally handling short strings.)
++original string, unmodified.
+
+ Hmmph. As always, things get perverted for other uses. This function was
+ originally for the "phrase" part of addresses. Now it is being used for much
+@@ -856,77 +855,57 @@ Arguments:
+ chars
+ len the length of the string
+ charset the name of the character set; NULL => iso-8859-1
+- buffer the buffer to put the answer in
+- buffer_size the size of the buffer
+ fold if TRUE, a newline is inserted before the separating space when
+ more than one encoded-word is generated
+
+ Returns: pointer to the original string, if no quoting needed, or
+- pointer to buffer containing the quoted string, or
+- a pointer to "String too long" if the buffer can't even hold
+- the introduction
++ pointer to allocated memory containing the quoted string
+ */
+
+ const uschar *
+-parse_quote_2047(const uschar *string, int len, uschar *charset, uschar *buffer,
+- int buffer_size, BOOL fold)
++parse_quote_2047(const uschar *string, int len, uschar *charset, BOOL fold)
+ {
+-const uschar *s = string;
+-uschar *p, *t;
+-int hlen;
++const uschar * s = string;
++int hlen, l;
+ BOOL coded = FALSE;
+ BOOL first_byte = FALSE;
++gstring * g =
++ string_fmt_append(NULL, "=?%s?Q?", charset ? charset : US"iso-8859-1");
+
+-if (!charset) charset = US"iso-8859-1";
++hlen = l = g->ptr;
+
+-/* We don't expect this to fail! */
+-
+-if (!string_format(buffer, buffer_size, "=?%s?Q?", charset))
+- return US"String too long";
+-
+-hlen = Ustrlen(buffer);
+-t = buffer + hlen;
+-p = buffer;
+-
+-for (; len > 0; len--)
++for (s = string; len > 0; s++, len--)
+ {
+- int ch = *s++;
+- if (t > buffer + buffer_size - hlen - 8) break;
++ int ch = *s;
+
+- if ((t - p > 67) && !first_byte)
++ if (g->ptr - l > 67 && !first_byte)
+ {
+- *t++ = '?';
+- *t++ = '=';
+- if (fold) *t++ = '\n';
+- *t++ = ' ';
+- p = t;
+- Ustrncpy(p, buffer, hlen);
+- t += hlen;
++ g = fold ? string_catn(g, US"?=\n ", 4) : string_catn(g, US"?= ", 3);
++ l = g->ptr;
++ g = string_catn(g, g->s, hlen);
+ }
+
+- if (ch < 33 || ch > 126 ||
+- Ustrchr("?=()<>@,;:\\\".[]_", ch) != NULL)
++ if ( ch < 33 || ch > 126
++ || Ustrchr("?=()<>@,;:\\\".[]_", ch) != NULL)
+ {
+ if (ch == ' ')
+ {
+- *t++ = '_';
++ g = string_catn(g, US"_", 1);
+ first_byte = FALSE;
+ }
+ else
+ {
+- t += sprintf(CS t, "=%02X", ch);
++ g = string_fmt_append(g, "=%02X", ch);
+ coded = TRUE;
+ first_byte = !first_byte;
+ }
+ }
+- else { *t++ = ch; first_byte = FALSE; }
++ else
++ { g = string_catn(g, s, 1); first_byte = FALSE; }
+ }
+
+-*t++ = '?';
+-*t++ = '=';
+-*t = 0;
+-
+-return coded ? buffer : string;
++g = string_catn(g, US"?=", 2);
++return coded ? string_from_gstring(g) : string;
+ }
+
+
+@@ -969,32 +948,25 @@ August 2000: Additional code added:
+ We *could* use this for all cases, getting rid of the messy original code,
+ but leave it for now. It would complicate simple cases like "John Q. Smith".
+
+-The result is passed back in the buffer; it is usually going to be added to
+-some other string. In order to be sure there is going to be no overflow,
+-restrict the length of the input to 1/4 of the buffer size - this allows for
+-every single character to be quoted or encoded without overflowing, and that
+-wouldn't happen because of amalgamation. If the phrase is too long, return a
+-fixed string.
++The result is passed back in allocated memory.
+
+ Arguments:
+ phrase an RFC822 phrase
+ len the length of the phrase
+- buffer a buffer to put the result in
+- buffer_size the size of the buffer
+
+ Returns: the fixed RFC822 phrase
+ */
+
+ const uschar *
+-parse_fix_phrase(const uschar *phrase, int len, uschar *buffer, int buffer_size)
++parse_fix_phrase(const uschar *phrase, int len)
+ {
+ int ch, i;
+ BOOL quoted = FALSE;
+ const uschar *s, *end;
++uschar * buffer;
+ uschar *t, *yield;
+
+ while (len > 0 && isspace(*phrase)) { phrase++; len--; }
+-if (len > buffer_size/4) return US"Name too long";
+
+ /* See if there are any non-printing characters, and if so, use the RFC 2047
+ encoding for the whole thing. */
+@@ -1002,11 +974,13 @@ encoding for the whole thing. */
+ for (i = 0, s = phrase; i < len; i++, s++)
+ if ((*s < 32 && *s != '\t') || *s > 126) break;
+
+-if (i < len) return parse_quote_2047(phrase, len, headers_charset, buffer,
+- buffer_size, FALSE);
++if (i < len)
++ return parse_quote_2047(phrase, len, headers_charset, FALSE);
+
+ /* No non-printers; use the RFC 822 quoting rules */
+
++buffer = store_get(len*4, is_tainted(phrase));
++
+ s = phrase;
+ end = s + len;
+ yield = t = buffer + 1;
+@@ -1173,6 +1147,7 @@ while (s < end)
+ }
+
+ *t = 0;
++store_release_above(t+1);
+ return yield;
+ }
+
+@@ -2102,7 +2077,6 @@ int main(void)
+ {
+ int start, end, domain;
+ uschar buffer[1024];
+-uschar outbuff[1024];
+
+ big_buffer = store_malloc(big_buffer_size);
+
+@@ -2115,8 +2089,7 @@ while (Ufgets(buffer, sizeof(buffer), stdin) != NULL)
+ {
+ buffer[Ustrlen(buffer)-1] = 0;
+ if (buffer[0] == 0) break;
+- printf("%s\n", CS parse_fix_phrase(buffer, Ustrlen(buffer), outbuff,
+- sizeof(outbuff)));
++ printf("%s\n", CS parse_fix_phrase(buffer, Ustrlen(buffer)));
+ }
+
+ printf("Testing parse_extract_address without group syntax and without UTF-8\n");
+diff --git src/rewrite.c src/rewrite.c
+index f942bec05..7bff8a273 100644
+--- src/rewrite.c
++++ src/rewrite.c
+@@ -292,16 +292,11 @@ for (rewrite_rule * rule = rewrite_rules;
+ uschar *p1 = new + start - 1;
+ uschar *p2 = new + end + 1;
+ const uschar *pf1, *pf2;
+- uschar buff1[256], buff2[256];
+
+ while (p1 > new && p1[-1] == ' ') p1--;
+- pf1 = parse_fix_phrase(new, p1 - new, buff1, sizeof(buff1));
++ pf1 = parse_fix_phrase(new, p1 - new);
+ while (*p2 == ' ') p2++;
+- pf2 = parse_fix_phrase(p2, Ustrlen(p2), buff2, sizeof(buff2));
+-
+- /* Note that pf1 and pf2 are NOT necessarily buff1 and buff2. For
+- a non-RFC 2047 phrase that does not need to be RFC 2822 quoted, they
+- will be buff1+1 and buff2+1. */
++ pf2 = parse_fix_phrase(p2, Ustrlen(p2));
+
+ start = Ustrlen(pf1) + start + new - p1;
+ end = start + Ustrlen(newparsed);
+diff --git src/sieve.c src/sieve.c
+index 18aa3e609..2038f336b 100644
+--- src/sieve.c
++++ src/sieve.c
+@@ -3087,11 +3087,8 @@ while (*filter->pc)
+ if ((pid = child_open_exim2(&fd, envelope_from, envelope_from,
+ US"sieve-notify")) >= 1)
+ {
+- FILE *f;
+- uschar *buffer;
+- int buffer_capacity;
++ FILE * f = fdopen(fd, "wb");
+
+- f = fdopen(fd, "wb");
+ fprintf(f,"From: %s\n", from.length == -1
+ ? expand_string(US"$local_part_prefix$local_part$local_part_suffix@$domain")
+ : from.character);
+@@ -3104,12 +3101,9 @@ while (*filter->pc)
+ message.character=US"Notification";
+ message.length=Ustrlen(message.character);
+ }
+- /* Allocation is larger than necessary, but enough even for split MIME words */
+- buffer_capacity = 32 + 4*message.length;
+- buffer=store_get(buffer_capacity, TRUE);
+ if (message.length != -1)
+ fprintf(f, "Subject: %s\n", parse_quote_2047(message.character,
+- message.length, US"utf-8", buffer, buffer_capacity, TRUE));
++ message.length, US"utf-8", TRUE));
+ fprintf(f,"\n");
+ if (body.length>0) fprintf(f,"%s\n",body.character);
+ fflush(f);
+@@ -3263,8 +3257,6 @@ while (*filter->pc)
+ if (exec)
+ {
+ address_item *addr;
+- uschar *buffer;
+- int buffer_capacity;
+ md5 base;
+ uschar digest[16];
+ uschar hexdigest[33];
+@@ -3342,11 +3334,8 @@ while (*filter->pc)
+ addr->reply->from = expand_string(US"$local_part@$domain");
+ else
+ addr->reply->from = from.character;
+- /* Allocation is larger than necessary, but enough even for split MIME words */
+- buffer_capacity=32+4*subject.length;
+- buffer = store_get(buffer_capacity, is_tainted(subject.character));
+ /* deconst cast safe as we pass in a non-const item */
+- addr->reply->subject = US parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity, TRUE);
++ addr->reply->subject = US parse_quote_2047(subject.character, subject.length, US"utf-8", TRUE);
+ addr->reply->oncelog = string_from_gstring(once);
+ addr->reply->once_repeat=days*86400;
+
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0024-Taint-fix-ACL-spam-condition-to-permit-tainted-name-argume b/mail/exim/files/patch-z0024-Taint-fix-ACL-spam-condition-to-permit-tainted-name-argume
new file mode 100644
index 000000000000..0c7e83bbb250
--- /dev/null
+++ b/mail/exim/files/patch-z0024-Taint-fix-ACL-spam-condition-to-permit-tainted-name-argume
@@ -0,0 +1,74 @@
+From 9681a2140b43cfc028e61b4e7ffb13539cecffe5 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Mon, 13 Jul 2020 13:46:14 +0100
+Subject: [PATCH 24/26] Taint: fix ACL "spam" condition, to permit tainted
+ name arguments
+
+Follow-on from: 62b2ccce05
+
+(cherry picked from commit 532800c8bf0e4bc2c27739477e70e0d7eef7df21)
+---
+ doc/ChangeLog | 6 +++---
+ src/spam.c | 15 +++++++--------
+
+diff --git doc/ChangeLog doc/ChangeLog
+index a1f39459e..aaea04caf 100644
+--- doc/ChangeLog
++++ doc/ChangeLog
+@@ -55,9 +55,9 @@ JH/13 Fix dsearch "subdir" filter to ignore ".". Previously only ".." was
+ JH/14 Bug 2606: Fix a segfault in sqlite lookups. When no, or a bad, filename
+ was given for the sqlite_dbfile a trap resulted.
+
+-JH/15 Fix "spam" ACL condition. Previously, tainted values for the "name"
+- argument resulted in a trap. There is no reason to disallow such; this
+- was a coding error.
++JH/15 Bug 2620: Fix "spam" ACL condition. Previously, tainted values for the
++ "name" argument resulted in a trap. There is no reason to disallow such;
++ this was a coding error.
+
+ JH/16 Bug 2615: Fix pause during message reception, on systems that have been
+ suspended/resumed. The Linux CLOCK_MONOTONIC does not account for time
+diff --git src/spam.c src/spam.c
+index 63ced4f65..340f8b92f 100644
+--- src/spam.c
++++ src/spam.c
+@@ -18,7 +18,7 @@ uschar spam_score_int_buffer[16];
+ uschar spam_bar_buffer[128];
+ uschar spam_action_buffer[32];
+ uschar spam_report_buffer[32600];
+-uschar prev_user_name[128] = "";
++uschar * prev_user_name = NULL;
+ int spam_ok = 0;
+ int spam_rc = 0;
+ uschar *prev_spamd_address_work = NULL;
+@@ -393,13 +393,12 @@ if (sd->is_rspamd)
+ }
+ else
+ { /* spamassassin variant */
+- (void)string_format(spamd_buffer,
+- sizeof(spamd_buffer),
+- "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n",
+- user_name,
+- mbox_size);
++ int n;
++ uschar * s = string_sprintf(
++ "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n%n",
++ user_name, mbox_size, &n);
+ /* send our request */
+- wrote = send(spamd_cctx.sock, spamd_buffer, Ustrlen(spamd_buffer), 0);
++ wrote = send(spamd_cctx.sock, s, n, 0);
+ }
+
+ if (wrote == -1)
+@@ -630,7 +629,7 @@ if (spamd_address_work != spamd_address)
+ prev_spamd_address_work = string_copy(spamd_address_work);
+
+ /* remember user name and "been here" for it */
+-Ustrcpy(prev_user_name, user_name);
++prev_user_name = user_name;
+ spam_ok = 1;
+
+ return override
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0025-Fix-debug_print_socket b/mail/exim/files/patch-z0025-Fix-debug_print_socket
new file mode 100644
index 000000000000..5db4662f48cf
--- /dev/null
+++ b/mail/exim/files/patch-z0025-Fix-debug_print_socket
@@ -0,0 +1,79 @@
+From 81cc39a7f5c17099f93b5c611bde5f58daaab71b Mon Sep 17 00:00:00 2001
+From: "Heiko Schlittermann (HS12-RIPE)" <hs@schlittermann.de>
+Date: Thu, 16 Jul 2020 23:45:55 +0200
+Subject: [PATCH 25/26] Fix debug_print_socket()
+
+debug_print_socket() crashed on AF_UNIX sockets
+---
+ src/debug.c | 34 +++++++++++++++++++---------------
+
+diff --git src/debug.c src/debug.c
+index 3a7d6a6f5..acc723a29 100644
+--- src/debug.c
++++ src/debug.c
+@@ -328,20 +328,21 @@ if (fstat(fd, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK)
+ gstring * g = NULL;
+ int val;
+ socklen_t vlen = sizeof(val);
+- struct sockaddr a;
++ struct sockaddr_storage a;
+ socklen_t alen = sizeof(a);
+ struct sockaddr_in * sinp = (struct sockaddr_in *)&a;
+ struct sockaddr_in6 * sin6p = (struct sockaddr_in6 *)&a;
+- struct sockaddr_un * sa_unp ; (struct sockaddr_un *)&a;
++ struct sockaddr_un * sunp = (struct sockaddr_un *)&a;
+
+- if (getsockname(fd, &a, &alen) == 0)
+- switch (sinp->sin_family)
++ if (getsockname(fd, (struct sockaddr*)&a, &alen) == 0)
++ switch (a.ss_family)
+ {
+ case AF_INET:
+ g = string_cat(g, US" domain AF_INET");
+ g = string_fmt_append(g, " lcl [%s]:%u",
+ inet_ntoa(sinp->sin_addr), ntohs(sinp->sin_port));
+- if (getpeername(fd, &a, &alen) == 0)
++ alen = sizeof(*sinp);
++ if (getpeername(fd, sinp, &alen) == 0)
+ g = string_fmt_append(g, " rmt [%s]:%u",
+ inet_ntoa(sinp->sin_addr), ntohs(sinp->sin_port));
+ break;
+@@ -352,22 +353,25 @@ if (fstat(fd, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK)
+ g = string_fmt_append(g, " lcl [%s]:%u",
+ inet_ntop(AF_INET6, &sin6p->sin6_addr, CS buf, sizeof(buf)),
+ ntohs(sin6p->sin6_port));
+- if (getpeername(fd, &a, &alen) == 0)
++ alen = sizeof(*sin6p);
++ if (getpeername(fd, sin6p, &alen) == 0)
+ g = string_fmt_append(g, " rmt [%s]:%u",
+ inet_ntop(AF_INET6, &sin6p->sin6_addr, CS buf, sizeof(buf)),
+ ntohs(sin6p->sin6_port));
+ break;
+ }
+ case AF_UNIX:
+- g = string_cat(g, US" domain AF_UNIX");
+- g = string_fmt_append(g, " lcl %s%s",
+- sa_unp->sun_path[0] ? US"" : US"@",
+- sa_unp->sun_path[0] ? sa_unp->sun_path : sa_unp->sun_path+1);
+- if (getpeername(fd, &a, &alen) == 0)
+- g = string_fmt_append(g, " rmt %s%s",
+- sa_unp->sun_path[0] ? US"" : US"@",
+- sa_unp->sun_path[0] ? sa_unp->sun_path : sa_unp->sun_path+1);
+- break;
++ g = string_cat(g, US"domain AF_UNIX");
++ if (alen > sizeof(sa_family_t)) /* not unix(7) "unnamed socket" */
++ g = string_fmt_append(g, " lcl %s%s",
++ sunp->sun_path[0] ? US"" : US"@",
++ sunp->sun_path[0] ? sunp->sun_path : sunp->sun_path+1);
++ alen = sizeof(*sunp);
++ if (getpeername(fd, sunp, &alen) == 0)
++ g = string_fmt_append(g, " rmt %s%s",
++ sunp->sun_path[0] ? US"" : US"@",
++ sunp->sun_path[0] ? sunp->sun_path : sunp->sun_path+1);
++ break;
+ default:
+ g = string_fmt_append(g, " domain %u", sinp->sin_family);
+ break;
+--
+2.24.3 (Apple Git-128)
+
diff --git a/mail/exim/files/patch-z0026-debug_print_socket-output-formatting b/mail/exim/files/patch-z0026-debug_print_socket-output-formatting
new file mode 100644
index 000000000000..d99b4c66a3ca
--- /dev/null
+++ b/mail/exim/files/patch-z0026-debug_print_socket-output-formatting
@@ -0,0 +1,51 @@
+From 73b748711caf8a4b18dd1c0d7c662b5d57798dfe Mon Sep 17 00:00:00 2001
+From: "Heiko Schlittermann (HS12-RIPE)" <hs@schlittermann.de>
+Date: Thu, 16 Jul 2020 23:53:27 +0200
+Subject: [PATCH 26/26] debug_print_socket(): output formatting
+
+---
+ src/debug.c | 8 ++++----
+
+diff --git src/debug.c src/debug.c
+index acc723a29..6d6132e39 100644
+--- src/debug.c
++++ src/debug.c
+@@ -338,7 +338,7 @@ if (fstat(fd, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK)
+ switch (a.ss_family)
+ {
+ case AF_INET:
+- g = string_cat(g, US" domain AF_INET");
++ g = string_cat(g, US"domain AF_INET");
+ g = string_fmt_append(g, " lcl [%s]:%u",
+ inet_ntoa(sinp->sin_addr), ntohs(sinp->sin_port));
+ alen = sizeof(*sinp);
+@@ -349,7 +349,7 @@ if (fstat(fd, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK)
+ case AF_INET6:
+ {
+ uschar buf[46];
+- g = string_cat(g, US" domain AF_INET6");
++ g = string_cat(g, US"domain AF_INET6");
+ g = string_fmt_append(g, " lcl [%s]:%u",
+ inet_ntop(AF_INET6, &sin6p->sin6_addr, CS buf, sizeof(buf)),
+ ntohs(sin6p->sin6_port));
+@@ -373,7 +373,7 @@ if (fstat(fd, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK)
+ sunp->sun_path[0] ? sunp->sun_path : sunp->sun_path+1);
+ break;
+ default:
+- g = string_fmt_append(g, " domain %u", sinp->sin_family);
++ g = string_fmt_append(g, "domain %u", sinp->sin_family);
+ break;
+ }
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &val, &vlen) == 0)
+@@ -388,7 +388,7 @@ if (fstat(fd, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK)
+ {
+ struct protoent * p = getprotobynumber(val);
+ g = p
+- ? string_fmt_append(g, " proto %s\n", p->p_name)
++ ? string_fmt_append(g, " proto %s", p->p_name)
+ : string_fmt_append(g, " proto %d", val);
+ }
+ #endif
+--
+2.24.3 (Apple Git-128)
+