]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
Complete work to allow DNSSEC validation with private DNS servers.
authorSimon Kelley <simon@thekelleys.org.uk>
Sat, 16 Jan 2016 18:39:54 +0000 (18:39 +0000)
committerSimon Kelley <simon@thekelleys.org.uk>
Sat, 16 Jan 2016 18:39:54 +0000 (18:39 +0000)
man/dnsmasq.8
src/forward.c
src/network.c

index d51b10fb1e5b73d08f17a77ab3449eb1df54bd1c..69acdae718afdfa0bb9308874bd80049dbd25b5f 100644 (file)
@@ -405,7 +405,10 @@ xxx.internal.thekelleys.org.uk at 192.168.1.1 then giving  the flag
 .B -S /internal.thekelleys.org.uk/192.168.1.1 
 will send all queries for
 internal machines to that nameserver, everything else will go to the
-servers in /etc/resolv.conf. An empty domain specification,
+servers in /etc/resolv.conf. DNSSEC validation is turned off for such
+private nameservers, UNLESS a
+.B --trust-anchor
+is specified for the domain in question. An empty domain specification,
 .B // 
 has the special meaning of "unqualified names only" ie names without any
 dots in them. A non-standard port may be specified as 
index 11c0d45f441ecd1e3a582f12ad1e2882cc9afe2f..c48fd7519163f55be5dcf1730e5aaa8c0607f11f 100644 (file)
@@ -151,7 +151,7 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
            hostname_isequal(matchstart, serv->domain) &&
            (domainlen == 0 || namelen == domainlen || *(matchstart-1) == '.' ))
          {
-           if (serv->flags & SERV_NO_REBIND)   
+           if ((serv->flags & SERV_NO_REBIND) && norebind)     
              *norebind = 1;
            else
              {
@@ -644,7 +644,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
     return resize_packet(header, n, pheader, plen);
   
   /* Complain loudly if the upstream server is non-recursive. */
-  if (!(header->hb4 & HB4_RA) && RCODE(header) == NOERROR && ntohs(header->ancount) == 0 &&
+  if (!(header->hb4 & HB4_RA) && RCODE(header) == NOERROR &&
       server && !(server->flags & SERV_WARNED_RECURSIVE))
     {
       prettyprint_addr(&server->addr, daemon->namebuff);
@@ -923,12 +923,40 @@ void reply_query(int fd, int family, time_t now)
                    status = STAT_ABANDONED;
                  else
                    {
-                     int fd;
+                     int fd, type;
                      struct frec *next = new->next;
+                     char *domain;
+                     
                      *new = *forward; /* copy everything, then overwrite */
                      new->next = next;
                      new->blocking_query = NULL;
+
+                     /* Find server to forward to. This will normally be the 
+                        same as for the original query, but may be another if
+                        servers for domains are involved. */                 
+                     if (search_servers(now, NULL, F_QUERY, daemon->keyname, &type, &domain, NULL) == 0)
+                       {
+                          struct server *start = server;
+                          type &= ~SERV_DO_DNSSEC;
+                          
+                          while (1)
+                            {
+                              if (type == (start->flags & SERV_TYPE) &&
+                                  (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
+                                  !(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
+                                {
+                                  server = start;
+                                  break;
+                                }
+                              
+                              if (!(start = start->next))
+                                start = daemon->servers;
+                              if (start == server)
+                                break;
+                            }
+                       }
                      new->sentto = server;
+
                      new->rfd4 = NULL;
 #ifdef HAVE_IPV6
                      new->rfd6 = NULL;
index 303ae50745474dcc6883c3ec9e17a389b9f8ad47..5451c6cd591ea86de065040a8f3f3bc87479a823 100644 (file)
@@ -1442,20 +1442,25 @@ void check_servers(void)
       if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
        {
 #ifdef HAVE_DNSSEC
-         if (option_bool(OPT_DNSSEC_VALID) && (serv->flags & SERV_HAS_DOMAIN))
-           {
-             struct ds_config *ds;
-             char *domain = serv->domain;
-
-             /* .example.com is valid */
-             while (*domain == '.')
-               domain++;
-             
-             for (ds = daemon->ds; ds; ds = ds->next)
-               if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
-                 break;
-
-             if (!ds)
+         if (option_bool(OPT_DNSSEC_VALID))
+           { 
+             if (serv->flags & SERV_HAS_DOMAIN)
+               {
+                 struct ds_config *ds;
+                 char *domain = serv->domain;
+                 
+                 /* .example.com is valid */
+                 while (*domain == '.')
+                   domain++;
+                 
+                 for (ds = daemon->ds; ds; ds = ds->next)
+                   if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
+                     break;
+                 
+                 if (!ds)
+                   serv->flags &= ~SERV_DO_DNSSEC;
+               }
+             else if (serv->flags & SERV_FOR_NODOTS) 
                serv->flags &= ~SERV_DO_DNSSEC;
            }
 #endif