From e7a03e8345b6ae20ce7ec815f3f45cb7120825db Mon Sep 17 00:00:00 2001 From: Dhanraj E Date: Thu, 15 Oct 2026 18:55:11 +0530 Subject: [PATCH] cf-execd: dot-stuff mailed output lines starting with '.' MailResult() copies each line of the agent output file into the SMTP DATA section as is. RFC 5321, section 4.5.2 requires the client to double a leading '.', because a line consisting of a single '.' marks the end of the message. Without it, a lone "." in the agent output, such as a continuation line of a multi-line report whose text comes from a file or command, ends the mail early. Every following output line is then read by the mail server as an SMTP command in cf-execd's session, so output containing e.g. "MAIL FROM:", "RCPT TO:" and "DATA" lines makes the relay send an arbitrary message on behalf of the host. Lines that merely start with '.' also lose their first character. Send an extra '.' before any line that starts with '.'. The new acceptance test fails before this change (the lone "." reaches the mock SMTP server unescaped) and passes after it. Changelog: Title Signed-off-by: Dhanraj E --- cf-execd/cf-execd-runner.c | 6 ++- tests/acceptance/25_cf-execd/mail_dot_line.cf | 44 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/acceptance/25_cf-execd/mail_dot_line.cf diff --git a/cf-execd/cf-execd-runner.c b/cf-execd/cf-execd-runner.c index 574bcf7534c..04edb8f3ccf 100644 --- a/cf-execd/cf-execd-runner.c +++ b/cf-execd/cf-execd-runner.c @@ -797,7 +797,11 @@ static void MailResult(const ExecConfig *config, const char *file) { continue; } - if (send(sd, line, n_read, 0) == -1 || + /* Dot-stuff lines starting with '.' (RFC 5321, section 4.5.2), or a + * lone "." in the output would end the DATA section early and the + * remaining lines would be read by the server as SMTP commands. */ + if ((line[0] == '.' && send(sd, ".", 1, 0) == -1) || + send(sd, line, n_read, 0) == -1 || send(sd, "\r\n", 2, 0) == -1) { Log(LOG_LEVEL_ERR, "Error while sending mail to mailserver " diff --git a/tests/acceptance/25_cf-execd/mail_dot_line.cf b/tests/acceptance/25_cf-execd/mail_dot_line.cf new file mode 100644 index 00000000000..7d43a5c9c30 --- /dev/null +++ b/tests/acceptance/25_cf-execd/mail_dot_line.cf @@ -0,0 +1,44 @@ +# Tests that a line consisting of a single "." in the agent output is +# dot-stuffed by cf-execd, so it does not end the SMTP DATA section early. +body common control +{ + inputs => { "../default.sub.cf", "mailfilter_common.cf.sub" }; + bundlesequence => { default($(this.promise_filename)) }; +} + +bundle agent init +{ + vars: + "reports" slist => { "CorrectString1$(const.n).$(const.n)CorrectString2" }; + "includes" slist => {}; + "excludes" slist => {}; + + methods: + "any" + usebundle => prepare_mailfilter_test( + @(reports), @(includes), @(excludes) + ); +} + +bundle agent test +{ + meta: + "test_soft_fail" + string => "windows", + meta => { "ENT-10215" }; +} + +bundle agent check +{ + vars: + "wanted" slist => { 'CorrectString1\r +\.\.\r +CorrectString2' }; + "empty_list" slist => {}; + + methods: + "any" + usebundle => check_cf_execd_mail( + @(wanted), @(empty_list), $(this.promise_filename) + ); +}