Added DomainKeys support. See doc/experimental-spec.txt for documentation.
[exim.git] / src / src / smtp_in.c
index 8bc12debfb26fbce983a47591ebbc6c94db1295a..98a8d6ddfb4707c2f3a3e298c16d18853efbbf35 100644 (file)
@@ -1,10 +1,10 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.12 2005/03/08 15:32:02 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2004 */
+/* Copyright (c) University of Cambridge 1995 - 2005 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions for handling an incoming SMTP call. */
@@ -167,17 +167,18 @@ static smtp_cmd_list *cmd_list_end =
 #define CMD_LIST_STARTTLS  4
 
 static uschar *protocols[] = {
-  US"local-smtp",
-  US"local-esmtp",
-  US"local-esmtpa",
-  US"local-esmtps",
-  US"local-esmtpsa"
+  US"local-smtp",        /* HELO */
+  US"local-smtps",       /* The rare case EHLO->STARTTLS->HELO */
+  US"local-esmtp",       /* EHLO */
+  US"local-esmtps",      /* EHLO->STARTTLS->EHLO */
+  US"local-esmtpa",      /* EHLO->AUTH */
+  US"local-esmtpsa"      /* EHLO->STARTTLS->EHLO->AUTH */
   };
 
 #define pnormal  0
-#define pextend  1
-#define pauthed  1  /* added to pextend */
-#define pcrpted  2  /* added to pextend */
+#define pextend  2
+#define pcrpted  1  /* added to pextend or pnormal */
+#define pauthed  2  /* added to pextend */
 #define pnlocal  6  /* offset to remove "local" */
 
 /* When reading SMTP from a remote host, we have to use our own versions of the
@@ -803,8 +804,14 @@ rcpt_count = rcpt_defer_count = rcpt_fail_count =
 message_size = -1;
 acl_warn_headers = NULL;
 queue_only_policy = FALSE;
-deliver_freeze = FALSE;             /* Can be set by ACL */
-submission_mode = FALSE;            /* Can be set by ACL */
+deliver_freeze = FALSE;                              /* Can be set by ACL */
+fake_reject = FALSE;                                 /* Can be set by ACL */
+#ifdef WITH_CONTENT_SCAN
+no_mbox_unspool = FALSE;                             /* Can be set by ACL */
+#endif
+submission_mode = FALSE;                             /* Can be set by ACL */
+active_local_from_check = local_from_check;          /* Can be set by ACL */
+active_local_sender_retain = local_sender_retain;    /* Can be set by ACL */
 sender_address = NULL;
 raw_sender = NULL;                  /* After SMTP rewrite, before qualifying */
 sender_address_unrewritten = NULL;  /* Set only after verify rewrite */
@@ -812,6 +819,19 @@ sender_verified_list = NULL;        /* No senders verified */
 memset(sender_address_cache, 0, sizeof(sender_address_cache));
 memset(sender_domain_cache, 0, sizeof(sender_domain_cache));
 authenticated_sender = NULL;
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+bmi_run = 0;
+bmi_verdicts = NULL;
+#endif
+#ifdef EXPERIMENTAL_DOMAINKEYS
+dk_do_verify = 0;
+#endif
+#ifdef EXPERIMENTAL_SPF
+spf_header_comment = NULL;
+spf_received = NULL;
+spf_result = NULL;
+spf_smtp_comment = NULL;
+#endif
 body_linecount = body_zerocount = 0;
 
 for (i = 0; i < ACL_M_MAX; i++) acl_var[ACL_C_MAX + i] = NULL;
@@ -1104,6 +1124,17 @@ int size = 256;
 int i, ptr;
 uschar *p, *s, *ss;
 
+/* If we are running in the test harness, and the incoming call is from
+127.0.0.2 (sic), have a short delay. This makes it possible to test handling of
+input sent too soon (before the banner is output). */
+
+if (running_in_test_harness &&
+    sender_host_address != NULL &&
+    Ustrcmp(sender_host_address, "127.0.0.2") == 0)
+  sleep(1);
+
+/* Default values for certain variables */
+
 helo_seen = esmtp = helo_accept_junk = FALSE;
 count_nonmail = TRUE_UNSET;
 synprot_error_count = unknown_command_count = nonmail_command_count = 0;
