Make verify=helo do the verification on the fly it if was not done
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Tue, 2 Aug 2005 15:19:20 +0000 (15:19 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Tue, 2 Aug 2005 15:19:20 +0000 (15:19 +0000)
earlier, like $sender_host_name handling.

doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/acl.c
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/smtp_in.c

index 0283defca73614d92d4056af1dcdf3919564678a..37b28a17d2cbbb0aa0adeff2dd9902722093e068 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.195 2005/08/02 13:43:04 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.196 2005/08/02 15:19:20 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -50,6 +50,12 @@ PH/12 There was a missing call to search_tidyup() before the fork() in rda.c to
       lookups in the parent process. There should also be a search_tidyup() at
       the end of the subprocess.
 
       lookups in the parent process. There should also be a search_tidyup() at
       the end of the subprocess.
 
+PH/13 Previously, if "verify = helo" was set in an ACL, the condition was true
+      only if the host matched helo_try_verify_hosts, which caused the
+      verification to occur when the EHLO/HELO command was issued. The ACL just
+      tested the remembered result. Now, if a previous verification attempt has
+      not happened, "verify = helo" does it there and then.
+
 
 Exim version 4.52
 -----------------
 
 Exim version 4.52
 -----------------
index 5936f198b65a556f298f283a6b2c1efdd7c240fd..2d653616df1a0ad011de867009056e27044a0892 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.60 2005/08/02 11:22:23 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.61 2005/08/02 15:19:20 ph10 Exp $
 
 New Features in Exim
 --------------------
 
 New Features in Exim
 --------------------
@@ -62,6 +62,12 @@ PH/04 The IGNOREQUOTA extension to the LMTP protocol is now available in both
       provided that the server has advertised support for IGNOREQUOTA in its
       response to the LHLO command.
 
       provided that the server has advertised support for IGNOREQUOTA in its
       response to the LHLO command.
 
+PH/05 Previously, if "verify = helo" was set in an ACL, the condition was true
+      only if the host matched helo_try_verify_hosts, which caused the
+      verification to occur when the EHLO/HELO command was issued. The ACL just
+      tested the remembered result. Now, if a previous verification attempt has
+      not happened, "verify = helo" does it there and then.
+
 
 Exim version 4.52
 -----------------
 
 Exim version 4.52
 -----------------
index 7bab711e0255fd81622ee2ae6e78ed1c1041bd15..f4788d19e55b94a8c575c688f96530a6900391e1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.42 2005/07/23 20:46:42 tom Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.43 2005/08/02 15:19:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1376,12 +1376,16 @@ if (strcmpic(ss, US"certificate") == 0)
   return FAIL;
   }
 
   return FAIL;
   }
 
