[exim-cvs] On a host lookup name->MX->A->ip sequence, requir…

Page principale
Supprimer ce message
Répondre à ce message
Auteur: Exim Git Commits Mailing List
Date:  
À: exim-cvs
Sujet: [exim-cvs] On a host lookup name->MX->A->ip sequence, require both stages to
Gitweb: http://git.exim.org/exim.git/commitdiff/cf2b569e3a2f8956b7045191e96bc5edfd366c78
Commit:     cf2b569e3a2f8956b7045191e96bc5edfd366c78
Parent:     2eb77f91023a3279166810a7ce9f15508d244e65
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Aug 10 11:49:49 2014 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sun Aug 10 11:49:49 2014 +0100


    On a host lookup name->MX->A->ip sequence, require both stages to
    be dnssec before declaring the lookup was secure.
---
 src/src/host.c        |   51 ++++++++++++++++++++++++++++++++----------------
 src/src/tls-openssl.c |    1 +
 test/confs/5850       |    8 ++++--
 3 files changed, 40 insertions(+), 20 deletions(-)


diff --git a/src/src/host.c b/src/src/host.c
index 00524f4..2eef0ba 100644
--- a/src/src/host.c
+++ b/src/src/host.c
@@ -2207,7 +2207,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_requested, BOOL dnssec_require)
+  BOOL dnssec_request, BOOL dnssec_require)
 {
 dns_record *rr;
 host_item *thishostlast = NULL;    /* Indicates not yet filled in anything */
@@ -2268,7 +2268,7 @@ for (; i >= 0; i--)
   dns_scan dnss;


   int rc = dns_lookup(&dnsa, host->name, type, fully_qualified_name);
-  lookup_dnssec_authenticated = !dnssec_requested ? NULL
+  lookup_dnssec_authenticated = !dnssec_request ? 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
@@ -2292,11 +2292,31 @@ for (; i >= 0; i--)
     if (rc != DNS_NOMATCH && rc != DNS_NODATA) v6_find_again = TRUE;
     continue;
     }
-  if (dnssec_require && !dns_is_secure(&dnsa))
+
+  if (dnssec_request)
     {
-    log_write(L_host_lookup_failed, LOG_MAIN, "dnssec fail on %s for %.256s",
+    if (dns_is_secure(&dnsa))
+      {
+      DEBUG(D_host_lookup) debug_printf("%s A DNSSEC\n", host->name);
+      if (host->dnssec == DS_UNK) /* set in host_find_bydns() */
+    host->dnssec = DS_YES;
+      }
+    else
+      {
+      if (dnssec_require)
+    {
+    log_write(L_host_lookup_failed, LOG_MAIN,
+        "dnssec fail on %s for %.256s",
         i>1 ? "A6" : i>0 ? "AAAA" : "A", host->name);
-    continue;
+    continue;
+    }
+      if (host->dnssec == DS_YES) /* set in host_find_bydns() */
+    {
+    DEBUG(D_host_lookup) debug_printf("%s A cancel DNSSEC\n", host->name);
+    host->dnssec = DS_NO;
+    lookup_dnssec_authenticated = US"no";
+    }
+      }
     }


   /* Lookup succeeded: fill in the given host item with the first non-ignored
@@ -2562,9 +2582,14 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0)
   if (dnssec_request)
     {
     if (dns_is_secure(&dnsa))
-      { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
+      { 
+      DEBUG(D_host_lookup) debug_printf("%s MX DNSSEC\n", host->name);
+      dnssec = DS_YES; lookup_dnssec_authenticated = US"yes";
+      }
     else
-      { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
+      {
+      dnssec = DS_NO; lookup_dnssec_authenticated = US"no";
+      }
     }


   switch (rc)
@@ -2578,7 +2603,7 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0)
       log_write(L_host_lookup_failed, LOG_MAIN,
           "dnssec fail on MX for %.256s", host->name);
       rc = DNS_FAIL;
-      /*FALLTRHOUGH*/
+      /*FALLTHROUGH*/


     case DNS_FAIL:
     case DNS_AGAIN:
@@ -2609,19 +2634,11 @@ if (rc != DNS_SUCCEED)
   last = host;        /* End of local chainlet */
   host->mx = MX_NONE;
   host->port = PORT_NONE;
-  dnssec = DS_UNK;
+  host->dnssec = DS_UNK;
   lookup_dnssec_authenticated = NULL;
   rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE,
     fully_qualified_name, dnssec_request, dnssec_require);


-  if (dnssec_request)
-    {
-    if (dns_is_secure(&dnsa))
-      { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
-    else
-      { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
-    }
-
   /* 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
   inserted, host_scan_for_local_hosts() can only return HOST_FOUND or
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 0bd23ac..eb74605 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -1664,6 +1664,7 @@ if (host->dnssec == DS_YES)
 else if (dane_required)
   {
   /* Hmm - what lookup, precisely? */
+  /*XXX a shame we only find this after making tcp & smtp connection */
   log_write(0, LOG_MAIN, "DANE error: previous lookup not DNSSEC");
   return FAIL;
   }
diff --git a/test/confs/5850 b/test/confs/5850
index 53cb78a..0b132e2 100644
--- a/test/confs/5850
+++ b/test/confs/5850
@@ -37,9 +37,11 @@ tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
 begin routers


client:
- driver = accept
+ driver = dnslookup
condition = ${if eq {SERVER}{server}{no}{yes}}
- retry_use_local_part
+# retry_use_local_part
+ dnssec_request_domains = *
+ self = send
transport = send_to_server

server:
@@ -54,7 +56,7 @@ begin transports
send_to_server:
driver = smtp
allow_localhost
- hosts = 127.0.0.1
+# hosts = 127.0.0.1
port = PORT_D
# tls_certificate = DIR/aux-fixed/cert2
# tls_privatekey = DIR/aux-fixed/cert2