@@ -1581,9 +1612,13 @@ if (smtp_enforce_sync && sender_host_address != NULL && !sender_host_notsocket)
   if (select(fileno(smtp_in) + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL,
       &tzero) > 0)
     {
+    int rc = read(fileno(smtp_in), smtp_inbuffer, in_buffer_size);
+    if (rc > 150) rc = 150;
+    smtp_inbuffer[rc] = 0;
     log_write(0, LOG_MAIN|LOG_REJECT, "SMTP protocol violation: "
       "synchronization error (input sent without waiting for greeting): "
-      "rejected connection from %s", host_and_ident(TRUE));
+      "rejected connection from %s input=\"%s\"", host_and_ident(TRUE),
+      string_printing(smtp_inbuffer));
     smtp_printf("554 SMTP synchronization error\r\n");
     return FALSE;
     }
@@ -1771,6 +1806,9 @@ BOOL drop = rc == FAIL_DROP;
 uschar *lognl;
 uschar *sender_info = US"";
 uschar *what = (where == ACL_WHERE_PREDATA)? US"DATA" :
+#ifdef WITH_CONTENT_SCAN
+               (where == ACL_WHERE_MIME)? US"during MIME ACL checks" :
+#endif
                (where == ACL_WHERE_DATA)? US"after DATA" :
   string_sprintf("%s %s", acl_wherenames[where], smtp_data);
 
@@ -1782,7 +1820,11 @@ fixed, sender_address at this point became the rewritten address. I'm not sure
 this is what should be logged, so I've changed to logging the unrewritten
 address to retain backward compatibility. */
 
+#ifndef WITH_CONTENT_SCAN
 if (where == ACL_WHERE_RCPT || where == ACL_WHERE_DATA)
+#else
+if (where == ACL_WHERE_RCPT || where == ACL_WHERE_DATA || where == ACL_WHERE_MIME)
+#endif
   {
   sender_info = string_sprintf("F=<%s> ", (sender_address_unrewritten != NULL)?
     sender_address_unrewritten : sender_address);
@@ -2337,6 +2379,11 @@ while (done <= 0)
         }
       }
 
+#ifdef EXPERIMENTAL_SPF
+    /* set up SPF context */
+    spf_init(sender_helo_name, sender_host_address);
+#endif
+
     /* Apply an ACL check if one is defined */
 
     if (acl_smtp_helo != NULL)
@@ -2360,7 +2407,7 @@ while (done <= 0)
         ((sender_host_authenticated != NULL)? pauthed : 0) +
         ((tls_active >= 0)? pcrpted : 0)]
       :
-      protocols[pnormal])
+      protocols[pnormal + ((tls_active >= 0)? pcrpted : 0)])
       +
       ((sender_host_address != NULL)? pnlocal : 0);
 
@@ -3032,8 +3079,13 @@ while (done <= 0)
       break;
       }
 
-    rc = (acl_smtp_predata == NULL)? OK :
-      acl_check(ACL_WHERE_PREDATA, NULL, acl_smtp_predata, &user_msg, &log_msg);
+    if (acl_smtp_predata == NULL) rc = OK; else
+      {
+      enable_dollar_recipients = TRUE;
+      rc = acl_check(ACL_WHERE_PREDATA, NULL, acl_smtp_predata, &user_msg,
+        &log_msg);
+      enable_dollar_recipients = FALSE;
+      }
 
     if (rc == OK)
       {
@@ -3071,7 +3123,7 @@ while (done <= 0)
         {
         address_item *addr = deliver_make_addr(address, FALSE);
         switch(verify_address(addr, NULL, vopt_is_recipient | vopt_qualify, -1,
-               -1, NULL, NULL, NULL))
+               -1, -1, NULL, NULL, NULL))
           {
           case OK:
           s = string_sprintf("250 <%s> is deliverable", address);
@@ -3108,7 +3160,8 @@ while (done <= 0)
       BOOL save_log_testing_mode = log_testing_mode;
       address_test_mode = log_testing_mode = TRUE;
       (void) verify_address(deliver_make_addr(smtp_data, FALSE), smtp_out,
-        vopt_is_recipient | vopt_qualify | vopt_expn, -1, -1, NULL, NULL, NULL);
+        vopt_is_recipient | vopt_qualify | vopt_expn, -1, -1, -1, NULL, NULL,
+        NULL);
       address_test_mode = FALSE;
       log_testing_mode = save_log_testing_mode;    /* true for -bh */
       }
@@ -3174,7 +3227,7 @@ while (done <= 0)
         protocols[pextend + pcrpted +
           ((sender_host_authenticated != NULL)? pauthed : 0)]
         :
-        protocols[pnormal])
+        protocols[pnormal + pcrpted])
         +
         ((sender_host_address != NULL)? pnlocal : 0);