-/* We can test the result of optional HELO verification */
+/* We can test the result of optional HELO verification that might have
+occurred earlier. If not, we can attempt the verification now. */
 
 if (strcmpic(ss, US"helo") == 0)
   {
   if (slash != NULL) goto NO_OPTIONS;
 
 if (strcmpic(ss, US"helo") == 0)
   {
   if (slash != NULL) goto NO_OPTIONS;
-  return helo_verified? OK : FAIL;
+  if (helo_verified) return OK;
+  if (helo_verify_failed) return FAIL;
+  if (smtp_verify_helo()) return helo_verified? OK : FAIL;
+  return DEFER;
   }
 
 /* Do Client SMTP Authorization checks in a separate function, and turn the
   }
 
 /* Do Client SMTP Authorization checks in a separate function, and turn the
index 00d0f67687e0409cc6398387c7b2fdd824a29b71..7e61c92f611330d4c87ce32ca32f072fb36736af 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/functions.h,v 1.17 2005/06/22 10:17:23 ph10 Exp $ */
+/* $Cambridge: exim/src/src/functions.h,v 1.18 2005/08/02 15:19:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -268,6 +268,7 @@ extern void    smtp_send_prohibition_message(int, uschar *);
 extern int     smtp_setup_msg(void);
 extern BOOL    smtp_start_session(void);
 extern int     smtp_ungetc(int);
 extern int     smtp_setup_msg(void);
 extern BOOL    smtp_start_session(void);
 extern int     smtp_ungetc(int);
+extern BOOL    smtp_verify_helo(void);
 extern int     smtp_write_command(smtp_outblock *, BOOL, char *, ...);
 #ifdef WITH_CONTENT_SCAN
 extern int     spam(uschar **);
 extern int     smtp_write_command(smtp_outblock *, BOOL, char *, ...);
 #ifdef WITH_CONTENT_SCAN
 extern int     spam(uschar **);
index 698b2fc33ae413c9f25573b7e6e44f482ca69526..c233e76bd69107cb695e14b1a3e77380ea162bb1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.32 2005/08/02 11:22:24 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.33 2005/08/02 15:19:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -569,6 +569,7 @@ uschar *helo_allow_chars       = US"";
 uschar *helo_lookup_domains    = US"@ : @[]";
 uschar *helo_try_verify_hosts  = NULL;
 BOOL    helo_verified          = FALSE;
 uschar *helo_lookup_domains    = US"@ : @[]";
 uschar *helo_try_verify_hosts  = NULL;
 BOOL    helo_verified          = FALSE;
+BOOL    helo_verify_failed     = FALSE;
 uschar *helo_verify_hosts      = NULL;
 uschar *hex_digits             = US"0123456789abcdef";
 uschar *hold_domains           = NULL;
 uschar *helo_verify_hosts      = NULL;
 uschar *hex_digits             = US"0123456789abcdef";
 uschar *hold_domains           = NULL;
index 5ef0d4e215fa851403355a537f603774737e92ee..484a8d4f95177efc9312c74986e5ac12442a19d7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.23 2005/08/02 11:22:24 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.24 2005/08/02 15:19:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -343,6 +343,7 @@ extern uschar *helo_allow_chars;       /* Rogue chars to allow in HELO/EHLO */
 extern uschar *helo_lookup_domains;    /* If these given, lookup host name */
 extern uschar *helo_try_verify_hosts;  /* Soft check HELO argument for these */
 extern BOOL    helo_verified;          /* True if HELO verified */
 extern uschar *helo_lookup_domains;    /* If these given, lookup host name */
 extern uschar *helo_try_verify_hosts;  /* Soft check HELO argument for these */
 extern BOOL    helo_verified;          /* True if HELO verified */
+extern BOOL    helo_verify_failed;     /* True if attempt failed */
 extern uschar *helo_verify_hosts;      /* Hard check HELO argument for these */
 extern uschar *hex_digits;             /* Used in several places */
 extern uschar *hold_domains;           /* Hold up deliveries to these */
 extern uschar *helo_verify_hosts;      /* Hard check HELO argument for these */
 extern uschar *hex_digits;             /* Used in several places */
 extern uschar *hold_domains;           /* Hold up deliveries to these */
index f7549bb7c8580c3bb01825838945e3a9d4d75dbc..9a736a4b7bb68af059af192b7a0beaffd1283905 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.21 2005/08/02 08:25:45 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.22 2005/08/02 15:19:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1932,6 +1932,130 @@ return 2;
 
 
 
 
 
 
+/*************************************************
+*             Verify HELO argument               *
+*************************************************/
+
+/* This function is called if helo_verify_hosts or helo_try_verify_hosts is
+matched. It is also called from ACL processing if verify = helo is used and
+verification was not previously tried (i.e. helo_try_verify_hosts was not
+matched). The result of its processing is to set helo_verified and
+helo_verify_failed. These variables should both be FALSE for this function to
+be called.
+
+Note that EHLO/HELO is legitimately allowed to quote an address literal. Allow
+for IPv6 ::ffff: literals.
+
+Argument:   none
+Returns:    TRUE if testing was completed;
+            FALSE on a temporary failure
+*/
+
+BOOL
+smtp_verify_helo(void)
+{
+BOOL yield = TRUE;
+
+HDEBUG(D_receive) debug_printf("verifying EHLO/HELO argument \"%s\"\n",
+  sender_helo_name);
+
+if (sender_helo_name == NULL)
+  {
+  HDEBUG(D_receive) debug_printf("no EHLO/HELO command was issued\n");
+  }
+
+else if (sender_helo_name[0] == '[')
+  {
+  helo_verified = Ustrncmp(sender_helo_name+1, sender_host_address,
+    Ustrlen(sender_host_address)) == 0;
+
+  #if HAVE_IPV6
+  if (!helo_verified)
+    {
+    if (strncmpic(sender_host_address, US"::ffff:", 7) == 0)
+      helo_verified = Ustrncmp(sender_helo_name + 1,
+        sender_host_address + 7, Ustrlen(sender_host_address) - 7) == 0;
+    }
+  #endif
+
+  HDEBUG(D_receive)
+    { if (helo_verified) debug_printf("matched host address\n"); }
+  }
+
+/* Do a reverse lookup if one hasn't already given a positive or negative
+response. If that fails, or the name doesn't match, try checking with a forward
+lookup. */
+
+else
+  {
+  if (sender_host_name == NULL && !host_lookup_failed)
+    yield = host_name_lookup() != DEFER;
+
+  /* If a host name is known, check it and all its aliases. */
+
+  if (sender_host_name != NULL)
+    {
+    helo_verified = strcmpic(sender_host_name, sender_helo_name) == 0;
+
+    if (helo_verified)
+      {
+      HDEBUG(D_receive) debug_printf("matched host name\n");
+      }
+    else
+      {
+      uschar **aliases = sender_host_aliases;
+      while (*aliases != NULL)
+        {
+        helo_verified = strcmpic(*aliases++, sender_helo_name) == 0;
+        if (helo_verified) break;
+        }
+      HDEBUG(D_receive)
+        {
+        if (helo_verified)
+          debug_printf("matched alias %s\n", *(--aliases));
+        }
+      }
+    }
+
+  /* Final attempt: try a forward lookup of the helo name */
+
+  if (!helo_verified)
+    {
+    int rc;
+    host_item h;
+    h.name = sender_helo_name;
+    h.address = NULL;
+    h.mx = MX_NONE;
+    h.next = NULL;
+    HDEBUG(D_receive) debug_printf("getting IP address for %s\n",
+      sender_helo_name);
+    rc = host_find_byname(&h, NULL, NULL, TRUE);
+    if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL)
+      {
+      host_item *hh = &h;
+      while (hh != NULL)
+        {
+        if (Ustrcmp(hh->address, sender_host_address) == 0)
+          {
+          helo_verified = TRUE;
+          HDEBUG(D_receive)
+            debug_printf("IP address for %s matches calling address\n",
+              sender_helo_name);
+          break;
+          }
+        hh = hh->next;
+        }
+      }
+    }
+  }
+
+if (!helo_verified) helo_verify_failed = FALSE;  /* We've tried ... */
+return yield;
+}
+
+
+
+
 /*************************************************
 *       Initialize for SMTP incoming message     *
 *************************************************/
 /*************************************************
 *       Initialize for SMTP incoming message     *
 *************************************************/
