Commit 92be34a4 authored by Simon Kelley's avatar Simon Kelley

Complete work to allow DNSSEC validation with private DNS servers.

parent bb58f63c
...@@ -405,7 +405,10 @@ xxx.internal.thekelleys.org.uk at 192.168.1.1 then giving the flag ...@@ -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 .B -S /internal.thekelleys.org.uk/192.168.1.1
will send all queries for will send all queries for
internal machines to that nameserver, everything else will go to the 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 // .B //
has the special meaning of "unqualified names only" ie names without any has the special meaning of "unqualified names only" ie names without any
dots in them. A non-standard port may be specified as dots in them. A non-standard port may be specified as
......
...@@ -151,7 +151,7 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne ...@@ -151,7 +151,7 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
hostname_isequal(matchstart, serv->domain) && hostname_isequal(matchstart, serv->domain) &&
(domainlen == 0 || namelen == domainlen || *(matchstart-1) == '.' )) (domainlen == 0 || namelen == domainlen || *(matchstart-1) == '.' ))
{ {
if (serv->flags & SERV_NO_REBIND) if ((serv->flags & SERV_NO_REBIND) && norebind)
*norebind = 1; *norebind = 1;
else else
{ {
...@@ -644,7 +644,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server ...@@ -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); return resize_packet(header, n, pheader, plen);
/* Complain loudly if the upstream server is non-recursive. */ /* 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)) server && !(server->flags & SERV_WARNED_RECURSIVE))
{ {
prettyprint_addr(&server->addr, daemon->namebuff); prettyprint_addr(&server->addr, daemon->namebuff);
...@@ -923,12 +923,40 @@ void reply_query(int fd, int family, time_t now) ...@@ -923,12 +923,40 @@ void reply_query(int fd, int family, time_t now)
status = STAT_ABANDONED; status = STAT_ABANDONED;
else else
{ {
int fd; int fd, type;
struct frec *next = new->next; struct frec *next = new->next;
char *domain;
*new = *forward; /* copy everything, then overwrite */ *new = *forward; /* copy everything, then overwrite */
new->next = next; new->next = next;
new->blocking_query = NULL; 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->sentto = server;
new->rfd4 = NULL; new->rfd4 = NULL;
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
new->rfd6 = NULL; new->rfd6 = NULL;
......
...@@ -1442,7 +1442,9 @@ void check_servers(void) ...@@ -1442,7 +1442,9 @@ void check_servers(void)
if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND))) if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
{ {
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID) && (serv->flags & SERV_HAS_DOMAIN)) if (option_bool(OPT_DNSSEC_VALID))
{
if (serv->flags & SERV_HAS_DOMAIN)
{ {
struct ds_config *ds; struct ds_config *ds;
char *domain = serv->domain; char *domain = serv->domain;
...@@ -1458,6 +1460,9 @@ void check_servers(void) ...@@ -1458,6 +1460,9 @@ void check_servers(void)
if (!ds) if (!ds)
serv->flags &= ~SERV_DO_DNSSEC; serv->flags &= ~SERV_DO_DNSSEC;
} }
else if (serv->flags & SERV_FOR_NODOTS)
serv->flags &= ~SERV_DO_DNSSEC;
}
#endif #endif
port = prettyprint_addr(&serv->addr, daemon->namebuff); port = prettyprint_addr(&serv->addr, daemon->namebuff);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment