Linewrap long lines in bounce bodies. Bug 2979
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 25 Feb 2023 15:50:58 +0000 (15:50 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 25 Feb 2023 15:59:34 +0000 (15:59 +0000)
doc/doc-txt/ChangeLog
src/src/deliver.c
test/confs/0635 [new file with mode: 0644]
test/log/0635 [new file with mode: 0644]
test/mail/4700.CALLER
test/runtest
test/scripts/0000-Basic/0635 [new file with mode: 0644]
test/stdout/0635 [new file with mode: 0644]

index bad73cc7bad8b41a7818ba1c17493c6079f9d309..860e95d9dafd7c8a7fad3a4cd9f2cf0b90a1c3e0 100644 (file)
@@ -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
 -----------------
index 993b242311e9db0d5cb1235653cacde835d51e51..d0e6d1c2ecbd9660b30ddcd7666c4687c84c3b10 100644 (file)
@@ -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 (file)
index 0000000..3c8a687
--- /dev/null
@@ -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 (file)
index 0000000..e91469b
--- /dev/null
@@ -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:<fred@undeliverable.org>: 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
index 378b05d7e4107a78f04fa0811a76037513eb2d65..c43b56c13f7cd4536b8d099cac9467ca2c739994 100644 (file)
@@ -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
index 32dfe73abf6d80cc057260a431e08f2ddbba2ec7..3931b06d4018bfdcc9db9ae75320a593eb275983 100755 (executable)
@@ -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 <name>"
 ##################################################
 $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) {
+                     $_ = <IN>;
+                     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 (file)
index 0000000..314c84e
--- /dev/null
@@ -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 (file)
index 0000000..b4bfe58
--- /dev/null
@@ -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:<CALLER@myhost.test.ex>
+250 ok
+RCPT TO:<fred@undeliverable.org>
+550-no mate\r
+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\r
+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:<CALLER@myhost.test.ex>
+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 <Mailer-Daemon@myhost.test.ex>
+To: CALLER@myhost.test.ex
+References: <E10HmaX-0005vi-00@myhost.test.ex>
+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: <E10HmaY-0005vi-00@myhost.test.ex>
+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:<fred@undeliverable.org>:
+    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:<fred@undeliverable.org>: 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: <CALLER@myhost.test.ex>
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <CALLER@myhost.test.ex>)
+       id 10HmaX-0005vi-00
+       for fred@undeliverable.org;
+       Tue, 2 Mar 1999 09:44:33 +0000
+Subject: test
+Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+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