From 379ba7d06d366c8cd151215e4c82424c36049375 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 20 Dec 2015 20:01:52 +0000 Subject: [PATCH] dnslists: permit use with explicit key(s) in nonsmtp ACLs. Bug 1748 --- doc/doc-txt/ChangeLog | 3 ++ src/src/acl.c | 8 ++-- src/src/functions.h | 2 +- src/src/verify.c | 20 ++++++--- test/confs/0571 | 78 ++++++++++++++++++++++++++++++++++++ test/log/0571 | 4 ++ test/rejectlog/0571 | 10 +++++ test/scripts/0000-Basic/0571 | 14 +++++++ 8 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 test/confs/0571 create mode 100644 test/log/0571 create mode 100644 test/rejectlog/0571 create mode 100644 test/scripts/0000-Basic/0571 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 6976d4bfe..03a4cedf5 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -137,6 +137,9 @@ JH/31 Fix bug with hosts_connection_nolog and named-lists which were wrongly JH/32 Move Redis support from Experimental to mainline, enabled for a build by defining LOOKUP_REDIS. The libhiredis library is required. +JH/33 Bug 1748: Permit ACL dnslists= condition in non-smtp ACLs if explicit + keys are given for lookup. + Exim version 4.86 ----------------- diff --git a/src/src/acl.c b/src/src/acl.c index 17f55c2ac..1456cc724 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -475,8 +475,10 @@ static unsigned int cond_forbids[] = { ~(1<next) #endif case ACLC_DNSLISTS: - rc = verify_check_dnsbl(&arg); + rc = verify_check_dnsbl(where, &arg, log_msgptr); break; case ACLC_DOMAINS: diff --git a/src/src/functions.h b/src/src/functions.h index bd43934f0..3b700873a 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -480,7 +480,7 @@ extern void utf8_version_report(FILE *); extern int verify_address(address_item *, FILE *, int, int, int, int, uschar *, uschar *, BOOL *); -extern int verify_check_dnsbl(const uschar **); +extern int verify_check_dnsbl(int, const uschar **, uschar **); extern int verify_check_header_address(uschar **, uschar **, int, int, int, uschar *, uschar *, int, int *); extern int verify_check_headers(uschar **); diff --git a/src/src/verify.c b/src/src/verify.c index b73f45a24..ef95394d3 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -3876,7 +3876,9 @@ Note: an address for testing DUL is 192.203.178.4 Note: a domain for testing RFCI is example.tld.dsn.rfc-ignorant.org Arguments: + where the acl type listptr the domain/address/data list + log_msgptr log message on error Returns: OK successful lookup (i.e. the address is on the list), or lookup deferred after +include_unknown @@ -3886,7 +3888,7 @@ Returns: OK successful lookup (i.e. the address is on the list), or */ int -verify_check_dnsbl(const uschar **listptr) +verify_check_dnsbl(int where, const uschar ** listptr, uschar ** log_msgptr) { int sep = 0; int defer_return = FAIL; @@ -3933,21 +3935,19 @@ while ((domain = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL /* See if there's explicit data to be looked up */ - key = Ustrchr(domain, '/'); - if (key != NULL) *key++ = 0; + if ((key = Ustrchr(domain, '/'))) *key++ = 0; /* See if there's a list of addresses supplied after the domain name. This is introduced by an = or a & character; if preceded by = we require all matches and if preceded by ! we invert the result. */ - iplist = Ustrchr(domain, '='); - if (iplist == NULL) + if (!(iplist = Ustrchr(domain, '='))) { bitmask = TRUE; iplist = Ustrchr(domain, '&'); } - if (iplist != NULL) /* Found either = or & */ + if (iplist) /* Found either = or & */ { if (iplist > domain && iplist[-1] == '!') /* Handle preceding ! */ { @@ -3966,6 +3966,7 @@ while ((domain = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL } } + /* If there is a comma in the domain, it indicates that a second domain for looking up TXT records is provided, before the main domain. Otherwise we must set domain_txt == domain. */ @@ -4011,6 +4012,13 @@ while ((domain = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL if (key == NULL) { + if (where == ACL_WHERE_NOTSMTP_START || where == ACL_WHERE_NOTSMTP) + { + *log_msgptr = string_sprintf + ("cannot test auto-keyed dnslists condition in %s ACL", + acl_wherenames[where]); + return ERROR; + } if (sender_host_address == NULL) return FAIL; /* can never match */ if (revadd[0] == 0) invert_address(revadd, sender_host_address); rc = one_check_dnsbl(domain, domain_txt, sender_host_address, revadd, diff --git a/test/confs/0571 b/test/confs/0571 new file mode 100644 index 000000000..64383cdd8 --- /dev/null +++ b/test/confs/0571 @@ -0,0 +1,78 @@ +# Exim test configuration 0571 + +LOG_SELECTOR= + +exim_path = EXIM_PATH +host_lookup_order = bydns +primary_hostname = myhost.test.ex +spool_directory = DIR/spool +log_file_path = DIR/spool/log/%slog +gecos_pattern = "" +gecos_name = CALLER_NAME +tls_advertise_hosts = + +# ----- Main settings ----- + +disable_ipv6 = true + +addresslist ok_senders = ok@ok.ok + +domainlist local_domains = test.ex : *.test.ex + +qualify_domain = test.ex +trusted_users = CALLER + +# Use first three components of from_domain to select ACL +acl_not_smtp = ${if def:sender_address \ + {acl_${sg{${tr{$sender_address_domain}{.}{_}}}{^(.*)_.*\$}{\$1}}} \ + {accept control=queue_only}} + +# ----- ACLs ----- + +begin acl + +acl_29_29_29: + deny dnslists = test.ex/$sender_address_domain + accept + +acl_29_29_0: + deny dnslists = test.ex + accept + +# ----- Transports ----- + +begin transports + +t1: + driver = appendfile + file = DIR/test-mail/$local_part + user = CALLER + +t2: + driver = appendfile + file = DIR/test-mail/okbatch + user = CALLER + batch_max = 100 + envelope_to_add + +# ----- Routers ----- + +begin routers + +r0: + driver = accept + local_parts = ^ok + transport = t2 + +r1: + driver = accept + local_parts = ^userx : ^cond- + transport = t1 + +r2: + driver = redirect + local_parts = fail + allow_fail + data = :fail: here is a fail message + +# End diff --git a/test/log/0571 b/test/log/0571 new file mode 100644 index 000000000..fc7dd5058 --- /dev/null +++ b/test/log/0571 @@ -0,0 +1,4 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 F= rejected by non-SMTP ACL: cannot test keyless dnslists condition in non-SMTP ACL +1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 no immediate delivery: queued by ACL +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= bill@29.29.29.com U=CALLER P=local S=sss diff --git a/test/rejectlog/0571 b/test/rejectlog/0571 new file mode 100644 index 000000000..494bffed6 --- /dev/null +++ b/test/rejectlog/0571 @@ -0,0 +1,10 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 F= rejected by non-SMTP ACL: cannot test keyless dnslists condition in non-SMTP ACL +Envelope-from: +Envelope-to: +P Received: from CALLER by myhost.test.ex with local (Exim x.yz) + (envelope-from ) + id 10HmaX-0005vi-00 + for ok1@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +I Message-Id: +F From: ted@29.29.0.com + Date: Tue, 2 Mar 1999 09:44:33 +0000 diff --git a/test/scripts/0000-Basic/0571 b/test/scripts/0000-Basic/0571 new file mode 100644 index 000000000..3eab04cbf --- /dev/null +++ b/test/scripts/0000-Basic/0571 @@ -0,0 +1,14 @@ +# ACL - dnslists in non-smtp ACL +# +1 +exim -f ted@29.29.0.com -odq ok1@test.ex +should fail +. +**** +# +exim -f bill@29.29.29.com -odq ok1@test.ex +should pass +. +**** +# +no_msglog_check -- 2.25.1