Merge branch 'exim-4.96+security' into master+security
[exim.git] / src / src / dns.c
index 8dc3695a118782926b1ec994997f2dfc420a5acb..db566f2e86b54a0840d9a229e3aca3a262994beb 100644 (file)
@@ -5,6 +5,7 @@
 /* Copyright (c) The Exim Maintainers 2020 - 2022 */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 
 /* Functions for interfacing with the DNS. */
 
@@ -800,6 +801,7 @@ dns_basic_lookup(dns_answer * dnsa, const uschar * name, int type)
 int rc;
 #ifndef STAND_ALONE
 const uschar * save_domain;
+static BOOL try_again_recursion = FALSE;
 #endif
 
 /* DNS lookup failures of any kind are cached in a tree. This is mainly so that
@@ -904,11 +906,31 @@ if (dnsa->answerlen < 0) switch (h_errno)
 
     /* Cut this out for various test programs */
 #ifndef STAND_ALONE
-    save_domain = deliver_domain;
-    deliver_domain = string_copy(name);  /* set $domain */
-    rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0,
-      &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
-    deliver_domain = save_domain;
+    /* Permitting dns_again_means nonexist for TLSA lookups breaks the
+    doewngrade resistance of dane, so avoid for those. */
+
+    if (type == T_TLSA)
+      rc = FAIL;
+    else
+      {
+      if (try_again_recursion)
+       {
+       log_write(0, LOG_MAIN|LOG_PANIC,
+         "dns_again_means_nonexist recursion seen for %s"
+         " (assuming nonexist)", name);
+       return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type),
+                             DNS_NOMATCH);
+       }
+
+      try_again_recursion = TRUE;
+      save_domain = deliver_domain;
+      deliver_domain = string_copy(name);  /* set $domain */
+      rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0,
+       &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
+      deliver_domain = save_domain;
+      try_again_recursion = FALSE;
+      }
+
     if (rc != OK)
       {
       DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n");
@@ -1323,7 +1345,7 @@ dns_pattern_init(void)
 {
 if (check_dns_names_pattern[0] != 0 && !regex_check_dns_names)
   regex_check_dns_names =
-    regex_must_compile(check_dns_names_pattern, FALSE, TRUE);
+    regex_must_compile(check_dns_names_pattern, MCS_NOFLAGS, TRUE);
 }
 
 /* vi: aw ai sw=2