From 4e0983dcef8dd8630fc77aad39f7606e2ed32199 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 24 Apr 2014 16:41:11 +0100 Subject: [PATCH] Dnssec observability: add variable $lookup_dnssec_authenticated --- doc/doc-docbook/spec.xfpt | 21 +++++++++++++++++++++ doc/doc-txt/ChangeLog | 1 + src/src/acl.c | 1 + src/src/dkim.c | 1 + src/src/expand.c | 1 + src/src/globals.c | 1 + src/src/globals.h | 1 + src/src/host.c | 16 +++++++++++++--- src/src/lookups/dnsdb.c | 3 +++ 9 files changed, 43 insertions(+), 3 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 4370aa0b5..0e6a38bd9 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -6981,6 +6981,8 @@ ${lookup dnsdb{a=one.host.com:two.host.com}} Thus, in the default case, as long as at least one of the DNS lookups yields some data, the lookup succeeds. +.new +.cindex "DNSSEC" "dns lookup" Use of &(DNSSEC)& is controlled by a dnssec modifier. The possible keywords are &"dnssec_strict"&, &"dnssec_lax"&, and &"dnssec_never"&. @@ -6991,6 +6993,9 @@ is not labelled as authenticated data is treated as equivalent to a temporary DNS error. The default is &"never"&. +See also the &$lookup_dnssec_authenticated$& variable. +.wen + @@ -11448,6 +11453,16 @@ ability to find the amount of free space (only true for experimental systems), the space value is -1. See also the &%check_log_space%& option. +.new +.vitem &$lookup_dnssec_authenticated$& +.vindex "&$lookup_dnssec_authenticated$&" +This variable is set after a DNS lookup done by +either a dnslookup router or a dnsdb lookup expansion. +It will be empty if &(DNSSEC)& was not requested, +&"no"& if the result was not labelled as authenticated data +and &"yes"& if it was. +.wen + .vitem &$mailstore_basename$& .vindex "&$mailstore_basename$&" This variable is set only when doing deliveries in &"mailstore"& format in the @@ -17649,6 +17664,7 @@ when there is a DNS lookup error. +.new .option dnssec_request_domains dnslookup "domain list&!!" unset .cindex "MX record" "security" .cindex "DNSSEC" "MX lookup" @@ -17658,8 +17674,12 @@ DNS lookups for domains matching &%dnssec_request_domains%& will be done with the dnssec request bit set. This applies to all of the SRV, MX A6, AAAA, A lookup sequence. +See also the &$lookup_dnssec_authenticated$& variable. +.wen + +.new .option dnssec_require_domains dnslookup "domain list&!!" unset .cindex "MX record" "security" .cindex "DNSSEC" "MX lookup" @@ -17669,6 +17689,7 @@ DNS lookups for domains matching &%dnssec_request_domains%& will be done with the dnssec request bit set. Any returns not having the Authenticated Data bit (AD bit) set wil be ignored and logged as a host-lookup failure. This applies to all of the SRV, MX A6, AAAA, A lookup sequence. +.wen diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 8bf42d537..ddbd91135 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -92,6 +92,7 @@ TL/08 Bugzilla 1453: New LDAP "SERVERS=" option allows admin to override list Schlichting. JH/18 New options dnssec_lax, dnssec_strict on dnsdb lookups. + New variable $lookup_dnssec_authenticated for observability. TL/09 Bugzilla 609: Add -C option to exiqgrep, specify which exim.conf to use. Patch submitted by Lars Timman. diff --git a/src/src/acl.c b/src/src/acl.c index 9d0842c1d..270a2f2c0 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1614,6 +1614,7 @@ else DNS_LOOKUP_AGAIN: #endif +lookup_dnssec_authenticated = NULL; switch (dns_lookup(&dnsa, target, type, NULL)) { /* If something bad happened (most commonly DNS_AGAIN), defer. */ diff --git a/src/src/dkim.c b/src/src/dkim.c index cb7fc7065..171fcccdb 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -23,6 +23,7 @@ int dkim_exim_query_dns_txt(char *name, char *answer) { dns_scan dnss; dns_record *rr; + lookup_dnssec_authenticated = NULL; if (dns_lookup(&dnsa, (uschar *)name, T_TXT, NULL) != DNS_SUCCEED) return PDKIM_FAIL; /* Search for TXT record */ diff --git a/src/src/expand.c b/src/src/expand.c index fd4f65abb..54b3abc54 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -510,6 +510,7 @@ static var_entry var_table[] = { { "localhost_number", vtype_int, &host_number }, { "log_inodes", vtype_pinodes, (void *)FALSE }, { "log_space", vtype_pspace, (void *)FALSE }, + { "lookup_dnssec_authenticated",vtype_stringptr,&lookup_dnssec_authenticated}, { "mailstore_basename", vtype_stringptr, &mailstore_basename }, #ifdef WITH_CONTENT_SCAN { "malware_name", vtype_stringptr, &malware_name }, diff --git a/src/src/globals.c b/src/src/globals.c index fbc3787f9..cb014fbe8 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -837,6 +837,7 @@ BOOL log_testing_mode = FALSE; BOOL log_timezone = FALSE; unsigned int log_write_selector= L_default; uschar *login_sender_address = NULL; +uschar *lookup_dnssec_authenticated = NULL; int lookup_open_max = 25; uschar *lookup_value = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index e18bddc01..cfa6d2bff 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -503,6 +503,7 @@ extern unsigned int log_write_selector;/* Bit map of logging options for log_wri extern uschar *login_sender_address; /* The actual sender address */ extern lookup_info **lookup_list; /* Array of pointers to available lookups */ extern int lookup_list_count; /* Number of entries in the list */ +extern uschar *lookup_dnssec_authenticated; /* AD status of dns lookup */ extern int lookup_open_max; /* Max lookup files to cache */ extern uschar *lookup_value; /* Value looked up from file */ diff --git a/src/src/host.c b/src/src/host.c index 495a44d58..05bcbe8c7 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -220,6 +220,8 @@ else int rc = dns_lookup(&dnsa, lname, type, NULL); int count = 0; + lookup_dnssec_authenticated = NULL; + switch(rc) { case DNS_SUCCEED: break; @@ -2207,7 +2209,7 @@ Returns: HOST_FIND_FAILED couldn't find A record static int set_address_from_dns(host_item *host, host_item **lastptr, uschar *ignore_target_hosts, BOOL allow_ip, uschar **fully_qualified_name, - BOOL dnssec_require) + BOOL dnssec_requested, BOOL dnssec_require) { dns_record *rr; host_item *thishostlast = NULL; /* Indicates not yet filled in anything */ @@ -2268,6 +2270,8 @@ for (; i >= 0; i--) dns_scan dnss; int rc = dns_lookup(&dnsa, host->name, type, fully_qualified_name); + lookup_dnssec_authenticated = !dnssec_requested ? NULL + : dns_is_secure(&dnsa) ? US"yes" : US"no"; /* We want to return HOST_FIND_AGAIN if one of the A, A6, or AAAA lookups fails or times out, but not if another one succeeds. (In the early @@ -2506,6 +2510,9 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0) magic. */ rc = dns_lookup(&dnsa, buffer, ind_type, &temp_fully_qualified_name); + lookup_dnssec_authenticated = !dnssec_request ? NULL + : dns_is_secure(&dnsa) ? US"yes" : US"no"; + if (temp_fully_qualified_name != buffer && fully_qualified_name != NULL) *fully_qualified_name = temp_fully_qualified_name + prefix_length; @@ -2541,6 +2548,9 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0) { ind_type = T_MX; rc = dns_lookup(&dnsa, host->name, ind_type, fully_qualified_name); + lookup_dnssec_authenticated = !dnssec_request ? NULL + : dns_is_secure(&dnsa) ? US"yes" : US"no"; + switch (rc) { case DNS_NOMATCH: @@ -2584,7 +2594,7 @@ if (rc != DNS_SUCCEED) host->mx = MX_NONE; host->port = PORT_NONE; rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE, - fully_qualified_name, dnssec_require); + fully_qualified_name, dnssec_request, dnssec_require); /* If one or more address records have been found, check that none of them are local. Since we know the host items all have their IP addresses @@ -2914,7 +2924,7 @@ for (h = host; h != last->next; h = h->next) { if (h->address != NULL) continue; /* Inserted by a multihomed host */ rc = set_address_from_dns(h, &last, ignore_target_hosts, allow_mx_to_ip, - NULL, dnssec_require); + NULL, dnssec_request, dnssec_require); if (rc != HOST_FOUND) { h->status = hstatus_unusable; diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index b7e50588b..ef3376505 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -354,6 +354,9 @@ while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer))) #endif rc = dns_special_lookup(&dnsa, domain, type, &found); + lookup_dnssec_authenticated = dnssec_mode==OK ? NULL + : dns_is_secure(&dnsa) ? US"yes" : US"no"; + if (rc == DNS_NOMATCH || rc == DNS_NODATA) continue; if (rc != DNS_SUCCEED) { -- 2.25.1