commit 173bd1c8f9cf83ad8c0e61a9e32678e7e371d41d Author: Jeremy Harris Date: Tue Jun 2 14:50:31 2020 +0100 Taint: fix pam expansion condition. Bug 2587 (cherry picked from commit f7f933a199be8bb7362c715e0040545b514cddca) diff --git a/src/src/auths/call_pam.c b/src/src/auths/call_pam.c index 2959cbbf3..80bb23ec3 100644 --- a/src/src/auths/call_pam.c +++ b/src/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 */ commit 63652bbaf66c4bdb388b08fdf3eb8ab1e4d91475 Author: Jeremy Harris Date: Tue Jun 2 15:03:36 2020 +0100 Taint: fix listcount expansion operator. Bug 2586 (cherry picked from commit 44644c2e404a3ea0191db0b0458e86924fb240bb) diff --git a/src/src/expand.c b/src/src/expand.c index 26f7f10ac..6ed22c14d 100644 --- a/src/src/expand.c +++ b/src/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; } commit aabe0ebe82297d7dec3abdfff9c3b1edc34fd8ab Author: Patrick Boutilier Date: Tue Jun 2 15:16:10 2020 +0100 Docs: fix mistaken variable name (cherry picked from commit eb55cb1d2c5552209e24345e9d21f83ec1eaccf6) diff --git a/src/README.UPDATING b/src/README.UPDATING index a0afa8df0..708027f2c 100644 --- a/src/README.UPDATING +++ b/src/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 commit 623f07cfdcaca96274ca765d0fcf0761bdf7151b Author: Jeremy Harris Date: Wed Jun 3 11:40:17 2020 +0100 Taint: fix multiple ACL actions to properly manage tainted argument data (cherry picked from commit 12b7f811de4a540d0724585aecfa33b5881e2a30) diff --git a/src/src/acl.c b/src/src/acl.c index c1d60bbd9..8619cd5ef 100644 --- a/src/src/acl.c +++ b/src/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 */ } commit 0e8319c3edebfec2158fbaa4898af27cb3225c99 Author: Jeremy Harris Date: Thu Jun 4 15:28:15 2020 +0100 Fix -bi. Bug 2590 Actual fix from pierre.labastie@neuf.fr ; additional coding and testcase bu jgh Broken-by: bdcc6f2bd5 (Cherry-picked from: 0e0e171628) diff --git a/src/src/exim.c b/src/src/exim.c index a60488e95..6143fe989 100644 --- a/src/src/exim.c +++ b/src/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; commit 701af1005a6effaac5ce249f1c2086dc6c0c2a7f Author: Jeremy Harris Date: Mon Jun 8 13:00:55 2020 +0100 Filters: fix "vacation" in Exim filter. Bug 2593 Broken-by: cfb9cf20cb (4.90) (cherry picked from commit 59eee1bc902f106d20f507ba16f37cb8ab5a5e8d) diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index 4c2c08b70..865abbf4f 100644 --- a/src/src/transports/autoreply.c +++ b/src/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) { commit 3fe5ec41e81831028c992f77a15292872fbbac75 Author: Jeremy Harris Date: Thu Jun 11 20:45:05 2020 +0100 TLS: use RFC 6125 rules for certifucate name checks when CNAMES are present. Bug 2594 (cherry picked from commit 0851a3bbf4667081d47f5d85b6b3a5cb33cbdba6) diff --git a/src/src/host.c b/src/src/host.c index 0e0e0130b..817d4446c 100644 --- a/src/src/host.c +++ b/src/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 a/src/src/structs.h b/src/src/structs.h index c6700d513..206237f04 100644 --- a/src/src/structs.h +++ b/src/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 a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 24114f05e..875c82efa 100644 --- a/src/src/tls-gnu.c +++ b/src/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 a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 8c9d8aa69..a62322928 100644 --- a/src/src/tls-openssl.c +++ b/src/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); commit 94d719d803caf2c0c902dceeb787795eac11a63b Author: Jeremy Harris Date: Fri Jun 12 00:46:34 2020 +0100 Taint: fix radius expansion condition (cherry picked from commit f91219c114a3d95792d052555664a5a7a3984a8d) diff --git a/src/src/auths/call_radius.c b/src/src/auths/call_radius.c index cc269dcd5..9d10b34c6 100644 --- a/src/src/auths/call_radius.c +++ b/src/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); commit c165e95889471bc1a644104dd9a6129c47c56c09 Author: Jeremy Harris Date: Fri Jun 12 20:43:43 2020 +0100 smtp_accept_map_per_host: call search_tidyup in fail path. Bug 2597 (cherry-picked from: d3a538c8fe) diff --git a/src/src/daemon.c b/src/src/daemon.c index 2bed143a1..9d491593f 100644 --- a/src/src/daemon.c +++ b/src/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; } } commit ecf1e77accda6355ebb745a0a03e97ba7eb298b2 Author: Jeremy Harris Date: Sun Jun 14 22:14:11 2020 +0100 Taint: fix verify. Bug 2598 (cherry-picked from 2b60ac1021 and 9eed571fd7) diff --git a/src/src/acl.c b/src/src/acl.c index 8619cd5ef..11d1fd028 100644 --- a/src/src/acl.c +++ b/src/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;