* 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. */
/* The main code for delivering a message. */
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;
/*************************************************
-* 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:
{
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;
}
#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" ");
{
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);
}
}
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;
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++;
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);
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 */
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;
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++;
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;
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));
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
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;
{
/* 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;
}
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 */
}