DSN: fix null deref when bounce is due to conn-timeout. Bug 1630
authorWolfgang Breyha <wbreyha@gmx.net>
Sat, 6 Jun 2015 19:07:04 +0000 (20:07 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 6 Jun 2015 19:07:04 +0000 (20:07 +0100)
src/src/deliver.c

index 5b2baabd35390acff85acd07d01ca600aeb8e265..40e13ee24f995b0e634900a2d11a47184d51cf27 100644 (file)
@@ -4852,9 +4852,9 @@ while (*s != 0)
 a bounce or a warning message. It tries to format the message reasonably as
 required by RFC 3461 by adding a space after each newline
 
-we assume that this function is only called if addr->host_used is set and if so
-a useable addr->message is available containing some Exim description with ": \n" 
-ending, followed by the L/SMTP error message.
+it uses the same logic as print_address_error() above. if af_pass_message is true
+and addr->message is set it uses the remote host answer. if not addr->user_message
+is used instead if available.
 
 Arguments:
   addr         the address
@@ -4866,21 +4866,33 @@ Returns:       nothing
 static void
 print_dsn_diagnostic_code(const address_item *addr, FILE *f)
 {
-uschar * s;
 
-/* check host_used, af_pass_message flag and addr->message for safety reasons */
-if (!addr->host_used && testflag(addr, af_pass_message) && addr->message)
-  return;
+uschar *s = testflag(addr, af_pass_message) ? addr->message : NULL;
 
-/* search first ": ". we assume to find the remote-MTA answer there */
-DEBUG(D_deliver)
-  debug_printf("DSN Diagnostic-Code: addr->dsn_message = %s\n", addr->message);
-if (!(s = Ustrstr(addr->message, ": ")))
-  return;                              /* not found, bail out */
+/* 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);
 
-fprintf(f, "Diagnostic-Code: smtp; ");
+  /* search first ": ". we assume to find the remote-MTA answer there */
+  if (!(s = Ustrstr(addr->message, ": ")))
+    return;                            /* not found, bail out */
+  s += 2;  /* skip ": " */
+  fprintf(f, "Diagnostic-Code: smtp; ");
+  }
+/* user_message set? use it instead */
+else if ((s = addr->user_message))
+  {
+  DEBUG(D_deliver)
+    debug_printf("DSN Diagnostic-Code: addr->user_message = %s\n", s);
+  /* local errors like timeout get 426 */
+  fprintf(f, "Diagnostic-Code: smtp; 426 ");
+  }
+/* no message available. do nothing */
+else
+  return;
 
-s += 2;  /* skip ": " */
 while (*s)
   if (*s == '\\' && s[1] == 'n')
     {