[exim-cvs] Propagate dnssec status from dnslookup router thr…

Page principale
Supprimer ce message
Répondre à ce message
Auteur: Exim Git Commits Mailing List
Date:  
À: exim-cvs
Sujet: [exim-cvs] Propagate dnssec status from dnslookup router through transport to tpda
Gitweb: http://git.exim.org/exim.git/commitdiff/783b385fe846f97aa5d7a7675cc0600e917b8795
Commit:     783b385fe846f97aa5d7a7675cc0600e917b8795
Parent:     c3680ef0b5c4c4fe71a8badba562780bd45ddce4
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Mon May 12 15:30:47 2014 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Mon May 12 15:30:47 2014 +0100


    Propagate dnssec status from dnslookup router through transport to tpda
---
 src/src/deliver.c         |   28 +++++++++++++++++++------
 src/src/host.c            |   48 ++++++++++++++++++++++++++++++++++++--------
 src/src/route.c           |    1 +
 src/src/structs.h         |    3 ++
 src/src/transports/smtp.c |    3 ++
 5 files changed, 67 insertions(+), 16 deletions(-)


diff --git a/src/src/deliver.c b/src/src/deliver.c
index 3334ba2..777ff8d 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -730,6 +730,7 @@ pointer to a single host item in their host list, for use by the transport. */
tpda_delivery_local_part = NULL;
tpda_delivery_domain = NULL;
tpda_delivery_confirmation = NULL;
+ lookup_dnssec_authenticated = NULL;
#endif

s = reset_point = store_get(size);
@@ -793,7 +794,7 @@ if (addr->transport->info->local)

 else
   {
-  if (addr->host_used != NULL)
+  if (addr->host_used)
     {
     s = d_hostlog(s, &size, &ptr, addr);
     if (continue_sequence > 1)
@@ -806,6 +807,11 @@ else
     tpda_delivery_local_part =   addr->local_part;
     tpda_delivery_domain =       addr->domain;
     tpda_delivery_confirmation = addr->message;
+
+    /* DNS lookup status */
+    lookup_dnssec_authenticated = addr->host_used->dnssec==DS_YES ? US"yes"
+                  : addr->host_used->dnssec==DS_NO ? US"no"
+                  : NULL;
     #endif
     }


@@ -3019,7 +3025,7 @@ while (!done)
       }
     while (*ptr++);
     break;
-    #endif
+    #endif    /*SUPPORT_TLS*/


     case 'C':    /* client authenticator information */
     switch (*ptr++)
@@ -3039,7 +3045,7 @@ while (!done)


 #ifdef EXPERIMENTAL_PRDR
     case 'P':
-      addr->flags |= af_prdr_used; break;
+    addr->flags |= af_prdr_used; break;
 #endif


     case 'A':
@@ -3066,7 +3072,7 @@ while (!done)
     addr->user_message = (*ptr)? string_copy(ptr) : NULL;
     while(*ptr++);


-    /* Always two strings for host information, followed by the port number */
+    /* Always two strings for host information, followed by the port number and DNSSEC mark */


     if (*ptr != 0)
       {
@@ -3077,6 +3083,10 @@ while (!done)
       while(*ptr++);
       memcpy(&(h->port), ptr, sizeof(h->port));
       ptr += sizeof(h->port);
+      h->dnssec = *ptr == '2' ? DS_YES
+        : *ptr == '1' ? DS_NO
+        : DS_UNK;
+      ptr++;
       addr->host_used = h;
       }
     else ptr++;
@@ -4104,11 +4114,9 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
       retry_item *r;


       /* The certificate verification status goes into the flags */
-
       if (tls_out.certificate_verified) setflag(addr, af_cert_verified);


       /* Use an X item only if there's something to send */
-
       #ifdef SUPPORT_TLS
       if (addr->cipher)
         {
@@ -4179,7 +4187,8 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
     }


       #ifdef EXPERIMENTAL_PRDR
-      if (addr->flags & af_prdr_used) rmt_dlv_checked_write(fd, "P", 1);
+      if (addr->flags & af_prdr_used)
+    rmt_dlv_checked_write(fd, "P", 1);
       #endif


       /* Retry information: for most success cases this will be null. */
@@ -4233,6 +4242,11 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
         while(*ptr++);
         memcpy(ptr, &(addr->host_used->port), sizeof(addr->host_used->port));
         ptr += sizeof(addr->host_used->port);
+
+        /* DNS lookup status */
+    *ptr++ = addr->host_used->dnssec==DS_YES ? '2'
+           : addr->host_used->dnssec==DS_NO ? '1' : '0';
+
         }
       rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
       }
diff --git a/src/src/host.c b/src/src/host.c
index a1db771..a59c438 100644
--- a/src/src/host.c
+++ b/src/src/host.c
@@ -2065,6 +2065,7 @@ for (i = 1; i <= times;
       host->port = PORT_NONE;
       host->status = hstatus_unknown;
       host->why = hwhy_unknown;
+      host->dnssec = DS_UNK;
       last = host;
       }


