]> git.netwichtig.de Git - user/henk/code/exim.git/blobdiff - src/src/deliver.c
Add optional authenticated_sender info to A= elements of log lines; bug 1314.
[user/henk/code/exim.git] / src / src / deliver.c
index b4d0251a721aefa1f07cb9d3be48d7a69e9f31e6..af39448c595962488b37a90afad4316008cf287e 100644 (file)
@@ -673,8 +673,15 @@ while (addr->parent != NULL)
 
 
 
+/* If msg is NULL this is a delivery log and logchar is used. Otherwise
+this is a nonstandard call; no two-characher delivery flag is written
+but sender-host and sender are prefixed and "msg" is inserted in the log line.
+
+Arguments:
+  flags                passed to log_write()
+*/
 void
-delivery_log(address_item * addr, int logchar)
+delivery_log(int flags, address_item * addr, int logchar, uschar * msg)
 {
 uschar *log_address;
 int size = 256;         /* Used for a temporary, */
@@ -689,12 +696,17 @@ have a pointer to the host item that succeeded; local deliveries can have a
 pointer to a single host item in their host list, for use by the transport. */
 
 s = reset_point = store_get(size);
-s[ptr++] = logchar;
 
 log_address = string_log_address(addr, (log_write_selector & L_all_parents) != 0, TRUE);
-s = string_append(s, &size, &ptr, 2, US"> ", log_address);
+if (msg)
+  s = string_append(s, &size, &ptr, 3, host_and_ident(TRUE), US" ", log_address);
+else
+  {
+  s[ptr++] = logchar;
+  s = string_append(s, &size, &ptr, 2, US"> ", log_address);
+  }
 
-if ((log_extra_selector & LX_sender_on_delivery) != 0)
+if ((log_extra_selector & LX_sender_on_delivery) != 0  ||  msg)
   s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");
 
 #ifdef EXPERIMENTAL_SRS
@@ -711,8 +723,10 @@ if (used_return_path != NULL &&
       (log_extra_selector & LX_return_path_on_delivery) != 0)
   s = string_append(s, &size, &ptr, 3, US" P=<", used_return_path, US">");
 
-/* For a delivery from a system filter, there may not be a router */
+if (msg)
+  s = string_append(s, &size, &ptr, 2, US" ", msg);
 
+/* For a delivery from a system filter, there may not be a router */
 if (addr->router != NULL)
   s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name);
 
@@ -760,6 +774,17 @@ else
       string_printing(addr->peerdn), US"\"");
   #endif
 
+  if (smtp_authenticated)
+    {
+    s = string_append(s, &size, &ptr, 2, US" A=", client_authenticator);
+    if (client_authenticated_id)
+      {
+      s = string_append(s, &size, &ptr, 2, US":", client_authenticated_id);
+      if (log_extra_selector & LX_smtp_mailauth  &&  client_authenticated_sender)
+        s = string_append(s, &size, &ptr, 2, US":", client_authenticated_sender);
+      }
+    }
+
   if ((log_extra_selector & LX_smtp_confirmation) != 0 &&
       addr->message != NULL)
     {
@@ -796,7 +821,7 @@ if ((log_extra_selector & LX_deliver_time) != 0)
 store we used to build the line after writing it. */
 
 s[ptr] = 0;
-log_write(0, LOG_MAIN, "%s", s);
+log_write(0, flags, "%s", s);
 store_reset(reset_point);
 return;
 }
@@ -992,7 +1017,7 @@ if (result == OK)
     child_done(addr, now);
     }
 
-  delivery_log(addr, logchar);
+  delivery_log(LOG_MAIN, addr, logchar, NULL);
   }
 
 
@@ -2899,6 +2924,23 @@ while (!done)
     break;
     #endif
 
+    case 'C':  /* client authenticator information */
+    switch (*ptr++)
+    {
+    case '1':
+      smtp_authenticated = TRUE;
+      client_authenticator = (*ptr)? string_copy(ptr) : NULL;
+      break;
+    case '2':
+      client_authenticated_id = (*ptr)? string_copy(ptr) : NULL;
+      break;
+    case '3':
+      client_authenticated_sender = (*ptr)? string_copy(ptr) : NULL;
+      break;
+    }
+    while (*ptr++);
+    break;
+
     case 'A':
     if (addr == NULL)
       {
@@ -3936,10 +3978,10 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
     memcpy(big_buffer+1, &transport_count, sizeof(transport_count));
     (void)write(fd, big_buffer, sizeof(transport_count) + 1);
 
-    /* Information about what happened to each address. Three item types are
-    used: an optional 'X' item first, for TLS information, followed by 'R'
-    items for any retry settings, and finally an 'A' item for the remaining
-    data. */
+    /* Information about what happened to each address. Four item types are
+    used: an optional 'X' item first, for TLS information, then an optional "C"
+    item for any client-auth info followed by 'R' items for any retry settings,
+    and finally an 'A' item for the remaining data. */
 
     for(; addr != NULL; addr = addr->next)
       {
@@ -3948,7 +3990,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
 
       /* The certificate verification status goes into the flags */
 
-      if (tls_certificate_verified) setflag(addr, af_cert_verified);
+      if (tls_out.certificate_verified) setflag(addr, af_cert_verified);
 
       /* Use an X item only if there's something to send */
 
@@ -3956,8 +3998,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
       if (addr->cipher != NULL)
         {
         ptr = big_buffer;
-        *ptr++ = 'X';
-        sprintf(CS ptr, "%.128s", addr->cipher);
+        sprintf(CS ptr, "X%.128s", addr->cipher);
         while(*ptr++);
         if (addr->peerdn == NULL) *ptr++ = 0; else
           {
@@ -3968,6 +4009,28 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
         }
       #endif
 
+      if (client_authenticator)
+        {
+        ptr = big_buffer;
+       sprintf(CS big_buffer, "C1%.64s", client_authenticator);
+        while(*ptr++);
+        (void)write(fd, big_buffer, ptr - big_buffer);
+       }
+      if (client_authenticated_id)
+        {
+        ptr = big_buffer;
+       sprintf(CS big_buffer, "C2%.64s", client_authenticated_id);
+        while(*ptr++);
+        (void)write(fd, big_buffer, ptr - big_buffer);
+       }
+      if (client_authenticated_sender)
+        {
+        ptr = big_buffer;
+       sprintf(CS big_buffer, "C3%.64s", client_authenticated_sender);
+        while(*ptr++);
+        (void)write(fd, big_buffer, ptr - big_buffer);
+       }
+
       /* Retry information: for most success cases this will be null. */
 
       for (r = addr->retries; r != NULL; r = r->next)
@@ -4501,6 +4564,7 @@ FILE *jread;
 int process_recipients = RECIP_ACCEPT;
 open_db dbblock;
 open_db *dbm_file;
+extern int acl_where;
 
 uschar *info = (queue_run_pid == (pid_t)0)?
   string_sprintf("delivering %s", id) :
@@ -4551,6 +4615,9 @@ message_size = 0;
 update_spool = FALSE;
 remove_journal = TRUE;
 
+/* Set a known context for any ACLs we call via expansions */
+acl_where = ACL_WHERE_DELIVERY;
+
 /* Reset the random number generator, so that if several delivery processes are
 started from a queue runner that has already used random numbers (for sorting),
 they don't all get the same sequence. */
@@ -7020,6 +7087,7 @@ expand_check_condition) to do a lookup. We must therefore be sure everything is
 released. */
 
 search_tidyup();
+acl_where = ACL_WHERE_UNKNOWN;
 return final_yield;
 }