X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/921dfc1193791b722844341c3ec97be158042c17..6f6dedccb47f231a0712d882da20feffbac8d0bc:/src/src/verify.c diff --git a/src/src/verify.c b/src/src/verify.c index b77978bfc..cb88f28a9 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2014 */ +/* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions concerned with verifying things. The original code for callout @@ -21,6 +21,7 @@ uschar ctbuffer[8192]; /* Structure for caching DNSBL lookups */ typedef struct dnsbl_cache_block { + time_t expiry; dns_address *rhs; uschar *text; int rc; @@ -70,7 +71,7 @@ cache_record = dbfn_read_with_length(dbm_file, key, &length); if (cache_record == NULL) { - HDEBUG(D_verify) debug_printf("callout cache: no %s record found\n", type); + HDEBUG(D_verify) debug_printf("callout cache: no %s record found for %s\n", type, key); return NULL; } @@ -84,7 +85,7 @@ now = time(NULL); if (now - cache_record->time_stamp > expire) { - HDEBUG(D_verify) debug_printf("callout cache: %s record expired\n", type); + HDEBUG(D_verify) debug_printf("callout cache: %s record expired for %s\n", type, key); return NULL; } @@ -111,7 +112,7 @@ if (type[0] == 'd' && cache_record->result != ccache_reject) cache_record->random_result = ccache_unknown; } -HDEBUG(D_verify) debug_printf("callout cache: found %s record\n", type); +HDEBUG(D_verify) debug_printf("callout cache: found %s record for %s\n", type, key); return cache_record; } @@ -443,7 +444,7 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount. host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET:AF_INET6; - if (!smtp_get_interface(tf->interface, host_af, addr, NULL, &interface, + if (!smtp_get_interface(tf->interface, host_af, addr, &interface, US"callout") || !smtp_get_port(tf->port, addr, &port, US"callout")) log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address, @@ -578,7 +579,7 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount. deliver_domain = addr->domain; transport_name = addr->transport->name; - if ( !smtp_get_interface(tf->interface, host_af, addr, NULL, &interface, + if ( !smtp_get_interface(tf->interface, host_af, addr, &interface, US"callout") || !smtp_get_port(tf->port, addr, &port, US"callout") ) @@ -2076,18 +2077,17 @@ while (addr_new != NULL) (void)host_find_byname(host, NULL, flags, NULL, TRUE); else { - uschar * d_request = NULL, * d_require = NULL; + dnssec_domains * dnssec_domains = NULL; if (Ustrcmp(addr->transport->driver_name, "smtp") == 0) { smtp_transport_options_block * ob = (smtp_transport_options_block *) addr->transport->options_block; - d_request = ob->dnssec_request_domains; - d_require = ob->dnssec_require_domains; + dnssec_domains = &ob->dnssec; } (void)host_find_bydns(host, NULL, flags, NULL, NULL, NULL, - d_request, d_require, NULL, NULL); + dnssec_domains, NULL, NULL); } } } @@ -2364,6 +2364,12 @@ for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++) while (len++ < maxaddlen) fprintf(f," "); if (h->mx >= 0) fprintf(f, "MX=%d", h->mx); if (h->port != PORT_NONE) fprintf(f, " port=%d", h->port); + if (running_in_test_harness) +#ifndef DISABLE_DNSSEC + fprintf(f, " ad=%s", h->dnssec==DS_YES ? "yes" : "no"); +#else + fprintf(f, " ad=no"); +#endif if (h->status == hstatus_unusable) fprintf(f, " ** unusable **"); fprintf(f, "\n"); } @@ -2911,7 +2917,7 @@ if (ip_bind(sock, host_af, interface_address, 0) < 0) if (ip_connect(sock, host_af, sender_host_address, port, rfc1413_query_timeout) < 0) { - if (errno == ETIMEDOUT && (log_extra_selector & LX_ident_timeout) != 0) + if (errno == ETIMEDOUT && LOGGING(ident_timeout)) { log_write(0, LOG_MAIN, "ident connection to %s timed out", sender_host_address); @@ -3241,6 +3247,10 @@ if (*t == 0) h.address = NULL; h.mx = MX_NONE; + /* Using byname rather than bydns here means we cannot determine dnssec + status. On the other hand it is unclear how that could be either + propagated up or enforced. */ + rc = host_find_byname(&h, NULL, HOST_FIND_QUALIFY_SINGLE, NULL, FALSE); if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL) { @@ -3575,21 +3585,37 @@ if (!string_format(query, sizeof(query), "%s.%s", prepend, domain)) /* Look for this query in the cache. */ -t = tree_search(dnsbl_cache, query); +if ( (t = tree_search(dnsbl_cache, query)) + && (cb = t->data.ptr)->expiry > time(NULL) + ) + +/* Previous lookup was cached */ + + { + HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n"); + } /* If not cached from a previous lookup, we must do a DNS lookup, and cache the result in permanent memory. */ -if (t == NULL) +else { + uint ttl = UINT_MAX; + store_pool = POOL_PERM; - /* Set up a tree entry to cache the lookup */ + if (t) + { + HDEBUG(D_dnsbl) debug_printf("cached data found but past valid time; "); + } - 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); + else + { /* 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 . */ @@ -3614,17 +3640,18 @@ if (t == NULL) dns_record *rr; dns_address **addrp = &(cb->rhs); for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); - rr != NULL; + rr; 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) + if (da) { *addrp = da; while (da->next != NULL) da = da->next; addrp = &(da->next); + if (ttl > rr->ttl) ttl = rr->ttl; } } } @@ -3636,17 +3663,10 @@ if (t == NULL) if (cb->rhs == NULL) cb->rc = DNS_NODATA; } + cb->expiry = time(NULL)+ttl; 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