Introduce EXPERIMENTAL_DANE feature
[users/heiko/exim.git] / src / src / spool_in.c
index 0e4bc413df8a7a74b3f7bfdca66ab9d89bb22e62..bbb4da6aaa117840f720166e04fbcacb2361cf9a 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2012 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions for reading spool files. When compiling for a utility (eximon),
@@ -283,15 +283,27 @@ dkim_collect_input = FALSE;
 #endif
 
 #ifdef SUPPORT_TLS
-tls_certificate_verified = FALSE;
-tls_cipher = NULL;
-tls_peerdn = NULL;
+tls_in.certificate_verified = FALSE;
+# ifdef EXPERIMENTAL_DANE
+tls_in.dane_verified = FALSE;
+# endif
+tls_in.cipher = NULL;
+tls_in.ourcert = NULL;
+tls_in.peercert = NULL;
+tls_in.peerdn = NULL;
+tls_in.sni = NULL;
+tls_in.ocsp = OCSP_NOT_REQ;
 #endif
 
 #ifdef WITH_CONTENT_SCAN
 spam_score_int = NULL;
 #endif
 
+#ifdef EXPERIMENTAL_DSN
+dsn_ret = 0;
+dsn_envid = NULL;
+#endif
+
 /* Generate the full name and open the file. If message_subdir is already
 set, just look in the given directory. Otherwise, look in both the split
 and unsplit directories, as for the data file above. */
@@ -466,13 +478,24 @@ for (;;)
     case 'd':
     if (Ustrcmp(p, "eliver_firsttime") == 0)
       deliver_firsttime = TRUE;
+    #ifdef EXPERIMENTAL_DSN
+    /* Check if the dsn flags have been set in the header file */
+    else if (Ustrncmp(p, "sn_ret", 6) == 0)
+      {
+      dsn_ret= atoi(big_buffer + 8);
+      }
+    else if (Ustrncmp(p, "sn_envid", 8) == 0)
+      {
+      dsn_envid = string_copy(big_buffer + 11);
+      }
+    #endif
     break;
 
     case 'f':
     if (Ustrncmp(p, "rozen", 5) == 0)
       {
       deliver_freeze = TRUE;
-      deliver_frozen_at = Uatoi(big_buffer + 7);
+      sscanf(CS big_buffer+7, TIME_T_FMT, &deliver_frozen_at);
       }
     break;
 
@@ -544,11 +567,21 @@ for (;;)
     #ifdef SUPPORT_TLS
     case 't':
     if (Ustrncmp(p, "ls_certificate_verified", 23) == 0)
-      tls_certificate_verified = TRUE;
+      tls_in.certificate_verified = TRUE;
     else if (Ustrncmp(p, "ls_cipher", 9) == 0)
-      tls_cipher = string_copy(big_buffer + 12);
+      tls_in.cipher = string_copy(big_buffer + 12);
+#ifndef COMPILE_UTILITY
+    else if (Ustrncmp(p, "ls_ourcert", 10) == 0)
+      (void) tls_import_cert(big_buffer + 13, &tls_in.ourcert);
+    else if (Ustrncmp(p, "ls_peercert", 11) == 0)
+      (void) tls_import_cert(big_buffer + 14, &tls_in.peercert);
+#endif
     else if (Ustrncmp(p, "ls_peerdn", 9) == 0)
-      tls_peerdn = string_copy(big_buffer + 12);
+      tls_in.peerdn = string_unprinting(string_copy(big_buffer + 12));
+    else if (Ustrncmp(p, "ls_sni", 6) == 0)
+      tls_in.sni = string_unprinting(string_copy(big_buffer + 9));
+    else if (Ustrncmp(p, "ls_ocsp", 7) == 0)
+      tls_in.ocsp = big_buffer[10] - '0';
     break;
     #endif
 
