ph10 2004/11/22 11:30:04 GMT
Modified files:
exim-doc/doc-txt ChangeLog NewStuff
exim-src/src verify.c
exim-test-orig/AutoTest/stderr 320
Added files:
exim-test-orig/AutoTest/confs 596
exim-test-orig/AutoTest/log 596
exim-test-orig/AutoTest/rejectlog 596
exim-test-orig/AutoTest/scripts 596
exim-test-orig/AutoTest/stdout 596
Log:
Allow a list of IP addresses or names to follow / in a dnslists ACL
condition.
Revision Changes Path
1.36 +4 -0 exim/exim-doc/doc-txt/ChangeLog
1.14 +30 -0 exim/exim-doc/doc-txt/NewStuff
1.7 +309 -232 exim/exim-src/src/verify.c
1.1 +28 -0 exim/exim-test-orig/AutoTest/confs/596 (new)
1.1 +3 -0 exim/exim-test-orig/AutoTest/log/596 (new)
1.1 +1 -0 exim/exim-test-orig/AutoTest/rejectlog/596 (new)
1.1 +3 -0 exim/exim-test-orig/AutoTest/scripts/596 (new)
1.2 +1 -0 exim/exim-test-orig/AutoTest/stderr/320
1.1 +1 -0 exim/exim-test-orig/AutoTest/stdout/596 (new)
Index: ChangeLog
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- ChangeLog 19 Nov 2004 15:18:57 -0000 1.35
+++ ChangeLog 22 Nov 2004 11:30:03 -0000 1.36
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.35 2004/11/19 15:18:57 ph10 Exp $
+$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.36 2004/11/22 11:30:03 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -159,6 +159,10 @@
(3) It is now possible to specify the separator character for use when
multiple records are returned.
+
+38. The dnslists ACL condition has been extended: it is now possible to supply
+ a list of IP addresses and/or domains to be looked up in a particular DNS
+ domain.
Exim version 4.43
Index: NewStuff
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-txt/NewStuff,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- NewStuff 19 Nov 2004 15:18:57 -0000 1.13
+++ NewStuff 22 Nov 2004 11:30:03 -0000 1.14
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-doc/doc-txt/NewStuff,v 1.13 2004/11/19 15:18:57 ph10 Exp $
+$Cambridge: exim/exim-doc/doc-txt/NewStuff,v 1.14 2004/11/22 11:30:03 ph10 Exp $
New Features in Exim
--------------------
@@ -165,6 +165,36 @@
The same effect could be achieved by wrapping the lookup in ${tr...}; this
feature is just a syntactic simplification.
+
+15. It is now possible to supply a list of domains and/or IP addresses to be
+ lookup up in a DNS blacklist. Previously, only a single domain name could
+ be given, for example:
+
+ dnslists = black.list.tld/$sender_host_name
+
+ What follows the slash can now be a list. As with all lists, the default
+ separator is a colon. However, because this is a sublist within the list of
+ DNS blacklist domains, it is necessary either to double the separators like
+ this:
+
+ dnslists = black.list.tld/name.1::name.2
+
+ or to change the separator character, like this:
+
+ dnslists = black.list.tld/<;name.1;name.2
+
+ If an item in the list is an IP address, it is inverted before the DNS
+ blacklist domain is appended. If it is not an IP address, no inversion
+ occurs. Consider this condition:
+
+ dnslists = black.list.tls/<;192.168.1.2;a.domain
+
+ The DNS lookups that occur are for
+
+ 2.1.168.192.black.list.tld and a.domain.black.list.tld
+
+ Once a DNS record has been found (that matches a specific IP return
+ address, if specified), no further lookups are done.
Version 4.43
Index: verify.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/verify.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- verify.c 18 Nov 2004 11:17:33 -0000 1.6
+++ verify.c 22 Nov 2004 11:30:04 -0000 1.7
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/verify.c,v 1.6 2004/11/18 11:17:33 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/verify.c,v 1.7 2004/11/22 11:30:04 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -2184,6 +2184,254 @@
/*************************************************
+* Perform a single dnsbl lookup *
+*************************************************/
+
+/* This function is called from verify_check_dnsbl() below.
+
+Arguments:
+ domain the outer dnsbl domain (for debug message)
+ keydomain the current keydomain (for debug message)
+ query the domain to be looked up
+ iplist the list of matching IP addresses
+ bitmask true if bitmask matching is wanted
+ invert_result true if result to be inverted
+ defer_return what to return for a defer
+
+Returns: OK if lookup succeeded
+ FAIL if not
+*/
+
+static int
+one_check_dnsbl(uschar *domain, uschar *keydomain, uschar *query,
+ uschar *iplist, BOOL bitmask, BOOL invert_result, int defer_return)
+{
+dns_answer dnsa;
+dns_scan dnss;
+tree_node *t;
+dnsbl_cache_block *cb;
+int old_pool = store_pool;
+
+/* Look for this query in the cache. */
+
+t = tree_search(dnsbl_cache, query);
+
+/* If not cached from a previous lookup, we must do a DNS lookup, and
+cache the result in permanent memory. */
+
+if (t == NULL)
+ {
+ store_pool = POOL_PERM;
+
+ /* Set up a tree entry to cache the lookup */
+
+ t = store_get(sizeof(tree_node) + Ustrlen(query));
+ Ustrcpy(t->name, query);
+ t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block));
+ (void)tree_insertnode(&dnsbl_cache, t);
+
+ /* Do the DNS loopup . */
+
+ HDEBUG(D_dnsbl) debug_printf("new DNS lookup for %s\n", query);
+ cb->rc = dns_basic_lookup(&dnsa, query, T_A);
+ cb->text_set = FALSE;
+ cb->text = NULL;
+ cb->rhs = NULL;
+
+ /* If the lookup succeeded, cache the RHS address. The code allows for
+ more than one address - this was for complete generality and the possible
+ use of A6 records. However, A6 records have been reduced to experimental
+ status (August 2001) and may die out. So they may never get used at all,
+ let alone in dnsbl records. However, leave the code here, just in case.
+
+ Quite apart from one A6 RR generating multiple addresses, there are DNS
+ lists that return more than one A record, so we must handle multiple
+ addresses generated in that way as well. */
+
+ if (cb->rc == DNS_SUCCEED)
+ {
+ dns_record *rr;
+ dns_address **addrp = &(cb->rhs);
+ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+ rr != NULL;
+ rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+ {
+ if (rr->type == T_A)
+ {
+ dns_address *da = dns_address_from_rr(&dnsa, rr);
+ if (da != NULL)
+ {
+ *addrp = da;
+ while (da->next != NULL) da = da->next;
+ addrp = &(da->next);
+ }
+ }
+ }
+
+ /* If we didn't find any A records, change the return code. This can
+ happen when there is a CNAME record but there are no A records for what
+ it points to. */
+
+ if (cb->rhs == NULL) cb->rc = DNS_NODATA;
+ }
+
+ store_pool = old_pool;
+ }
+
+/* Previous lookup was cached */
+
+else
+ {
+ HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n");
+ cb = t->data.ptr;
+ }
+
+/* We now have the result of the DNS lookup, either newly done, or cached
+from a previous call. If the lookup succeeded, check against the address
+list if there is one. This may be a positive equality list (introduced by
+"="), a negative equality list (introduced by "!="), a positive bitmask
+list (introduced by "&"), or a negative bitmask list (introduced by "!&").*/
+
+if (cb->rc == DNS_SUCCEED)
+ {
+ dns_address *da = NULL;
+ uschar *addlist = cb->rhs->address;
+
+ /* For A and AAAA records, there may be multiple addresses from multiple
+ records. For A6 records (currently not expected to be used) there may be
+ multiple addresses from a single record. */
+
+ for (da = cb->rhs->next; da != NULL; da = da->next)
+ addlist = string_sprintf("%s, %s", addlist, da->address);
+
+ HDEBUG(D_dnsbl) debug_printf("DNS lookup for %s succeeded (yielding %s)\n",
+ query, addlist);
+
+ /* Address list check; this can be either for equality, or via a bitmask.
+ In the latter case, all the bits must match. */
+
+ if (iplist != NULL)
+ {
+ int ipsep = ',';
+ uschar ip[46];
+ uschar *ptr = iplist;
+
+ while (string_nextinlist(&ptr, &ipsep, ip, sizeof(ip)) != NULL)
+ {
+ /* Handle exact matching */
+ if (!bitmask)
+ {
+ for (da = cb->rhs; da != NULL; da = da->next)
+ {
+ if (Ustrcmp(CS da->address, ip) == 0) break;
+ }
+ }
+ /* Handle bitmask matching */
+ else
+ {
+ int address[4];
+ int mask = 0;
+
+ /* At present, all known DNS blocking lists use A records, with
+ IPv4 addresses on the RHS encoding the information they return. I
+ wonder if this will linger on as the last vestige of IPv4 when IPv6
+ is ubiquitous? Anyway, for now we use paranoia code to completely
+ ignore IPv6 addresses. The default mask is 0, which always matches.
+ We change this only for IPv4 addresses in the list. */
+
+ if (host_aton(ip, address) == 1) mask = address[0];
+
+ /* Scan the returned addresses, skipping any that are IPv6 */
+
+ for (da = cb->rhs; da != NULL; da = da->next)
+ {
+ if (host_aton(da->address, address) != 1) continue;
+ if ((address[0] & mask) == mask) break;
+ }
+ }
+
+ /* Break out if a match has been found */
+
+ if (da != NULL) break;
+ }
+
+ /* If either
+
+ (a) No IP address in a positive list matched, or
+ (b) An IP address in a negative list did match
+
+ then behave as if the DNSBL lookup had not succeeded, i.e. the host is
+ not on the list. */
+
+ if (invert_result != (da == NULL))
+ {
+ HDEBUG(D_dnsbl)
+ {
+ debug_printf("=> but we are not accepting this block class because\n");
+ debug_printf("=> there was %s match for %c%s\n",
+ invert_result? "an exclude":"no", bitmask? '&' : '=', iplist);
+ }
+ return FAIL;
+ }
+ }
+
+ /* Either there was no IP list, or the record matched. Look up a TXT record
+ if it hasn't previously been done. */
+
+ if (!cb->text_set)
+ {
+ cb->text_set = TRUE;
+ if (dns_basic_lookup(&dnsa, query, T_TXT) == DNS_SUCCEED)
+ {
+ dns_record *rr;
+ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+ rr != NULL;
+ rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+ if (rr->type == T_TXT) break;
+ if (rr != NULL)
+ {
+ int len = (rr->data)[0];
+ if (len > 511) len = 127;
+ store_pool = POOL_PERM;
+ cb->text = string_sprintf("%.*s", len, (const uschar *)(rr->data+1));
+ store_pool = old_pool;
+ }
+ }
+ }
+
+ dnslist_value = addlist;
+ dnslist_text = cb->text;
+ return OK;
+ }
+
+/* There was a problem with the DNS lookup */
+
+if (cb->rc != DNS_NOMATCH && cb->rc != DNS_NODATA)
+ {
+ log_write(L_dnslist_defer, LOG_MAIN,
+ "DNS list lookup defer (probably timeout) for %s: %s", query,
+ (defer_return == OK)? US"assumed in list" :
+ (defer_return == FAIL)? US"assumed not in list" :
+ US"returned DEFER");
+ return defer_return;
+ }
+
+/* No entry was found in the DNS; continue for next domain */
+
+HDEBUG(D_dnsbl)
+ {
+ debug_printf("DNS lookup for %s failed\n", query);
+ debug_printf("=> that means %s is not listed at %s\n",
+ keydomain, domain);
+ }
+
+return FAIL;
+}
+
+
+
+
+/*************************************************
* Check host against DNS black lists *
*************************************************/
@@ -2227,7 +2475,6 @@
{
int sep = 0;
int defer_return = FAIL;
-int old_pool = store_pool;
BOOL invert_result = FALSE;
uschar *list = *listptr;
uschar *domain;
@@ -2240,18 +2487,19 @@
revadd[0] = 0;
+/* In case this is the first time the DNS resolver is being used. */
+
+dns_init(FALSE, FALSE);
+
/* Loop through all the domains supplied, until something matches */
while ((domain = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
{
+ int rc;
BOOL frc;
BOOL bitmask = FALSE;
- dns_answer dnsa;
- dns_scan dnss;
uschar *iplist;
uschar *key;
- tree_node *t;
- dnsbl_cache_block *cb;
HDEBUG(D_dnsbl) debug_printf("DNS list check: %s\n", domain);
@@ -2310,251 +2558,80 @@
}
}
- /* Construct the query by adding the domain onto either the sending host
- address, or the given key string. */
-
+ /* If there is no key string, construct the query by adding the domain name
+ onto the inverted host address, and perform a single DNS lookup. */
+
if (key == NULL)
{
if (sender_host_address == NULL) return FAIL; /* can never match */
if (revadd[0] == 0) invert_address(revadd, sender_host_address);
frc = string_format(query, sizeof(query), "%s%s", revadd, domain);
- }
- else
- {
- frc = string_format(query, sizeof(query), "%s.%s", key, domain);
- }
-
- if (!frc)
- {
- log_write(0, LOG_MAIN|LOG_PANIC, "dnslist query is too long "
- "(ignored): %s...", query);
- continue;
- }
-
- /* Look for this query in the cache. */
-
- t = tree_search(dnsbl_cache, query);
-
- /* If not cached from a previous lookup, we must do a DNS lookup, and
- cache the result in permanent memory. */
-
- if (t == NULL)
- {
- store_pool = POOL_PERM;
-
- /* In case this is the first time the DNS resolver is being used. */
-
- dns_init(FALSE, FALSE);
-
- /* Set up a tree entry to cache the lookup */
-
- t = store_get(sizeof(tree_node) + Ustrlen(query));
- Ustrcpy(t->name, query);
- t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block));
- (void)tree_insertnode(&dnsbl_cache, t);
-
- /* Do the DNS loopup . */
-
- HDEBUG(D_dnsbl) debug_printf("new DNS lookup for %s\n", query);
- cb->rc = dns_basic_lookup(&dnsa, query, T_A);
- cb->text_set = FALSE;
- cb->text = NULL;
- cb->rhs = NULL;
-
- /* If the lookup succeeded, cache the RHS address. The code allows for
- more than one address - this was for complete generality and the possible
- use of A6 records. However, A6 records have been reduced to experimental
- status (August 2001) and may die out. So they may never get used at all,
- let alone in dnsbl records. However, leave the code here, just in case.
-
- Quite apart from one A6 RR generating multiple addresses, there are DNS
- lists that return more than one A record, so we must handle multiple
- addresses generated in that way as well. */
-
- if (cb->rc == DNS_SUCCEED)
+
+ if (!frc)
{
- dns_record *rr;
- dns_address **addrp = &(cb->rhs);
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
- rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
- {
- if (rr->type == T_A)
- {
- dns_address *da = dns_address_from_rr(&dnsa, rr);
- if (da != NULL)
- {
- *addrp = da;
- while (da->next != NULL) da = da->next;
- addrp = &(da->next);
- }
- }
- }
-
- /* If we didn't find any A records, change the return code. This can
- happen when there is a CNAME record but there are no A records for what
- it points to. */
-
- if (cb->rhs == NULL) cb->rc = DNS_NODATA;
+ log_write(0, LOG_MAIN|LOG_PANIC, "dnslist query is too long "
+ "(ignored): %s...", query);
+ continue;
+ }
+
+ rc = one_check_dnsbl(domain, sender_host_address, query, iplist, bitmask,
+ invert_result, defer_return);
+
+ if (rc == OK)
+ {
+ dnslist_domain = string_copy(domain);
+ HDEBUG(D_dnsbl) debug_printf("=> that means %s is listed at %s\n",
+ sender_host_address, domain);
}
-
- store_pool = old_pool;
+
+ if (rc != FAIL) return rc; /* OK or DEFER */
}
-
- /* Previous lookup was cached */
-
+
+ /* If there is a key string, it can be a list of domains or IP addresses to
+ be concatenated with the main domain. */
+
else
{
- HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n");
- cb = t->data.ptr;
- }
-
- /* We now have the result of the DNS lookup, either newly done, or cached
- from a previous call. If the lookup succeeded, check against the address
- list if there is one. This may be a positive equality list (introduced by
- "="), a negative equality list (introduced by "!="), a positive bitmask
- list (introduced by "&"), or a negative bitmask list (introduced by "!&").*/
-
- if (cb->rc == DNS_SUCCEED)
- {
- dns_address *da = NULL;
- uschar *addlist = cb->rhs->address;
-
- /* For A and AAAA records, there may be multiple addresses from multiple
- records. For A6 records (currently not expected to be used) there may be
- multiple addresses from a single record. */
-
- for (da = cb->rhs->next; da != NULL; da = da->next)
- addlist = string_sprintf("%s, %s", addlist, da->address);
-
- HDEBUG(D_dnsbl) debug_printf("DNS lookup for %s succeeded (yielding %s)\n",
- query, addlist);
-
- /* Address list check; this can be either for equality, or via a bitmask.
- In the latter case, all the bits must match. */
-
- if (iplist != NULL)
- {
- int ipsep = ',';
- uschar ip[46];
- uschar *ptr = iplist;
-
- while (string_nextinlist(&ptr, &ipsep, ip, sizeof(ip)) != NULL)
- {
- /* Handle exact matching */
- if (!bitmask)
- {
- for (da = cb->rhs; da != NULL; da = da->next)
- {
- if (Ustrcmp(CS da->address, ip) == 0) break;
- }
- }
- /* Handle bitmask matching */
- else
- {
- int address[4];
- int mask = 0;
-
- /* At present, all known DNS blocking lists use A records, with
- IPv4 addresses on the RHS encoding the information they return. I
- wonder if this will linger on as the last vestige of IPv4 when IPv6
- is ubiquitous? Anyway, for now we use paranoia code to completely
- ignore IPv6 addresses. The default mask is 0, which always matches.
- We change this only for IPv4 addresses in the list. */
-
- if (host_aton(ip, address) == 1) mask = address[0];
-
- /* Scan the returned addresses, skipping any that are IPv6 */
-
- for (da = cb->rhs; da != NULL; da = da->next)
- {
- if (host_aton(da->address, address) != 1) continue;
- if ((address[0] & mask) == mask) break;
- }
- }
-
- /* Break out if a match has been found */
-
- if (da != NULL) break;
+ int keysep = 0;
+ uschar *keydomain;
+ uschar keybuffer[256];
+
+ while ((keydomain = string_nextinlist(&key, &keysep, keybuffer,
+ sizeof(keybuffer))) != NULL)
+ {
+ if (string_is_ip_address(keydomain, NULL))
+ {
+ uschar keyrevadd[128];
+ invert_address(keyrevadd, keydomain);
+ frc = string_format(query, sizeof(query), "%s%s", keyrevadd, domain);
+ }
+ else
+ {
+ frc = string_format(query, sizeof(query), "%s.%s", keydomain, domain);
}
- /* If either
-
- (a) No IP address in a positive list matched, or
- (b) An IP address in a negative list did match
-
- then behave as if the DNSBL lookup had not succeeded, i.e. the host is
- not on the list. */
-
- if (invert_result != (da == NULL))
+ if (!frc)
{
- HDEBUG(D_dnsbl)
- {
- debug_printf("=> but we are not accepting this block class because\n");
- debug_printf("=> there was %s match for %c%s\n",
- invert_result? "an exclude":"no", bitmask? '&' : '=', iplist);
- }
- continue; /* With next DNSBL domain */
+ log_write(0, LOG_MAIN|LOG_PANIC, "dnslist query is too long "
+ "(ignored): %s...", query);
+ continue;
}
- }
-
- /* Either there was no IP list, or the record matched. Look up a TXT record
- if it hasn't previously been done. */
-
- if (!cb->text_set)
- {
- cb->text_set = TRUE;
- if (dns_basic_lookup(&dnsa, query, T_TXT) == DNS_SUCCEED)
+
+ rc = one_check_dnsbl(domain, keydomain, query, iplist, bitmask,
+ invert_result, defer_return);
+
+ if (rc == OK)
{
- dns_record *rr;
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
- rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
- if (rr->type == T_TXT) break;
- if (rr != NULL)
- {
- int len = (rr->data)[0];
- if (len > 511) len = 127;
- store_pool = POOL_PERM;
- cb->text = string_sprintf("%.*s", len, (const uschar *)(rr->data+1));
- store_pool = old_pool;
- }
+ dnslist_domain = string_copy(domain);
+ HDEBUG(D_dnsbl) debug_printf("=> that means %s is listed at %s\n",
+ keydomain, domain);
}
- }
+
+ if (rc != FAIL) return rc; /* OK or DEFER */
- HDEBUG(D_dnsbl)
- {
- debug_printf("=> that means %s is listed at %s\n",
- (key == NULL)? sender_host_address : key, domain);
- }
-
- dnslist_domain = string_copy(domain);
- dnslist_value = addlist;
- dnslist_text = cb->text;
- return OK;
- }
-
- /* There was a problem with the DNS lookup */
-
- if (cb->rc != DNS_NOMATCH && cb->rc != DNS_NODATA)
- {
- log_write(L_dnslist_defer, LOG_MAIN,
- "DNS list lookup defer (probably timeout) for %s: %s", query,
- (defer_return == OK)? US"assumed in list" :
- (defer_return == FAIL)? US"assumed not in list" :
- US"returned DEFER");
- return defer_return;
- }
-
- /* No entry was found in the DNS; continue for next domain */
-
- HDEBUG(D_dnsbl)
- {
- debug_printf("DNS lookup for %s failed\n", query);
- debug_printf("=> that means %s is not listed at %s\n",
- (key == NULL)? sender_host_address : key, domain);
- }
- } /* Continue with next domain */
+ } /* continue with next keystring domain/address */
+ }
+ } /* continue with next dnsdb outer domain */
return FAIL;
}
Index: 596
====================================================================
# Exim test configuration 596
# Macros are set externally in order to get the path
# of the Exim that is being tested, and the directory
# in which the test data lives.
exim_path = EXIM_PATH
primary_hostname = myhost.test.ex
spool_directory = DIR/spool
# ----- Main settings -----
acl_smtp_connect = check_connect
# ----- ACL -----
begin acl
check_connect:
warn dnslists = rbl.test.ex/<;1.2.3.4;10.11.12.13
logwrite = rbl.test.ex/<;1.2.3.4;10.11.12.13
warn dnslists = test.ex/a.b.c.d::ten-1
logwrite = test.ex/a.b.c.d::ten-1
# End
Index: 596
====================================================================
1999-03-02 09:44:33 rbl.test.ex/<;1.2.3.4;10.11.12.13
1999-03-02 09:44:33 test.ex/a.b.c.d::ten-1
1999-03-02 09:44:33 U=ph10 rejected connection in "connect" ACL
Index: 596
====================================================================
1999-03-02 09:44:33 U=ph10 rejected connection in "connect" ACL
Index: 596
====================================================================
0 list of keys in dnslists
exim -bs
****
Index: 320
===================================================================
RCS file: /home/cvs/exim/exim-test-orig/AutoTest/stderr/320,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- 320 8 Oct 2004 14:50:08 -0000 1.1
+++ 320 22 Nov 2004 11:30:04 -0000 1.2
@@ -1269,6 +1269,7 @@
>>> DNS list check: test.again.dns
>>> using result of previous DNS lookup
LOG: DNS list lookup defer (probably timeout) for 44.44.44.44.test.again.dns: assumed in list
+>>> => that means 44.44.44.44 is listed at test.again.dns
>>> warn: condition test succeeded
>>> processing "warn"
>>> check dnslists = +exclude_unknown : test.again.dns
Index: 596
====================================================================
550 Administrative prohibition