dnssec_strict, _lax, _never modifiers for dnsdb lookups
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 23 Apr 2014 23:49:56 +0000 (00:49 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Thu, 24 Apr 2014 13:02:19 +0000 (14:02 +0100)
Lacking testsuite coverage

doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/lookups/dnsdb.c

index 6f0a16f3710cb9f0cc2d438a5c22f3fd64495fb5..612d147a535ca64311c211e81f7712f98b72ba46 100644 (file)
@@ -6959,11 +6959,16 @@ The data from each lookup is concatenated, with newline separators by default,
 in the same way that multiple DNS records for a single item are handled. A
 different separator can be specified, as described above.
 
 in the same way that multiple DNS records for a single item are handled. A
 different separator can be specified, as described above.
 
+Modifiers for &(dnsdb)& lookups are givien by optional keywords,
+each followed by a comma,
+that may appear before the record type.
+
 The &(dnsdb)& lookup fails only if all the DNS lookups fail. If there is a
 temporary DNS error for any of them, the behaviour is controlled by
 The &(dnsdb)& lookup fails only if all the DNS lookups fail. If there is a
 temporary DNS error for any of them, the behaviour is controlled by
-an optional keyword followed by a comma that may appear before the record
-type. The possible keywords are &"defer_strict"&, &"defer_never"&, and
-&"defer_lax"&. With &"strict"& behaviour, any temporary DNS error causes the
+a defer-option modifier.
+The possible keywords are
+&"defer_strict"&, &"defer_never"&, and &"defer_lax"&.
+With &"strict"& behaviour, any temporary DNS error causes the
 whole lookup to defer. With &"never"& behaviour, a temporary DNS error is
 ignored, and the behaviour is as if the DNS lookup failed to find anything.
 With &"lax"& behaviour, all the queries are attempted, but a temporary DNS
 whole lookup to defer. With &"never"& behaviour, a temporary DNS error is
 ignored, and the behaviour is as if the DNS lookup failed to find anything.
 With &"lax"& behaviour, all the queries are attempted, but a temporary DNS
@@ -6976,6 +6981,16 @@ ${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.
 
 Thus, in the default case, as long as at least one of the DNS lookups
 yields some data, the lookup succeeds.
 
+Use of &(DNSSEC)& is controlled by a dnssec modifier.
+The possible keywords are
+&"dnssec_strict"&, &"dnssec_lax"&, and &"dnssec_never"&.
+With &"strict"& or &"lax"& DNSSEC information is requested
+with the lookup.
+With &"strict"& a response from the DNS resolver that
+is not labelled as authenticated data
+is treated as equivalent to a temporary DNS error.
+The default is &"never".
+
 
 
 
 
 
 
index 30b27a012ccf4e57d51b57ba258421548d6e3445..649b730f011ae30cc6105a089c47aa8244337dfb 100644 (file)
@@ -91,6 +91,9 @@ TL/08 Bugzilla 1453: New LDAP "SERVERS=" option allows admin to override list
       of ldap servers used for a specific lookup.  Patch provided by Heiko
       Schlichting.
 
       of ldap servers used for a specific lookup.  Patch provided by Heiko
       Schlichting.
 
+JH/18 New options dnssec_lax, dnssec_strict on dnsdb lookups.
+
+
 Exim version 4.82
 -----------------
 
 Exim version 4.82
 -----------------
 
index a1eb2b6587813cb353347da76f746c89a69cf732..b7e50588b6e851c1859fe9ff90068a553ca2cf24 100644 (file)
@@ -114,11 +114,15 @@ any defer causes the whole lookup to defer; 'lax', where a defer causes the
 whole lookup to defer only if none of the DNS queries succeeds; and 'never',
 where all defers are as if the lookup failed. The default is 'lax'.
 
 whole lookup to defer only if none of the DNS queries succeeds; and 'never',
 where all defers are as if the lookup failed. The default is 'lax'.
 
-(d) If the next sequence of characters is a sequence of letters and digits
+(d) Another optional comma-sep field: 'dnssec_FOO', with 'strict', 'lax'
+and 'never' (default); can appear before or after (c).  The meanings are
+require, try and don't-try dnssec respectively.
+
+(e) If the next sequence of characters is a sequence of letters and digits
 followed by '=', it is interpreted as the name of the DNS record type. The
 default is "TXT".
 
 followed by '=', it is interpreted as the name of the DNS record type. The
 default is "TXT".
 
-(e) Then there follows list of domain names. This is a generalized Exim list,
+(f) Then there follows list of domain names. This is a generalized Exim list,
 which may start with '<' in order to set a specific separator. The default
 separator, as always, is colon. */
 
 which may start with '<' in order to set a specific separator. The default
 separator, as always, is colon. */
 
@@ -131,6 +135,7 @@ int size = 256;
 int ptr = 0;
 int sep = 0;
 int defer_mode = PASS;
 int ptr = 0;
 int sep = 0;
 int defer_mode = PASS;
+int dnssec_mode = OK;
 int type;
 int failrc = FAIL;
 uschar *outsep = US"\n";
 int type;
 int failrc = FAIL;
 uschar *outsep = US"\n";
@@ -173,35 +178,64 @@ if (*keystring == '>')
   while (isspace(*keystring)) keystring++;
   }
 
   while (isspace(*keystring)) keystring++;
   }
 