@@ -2282,104 +2406,16 @@ while (done <= 0)
         (tls_active >= 0)? " TLS" : "", host_and_ident(FALSE));
 
       /* Verify if configured. This doesn't give much security, but it does
         (tls_active >= 0)? " TLS" : "", host_and_ident(FALSE));
 
       /* Verify if configured. This doesn't give much security, but it does
-      make some people happy to be able to do it. Note that HELO is legitimately
-      allowed to quote an address literal. Allow for IPv6 ::ffff: literals. */
+      make some people happy to be able to do it. If helo_required is set,
+      (host matches helo_verify_hosts) failure forces rejection. If helo_verify
+      is set (host matches helo_try_verify_hosts), it does not. This is perhaps
+      now obsolescent, since the verification can now be requested selectively
+      at ACL time. */
 
 
-      helo_verified = FALSE;
+      helo_verified = helo_verify_failed = FALSE;
       if (helo_required || helo_verify)
         {
       if (helo_required || helo_verify)
         {
-        BOOL tempfail = FALSE;
-
-        HDEBUG(D_receive) debug_printf("verifying %s %s\n", hello,
-          sender_helo_name);
-        if (sender_helo_name[0] == '[')
-          {
-          helo_verified = Ustrncmp(sender_helo_name+1, sender_host_address,
-            Ustrlen(sender_host_address)) == 0;
-
-          #if HAVE_IPV6
-          if (!helo_verified)
-            {
-            if (strncmpic(sender_host_address, US"::ffff:", 7) == 0)
-              helo_verified = Ustrncmp(sender_helo_name + 1,
-                sender_host_address + 7, Ustrlen(sender_host_address) - 7) == 0;
-            }
-          #endif
-
-          HDEBUG(D_receive)
-            { if (helo_verified) debug_printf("matched host address\n"); }
-          }
-
-        /* Do a reverse lookup if one hasn't already given a positive or
-        negative response. If that fails, or the name doesn't match, try
-        checking with a forward lookup. */
-
-        else
-          {
-          if (sender_host_name == NULL && !host_lookup_failed)
-            tempfail = host_name_lookup() == DEFER;
-
-          /* If a host name is known, check it and all its aliases. */
-
-          if (sender_host_name != NULL)
-            {
-            helo_verified = strcmpic(sender_host_name, sender_helo_name) == 0;
-
-            if (helo_verified)
-              {
-              HDEBUG(D_receive) debug_printf("matched host name\n");
-              }
-            else
-              {
-              uschar **aliases = sender_host_aliases;
-              while (*aliases != NULL)
-                {
-                helo_verified = strcmpic(*aliases++, sender_helo_name) == 0;
-                if (helo_verified) break;
-                }
-              HDEBUG(D_receive)
-                {
-                if (helo_verified)
-                  debug_printf("matched alias %s\n", *(--aliases));
-                }
-              }
-            }
-
-          /* Final attempt: try a forward lookup of the helo name */
-
-          if (!helo_verified)
-            {
-            int rc;
-            host_item h;
-            h.name = sender_helo_name;
-            h.address = NULL;
-            h.mx = MX_NONE;
-            h.next = NULL;
-            HDEBUG(D_receive) debug_printf("getting IP address for %s\n",
-              sender_helo_name);
-            rc = host_find_byname(&h, NULL, NULL, TRUE);
-            if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL)
-              {
-              host_item *hh = &h;
-              while (hh != NULL)
-                {
-                if (Ustrcmp(hh->address, sender_host_address) == 0)
-                  {
-                  helo_verified = TRUE;
-                  HDEBUG(D_receive)
-                    debug_printf("IP address for %s matches calling address\n",
-                      sender_helo_name);
-                  break;
-                  }
-                hh = hh->next;
-                }
-              }
-            }
-          }
-
-        /* Verification failed. A temporary lookup failure gives a temporary
-        error. */
-
+        BOOL tempfail = !smtp_verify_helo();
         if (!helo_verified)
           {
           if (helo_required)
         if (!helo_verified)
           {
           if (helo_required)