Code for verify=header_names_ascii
[exim.git] / src / src / verify.c
index a1b8142a9e75346571e47685374cde0e36078105..3d3bfdaf017968f0dd9c28c19b0b2037870d02b8 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 - 2014 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions concerned with verifying things. The original code for callout
@@ -538,7 +538,7 @@ else
     #endif
       if (!(done= smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer), '2', callout)))
         goto RESPONSE_FAILED;
-    
+
     /* Not worth checking greeting line for ESMTP support */
     if (!(esmtp = verify_check_this_host(&(ob->hosts_avoid_esmtp), NULL,
       host->name, host->address, NULL) != OK))
@@ -634,12 +634,14 @@ else
       else
         {
         int rc = tls_client_start(inblock.sock, host, addr,
-        NULL,                    /* No DH param */
         ob->tls_certificate, ob->tls_privatekey,
         ob->tls_sni,
         ob->tls_verify_certificates, ob->tls_crl,
-        ob->tls_require_ciphers,     ob->tls_dh_min_bits,
-        callout);
+        ob->tls_require_ciphers,
+#ifdef EXPERIMENTAL_OCSP
+        ob->hosts_require_ocsp,
+#endif
+        ob->tls_dh_min_bits,         callout);
 
         /* TLS negotiation failed; give an error.  Try in clear on a new connection,
            if the options permit it for this host. */
@@ -692,13 +694,23 @@ else
 
     done = TRUE; /* so far so good; have response to HELO */
 
-    /*XXX the EHLO response would be analyzed here for IGNOREQUOTA, SIZE, PIPELINING, AUTH */
-    /* If we haven't authenticated, but are required to, give up. */
+    /*XXX the EHLO response would be analyzed here for IGNOREQUOTA, SIZE, PIPELINING */
 
-    /*XXX "filter command specified for this transport" ??? */
-    /* for now, transport_filter by cutthrough-delivery is not supported */
+    /* For now, transport_filter by cutthrough-delivery is not supported */
     /* Need proper integration with the proper transport mechanism. */
-
+    if (cutthrough_delivery)
+      {
+      if (addr->transport->filter_command)
+        {
+        cutthrough_delivery= FALSE;
+        HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of transport filter\n");
+        }
+      if (ob->dkim_domain)
+        {
+        cutthrough_delivery= FALSE;
+        HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of DKIM signing\n");
+        }
+      }
 
     SEND_FAILED:
     RESPONSE_FAILED:
@@ -720,11 +732,27 @@ else
         }
       }
 
+    /* If we haven't authenticated, but are required to, give up. */
+    /* Try to AUTH */
+
+    else done = smtp_auth(responsebuffer, sizeof(responsebuffer),
+       addr, host, ob, esmtp, &inblock, &outblock) == OK  &&
+
+               /* Copy AUTH info for logging */
+      ( (addr->authenticator = client_authenticator),
+        (addr->auth_id = client_authenticated_id),
+
+    /* Build a mail-AUTH string (re-using responsebuffer for convenience */
+        !smtp_mail_auth_str(responsebuffer, sizeof(responsebuffer), addr, ob)
+      )  &&
+
+      ( (addr->auth_sndr = client_authenticated_sender),
+
     /* Send the MAIL command */
+        (smtp_write_command(&outblock, FALSE, "MAIL FROM:<%s>%s\r\n",
+          from_address, responsebuffer) >= 0)
+      )  &&
 
-    else done =
-      smtp_write_command(&outblock, FALSE, "MAIL FROM:<%s>\r\n",
-        from_address) >= 0 &&
       smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
         '2', callout);
 
@@ -2127,6 +2155,41 @@ return yield;
 }
 
 
+/*************************************************
+*      Check header names for 8-bit characters   *
+*************************************************/
+
+/* This function checks for invalid charcters in header names. See
+RFC 5322, 2.2. and RFC 6532, 3.
+
+Arguments:
+  msgptr     where to put an error message
+
+Returns:     OK
+             FAIL
+*/
+
+int
+verify_check_header_names_ascii(uschar **msgptr)
+{
+header_line *h;
+uschar *colon, *s;
+
+for (h = header_list; h != NULL; h = h->next)
+  {
+   colon = Ustrchr(h->text, ':');
+   for(s = h->text; s < colon; s++)
+     {
+        if ((*s < 33) || (*s > 126))
+        {
+                *msgptr = string_sprintf("Invalid character in header \"%.*s\" found",
+                                         colon - h->text, h->text);
+                return FAIL;
+        }
+     }
+  }
+return OK;
+}
 
 /*************************************************
 *          Check for blind recipients            *