-/* Check for a defer behaviour keyword. */
+/* Check for a modifier keyword. */
 
 
-if (strncmpic(keystring, US"defer_", 6) == 0)
+while (  strncmpic(keystring, US"defer_", 6) == 0
+      || strncmpic(keystring, US"dnssec_", 7) == 0
+      )
   {
   {
-  keystring += 6;
-  if (strncmpic(keystring, US"strict", 6) == 0)
+  if (strncmpic(keystring, US"defer_", 6) == 0)
     {
     {
-    defer_mode = DEFER;
     keystring += 6;
     keystring += 6;
-    }
-  else if (strncmpic(keystring, US"lax", 3) == 0)
-    {
-    defer_mode = PASS;
-    keystring += 3;
-    }
-  else if (strncmpic(keystring, US"never", 5) == 0)
-    {
-    defer_mode = OK;
-    keystring += 5;
+    if (strncmpic(keystring, US"strict", 6) == 0)
+      {
+      defer_mode = DEFER;
+      keystring += 6;
+      }
+    else if (strncmpic(keystring, US"lax", 3) == 0)
+      {
+      defer_mode = PASS;
+      keystring += 3;
+      }
+    else if (strncmpic(keystring, US"never", 5) == 0)
+      {
+      defer_mode = OK;
+      keystring += 5;
+      }
+    else
+      {
+      *errmsg = US"unsupported dnsdb defer behaviour";
+      return DEFER;
+      }
     }
   else
     {
     }
   else
     {
-    *errmsg = US"unsupported dnsdb defer behaviour";
-    return DEFER;
+    keystring += 7;
+    if (strncmpic(keystring, US"strict", 6) == 0)
+      {
+      dnssec_mode = DEFER;
+      keystring += 6;
+      }
+    else if (strncmpic(keystring, US"lax", 3) == 0)
+      {
+      dnssec_mode = PASS;
+      keystring += 3;
+      }
+    else if (strncmpic(keystring, US"never", 5) == 0)
+      {
+      dnssec_mode = OK;
+      keystring += 5;
+      }
+    else
+      {
+      *errmsg = US"unsupported dnsdb dnssec behaviour";
+      return DEFER;
+      }
     }
   while (isspace(*keystring)) keystring++;
   if (*keystring++ != ',')
     {
     }
   while (isspace(*keystring)) keystring++;
   if (*keystring++ != ',')
     {
-    *errmsg = US"dnsdb defer behaviour syntax error";
+    *errmsg = US"dnsdb modifier syntax error";
     return DEFER;
     }
   while (isspace(*keystring)) keystring++;
     return DEFER;
     }
   while (isspace(*keystring)) keystring++;
@@ -241,7 +275,7 @@ if ((equals = Ustrchr(keystring, '=')) != NULL)
 
 /* Initialize the resolver in case this is the first time it has been used. */
 
 
 /* Initialize the resolver in case this is the first time it has been used. */
 
-dns_init(FALSE, FALSE, FALSE); /*XXX dnssec? */
+dns_init(FALSE, FALSE, dnssec_mode != OK);
 
 /* The remainder of the string must be a list of domains. As long as the lookup
 for at least one of them succeeds, we return success. Failure means that none
 
 /* The remainder of the string must be a list of domains. As long as the lookup
 for at least one of them succeeds, we return success. Failure means that none
@@ -323,10 +357,20 @@ while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer)))
     if (rc == DNS_NOMATCH || rc == DNS_NODATA) continue;
     if (rc != DNS_SUCCEED)
       {
     if (rc == DNS_NOMATCH || rc == DNS_NODATA) continue;
     if (rc != DNS_SUCCEED)
       {
-      if (defer_mode == DEFER) return DEFER;          /* always defer */
+      if (defer_mode == DEFER)
+       {
+       dns_init(FALSE, FALSE, FALSE);
+       return DEFER;                                   /* always defer */
+       }
       if (defer_mode == PASS) failrc = DEFER;         /* defer only if all do */
       continue;                                       /* treat defer as fail */
       }
       if (defer_mode == PASS) failrc = DEFER;         /* defer only if all do */
       continue;                                       /* treat defer as fail */
       }
+    if (dnssec_mode == DEFER && !dns_is_secure(&dnsa))
+      {
+      failrc = DEFER;
+      continue;
+      }
+
 
     /* Search the returned records */
 
 
     /* Search the returned records */
 
@@ -494,6 +538,8 @@ store_reset(yield + ptr + 1);
 /* If ptr == 0 we have not found anything. Otherwise, insert the terminating
 zero and return the result. */
 
 /* If ptr == 0 we have not found anything. Otherwise, insert the terminating
 zero and return the result. */
 
+dns_init(FALSE, FALSE, FALSE); /* clear the dnssec bit for getaddrbyname */
+
 if (ptr == 0) return failrc;
 yield[ptr] = 0;
 *result = yield;
 if (ptr == 0) return failrc;
 yield[ptr] = 0;
 *result = yield;
@@ -538,4 +584,6 @@ static lookup_info _lookup_info = {
 static lookup_info *_lookup_list[] = { &_lookup_info };
 lookup_module_info dnsdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
 
 static lookup_info *_lookup_list[] = { &_lookup_info };
 lookup_module_info dnsdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
 
+/* vi: aw ai sw=2
+*/
 /* End of lookups/dnsdb.c */
 /* End of lookups/dnsdb.c */