From 7c60296900bdff369ffd2bf54eecfe6097b997a4 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 25 Feb 2023 15:50:58 +0000 Subject: [PATCH 1/1] Linewrap long lines in bounce bodies. Bug 2979 --- doc/doc-txt/ChangeLog | 11 +++- src/src/deliver.c | 107 ++++++++++++++++++++++++++++------ test/confs/0635 | 31 ++++++++++ test/log/0635 | 6 ++ test/mail/4700.CALLER | 9 ++- test/runtest | 12 +++- test/scripts/0000-Basic/0635 | 37 ++++++++++++ test/stdout/0635 | 108 +++++++++++++++++++++++++++++++++++ 8 files changed, 297 insertions(+), 24 deletions(-) create mode 100644 test/confs/0635 create mode 100644 test/log/0635 create mode 100644 test/scripts/0000-Basic/0635 create mode 100644 test/stdout/0635 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index bad73cc7b..860e95d9d 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -98,17 +98,22 @@ JH/20 Bug 2954: (OpenSSL) Fix setting of explicit EC curve/group. Previously this always failed, probably leading to the usual downgrade to in-clear connections. -JH/20 Fix TLSA lookups. Previously dns_again_means_nonexist would affect +JH/21 Fix TLSA lookups. Previously dns_again_means_nonexist would affect SERVFAIL results, which breaks the downgrade resistance of DANE. Change - to not checking that list for these looks. + to not checking that list for these lookups. -JH/21 Bug 2434: Add connection-elapsed "D=" element to more connection +JH/22 Bug 2434: Add connection-elapsed "D=" element to more connection closure log lines. JH/23 Fix crash in string expansions. Previously, if an empty variable was immediately followed by an expansion operator, a null-indirection read was done, killing the process. +JH/24 Bug 2997: When built with EXPERIMENTAL_DSN_INFO, bounce messages can + include an SMTP response string which is longer than that supported + by the delivering transport. Alleviate by wrapping such lines before + column 80. + Exim version 4.96 ----------------- diff --git a/src/src/deliver.c b/src/src/deliver.c index 993b24231..d0e6d1c2e 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -5400,19 +5400,18 @@ 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) - { - DEBUG(D_deliver) - debug_printf("DSN Diagnostic-Code: addr->message = %s\n", addr->message); +if (!s) + return; - /* search first ": ". we assume to find the remote-MTA answer there */ - if (!(s = Ustrstr(addr->message, ": "))) - return; /* not found, bail out */ - s += 2; /* skip ": " */ - cnt = fprintf(f, "Diagnostic-Code: smtp; "); - } -/* no message available. do nothing */ -else return; +DEBUG(D_deliver) + debug_printf("DSN Diagnostic-Code: addr->message = %s\n", addr->message); + +/* search first ": ". we assume to find the remote-MTA answer there */ +if (!(s = Ustrstr(addr->message, ": "))) + return; /* not found, bail out */ + +s += 2; /* skip ": " */ +cnt = fprintf(f, "Diagnostic-Code: smtp; "); while (*s) { @@ -5551,6 +5550,82 @@ else if (!(fp = Ufopen(s, "rb"))) return fp; } + +/* Output the given header and string, converting either +the sequence "\n" or a real newline into newline plus space. +If that still takes us past column 78, look for the last space +and split there too. +Append a newline if string did not have one. +Limit to about 1024 chars total. */ + +static void +dsn_put_wrapped(FILE * fp, const uschar * header, const uschar * s) +{ +const uschar * t; +int llen = fprintf(fp, "%s", CS header), sleft = Ustrlen(s); +int remain = 1022 - llen; + +if (*s && remain > 0) + { + for(;;) + { + unsigned ltail; /* source chars to skip */ + + /* Chop at a newline, or end of string */ + + if ((t = Ustrchr(s, '\\')) && t[1] == 'n') + ltail = 2; + else if ((t = Ustrchr(s, '\n'))) + ltail = 1; + else + { + t = s + sleft; + ltail = 0; + } + + /* If that is too long, search backward for a space */ + + if ((llen + t - s) > 78) + { + const uschar * u; + for (u = s + 78 - llen; u > s + 10; --u) if (*u == ' ') break; + if (u > s + 10) + { /* found a space to linebreak at */ + llen = u - s; + remain -= fprintf(fp, "%.*s", (int)llen, s); + s += ++llen; /* skip the space also */ + } + else if (llen < 78) + { /* just linebreak at 78 */ + llen = 78 - llen; + remain -= fprintf(fp, "%.*s", llen, s); + s += llen; + } + else /* header rather long */ + llen = 0; + } + else + { + llen = t - s; + remain -= fprintf(fp, "%.*s", llen, s); + s = t + ltail; + } + + sleft -= llen; + remain -= 2; + if (!*s || remain <= 0) + break; + fputs("\n ", fp); + llen = 1; /* one for the leading space output above */ + } + + if (s[-1] != '\n') fputs("\n", fp); + } +else + fputs("\n", fp); +} + + /************************************************* * Send a bounce message * *************************************************/ @@ -5818,7 +5893,7 @@ wording. */ if (dsn_envid) { /* must be decoded from xtext: see RFC 3461:6.3a */ - uschar *xdec_envid; + uschar * xdec_envid; if (auth_xtextdecode(dsn_envid, &xdec_envid) > 0) fprintf(fp, "Original-Envelope-ID: %s\n", dsn_envid); else @@ -5845,11 +5920,11 @@ wording. */ 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; %.900s\n", s); + dsn_put_wrapped(fp, US"X-Remote-MTA-smtp-greeting: X-str; ", s); if ((s = addr->helo_response) && *s) - fprintf(fp, "X-Remote-MTA-helo-response: X-str; %.900s\n", s); + dsn_put_wrapped(fp, US"X-Remote-MTA-helo-response: X-str; ", s); if ((s = addr->message) && *s) - fprintf(fp, "X-Exim-Diagnostic: X-str; %.900s\n", s); + dsn_put_wrapped(fp, US"X-Exim-Diagnostic: X-str; ", s); } #endif print_dsn_diagnostic_code(addr, fp); diff --git a/test/confs/0635 b/test/confs/0635 new file mode 100644 index 000000000..3c8a68708 --- /dev/null +++ b/test/confs/0635 @@ -0,0 +1,31 @@ +# Exim test configuration 0635 + +.include DIR/aux-var/std_conf_prefix + +primary_hostname = myhost.test.ex + +# ----- Main settings ----- + +trusted_users = CALLER +bounce_return_linesize_limit = 20 +acl_smtp_rcpt = accept + + +# ----- Routers ----- + +begin routers + +my_main_router: + driver = manualroute + transport = t1 + route_list = * 127.0.0.1::PORT_S + self = send + +# ----- Transports ----- + +begin transports + +t1: + driver = smtp + +# End diff --git a/test/log/0635 b/test/log/0635 new file mode 100644 index 000000000..e91469bda --- /dev/null +++ b/test/log/0635 @@ -0,0 +1,6 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 ** fred@undeliverable.org R=my_main_router T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550-no mate\n550-123456789 100 123456789 a really long line to blow the limits 123456789 123456789 123456789 123456789 200 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 300 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 400 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 500 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 600 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 700 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 800 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 900 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1000 123456789 12 +1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 => CALLER@myhost.test.ex R=my_main_router T=t1 H=127.0.0.1 [127.0.0.1] C="250 got that" +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed diff --git a/test/mail/4700.CALLER b/test/mail/4700.CALLER index 378b05d7e..c43b56c13 100644 --- a/test/mail/4700.CALLER +++ b/test/mail/4700.CALLER @@ -39,7 +39,8 @@ Status: 5.0.0 Remote-MTA: dns; localhost4.test.ex Remote-MTA: X-ip; [127.0.0.1]:1111 X-Remote-MTA-smtp-greeting: X-str; 550 Go away -X-Exim-Diagnostic: X-str; SMTP error from remote mail server after initial connection: 550 Go away +X-Exim-Diagnostic: X-str; SMTP error from remote mail server after initial + connection: 550 Go away Diagnostic-Code: smtp; 550 Go away --NNNNNNNNNN-eximdsn-MMMMMMMMMM @@ -106,7 +107,8 @@ Remote-MTA: dns; localhost4.test.ex Remote-MTA: X-ip; [127.0.0.1]:1111 X-Remote-MTA-smtp-greeting: X-str; 220 Connected OK X-Remote-MTA-helo-response: X-str; 550 Go away -X-Exim-Diagnostic: X-str; SMTP error from remote mail server after HELO the.local.host.name: 550 Go away +X-Exim-Diagnostic: X-str; SMTP error from remote mail server after HELO + the.local.host.name: 550 Go away Diagnostic-Code: smtp; 550 Go away Action: failed @@ -116,7 +118,8 @@ Remote-MTA: dns; localhost4.test.ex Remote-MTA: X-ip; [127.0.0.1]:1111 X-Remote-MTA-smtp-greeting: X-str; 220 Connected OK X-Remote-MTA-helo-response: X-str; 550 Go away -X-Exim-Diagnostic: X-str; SMTP error from remote mail server after HELO the.local.host.name: 550 Go away +X-Exim-Diagnostic: X-str; SMTP error from remote mail server after HELO + the.local.host.name: 550 Go away Diagnostic-Code: smtp; 550 Go away --NNNNNNNNNN-eximdsn-MMMMMMMMMM diff --git a/test/runtest b/test/runtest index 32dfe73ab..3931b06d4 100755 --- a/test/runtest +++ b/test/runtest @@ -399,6 +399,7 @@ RESET_AFTER_EXTRA_LINE_READ: { next if $extra =~ m%^/% && eval $extra; eval $extra if $extra =~ m/^s/; + eval substr($extra, 1) if $extra =~ m/^R/; } # Check for "*** truncated ***" @@ -1926,7 +1927,8 @@ return 2; # Usable files are: # paniclog, rejectlog, mainlog, stdout, stderr, msglog, mail # Search strings starting with 's' do substitutions; -# with '/' do line-skips. +# with '/' do line-skips, +# with 'R' run given code. # Triggered by a scriptfile line "munge " ################################################## $munges = @@ -1973,7 +1975,13 @@ $munges = }, 'optional_dsn_info' => - { 'mail' => '/^(X-(Remote-MTA-(smtp-greeting|helo-response)|Exim-Diagnostic|(body|message)-linecount):|Remote-MTA: X-ip;)/' + { 'mail' => 'Rif (/^(X-(Remote-MTA-(smtp-greeting|helo-response)|Exim-Diagnostic|(body|message)-linecount):|Remote-MTA: X-ip;)/) { + while (1) { + $_ = ; + next if /^ /; + goto RESET_AFTER_EXTRA_LINE_READ; + } + }' }, 'optional_config' => diff --git a/test/scripts/0000-Basic/0635 b/test/scripts/0000-Basic/0635 new file mode 100644 index 000000000..314c84ebb --- /dev/null +++ b/test/scripts/0000-Basic/0635 @@ -0,0 +1,37 @@ +# bounce from long SMTP response +# +server PORT_S 2 +220 Hi +EHLO +250 Yo +MAIL FROM +250 ok +RCPT TO +550-no mate\x0d\x0a550-123456789 100 123456789 a really long line to blow the limits 123456789 123456789 123456789 123456789 200 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 300 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 400 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 500 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 600 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 700 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 800 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 900 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1000 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1100 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789\x0d\x0a550 go away +QUIT +250 bye +*eof +220 Hi +EHLO +250 Yo +MAIL FROM:<> +250 ok +RCPT TO +250 acceptable +DATA +354 go ahead +. +250 got that +QUIT +250 bye +**** +# +exim -odi fred@undeliverable.org +Subject: test + +msg with ok lines +00000000001111111 +01234567890123456 +**** +# +no_msglog_check diff --git a/test/stdout/0635 b/test/stdout/0635 new file mode 100644 index 000000000..b4bfe581f --- /dev/null +++ b/test/stdout/0635 @@ -0,0 +1,108 @@ + +******** SERVER ******** +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Hi +EHLO myhost.test.ex +250 Yo +MAIL FROM: +250 ok +RCPT TO: +550-no mate +550-123456789 100 123456789 a really long line to blow the limits 123456789 123456789 123456789 123456789 200 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 300 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 400 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 500 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 600 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 700 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 800 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 900 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1000 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1100 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 +550 go away +QUIT +250 bye +Expected EOF read from client +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Hi +EHLO myhost.test.ex +250 Yo +MAIL FROM:<> +250 ok +RCPT TO: +250 acceptable +DATA +354 go ahead +Received: from EXIMUSER by myhost.test.ex with local (Exim x.yz) + id 10HmaY-0005vi-00 + for CALLER@myhost.test.ex; + Tue, 2 Mar 1999 09:44:33 +0000 +X-Failed-Recipients: fred@undeliverable.org +Auto-Submitted: auto-replied +From: Mail Delivery System +To: CALLER@myhost.test.ex +References: +Content-Type: multipart/report; report-type=delivery-status; boundary=NNNNNNNNNN-eximdsn-MMMMMMMMMM +MIME-Version: 1.0 +Subject: Mail delivery failed: returning message to sender +Message-Id: +Date: Tue, 2 Mar 1999 09:44:33 +0000 + +--NNNNNNNNNN-eximdsn-MMMMMMMMMM +Content-type: text/plain; charset=us-ascii + +This message was created automatically by mail delivery software. + +A message that you sent could not be delivered to one or more of its +recipients. This is a permanent error. The following address(es) failed: + + fred@undeliverable.org + host 127.0.0.1 [127.0.0.1] + SMTP error from remote mail server after RCPT TO:: + 550-no mate + 550-123456789 100 123456789 a really long line to blow the limits 123456789 123456789 123456789 123456789 200 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 300 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 400 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 500 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 600 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 700 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 800 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 900 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1000 123456789 12 + +--NNNNNNNNNN-eximdsn-MMMMMMMMMM +Content-type: message/delivery-status + +Reporting-MTA: dns; myhost.test.ex + +Action: failed +Final-Recipient: rfc822;fred@undeliverable.org +Status: 5.0.0 +Remote-MTA: dns; 127.0.0.1 +Remote-MTA: X-ip; [127.0.0.1]:1111 +X-Exim-Diagnostic: X-str; SMTP error from remote mail server after RCPT + TO:: 550-no mate + 550-123456789 100 123456789 a really long line to blow the limits + 123456789 123456789 123456789 123456789 200 123456789 123456789 + 123456789 123456789 123456789 123456789 123456789 123456789 123456789 300 + 123456789 123456789 123456789 123456789 123456789 123456789 123456789 + 123456789 123456789 400 123456789 123456789 123456789 123456789 + 123456789 123456789 123456789 123456789 123456789 500 123456789 + 123456789 123456789 123456789 123456789 123456789 123456789 123456789 + 123456789 600 123456789 123456789 123456789 123456789 123456789 + 123456789 123456789 123456789 123456789 700 123456789 123456789 + 123456789 123456789 123456789 123456789 123456789 123456789 123456789 800 + 123456789 123456789 123456789 123456789 123456789 123456789 123456789 + 123456789 123456789 900 123456789 123456789 123456789 123456789 + 123456789 123456789 123456789 123456789 123456789 1000 123456789 12 +Diagnostic-Code: smtp; 550-no mate + 550-123456789 100 123456789 a really long line to blow the limits 123456789 123456789 123456789 123456789 200 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 300 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 400 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 500 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 600 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 700 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 800 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 900 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1[truncated] + +--NNNNNNNNNN-eximdsn-MMMMMMMMMM +Content-type: message/rfc822 + +Return-path: +Received: from CALLER by myhost.test.ex with local (Exim x.yz) + (envelope-from ) + id 10HmaX-0005vi-00 + for fred@undeliverable.org; + Tue, 2 Mar 1999 09:44:33 +0000 +Subject: test +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 + +msg with ok lines +00000000001111111 +01234567890123456 + +--NNNNNNNNNN-eximdsn-MMMMMMMMMM-- +. +250 got that +QUIT +250 bye +End of script -- 2.30.2