summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2005-08-02 15:19:20 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2005-08-02 15:19:20 +0000
commitd7b47fd0a4d44449ac35fd06c7c6bf5467a31878 (patch)
treeef84b7058f97145d3d736a10aadba12a6c0d21e0
parentaf46795e64ccdde2432105a8549a5da4b54546e9 (diff)
Make verify=helo do the verification on the fly it if was not done
earlier, like $sender_host_name handling.
-rw-r--r--doc/doc-txt/ChangeLog8
-rw-r--r--doc/doc-txt/NewStuff8
-rw-r--r--src/src/acl.c10
-rw-r--r--src/src/functions.h3
-rw-r--r--src/src/globals.c3
-rw-r--r--src/src/globals.h3
-rw-r--r--src/src/smtp_in.c228
7 files changed, 159 insertions, 104 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 0283defca..37b28a17d 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -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
-------------------------------------------
@@ -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.
+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
-----------------
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 5936f198b..2d653616d 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -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
--------------------
@@ -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.
+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
-----------------
diff --git a/src/src/acl.c b/src/src/acl.c
index 7bab711e0..f4788d19e 100644
--- a/src/src/acl.c
+++ b/src/src/acl.c
@@ -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 *
@@ -1376,12 +1376,16 @@ if (strcmpic(ss, US"certificate") == 0)
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;
- 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
diff --git a/src/src/functions.h b/src/src/functions.h
index 00d0f6768..7e61c92f6 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -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 *
@@ -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 BOOL smtp_verify_helo(void);
extern int smtp_write_command(smtp_outblock *, BOOL, char *, ...);
#ifdef WITH_CONTENT_SCAN
extern int spam(uschar **);
diff --git a/src/src/globals.c b/src/src/globals.c
index 698b2fc33..c233e76bd 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -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 *
@@ -569,6 +569,7 @@ uschar *helo_allow_chars = US"";
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;
diff --git a/src/src/globals.h b/src/src/globals.h
index 5ef0d4e21..484a8d4f9 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -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 *
@@ -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 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 */
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index f7549bb7c..9a736a4b7 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -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 *
@@ -1933,6 +1933,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 *
*************************************************/
@@ -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
- 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)
{
- 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)