@@ -601,6 +634,10 @@ for (recipients_count = 0; recipients_count < rcount; recipients_count++)
   {
   int nn;
   int pno = -1;
+  #ifdef EXPERIMENTAL_DSN
+  int dsn_flags = 0;
+  uschar *orcpt = NULL;
+  #endif
   uschar *errors_to = NULL;
   uschar *p;
 
@@ -643,6 +680,9 @@ for (recipients_count = 0; recipients_count < rcount; recipients_count++)
       ends with <errors_to address><space><len>,<pno> where pno is
       the parent number for one_time addresses, and len is the length
       of the errors_to address (zero meaning none).
+
+    Bit 02 indicates that, again reading from right to left, the data continues
+     with orcpt len(orcpt),dsn_flags
    */
 
   while (isdigit(*p)) p--;
@@ -673,6 +713,13 @@ for (recipients_count = 0; recipients_count < rcount; recipients_count++)
   else if (*p == '#')
     {
     int flags;
+
+    #ifdef EXPERIMENTAL_DSN
+    #ifndef COMPILE_UTILITY
+      DEBUG(D_deliver) debug_printf("**** SPOOL_IN - Exim 4 standard format spoolfile\n");
+    #endif  /* COMPILE_UTILITY */
+    #endif
+
     (void)sscanf(CS p+1, "%d", &flags);
 
     if ((flags & 0x01) != 0)      /* one_time data exists */
@@ -685,15 +732,54 @@ for (recipients_count = 0; recipients_count < rcount; recipients_count++)
         {
         p -= len;
         errors_to = string_copy(p);
-        }
+        }      
       }
 
     *(--p) = 0;   /* Terminate address */
+#ifdef EXPERIMENTAL_DSN
+    if ((flags & 0x02) != 0)      /* one_time data exists */
+      {
+      int len;
+      while (isdigit(*(--p)) || *p == ',' || *p == '-');
+      (void)sscanf(CS p+1, "%d,%d", &len, &dsn_flags);
+      *p = 0;
+      if (len > 0)
+        {
+        p -= len;
+        orcpt = string_copy(p);
+        }      
+      }
+
+    *(--p) = 0;   /* Terminate address */
+#endif  /* EXPERIMENTAL_DSN */
+    }
+#ifdef EXPERIMENTAL_DSN
+  #ifndef COMPILE_UTILITY
+  else
+    {
+       DEBUG(D_deliver) debug_printf("**** SPOOL_IN - No additional fields\n");
+    }
+
+  if ((orcpt != NULL) || (dsn_flags != 0))
+    {
+    DEBUG(D_deliver) debug_printf("**** SPOOL_IN - address: |%s| orcpt: |%s| dsn_flags: %d\n",
+      big_buffer, orcpt, dsn_flags);
     }
+  if (errors_to != NULL)
+    {
+    DEBUG(D_deliver) debug_printf("**** SPOOL_IN - address: |%s| errorsto: |%s|\n",
+      big_buffer, errors_to);
+    }
+  #endif  /* COMPILE_UTILITY */
+#endif  /* EXPERIMENTAL_DSN */
 
   recipients_list[recipients_count].address = string_copy(big_buffer);
   recipients_list[recipients_count].pno = pno;
   recipients_list[recipients_count].errors_to = errors_to;
+  #ifdef EXPERIMENTAL_DSN
+  recipients_list[recipients_count].orcpt = orcpt;
+  recipients_list[recipients_count].dsn_flags = dsn_flags;
+  #endif
   }
 
 /* The remainder of the spool header file contains the headers for the message,
@@ -715,8 +801,8 @@ while ((n = fgetc(f)) != EOF)
   int i;
 
   if (!isdigit(n)) goto SPOOL_FORMAT_ERROR;
-  (void)ungetc(n, f);
-  (void)fscanf(f, "%d%c ", &n, flag);
+  if(ungetc(n, f) == EOF  ||  fscanf(f, "%d%c ", &n, flag) == EOF)
+    goto SPOOL_READ_ERROR;
   if (flag[0] != '*') message_size += n;  /* Omit non-transmitted headers */
 
   if (read_headers)
@@ -796,4 +882,6 @@ errno = ERRNO_SPOOLFORMAT;
 return inheader? spool_read_hdrerror : spool_read_enverror;
 }
 
+/* vi: aw ai sw=2
+*/
 /* End of spool_in.c */