From d7b47fd0a4d44449ac35fd06c7c6bf5467a31878 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Tue, 2 Aug 2005 15:19:20 +0000 Subject: [PATCH] Make verify=helo do the verification on the fly it if was not done earlier, like $sender_host_name handling. --- doc/doc-txt/ChangeLog | 8 +- doc/doc-txt/NewStuff | 8 +- src/src/acl.c | 10 +- src/src/functions.h | 3 +- src/src/globals.c | 3 +- src/src/globals.h | 3 +- src/src/smtp_in.c | 228 ++++++++++++++++++++++++------------------ 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 * @@ -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 * *************************************************/ @@ -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) -- 2.25.1