SECURITY: off-by-one in smtp transport (read response)
[exim.git] / src / src / spool_in.c
index 7d95fccc132cb8299dee29974159155aaa038962..f64c52c5a57ad411b2fed5cff1771a3ad8081ba3 100644 (file)
@@ -253,7 +253,7 @@ sender_helo_name = NULL;
 sender_host_address = NULL;
 sender_host_name = NULL;
 sender_host_port = 0;
-sender_host_authenticated = NULL;
+sender_host_authenticated = sender_host_auth_pubname = NULL;
 sender_ident = NULL;
 f.sender_local = FALSE;
 f.sender_set_untrusted = FALSE;
@@ -422,6 +422,8 @@ if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR;
 if (sscanf(CS big_buffer, TIME_T_FMT " %d", &received_time.tv_sec, &warning_count) != 2)
   goto SPOOL_FORMAT_ERROR;
 received_time.tv_usec = 0;
+received_time_complete = received_time;
+
 
 message_age = time(NULL) - received_time.tv_sec;
 #ifndef COMPILE_UTILITY
@@ -580,6 +582,8 @@ for (;;)
       host_lookup_deferred = TRUE;
     else if (Ustrcmp(p, "ost_lookup_failed") == 0)
       host_lookup_failed = TRUE;
+    else if (Ustrncmp(p, "ost_auth_pubname", 16) == 0)
+      sender_host_auth_pubname = string_copy_taint(var + 18, tainted);
     else if (Ustrncmp(p, "ost_auth", 8) == 0)
       sender_host_authenticated = string_copy_taint(var + 10, tainted);
     else if (Ustrncmp(p, "ost_name", 8) == 0)
@@ -637,7 +641,19 @@ for (;;)
       {
       unsigned usec;
       if (sscanf(CS var + 20, "%u", &usec) == 1)
+       {
        received_time.tv_usec = usec;
+       if (!received_time_complete.tv_sec) received_time_complete.tv_usec = usec;
+       }
+      }
+    else if (Ustrncmp(p, "eceived_time_complete", 21) == 0)
+      {
+      unsigned sec, usec;
+      if (sscanf(CS var + 23, "%u.%u", &sec, &usec) == 2)
+       {
+       received_time_complete.tv_sec = sec;
+       received_time_complete.tv_usec = usec;
+       }
       }
     break;
 
@@ -991,6 +1007,47 @@ errno = ERRNO_SPOOLFORMAT;
 return inheader? spool_read_hdrerror : spool_read_enverror;
 }
 
+
+#ifndef COMPILE_UTILITY
+/* Read out just the (envelope) sender string from the spool -H file.
+Remove the <> wrap and return it in allocated store.  Return NULL on error.
+
+We assume that message_subdir is already set.
+*/
+
+uschar *
+spool_sender_from_msgid(const uschar * id)
+{
+uschar * name = string_sprintf("%s-H", id);
+FILE * fp;
+int n;
+uschar * yield = NULL;
+
+if (!(fp = Ufopen(spool_fname(US"input", message_subdir, name, US""), "rb")))
+  return NULL;
+
+DEBUG(D_deliver) debug_printf_indent("reading spool file %s\n", name);
+
+/* Skip the line with the copy of the filename, then the line with login/uid/gid.
+Read the next line, which should be the envelope sender.
+Do basic validation on that. */
+
+if (  Ufgets(big_buffer, big_buffer_size, fp) != NULL
+   && Ufgets(big_buffer, big_buffer_size, fp) != NULL
+   && Ufgets(big_buffer, big_buffer_size, fp) != NULL
+   && (n = Ustrlen(big_buffer)) >= 3
+   && big_buffer[0] == '<' && big_buffer[n-2] == '>'
+   )
+  {
+  yield = store_get(n-2, TRUE);        /* tainted */
+  Ustrncpy(yield, big_buffer+1, n-3);
+  yield[n-3] = 0;
+  }
+fclose(fp);
+return yield;
+}
+#endif  /* COMPILE_UTILITY */
+
 /* vi: aw ai sw=2
 */
 /* End of spool_in.c */