X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/973689b1de83eb3dee860a3bb6895e8d5a7b42b2..a85c067ba6c6940512cf57ec213277a370d87e70:/src/src/deliver.c diff --git a/src/src/deliver.c b/src/src/deliver.c index 8322a367c..719fa9d93 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -2,9 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* The main code for delivering a message. */ @@ -146,7 +147,7 @@ Returns: a pointer to an initialized address_item address_item * deliver_make_addr(uschar *address, BOOL copy) { -address_item *addr = store_get(sizeof(address_item), FALSE); +address_item * addr = store_get(sizeof(address_item), GET_UNTAINTED); *addr = address_defaults; if (copy) address = string_copy(address); addr->address = address; @@ -953,9 +954,22 @@ router_name = transport_name = NULL; /************************************************* -* Generate local prt for logging * +* Generate local part for logging * *************************************************/ +static uschar * +string_get_lpart_sub(const address_item * addr, uschar * s) +{ +#ifdef SUPPORT_I18N +if (testflag(addr, af_utf8_downcvt)) + { + uschar * t = string_localpart_utf8_to_alabel(s, NULL); + return t ? t : s; /* t is NULL on a failed conversion */ + } +#endif +return s; +} + /* This function is a subroutine for use in string_log_address() below. Arguments: @@ -970,32 +984,13 @@ string_get_localpart(address_item * addr, gstring * yield) { uschar * s; -s = addr->prefix; -if (testflag(addr, af_include_affixes) && s) - { -#ifdef SUPPORT_I18N - if (testflag(addr, af_utf8_downcvt)) - s = string_localpart_utf8_to_alabel(s, NULL); -#endif - yield = string_cat(yield, s); - } +if (testflag(addr, af_include_affixes) && (s = addr->prefix)) + yield = string_cat(yield, string_get_lpart_sub(addr, s)); -s = addr->local_part; -#ifdef SUPPORT_I18N -if (testflag(addr, af_utf8_downcvt)) - s = string_localpart_utf8_to_alabel(s, NULL); -#endif -yield = string_cat(yield, s); +yield = string_cat(yield, string_get_lpart_sub(addr, addr->local_part)); -s = addr->suffix; -if (testflag(addr, af_include_affixes) && s) - { -#ifdef SUPPORT_I18N - if (testflag(addr, af_utf8_downcvt)) - s = string_localpart_utf8_to_alabel(s, NULL); -#endif - yield = string_cat(yield, s); - } +if (testflag(addr, af_include_affixes) && (s = addr->suffix)) + yield = string_cat(yield, string_get_lpart_sub(addr, s)); return yield; } @@ -1148,7 +1143,7 @@ pointer to a single host item in their host list, for use by the transport. */ #endif reset_point = store_mark(); -g = string_get_tainted(256, TRUE); /* addrs will be tainted, so avoid copy */ +g = string_get_tainted(256, GET_TAINTED); /* addrs will be tainted, so avoid copy */ if (msg) g = string_append(g, 2, host_and_ident(TRUE), US" "); @@ -2376,27 +2371,29 @@ if ((pid = exim_fork(US"delivery-local")) == 0) { BOOL ok = TRUE; set_process_info("delivering %s to %s using %s", message_id, - addr->local_part, addr->transport->name); + addr->local_part, tp->name); - /* Setting this global in the subprocess means we need never clear it */ + /* Setting these globals in the subprocess means we need never clear them */ transport_name = addr->transport->name; + driver_srcfile = tp->srcfile; + driver_srcline = tp->srcline; /* If a transport filter has been specified, set up its argument list. Any errors will get put into the address, and FALSE yielded. */ - if (addr->transport->filter_command) + if (tp->filter_command) { ok = transport_set_up_command(&transport_filter_argv, - addr->transport->filter_command, - TRUE, PANIC, addr, US"transport filter", NULL); - transport_filter_timeout = addr->transport->filter_timeout; + tp->filter_command, + TRUE, PANIC, addr, FALSE, US"transport filter", NULL); + transport_filter_timeout = tp->filter_timeout; } else transport_filter_argv = NULL; if (ok) { - debug_print_string(addr->transport->debug_string); - replicate = !(addr->transport->info->code)(addr->transport, addr); + debug_print_string(tp->debug_string); + replicate = !(tp->info->code)(addr->transport, addr); } } @@ -3049,7 +3046,7 @@ while (addr_local) else for (addr2 = addr; addr2; addr2 = addr2->next) if (addr2->transport_return == OK) { - addr3 = store_get(sizeof(address_item), FALSE); + addr3 = store_get(sizeof(address_item), GET_UNTAINTED); *addr3 = *addr2; addr3->next = NULL; addr3->shadow_message = US &addr2->shadow_message; @@ -3444,7 +3441,7 @@ while (!done) if (!r || !(*ptr & rf_delete)) { - r = store_get(sizeof(retry_item), FALSE); + r = store_get(sizeof(retry_item), GET_UNTAINTED); r->next = addr->retries; addr->retries = r; r->flags = *ptr++; @@ -3635,7 +3632,7 @@ while (!done) if (*ptr) { - h = store_get(sizeof(host_item), FALSE); + h = store_get(sizeof(host_item), GET_UNTAINTED); h->name = string_copy(ptr); while (*ptr++); h->address = string_copy(ptr); @@ -4213,10 +4210,10 @@ set up, do so. */ if (!parlist) { - parlist = store_get(remote_max_parallel * sizeof(pardata), FALSE); + parlist = store_get(remote_max_parallel * sizeof(pardata), GET_UNTAINTED); for (poffset = 0; poffset < remote_max_parallel; poffset++) parlist[poffset].pid = 0; - parpoll = store_get(remote_max_parallel * sizeof(struct pollfd), FALSE); + parpoll = store_get(remote_max_parallel * sizeof(struct pollfd), GET_UNTAINTED); } /* Now loop for each remote delivery */ @@ -4664,8 +4661,10 @@ all pipes, so I do not see a reason to use non-blocking IO here int fd = pfd[pipe_write]; host_item *h; - /* Setting this global in the subprocess means we need never clear it */ - transport_name = tp->name; + /* Setting these globals in the subprocess means we need never clear them */ + transport_name = addr->transport->name; + driver_srcfile = tp->srcfile; + driver_srcline = tp->srcline; /* There are weird circumstances in which logging is disabled */ f.disable_logging = tp->disable_logging; @@ -5111,7 +5110,7 @@ where they are locally interpreted. [The new draft "821" is more explicit on this, Jan 1999.] We know the syntax is valid, so this can be done by simply removing quoting backslashes and any unquoted doublequotes. */ -t = addr->cc_local_part = store_get(len+1, is_tainted(address)); +t = addr->cc_local_part = store_get(len+1, address); while(len-- > 0) { int c = *address++; @@ -5154,7 +5153,7 @@ if (percent_hack_domains) if (new_address) { - address_item *new_parent = store_get(sizeof(address_item), FALSE); + address_item * new_parent = store_get(sizeof(address_item), GET_UNTAINTED); *new_parent = *addr; addr->parent = new_parent; new_parent->child_count = 1; @@ -5545,11 +5544,10 @@ FILE * fp = NULL; if (!s || !*s) log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s: '%s'\n", varname, filename); -else if (*s != '/') - log_write(0, LOG_MAIN|LOG_PANIC, "%s is not absolute after expansion: '%s'\n", - varname, s); -else if (is_tainted2(s, LOG_MAIN|LOG_PANIC, "Tainted %s after expansion: '%s'\n", varname, s)) - ; +else if (*s != '/' || is_tainted(s)) + log_write(0, LOG_MAIN|LOG_PANIC, + "%s is not %s after expansion: '%s'\n", + varname, *s == '/' ? "untainted" : "absolute", s); else if (!(fp = Ufopen(s, "rb"))) log_write(0, LOG_MAIN|LOG_PANIC, "Failed to open %s for %s " "message texts: %s", s, reason, strerror(errno)); @@ -6159,10 +6157,9 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) if (!tmp) p->message = string_sprintf("failed to expand \"%s\" as a " "system filter transport name", tpname); - { uschar *m; - if ((m = is_tainted2(tmp, 0, "Tainted values '%s' " "for transport '%s' as a system filter", tmp, tpname))) - p->message = m; - } + if (is_tainted(tmp)) + p->message = string_sprintf("attempt to used tainted value '%s' for" + "transport '%s' as a system filter", tmp, tpname); tpname = tmp; } else @@ -6554,7 +6551,7 @@ while (addr_new) /* Loop until all addresses dealt with */ if (Ustrcmp(addr->address, "/dev/null") == 0) { transport_instance * save_t = addr->transport; - transport_instance * t = store_get(sizeof(*t), is_tainted(save_t)); + transport_instance * t = store_get(sizeof(*t), save_t); *t = *save_t; t->name = US"**bypassed**"; addr->transport = t; @@ -7207,7 +7204,7 @@ local and remote LMTP deliveries. */ if (!regex_IGNOREQUOTA) regex_IGNOREQUOTA = - regex_must_compile(US"\\n250[\\s\\-]IGNOREQUOTA(\\s|\\n|$)", FALSE, TRUE); + regex_must_compile(US"\\n250[\\s\\-]IGNOREQUOTA(\\s|\\n|$)", MCS_NOFLAGS, TRUE); /* Handle local deliveries */ @@ -7388,7 +7385,7 @@ for (address_item * a = addr_succeed; a; a = a->next) { /* copy and relink address_item and send report with all of them at once later */ address_item * addr_next = addr_senddsn; - addr_senddsn = store_get(sizeof(address_item), FALSE); + addr_senddsn = store_get(sizeof(address_item), GET_UNTAINTED); *addr_senddsn = *a; addr_senddsn->next = addr_next; } @@ -8607,7 +8604,7 @@ if (cutthrough.cctx.sock >= 0 && cutthrough.callout_hold_only) if (pid == 0) /* child: will fork again to totally disconnect */ { smtp_proxy_tls(cutthrough.cctx.tls_ctx, big_buffer, big_buffer_size, - pfd, 5*60); + pfd, 5*60, cutthrough.host.name); /* does not return */ }