DSN: add References: header. Bug 2452
[exim.git] / src / src / deliver.c
index ba9572e48be0423fd267fd2b15c4e0e0e1ca3b32..7433b5fb2d9426874077ec2f8a80c7c61bb41896 100644 (file)
@@ -107,21 +107,21 @@ Returns:      the amount of bytes read
 static ssize_t
 readn(int fd, void * buffer, size_t len)
 {
-  void * next = buffer;
-  void * end = buffer + len;
+uschar * next = buffer;
+uschar * end = next + len;
 
-  while (next < end)
-    {
-    ssize_t got = read(fd, next, end - next);
+while (next < end)
+  {
+  ssize_t got = read(fd, next, end - next);
 
-    /* I'm not sure if there are signals that can interrupt us,
-    for now I assume the worst */
-    if (got == -1 && errno == EINTR) continue;
-    if (got <= 0) return next - buffer;
-    next += got;
-    }
+  /* I'm not sure if there are signals that can interrupt us,
+  for now I assume the worst */
+  if (got == -1 && errno == EINTR) continue;
+  if (got <= 0) return next - US buffer;
+  next += got;
+  }
 
-  return len;
+return len;
 }
 
 
@@ -328,6 +328,10 @@ Returns:    a file descriptor, or -1 (with errno set)
 static int
 open_msglog_file(uschar *filename, int mode, uschar **error)
 {
+if (Ustrstr(filename, US"/../"))
+  log_write(0, LOG_MAIN|LOG_PANIC,
+    "Attempt to open msglog file path with upward-traversal: '%s'\n", filename);
+
 for (int i = 2; i > 0; i--)
   {
   int fd = Uopen(filename,
@@ -4794,7 +4798,6 @@ all pipes, so I do not see a reason to use non-blocking IO here
     for(; addr; addr = addr->next)
       {
       uschar *ptr;
-      retry_item *r;
 
       /* The certificate verification status goes into the flags */
       if (tls_out.certificate_verified) setflag(addr, af_cert_verified);
@@ -4827,7 +4830,7 @@ all pipes, so I do not see a reason to use non-blocking IO here
       if (addr->peercert)
        {
         ptr = big_buffer;
-       if (!tls_export_cert(ptr, big_buffer_size-2, addr->peercert))
+       if (tls_export_cert(ptr, big_buffer_size-2, addr->peercert))
          while(*ptr++);
        else
          *ptr++ = 0;
@@ -4836,7 +4839,7 @@ all pipes, so I do not see a reason to use non-blocking IO here
       if (addr->ourcert)
        {
         ptr = big_buffer;
-       if (!tls_export_cert(ptr, big_buffer_size-2, addr->ourcert))
+       if (tls_export_cert(ptr, big_buffer_size-2, addr->ourcert))
          while(*ptr++);
        else
          *ptr++ = 0;
@@ -4894,7 +4897,7 @@ all pipes, so I do not see a reason to use non-blocking IO here
 
       /* Retry information: for most success cases this will be null. */
 
-      for (r = addr->retries; r; r = r->next)
+      for (retry_item * r = addr->retries; r; r = r->next)
         {
         sprintf(CS big_buffer, "%c%.500s", r->flags, r->key);
         ptr = big_buffer + Ustrlen(big_buffer+2) + 3;
@@ -6734,7 +6737,7 @@ while (addr_new)           /* Loop until all addresses dealt with */
       (void)post_process_one(addr, DEFER, LOG_MAIN, EXIM_DTYPE_ROUTER, 0);
 
       /* For remote-retry errors (here and just above) that we've not yet
-      hit the rery time, use the error recorded in the retry database
+      hit the retry time, use the error recorded in the retry database
       as info in the warning message.  This lets us send a message even
       when we're not failing on a fresh attempt.  We assume that this
       info is not sensitive. */
@@ -7341,7 +7344,7 @@ if (addr_senddsn)
   if (pid < 0)  /* Creation of child failed */
     {
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Process %d (parent %d) failed to "
-      "create child process to send failure message: %s", getpid(),
+      "create child process to send success-dsn message: %s", getpid(),
       getppid(), strerror(errno));
 
     DEBUG(D_deliver) debug_printf("DSN: child_open_exim failed\n");
@@ -7354,7 +7357,7 @@ if (addr_senddsn)
     transport_ctx tctx = {{0}};
 
     DEBUG(D_deliver)
-      debug_printf("sending error message to: %s\n", sender_address);
+      debug_printf("sending success-dsn to: %s\n", sender_address);
 
     /* build unique id for MIME boundary */
     bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
@@ -7366,8 +7369,11 @@ if (addr_senddsn)
     moan_write_from(f);
     fprintf(f, "Auto-Submitted: auto-generated\n"
        "To: %s\n"
-       "Subject: Delivery Status Notification\n"
-       "Content-Type: multipart/report; report-type=delivery-status; boundary=%s\n"
+       "Subject: Delivery Status Notification\n",
+      sender_address);
+    moan_write_references(f, NULL);
+    fprintf(f, "Content-Type: multipart/report;"
+               " report-type=delivery-status; boundary=%s\n"
        "MIME-Version: 1.0\n\n"
 
        "--%s\n"
@@ -7375,7 +7381,7 @@ if (addr_senddsn)
 
        "This message was created automatically by mail delivery software.\n"
        " ----- The following addresses had successful delivery notifications -----\n",
-      sender_address, bound, bound);
+      bound, bound);
 
     for (address_item * a = addr_senddsn; a; a = a->next)
       fprintf(f, "<%s> (relayed %s)\n\n",
@@ -7604,6 +7610,7 @@ while (addr_failed)
       fprintf(fp, "Auto-Submitted: auto-replied\n");
       moan_write_from(fp);
       fprintf(fp, "To: %s\n", bounce_recipient);
+      moan_write_references(fp, NULL);
 
       /* generate boundary string and output MIME-Headers */
       bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
@@ -8189,7 +8196,8 @@ else if (addr_defer != (address_item *)(+1))
 
     DEBUG(D_deliver)
       {
-      debug_printf("time on queue = %s  id %s  addr %s\n", readconf_printtime(queue_time), message_id, addr_defer->address);
+      debug_printf("time on queue = %s  id %s  addr %s\n",
+       readconf_printtime(queue_time), message_id, addr_defer->address);
       debug_printf("warning counts: required %d done %d\n", count,
         warning_count);
       }
@@ -8227,6 +8235,7 @@ else if (addr_defer != (address_item *)(+1))
         fprintf(f, "Auto-Submitted: auto-replied\n");
         moan_write_from(f);
         fprintf(f, "To: %s\n", recipients);
+       moan_write_references(f, NULL);
 
         /* generated boundary string and output MIME-Headers */
         bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
@@ -8284,13 +8293,9 @@ else if (addr_defer != (address_item *)(+1))
 
         /* List the addresses, with error information if allowed */
 
-        /* store addr_defer for machine readable part */
-        address_item *addr_dsndefer = addr_defer;
         fputc('\n', f);
-        while (addr_defer)
+       for (address_item * addr = addr_defer; addr; addr = addr->next)
           {
-          address_item *addr = addr_defer;
-          addr_defer = addr->next;
           if (print_address_information(addr, f, US"  ", US"\n    ", US""))
             print_address_error(addr, f, US"Delay reason: ");
           fputc('\n', f);
@@ -8333,16 +8338,16 @@ else if (addr_defer != (address_item *)(+1))
           }
         fputc('\n', f);
 
-        for ( ; addr_dsndefer; addr_dsndefer = addr_dsndefer->next)
+       for (address_item * addr = addr_defer; addr; addr = addr->next)
           {
          host_item * hu;
 
-         print_dsn_addr_action(f, addr_dsndefer, US"delayed", US"4.0.0");
+         print_dsn_addr_action(f, addr, US"delayed", US"4.0.0");
 
-          if ((hu = addr_dsndefer->host_used) && hu->name)
+          if ((hu = addr->host_used) && hu->name)
             {
             fprintf(f, "Remote-MTA: dns; %s\n", hu->name);
-            print_dsn_diagnostic_code(addr_dsndefer, f);
+            print_dsn_diagnostic_code(addr, f);
             }
          fputc('\n', f);
           }