# module configuration of the server. A string with identifiers
# separated by spaces. "iterator" or "validator iterator"
# module-config: "validator iterator"
+
+ # File with trusted keys for validation.
+ # Zone file format, with DS and DNSKEY entries.
+ # trust-anchor-file: ""
# Stub zones.
# Create entries like below, to make all queries for 'example.com' and
the string with quotes (""). The modules can be validator, iterator.
Setting this to "iterator" will result in a non-validating server.
Setting this to "validator iterator" will turn on validation.
+.It \fBtrust-anchor-file:\fR <filename>
+File with trusted keys for validation. Both DS and DNSKEY entries can appear
+in the file. The format of the file is the standard DNS Zone file format.
+Default is "", or no trust anchor file.
.El
.Ss Stub Zone Options
cfg->hide_version = 0;
cfg->identity = NULL;
cfg->version = NULL;
+ cfg->trust_anchor_file = NULL;
if(!(cfg->module_conf = strdup("iterator"))) goto error_exit;
return cfg;
error_exit:
free(cfg->identity);
free(cfg->version);
free(cfg->module_conf);
+ free(cfg->trust_anchor_file);
free(cfg);
}
/** the module configuration string */
char* module_conf;
+ /** file with trusted DS and DNSKEYs in zonefile format */
+ char* trust_anchor_file;
+
/** daemonize, i.e. fork into the background. */
int do_daemonize;
};
identity{COLON} { YDOUT; return VAR_IDENTITY;}
version{COLON} { YDOUT; return VAR_VERSION;}
module-conf{COLON} { YDOUT; return VAR_MODULE_CONF;}
+trust-anchor-file{COLON} { YDOUT; return VAR_TRUST_ANCHOR_FILE;}
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;}
/* Quoted strings. Strip leading and ending quotes */
%token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
%token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
%token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF
+%token VAR_TRUST_ANCHOR_FILE
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
server_harden_short_bufsize | server_harden_large_queries |
server_do_not_query_address | server_hide_identity |
server_hide_version | server_identity | server_version |
- server_harden_glue | server_module_conf
+ server_harden_glue | server_module_conf | server_trust_anchor_file
;
stubstart: VAR_STUB_ZONE
{
cfg_parser->cfg->pidfile = $2;
}
;
+server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING
+ {
+ OUTYY(("P(server_trust_anchor_file:%s)\n", $2));
+ free(cfg_parser->cfg->trust_anchor_file);
+ cfg_parser->cfg->trust_anchor_file = $2;
+ }
+ ;
server_hide_identity: VAR_HIDE_IDENTITY STRING
{
OUTYY(("P(server_hide_identity:%s)\n", $2));
--- /dev/null
+/*
+ * validator/val_anchor.c - validator trust anchor storage.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains storage for the trust anchors for the validator.
+ */
+#include "config.h"
+#include "validator/val_anchor.h"
+#include "util/data/packed_rrset.h"
+#include "util/data/dname.h"
+#include "util/log.h"
+#include "util/region-allocator.h"
+#include "util/config_file.h"
+
+/** compare two trust anchors */
+static int
+anchor_cmp(const void* k1, const void* k2)
+{
+ int m;
+ struct trust_anchor* n1 = (struct trust_anchor*)k1;
+ struct trust_anchor* n2 = (struct trust_anchor*)k2;
+ /* no need to ntohs(class) because sort order is irrelevant */
+ if(n1->dclass != n2->dclass) {
+ if(n1->dclass < n2->dclass)
+ return -1;
+ return 1;
+ }
+ return dname_lab_cmp(n1->name, n1->namelabs, n2->name, n2->namelabs,
+ &m);
+}
+
+struct val_anchors*
+anchors_create()
+{
+ struct val_anchors* a = (struct val_anchors*)calloc(1, sizeof(*a));
+ if(!a)
+ return NULL;
+ a->region = region_create(malloc, free);
+ if(!a->region) {
+ free(a);
+ return NULL;
+ }
+ a->tree = rbtree_create(anchor_cmp);
+ if(!a->tree) {
+ anchors_delete(a);
+ return NULL;
+ }
+ return a;
+}
+
+void
+anchors_delete(struct val_anchors* anchors)
+{
+ if(!anchors)
+ return;
+ free(anchors->tree);
+ region_destroy(anchors->region);
+ free(anchors);
+}
+
+/** initialise parent pointers in the tree */
+static void
+init_parents(struct val_anchors* anchors)
+{
+ struct trust_anchor* node, *prev = NULL, *p;
+ int m;
+ RBTREE_FOR(node, struct trust_anchor*, anchors->tree) {
+ node->parent = NULL;
+ if(!prev || prev->dclass != node->dclass) {
+ prev = node;
+ continue;
+ }
+ (void)dname_lab_cmp(prev->name, prev->namelabs, node->name,
+ node->namelabs, &m); /* we know prev is smaller */
+ /* sort order like: . com. bla.com. zwb.com. net. */
+ /* find the previous, or parent-parent-parent */
+ for(p = prev; p; p = p->parent)
+ /* looking for name with few labels, a parent */
+ if(p->namelabs <= m) {
+ /* ==: since prev matched m, this is closest*/
+ /* <: prev matches more, but is not a parent,
+ * this one is a (grand)parent */
+ node->parent = p;
+ break;
+ }
+ prev = node;
+ }
+}
+
+int
+anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
+{
+ if(cfg->trust_anchor_file && cfg->trust_anchor_file[0]) {
+ /* read trust anchor file */
+ }
+ init_parents(anchors);
+ return 1;
+}
+
+struct trust_anchor*
+anchors_lookup(struct val_anchors* anchors,
+ uint8_t* qname, size_t qname_len, uint16_t qclass)
+{
+ return NULL;
+}
--- /dev/null
+/*
+ * validator/val_anchor.h - validator trust anchor storage.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains storage for the trust anchors for the validator.
+ */
+
+#ifndef VALIDATOR_VAL_ANCHOR_H
+#define VALIDATOR_VAL_ANCHOR_H
+#include "util/rbtree.h"
+struct region;
+struct trust_anchor;
+struct config_file;
+
+/**
+ * Trust anchor store.
+ */
+struct val_anchors {
+ /** region where trust anchors are allocated */
+ struct region* region;
+ /**
+ * Anchors are store in this tree. Sort order is chosen, so that
+ * dnames are in nsec-like order. A lookup on class, name will return
+ * an exact match of the closest match, with the ancestor needed.
+ * contents of type trust_anchor.
+ */
+ rbtree_t* tree;
+};
+
+/**
+ * Trust anchor key
+ */
+struct ta_key {
+ /** next in list */
+ struct ta_key* next;
+ /** rdata, in wireformat of the key RR. */
+ uint8_t* data;
+ /** length of the rdata */
+ size_t len;
+ /** DNS type (host format) of the key, DS or DNSKEY */
+ uint16_t type;
+};
+
+/**
+ * A trust anchor in the trust anchor store.
+ * Unique by name, class.
+ */
+struct trust_anchor {
+ /** rbtree node, key is this structure */
+ rbnode_t node;
+ /** name of this trust anchor */
+ uint8_t* name;
+ /** number of labels in name of rrset */
+ int namelabs;
+ /** the ancestor in the trustanchor tree */
+ struct trust_anchor* parent;
+ /**
+ * List of DS or DNSKEY rrs that form the trust anchor.
+ * It is allocated in the region.
+ */
+ struct ta_key* keylist;
+ /** number of DSs in the keylist */
+ size_t numDS;
+ /** number of DNSKEYs in the keylist */
+ size_t numDNSKEY;
+ /** class of the trust anchor */
+ uint16_t dclass;
+};
+
+/**
+ * Create trust anchor storage
+ * @return new storage or NULL on error.
+ */
+struct val_anchors* anchors_create();
+
+/**
+ * Delete trust anchor storage.
+ * @param anchors: to delete.
+ */
+void anchors_delete(struct val_anchors* anchors);
+
+/**
+ * Process trust anchor config.
+ * @param anchors: struct anchor storage
+ * @param cfg: config options.
+ * @return 0 on error.
+ */
+int anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg);
+
+/**
+ * Given a qname/qclass combination, find the trust anchor closest above it.
+ * Or return NULL if none exists.
+ *
+ * @param anchors: struct anchor storage
+ * @param qname: query name, uncompressed wireformat.
+ * @param qname_len: length of qname.
+ * @param qclass: class to query for.
+ * @return the trust anchor or NULL if none is found.
+ */
+struct trust_anchor* anchors_lookup(struct val_anchors* anchors,
+ uint8_t* qname, size_t qname_len, uint16_t qclass);
+
+#endif /* VALIDATOR_VAL_ANCHOR_H */
*/
#include "config.h"
#include "validator/validator.h"
+#include "validator/val_anchor.h"
#include "services/cache/dns.h"
#include "util/module.h"
#include "util/log.h"
#include "util/net_help.h"
#include "util/region-allocator.h"
+/** apply config settings to validator */
+static int
+val_apply_cfg(struct val_env* val_env, struct config_file* cfg)
+{
+ if(!val_env->anchors)
+ val_env->anchors = anchors_create();
+ if(!val_env->anchors) {
+ log_err("out of memory");
+ return 0;
+ }
+ if(!anchors_apply_cfg(val_env->anchors, cfg)) {
+ log_err("validator: error in trustanchors config");
+ return 0;
+ }
+ return 1;
+}
+
/** validator init */
static int
val_init(struct module_env* env, int id)
return 0;
}
env->modinfo[id] = (void*)val_env;
- /*if(!val_apply_cfg(val_env, env->cfg)) {
+ if(!val_apply_cfg(val_env, env->cfg)) {
log_err("validator: could not apply configuration settings.");
return 0;
- }*/
+ }
return 1;
}
if(!env || !env->modinfo || !env->modinfo[id])
return;
val_env = (struct val_env*)env->modinfo[id];
+ anchors_delete(val_env->anchors);
free(val_env);
}
#define VALIDATOR_VALIDATOR_H
struct module_func_block;
#include "util/data/msgreply.h"
+struct val_anchors;
/**
* Global state for the validator.
*/
struct val_env {
- /** global state placeholder */
- int option;
-
/** trusted key storage */
+ struct val_anchors* anchors;
/** key cache */
};