@@ -2080,6 +2081,7 @@ for (i = 1; i <= times;
       next->port = PORT_NONE;
       next->status = hstatus_unknown;
       next->why = hwhy_unknown;
+      next->dnssec = DS_UNK;
       next->last_try = 0;
       next->next = last->next;
       last->next = next;
@@ -2475,10 +2477,12 @@ int ind_type = 0;
 int yield;
 dns_answer dnsa;
 dns_scan dnss;
-BOOL dnssec_request = match_isinlist(host->name, &dnssec_request_domains,
-                    0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
 BOOL dnssec_require = match_isinlist(host->name, &dnssec_require_domains,
                     0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
+BOOL dnssec_request = dnssec_require
+            || match_isinlist(host->name, &dnssec_request_domains,
+                    0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
+dnssec_status_t dnssec;


 /* Set the default fully qualified name to the incoming name, initialize the
 resolver if necessary, set up the relevant options, and initialize the flag
@@ -2487,7 +2491,7 @@ that gets set for DNS syntax check errors. */
 if (fully_qualified_name != NULL) *fully_qualified_name = host->name;
 dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0,
          (whichrrs & HOST_FIND_SEARCH_PARENTS) != 0,
-     dnssec_request || dnssec_require
+     dnssec_request
      );
 host_find_failed_syntax = FALSE;


@@ -2509,9 +2513,17 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0)
the input name, pass back the new original domain, without the prepended
magic. */

+  dnssec = DS_UNK;
+  lookup_dnssec_authenticated = NULL;
   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 (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 (temp_fully_qualified_name != buffer && fully_qualified_name != NULL)
     *fully_qualified_name = temp_fully_qualified_name + prefix_length;
@@ -2547,9 +2559,17 @@ listed as one for which we continue. */
 if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0)
   {
   ind_type = T_MX;
+  dnssec = DS_UNK;
+  lookup_dnssec_authenticated = NULL;
   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";
+
+  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"; }
+    }


   switch (rc)
     {
@@ -2593,9 +2613,19 @@ if (rc != DNS_SUCCEED)
   last = host;        /* End of local chainlet */
   host->mx = MX_NONE;
   host->port = PORT_NONE;
+  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
@@ -2665,9 +2695,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
   the same precedence to sort randomly. */


   if (ind_type == T_MX)
-    {
     weight = random_number(500);
-    }


   /* SRV records are specified with a port and a weight. The weight is used
   in a special algorithm. However, to start with, we just use it to order the
@@ -2731,6 +2759,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
     host->sort_key = precedence * 1000 + weight;
     host->status = hstatus_unknown;
     host->why = hwhy_unknown;
+    host->dnssec = dnssec;
     last = host;
     }


@@ -2747,6 +2776,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
     next->sort_key = sort_key;
     next->status = hstatus_unknown;
     next->why = hwhy_unknown;
+    next->dnssec = dnssec;
     next->last_try = 0;


     /* Handle the case when we have to insert before the first item. */
diff --git a/src/src/route.c b/src/src/route.c
index 271175e..0116e12 100644
--- a/src/src/route.c
+++ b/src/src/route.c
@@ -1941,6 +1941,7 @@ DEBUG(D_route)
     if (h->mx >= 0) debug_printf(" MX=%d", h->mx);
       else if (h->mx != MX_NONE) debug_printf(" rgroup=%d", h->mx);
     if (h->port != PORT_NONE) debug_printf(" port=%d", h->port);
+    /* if (h->dnssec != DS_UNK) debug_printf(" dnssec=%s", h->dnssec==DS_YES ? "yes" : "no"); */
     debug_printf("\n");
     }
   }
diff --git a/src/src/structs.h b/src/src/structs.h
index aba579f..989653e 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -55,6 +55,8 @@ typedef struct ugid_block {
 but also used when checking lists of hosts and when transporting. Looking up
 host addresses is done using this structure. */


+typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t;
+
 typedef struct host_item {
   struct host_item *next;
   uschar *name;                   /* Host name */
@@ -65,6 +67,7 @@ typedef struct host_item {
   int     status;                 /* Usable, unusable, or unknown */
   int     why;                    /* Why host is unusable */
   int     last_try;               /* Time of last try if known */
+  dnssec_status_t dnssec;
 } host_item;


/* Chain of rewrite rules, read from the rewrite config, or parsed from the
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index fd89486..020f76c 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -2919,6 +2919,9 @@ for (cutoff_retry = 0; expired &&

     deliver_host = host->name;
     deliver_host_address = host->address;
+    lookup_dnssec_authenticated = host->dnssec == DS_YES ? US"yes"
+                : host->dnssec == DS_NO ? US"no"
+                : US"";


     /* Set up a string for adding to the retry key if the port number is not
     the standard SMTP port. A host may have its own port setting that overrides