*************************************************/
/* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */
/* The main code for delivering a message. */
search_tidyup();
- DEBUG(D_deliver) debug_printf("forking transport process\n");
if ((pid = exim_fork(US"transport")) == 0)
{
int fd = pfd[pipe_write];
/* Show pids on debug output if parallelism possible */
if (parmax > 1 && (parcount > 0 || addr_remote))
- {
DEBUG(D_any|D_v) debug_selector |= D_pid;
- DEBUG(D_deliver) debug_printf("Remote delivery process started\n");
- }
/* Reset the random number generator, so different processes don't all
have the same sequence. In the test harness we want different, but
(void)close(fd);
exit(EXIT_SUCCESS);
}
- DEBUG(D_deliver) debug_printf("forked transport process (%d)\n", pid);
/* Back in the mainline: close the unwanted half of the pipe. */
static void
print_dsn_diagnostic_code(const address_item *addr, FILE *f)
{
-uschar *s = testflag(addr, af_pass_message) ? addr->message : NULL;
+uschar * s = testflag(addr, af_pass_message) ? addr->message : NULL;
+unsigned cnt;
/* af_pass_message and addr->message set ? print remote host answer */
if (s)
if (!(s = Ustrstr(addr->message, ": ")))
return; /* not found, bail out */
s += 2; /* skip ": " */
- fprintf(f, "Diagnostic-Code: smtp; ");
+ cnt = fprintf(f, "Diagnostic-Code: smtp; ");
}
/* no message available. do nothing */
else return;
while (*s)
+ {
+ if (cnt > 950) /* RFC line length limit: 998 */
+ {
+ DEBUG(D_deliver) debug_printf("print_dsn_diagnostic_code() truncated line\n");
+ fputs("[truncated]", f);
+ break;
+ }
+
if (*s == '\\' && s[1] == 'n')
{
fputs("\n ", f); /* as defined in RFC 3461 */
s += 2;
+ cnt += 2;
}
else
+ {
fputc(*s++, f);
+ cnt++;
+ }
+ }
fputc('\n', f);
}
return actual_time;
}
+/************************************************/
+
+static FILE *
+expand_open(const uschar * filename,
+ const uschar * varname, const uschar * reason)
+{
+const uschar * s = expand_cstring(filename);
+FILE * fp = NULL;
+
+if (!s || !*s)
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "Failed to expand %s: '%s'\n", varname, filename);
+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));
+return fp;
+}
+
/*************************************************
* Deliver one message *
*************************************************/
carry on - default texts will be used. */
if (bounce_message_file)
- if (!(emf = Ufopen(bounce_message_file, "rb")))
- log_write(0, LOG_MAIN|LOG_PANIC, "Failed to open %s for error "
- "message texts: %s", bounce_message_file, strerror(errno));
+ emf = expand_open(bounce_message_file,
+ US"bounce_message_file", US"error");
/* Quietly copy to configured additional addresses if required. */
fprintf(fp, "Remote-MTA: X-ip; [%s]%s\n", hu->address, p);
}
if ((s = addr->smtp_greeting) && *s)
- fprintf(fp, "X-Remote-MTA-smtp-greeting: X-str; %s\n", s);
+ fprintf(fp, "X-Remote-MTA-smtp-greeting: X-str; %.900s\n", s);
if ((s = addr->helo_response) && *s)
- fprintf(fp, "X-Remote-MTA-helo-response: X-str; %s\n", s);
+ fprintf(fp, "X-Remote-MTA-helo-response: X-str; %.900s\n", s);
if ((s = addr->message) && *s)
- fprintf(fp, "X-Exim-Diagnostic: X-str; %s\n", s);
+ fprintf(fp, "X-Exim-Diagnostic: X-str; %.900s\n", s);
}
#endif
print_dsn_diagnostic_code(addr, fp);
if (pid > 0)
{
- uschar *wmf_text;
- FILE *wmf = NULL;
- FILE *f = fdopen(fd, "wb");
+ uschar * wmf_text;
+ FILE * wmf = NULL;
+ FILE * f = fdopen(fd, "wb");
uschar * bound;
transport_ctx tctx = {{0}};
if (warn_message_file)
- if (!(wmf = Ufopen(warn_message_file, "rb")))
- log_write(0, LOG_MAIN|LOG_PANIC, "Failed to open %s for warning "
- "message texts: %s", warn_message_file, strerror(errno));
+ wmf = expand_open(warn_message_file,
+ US"warn_message_file", US"warning");
warnmsg_recipients = recipients;
warnmsg_delay = queue_time < 120*60
where = US"fork";
testharness_pause_ms(150);
- if ((pid = exim_fork(US"tls-proxy interproc")) < 0)
+ if ((pid = exim_fork(US"tls-proxy-interproc")) < 0)
goto fail;
if (pid == 0) /* child: will fork again to totally disconnect */
/* does not return */
}
- DEBUG(D_transport) debug_printf("proxy-proc inter-pid %d\n", pid);
close(pfd[0]);
waitpid(pid, NULL, 0);
(void) close(channel_fd); /* release the client socket */