diff -urN ../exim-4.96.orig/doc/ChangeLog ./doc/ChangeLog --- ../exim-4.96.orig/doc/ChangeLog 2022-06-23 16:41:10.000000000 +0300 +++ ./doc/ChangeLog 2023-09-09 15:55:26.462636000 +0300 @@ -2,6 +2,29 @@ affect Exim's operation, with an unchanged configuration file. For new options, and new features, see the NewStuff file next to this ChangeLog. +Exim version 4.96+fixes +----------------------- + +HS/01 Bug 2728: Introduce EDITME option "DMARC_API" to work around incompatible + API changes in libopendmarc. + +HS/02 Backported the essence of 44b6e0 (Fix argument parsing for ${run } + expansion + +JH/15 Fix argument parsing for ${run } expansion. Previously, when an argument + included a close-brace character (eg. it itself used an expansion) an + error occurred. + +HS/02 Backported the essence of 44b6e0 (Fix argument parsing for ${run } + expansion + +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. + +JH/34 Bug 3013: Fix use of $recipients within arguments for ${run...}. + In 4.96 this would expand to empty. + + Exim version 4.96 ----------------- diff -urN ../exim-4.96.orig/src/EDITME ./src/EDITME --- ../exim-4.96.orig/src/EDITME 2022-06-23 16:41:10.000000000 +0300 +++ ./src/EDITME 2023-09-09 15:55:26.482390000 +0300 @@ -602,14 +602,17 @@ # 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. diff -urN ../exim-4.96.orig/src/config.h.defaults ./src/config.h.defaults --- ../exim-4.96.orig/src/config.h.defaults 2022-06-23 16:41:10.000000000 +0300 +++ ./src/config.h.defaults 2023-09-09 15:55:26.489232000 +0300 @@ -150,6 +150,7 @@ #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 diff -urN ../exim-4.96.orig/src/deliver.c ./src/deliver.c --- ../exim-4.96.orig/src/deliver.c 2022-06-23 16:41:10.000000000 +0300 +++ ./src/deliver.c 2023-09-09 15:55:26.495713000 +0300 @@ -2384,7 +2384,7 @@ { ok = transport_set_up_command(&transport_filter_argv, tp->filter_command, - TRUE, PANIC, addr, FALSE, US"transport filter", NULL); + TSUC_EXPAND_ARGS, PANIC, addr, US"transport filter", NULL); transport_filter_timeout = tp->filter_timeout; } else transport_filter_argv = NULL; diff -urN ../exim-4.96.orig/src/dmarc.c ./src/dmarc.c --- ../exim-4.96.orig/src/dmarc.c 2022-06-23 16:41:10.000000000 +0300 +++ ./src/dmarc.c 2023-09-09 15:55:26.496434000 +0300 @@ -459,7 +459,12 @@ 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) diff -urN ../exim-4.96.orig/src/expand.c ./src/expand.c --- ../exim-4.96.orig/src/expand.c 2022-06-23 16:41:10.000000000 +0300 +++ ./src/expand.c 2023-09-09 15:55:26.506627000 +0300 @@ -5527,7 +5527,9 @@ { FILE * f; const uschar * arg, ** argv; - BOOL late_expand = TRUE; + unsigned late_expand = TSUC_EXPAND_ARGS | TSUC_ALLOW_TAINTED_ARGS | TSUC_ALLOW_RECIPIENTS; + uschar * save_value = lookup_value; + int yesno; if ((expand_forbid & RDO_RUN) != 0) { @@ -5540,7 +5542,7 @@ while (*s == ',') { if (Ustrncmp(++s, "preexpand", 9) == 0) - { late_expand = FALSE; s += 9; } + { late_expand = 0; s += 9; } else { const uschar * t = s; @@ -5560,8 +5562,16 @@ s++; if (late_expand) /* this is the default case */ - { - int n = Ustrcspn(s, "}"); + { /* backported from 44b6e099b7 */ + int n; + const uschar * t; + /* Locate the end of the args */ + /* expand_string_internal(s, ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | ESI_SKIPPING, &t, NULL, NULL); + * honour_dollar ----------------------------------, + * skipping ----------------------------------, | + * BRACE_ENDS --------------------, | | */ + (void) expand_string_internal(s, TRUE, &t, skipping, TRUE, NULL); + n = t - s; arg = skipping ? NULL : string_copyn(s, n); s += n; } @@ -5593,7 +5603,6 @@ late_expand, /* expand args if not already done */ 0, /* not relevant when... */ NULL, /* no transporting address */ - late_expand, /* allow tainted args, when expand-after-split */ US"${run} expansion", /* for error messages */ &expand_string_message)) /* where to put error message */ goto EXPAND_FAILED; diff -urN ../exim-4.96.orig/src/functions.h ./src/functions.h --- ../exim-4.96.orig/src/functions.h 2022-06-23 16:41:10.000000000 +0300 +++ ./src/functions.h 2023-09-09 15:55:26.507685000 +0300 @@ -617,7 +617,7 @@ ); extern uschar *transport_rcpt_address(address_item *, BOOL); extern BOOL transport_set_up_command(const uschar ***, const uschar *, - BOOL, int, address_item *, BOOL, const uschar *, uschar **); + unsigned, int, address_item *, const uschar *, uschar **); extern void transport_update_waiting(host_item *, uschar *); extern BOOL transport_write_block(transport_ctx *, uschar *, int, BOOL); extern void transport_write_reset(int); diff -urN ../exim-4.96.orig/src/macros.h ./src/macros.h --- ../exim-4.96.orig/src/macros.h 2022-06-23 16:41:10.000000000 +0300 +++ ./src/macros.h 2023-09-09 15:55:26.517823000 +0300 @@ -1114,4 +1114,9 @@ #define NOTIFY_MSG_QRUN 1 /* Notify message types */ #define NOTIFY_QUEUE_SIZE_REQ 2 +/* Flags for transport_set_up_command() */ +#define TSUC_EXPAND_ARGS BIT(0) +#define TSUC_ALLOW_TAINTED_ARGS BIT(1) +#define TSUC_ALLOW_RECIPIENTS BIT(2) + /* End of macros.h */ diff -urN ../exim-4.96.orig/src/routers/queryprogram.c ./src/routers/queryprogram.c --- ../exim-4.96.orig/src/routers/queryprogram.c 2022-06-23 16:41:10.000000000 +0300 +++ ./src/routers/queryprogram.c 2023-09-09 15:55:26.530761000 +0300 @@ -288,10 +288,9 @@ if (!transport_set_up_command(&argvptr, /* anchor for arg list */ ob->command, /* raw command */ - TRUE, /* expand the arguments */ + TSUC_EXPAND_ARGS, /* arguments expanded but must not be tainted */ 0, /* not relevant when... */ NULL, /* no transporting address */ - FALSE, /* args must be untainted */ US"queryprogram router", /* for error messages */ &addr->message)) /* where to put error message */ return DEFER; diff -urN ../exim-4.96.orig/src/smtp_in.c ./src/smtp_in.c --- ../exim-4.96.orig/src/smtp_in.c 2022-06-23 16:41:10.000000000 +0300 +++ ./src/smtp_in.c 2023-09-09 15:55:26.535188000 +0300 @@ -5825,8 +5825,8 @@ BOOL rc; etrn_command = smtp_etrn_command; deliver_domain = smtp_cmd_data; - rc = transport_set_up_command(&argv, smtp_etrn_command, TRUE, 0, NULL, - FALSE, US"ETRN processing", &error); + rc = transport_set_up_command(&argv, smtp_etrn_command, TSUC_EXPAND_ARGS, 0, NULL, + US"ETRN processing", &error); deliver_domain = NULL; if (!rc) { diff -urN ../exim-4.96.orig/src/transport.c ./src/transport.c --- ../exim-4.96.orig/src/transport.c 2022-06-23 16:41:10.000000000 +0300 +++ ./src/transport.c 2023-09-09 15:55:26.542862000 +0300 @@ -2084,18 +2084,18 @@ /* This function is called when a command line is to be parsed and executed directly, without the use of /bin/sh. It is called by the pipe transport, -the queryprogram router, and also from the main delivery code when setting up a +the queryprogram router, for any ${run } expansion, +and also from the main delivery code when setting up a transport filter process. The code for ETRN also makes use of this; in that case, no addresses are passed. Arguments: argvptr pointer to anchor for argv vector cmd points to the command string (modified IN PLACE) - expand_arguments true if expansion is to occur + flags bits for expand-args, allow taint, allow $recipients expand_failed error value to set if expansion fails; not relevant if addr == NULL addr chain of addresses, or NULL - allow_tainted_args as it says; used for ${run} etext text for use in error messages errptr where to put error message if addr is NULL; otherwise it is put in the first address @@ -2106,8 +2106,8 @@ BOOL transport_set_up_command(const uschar *** argvptr, const uschar * cmd, - BOOL expand_arguments, int expand_failed, address_item * addr, - BOOL allow_tainted_args, const uschar * etext, uschar ** errptr) + unsigned flags, int expand_failed, address_item * addr, + const uschar * etext, uschar ** errptr) { const uschar ** argv, * s; int address_count = 0, argcount = 0, max_args; @@ -2182,10 +2182,10 @@ debug_printf(" argv[%d] = '%s'\n", i, string_printing(argv[i])); } -if (expand_arguments) +if (flags & TSUC_EXPAND_ARGS) { - BOOL allow_dollar_recipients = addr && addr->parent - && Ustrcmp(addr->parent->address, "system-filter") == 0; + BOOL allow_dollar_recipients = (flags & TSUC_ALLOW_RECIPIENTS) + || (addr && addr->parent && Ustrcmp(addr->parent->address, "system-filter") == 0); /*XXX could we check this at caller? */ for (int i = 0; argv[i]; i++) { @@ -2344,9 +2344,10 @@ 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) { @@ -2369,7 +2370,7 @@ debug_printf("SPECIFIC TESTSUITE EXEMPTION: tainted arg '%s'\n", expanded_arg); } - else if ( !allow_tainted_args + else if ( !(flags & TSUC_ALLOW_TAINTED_ARGS) && arg_is_tainted(expanded_arg, i, addr, etext, errptr)) return FALSE; argv[i] = expanded_arg; diff -urN ../exim-4.96.orig/src/transports/lmtp.c ./src/transports/lmtp.c --- ../exim-4.96.orig/src/transports/lmtp.c 2022-06-23 16:41:10.000000000 +0300 +++ ./src/transports/lmtp.c 2023-09-09 15:55:26.545295000 +0300 @@ -489,8 +489,8 @@ { DEBUG(D_transport) debug_printf("using command %s\n", ob->cmd); sprintf(CS buffer, "%.50s transport", tblock->name); - if (!transport_set_up_command(&argv, ob->cmd, TRUE, PANIC, addrlist, FALSE, - buffer, NULL)) + if (!transport_set_up_command(&argv, ob->cmd, TSUC_EXPAND_ARGS, PANIC, + addrlist, buffer, NULL)) return FALSE; /* If the -N option is set, can't do any more. Presume all has gone well. */ diff -urN ../exim-4.96.orig/src/transports/pipe.c ./src/transports/pipe.c --- ../exim-4.96.orig/src/transports/pipe.c 2022-06-23 16:41:10.000000000 +0300 +++ ./src/transports/pipe.c 2023-09-09 15:55:26.545663000 +0300 @@ -291,9 +291,9 @@ */ static BOOL -set_up_direct_command(const uschar ***argvptr, uschar *cmd, - BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname, - pipe_transport_options_block *ob) +set_up_direct_command(const uschar *** argvptr, uschar * cmd, + BOOL expand_arguments, int expand_fail, address_item * addr, uschar * tname, + pipe_transport_options_block * ob) { BOOL permitted = FALSE; const uschar **argv; @@ -303,8 +303,9 @@ the items if necessary. If it fails, this function fails (error information is in the addresses). */ -if (!transport_set_up_command(argvptr, cmd, expand_arguments, expand_fail, - addr, FALSE, string_sprintf("%.50s transport", tname), NULL)) +if (!transport_set_up_command(argvptr, cmd, + expand_arguments ? TSUC_EXPAND_ARGS : 0, + expand_fail, addr, string_sprintf("%.50s transport", tname), NULL)) return FALSE; /* Point to the set-up arguments. */ diff -urN ../exim-4.96.orig/src/transports/smtp.c ./src/transports/smtp.c --- ../exim-4.96.orig/src/transports/smtp.c 2022-06-23 16:41:10.000000000 +0300 +++ ./src/transports/smtp.c 2023-09-09 15:55:26.547473000 +0300 @@ -3802,7 +3802,7 @@ yield ERROR. */ if (!transport_set_up_command(&transport_filter_argv, - tblock->filter_command, TRUE, DEFER, addrlist, FALSE, + tblock->filter_command, TSUC_EXPAND_ARGS, DEFER, addrlist, string_sprintf("%.50s transport filter", tblock->name), NULL)) { set_errno_nohost(addrlist->next, addrlist->basic_errno, addrlist->message, DEFER, diff -urN ../exim-4.96.orig/src/version.h ./src/version.h --- ../exim-4.96.orig/src/version.h 2022-06-25 16:36:07.000000000 +0300 +++ ./src/version.h 2023-09-09 15:55:27.132183000 +0300 @@ -1,5 +1,5 @@ /* automatically generated file - see ../scripts/reversion */ -#define EXIM_RELEASE_VERSION "4.96" +#define EXIM_RELEASE_VERSION "4.96-5-0b7d99389" #ifdef EXIM_VARIANT_VERSION #define EXIM_VERSION_STR EXIM_RELEASE_VERSION "-" EXIM_VARIANT_VERSION #else diff -urN ../exim-4.96.orig/src/version.sh ./src/version.sh --- ../exim-4.96.orig/src/version.sh 2022-06-25 16:36:07.000000000 +0300 +++ ./src/version.sh 2023-09-09 15:55:27.131854000 +0300 @@ -1,3 +1,3 @@ # automatically generated file - see ../scripts/reversion -EXIM_RELEASE_VERSION="4.96" +EXIM_RELEASE_VERSION="4.96-5-0b7d99389" EXIM_COMPILE_NUMBER="1"