+1328. [func] DS (delegation signer) support.
+
1327. [bug] nsupdate: allow white space base64 key data.
1326. [bug] Badly encoded LOC record when the size, horizontal
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.21 2001/11/06 20:05:00 bwelling Exp $
+# $Id: Makefile.in,v 1.22 2002/06/17 04:01:03 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
# Alphabetically
-TARGETS = dnssec-keygen \
- dnssec-makekeyset \
- dnssec-signkey \
- dnssec-signzone
+TARGETS = dnssec-keygen dnssec-signzone
OBJS = dnssectool.@O@
-SRCS = dnssec-keygen.c dnssec-makekeyset.c \
- dnssec-signkey.c dnssec-signzone.c \
- dnssectool.c
+SRCS = dnssec-keygen.c dnssec-signzone.c dnssectool.c
-MANPAGES = dnssec-keygen.8 \
- dnssec-makekeyset.8 \
- dnssec-signkey.8 \
- dnssec-signzone.8
+MANPAGES = dnssec-keygen.8 dnssec-signzone.8
-HTMLPAGES = dnssec-keygen.html \
- dnssec-makekeyset.html \
- dnssec-signkey.html \
- dnssec-signzone.html
+HTMLPAGES = dnssec-keygen.html dnssec-signzone.html
MANOBJS = ${MANPAGES} ${HTMLPAGES}
dnssec-keygen: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS}
${LIBTOOL} ${PURIFY} ${CC} ${CFLAGS} -o $@ dnssec-keygen.@O@ ${OBJS} ${LIBS}
-dnssec-makekeyset: dnssec-makekeyset.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL} ${PURIFY} ${CC} ${CFLAGS} -o $@ dnssec-makekeyset.@O@ ${OBJS} ${LIBS}
-
-dnssec-signkey: dnssec-signkey.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL} ${PURIFY} ${CC} ${CFLAGS} -o $@ dnssec-signkey.@O@ ${OBJS} ${LIBS}
-
dnssec-signzone.@O@: dnssec-signzone.c
${LIBTOOL} ${PURIFY} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" -c $<
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.159 2002/02/20 03:33:02 marka Exp $ */
+/* $Id: dnssec-signzone.c,v 1.160 2002/06/17 04:01:05 marka Exp $ */
#include <config.h>
#include <dns/dbiterator.h>
#include <dns/diff.h>
#include <dns/dnssec.h>
+#include <dns/ds.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
int verbose;
#define BUFSIZE 2048
+#define MAXDSKEYS 8
typedef struct signer_key_struct signer_key_t;
struct signer_key_struct {
dst_key_t *key;
isc_boolean_t isdefault;
+ isc_boolean_t keysigning;
unsigned int position;
ISC_LINK(signer_key_t) link;
};
static dns_db_t *gdb; /* The database */
static dns_dbversion_t *gversion; /* The database version */
static dns_dbiterator_t *gdbiter; /* The database iterator */
+static dns_rdataclass_t gclass; /* The class */
static dns_name_t *gorigin; /* The database origin */
static isc_task_t *master = NULL;
static unsigned int ntasks = 0;
check_result(result, "dns_master_dumpnodetostream");
}
+static void
+dumpdb(dns_db_t *db) {
+ dns_dbiterator_t *dbiter = NULL;
+ dns_dbnode_t *node;
+ dns_fixedname_t fname;
+ dns_name_t *name;
+ isc_result_t result;
+
+ dbiter = NULL;
+ result = dns_db_createiterator(db, ISC_FALSE, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ node = NULL;
+
+ for (result = dns_dbiterator_first(dbiter);
+ result == ISC_R_SUCCESS;
+ result = dns_dbiterator_next(dbiter))
+ {
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_result(result, "dns_dbiterator_current()");
+ dumpnode(name, node);
+ dns_db_detachnode(db, &node);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("iterating database: %s", isc_result_totext(result));
+
+ dns_dbiterator_destroy(&dbiter);
+}
+
static signer_key_t *
-newkeystruct(dst_key_t *dstkey, isc_boolean_t isdefault) {
+newkeystruct(dst_key_t *dstkey, isc_boolean_t isdefault,
+ isc_boolean_t iskeysigning)
+{
signer_key_t *key;
key = isc_mem_get(mctx, sizeof(signer_key_t));
fatal("out of memory");
key->key = dstkey;
key->isdefault = isdefault;
+ key->keysigning = iskeysigning;
key->position = keycount++;
ISC_LINK_INIT(key, link);
return (key);
NULL, mctx, &privkey);
if (result == ISC_R_SUCCESS) {
dst_key_free(&pubkey);
- key = newkeystruct(privkey, ISC_FALSE);
+ key = newkeystruct(privkey, ISC_FALSE, ISC_FALSE);
} else
- key = newkeystruct(pubkey, ISC_FALSE);
+ key = newkeystruct(pubkey, ISC_FALSE, ISC_FALSE);
ISC_LIST_APPEND(keylist, key, link);
return (key);
}
unsigned char array[BUFSIZE];
char keystr[KEY_FORMATSIZE];
- if (!key->isdefault || nowsignedby[key->position])
+ if (nowsignedby[key->position])
+ continue;
+
+ if (!(key->isdefault ||
+ (key->keysigning &&
+ set->type == dns_rdatatype_key &&
+ dns_name_equal(name, gorigin))))
continue;
key_format(key->key, keystr, sizeof(keystr));
isc_mem_put(mctx, nowsignedby, arraysize * sizeof(isc_boolean_t));
}
-/* Determine if a KEY set contains a null key */
-static isc_boolean_t
-hasnullkey(dns_rdataset_t *rdataset) {
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- for (result = dns_rdataset_first(rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(rdataset))
- {
- dst_key_t *key = NULL;
-
- dns_rdata_reset(&rdata);
- dns_rdataset_current(rdataset, &rdata);
- result = dns_dnssec_keyfromrdata(dns_rootname,
- &rdata, mctx, &key);
- if (result != ISC_R_SUCCESS)
- fatal("could not convert KEY into internal "
- "format: %s", isc_result_totext(result));
- if (dst_key_isnullkey(key)) {
- dst_key_free(&key);
- return (ISC_TRUE);
- }
- dst_key_free(&key);
- }
- if (result != ISC_R_NOMORE)
- fatal("failure looking for null keys");
- return (ISC_FALSE);
-}
-
static void
opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
dns_db_t **dbp)
}
/*
- * Looks for signatures of the zone keys by the parent, and imports them
- * if found.
+ * Loads the key set for a child zone, if there is one, and builds DS records.
*/
-static void
-importparentsig(dns_diff_t *diff, dns_name_t *name, dns_rdataset_t *set) {
- dns_db_t *newdb = NULL;
- dns_dbnode_t *newnode = NULL;
- dns_rdataset_t newset, sigset;
- dns_rdata_t rdata = DNS_RDATA_INIT, newrdata = DNS_RDATA_INIT;
+static isc_result_t
+loadds(dns_name_t *name, dns_rdataset_t *dsset) {
+ dns_db_t *db = NULL;
+ dns_dbversion_t *ver = NULL;
+ dns_dbnode_t *node = NULL;
isc_result_t result;
+ dns_rdataset_t keyset;
+ dns_rdata_t key, ds;
+ unsigned char dsbuf[DNS_DS_BUFFERSIZE];
+ dns_diff_t diff;
+ dns_difftuple_t *tuple = NULL;
- dns_rdataset_init(&newset);
- dns_rdataset_init(&sigset);
-
- opendb("signedkey-", name, dns_db_class(gdb), &newdb);
- if (newdb == NULL)
- return;
-
- result = dns_db_findnode(newdb, name, ISC_FALSE, &newnode);
- if (result != ISC_R_SUCCESS)
- goto failure;
- result = dns_db_findrdataset(newdb, newnode, NULL, dns_rdatatype_key,
- 0, 0, &newset, &sigset);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- if (!dns_rdataset_isassociated(&newset) ||
- !dns_rdataset_isassociated(&sigset))
- goto failure;
-
- if (dns_rdataset_count(set) != dns_rdataset_count(&newset)) {
- result = DNS_R_BADDB;
- goto failure;
- }
+ opendb("keyset-", name, gclass, &db);
+ if (db == NULL)
+ return (ISC_R_NOTFOUND);
- result = dns_rdataset_first(set);
- check_result(result, "dns_rdataset_first()");
- for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(set)) {
- dns_rdataset_current(set, &rdata);
- result = dns_rdataset_first(&newset);
- check_result(result, "dns_rdataset_first()");
- for (;
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&newset))
- {
- dns_rdataset_current(&newset, &newrdata);
- if (dns_rdata_compare(&rdata, &newrdata) == 0)
- break;
- dns_rdata_reset(&newrdata);
- }
- dns_rdata_reset(&newrdata);
- dns_rdata_reset(&rdata);
- if (result != ISC_R_SUCCESS)
- break;
+ result = dns_db_findnode(db, name, ISC_FALSE, &node);
+ if (result != ISC_R_SUCCESS) {
+ dns_db_detach(&db);
+ return (DNS_R_BADDB);
}
- if (result != ISC_R_NOMORE)
- goto failure;
-
- vbprintf(2, "found the parent's signature of our zone key\n");
-
- result = dns_rdataset_first(&sigset);
- while (result == ISC_R_SUCCESS) {
- dns_difftuple_t *tuple = NULL;
-
- dns_rdataset_current(&sigset, &rdata);
- result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
- sigset.ttl, &rdata, &tuple);
- check_result(result, "dns_difftuple_create");
- dns_diff_append(diff, &tuple);
- result = dns_rdataset_next(&sigset);
- dns_rdata_reset(&rdata);
+ dns_rdataset_init(&keyset);
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_key, 0, 0,
+ &keyset, NULL);
+ if (result != ISC_R_SUCCESS) {
+ dns_db_detachnode(db, &node);
+ dns_db_detach(&db);
+ return (result);
}
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- failure:
- if (dns_rdataset_isassociated(&newset))
- dns_rdataset_disassociate(&newset);
- if (dns_rdataset_isassociated(&sigset))
- dns_rdataset_disassociate(&sigset);
- if (newnode != NULL)
- dns_db_detachnode(newdb, &newnode);
- if (newdb != NULL)
- dns_db_detach(&newdb);
- if (result != ISC_R_SUCCESS)
- fatal("zone signedkey file is invalid or does not match zone");
-}
-
-/*
- * Looks for our signatures of child keys. If present, inform the caller.
- */
-static isc_boolean_t
-haschildkey(dns_name_t *name) {
- dns_db_t *newdb = NULL;
- dns_dbnode_t *newnode = NULL;
- dns_rdataset_t set, sigset;
- dns_rdata_t sigrdata = DNS_RDATA_INIT;
- isc_result_t result;
- isc_boolean_t found = ISC_FALSE;
- dns_rdata_sig_t sig;
- signer_key_t *key;
- dns_rdataset_init(&set);
- dns_rdataset_init(&sigset);
+ vbprintf(2, "found KEY records\n");
- opendb("signedkey-", name, dns_db_class(gdb), &newdb);
- if (newdb == NULL)
- return (ISC_FALSE);
+ result = dns_db_newversion(db, &ver);
+ check_result(result, "dns_db_newversion");
- result = dns_db_findnode(newdb, name, ISC_FALSE, &newnode);
- if (result != ISC_R_SUCCESS)
- goto failure;
- result = dns_db_findrdataset(newdb, newnode, NULL, dns_rdatatype_key,
- 0, 0, &set, &sigset);
- if (result != ISC_R_SUCCESS)
- goto failure;
+ dns_diff_init(mctx, &diff);
- if (!dns_rdataset_isassociated(&set) ||
- !dns_rdataset_isassociated(&sigset))
- goto failure;
+ for (result = dns_rdataset_first(&keyset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&keyset))
+ {
+ dns_rdata_init(&key);
+ dns_rdata_init(&ds);
+ dns_rdataset_current(&keyset, &key);
+ result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA1,
+ dsbuf, &ds);
+ check_result(result, "dns_ds_buildrdata");
- result = dns_rdataset_first(&sigset);
- check_result(result, "dns_rdataset_first()");
- dns_rdata_init(&sigrdata);
- for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(&sigset)) {
- dns_rdataset_current(&sigset, &sigrdata);
- result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
- if (result != ISC_R_SUCCESS)
- goto failure;
- key = keythatsigned(&sig);
- dns_rdata_freestruct(&sig);
- if (key == NULL) {
- char namestr[DNS_NAME_FORMATSIZE];
- dns_name_format(name, namestr, sizeof(namestr));
- vbprintf(1, "unknown KEY in %s signedkey file\n",
- namestr);
- goto failure;
- }
- result = dns_dnssec_verify(name, &set, key->key,
- ISC_FALSE, mctx, &sigrdata);
- if (result == ISC_R_SUCCESS) {
- found = ISC_TRUE;
- break;
- } else {
- char namestr[DNS_NAME_FORMATSIZE];
- dns_name_format(name, namestr, sizeof(namestr));
- vbprintf(1, "verifying SIG in %s signedkey file: %s\n",
- namestr, isc_result_totext(result));
- }
- dns_rdata_reset(&sigrdata);
+ result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
+ zonettl, &ds, &tuple);
+ check_result(result, "dns_difftuple_create");
+ dns_diff_append(&diff, &tuple);
}
+ result = dns_diff_apply(&diff, db, ver);
+ check_result(result, "dns_diff_apply");
+ dns_diff_clear(&diff);
- failure:
- if (dns_rdataset_isassociated(&set))
- dns_rdataset_disassociate(&set);
- if (dns_rdataset_isassociated(&sigset))
- dns_rdataset_disassociate(&sigset);
- if (newnode != NULL)
- dns_db_detachnode(newdb, &newnode);
- if (newdb != NULL)
- dns_db_detach(&newdb);
+ dns_db_closeversion(db, &ver, ISC_TRUE);
- return (found);
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, 0,
+ dsset, NULL);
+ check_result(result, "dns_db_findrdataset");
+
+ dns_rdataset_disassociate(&keyset);
+ dns_db_detachnode(db, &node);
+ dns_db_detach(&db);
+ return (result);
}
-/*
- * There probably should be a dns_nxt_setbit, but it can get complicated if
- * the length of the bit set needs to be increased. In this case, since the
- * NXT bit is set and both SIG and KEY are less than NXT, the easy way works.
- */
+/* XXX fix me */
static void
-nxt_setbit(dns_rdataset_t *rdataset, dns_rdatatype_t type) {
+nxt_setbit(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdatatype_t type,
+ unsigned int val)
+{
isc_result_t result;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_nxt_t nxt;
+ unsigned int newlen;
- REQUIRE(type <= dns_rdatatype_nxt);
+ INSIST(type < 128);
result = dns_rdataset_first(rdataset);
check_result(result, "dns_rdataset_first()");
dns_rdataset_current(rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &nxt, NULL);
check_result(result, "dns_rdata_tostruct");
- set_bit(nxt.typebits, type, 1);
- dns_rdata_freestruct(&nxt);
-}
-static void
-createnullkey(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
- dns_ttl_t ttl)
-{
- unsigned char keydata[4];
- dns_rdata_t keyrdata = DNS_RDATA_INIT;
- dns_rdata_key_t key;
- dns_diff_t diff;
- dns_difftuple_t *tuple = NULL;
- isc_buffer_t b;
- isc_result_t result;
- char namestr[DNS_NAME_FORMATSIZE];
-
- dns_name_format(name, namestr, sizeof(namestr));
- vbprintf(2, "adding null key at %s\n", namestr);
-
- key.common.rdclass = dns_db_class(db);
- key.common.rdtype = dns_rdatatype_key;
- ISC_LINK_INIT(&key.common, link);
- key.mctx = NULL;
- key.flags = DNS_KEYTYPE_NOKEY | DNS_KEYOWNER_ZONE;
- key.protocol = DNS_KEYPROTO_DNSSEC;
- key.algorithm = DNS_KEYALG_DSA;
- key.datalen = 0;
- key.data = NULL;
- isc_buffer_init(&b, keydata, sizeof(keydata));
- result = dns_rdata_fromstruct(&keyrdata, dns_db_class(db),
- dns_rdatatype_key, &key, &b);
- if (result != ISC_R_SUCCESS)
- fatal("failed to build null key");
+ newlen = type / 8 + 1;
- dns_diff_init(mctx, &diff);
+ if (newlen <= nxt.len)
+ set_bit(nxt.typebits, type, val);
+ else {
+ unsigned char bitmap[16];
+ unsigned char nxtdata[16 + DNS_NAME_MAXWIRE];
+ unsigned int len = newlen;
+ dns_rdata_t newrdata = DNS_RDATA_INIT;
+ isc_buffer_t b;
+ dns_diff_t diff;
+ dns_difftuple_t *tuple = NULL;
- result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, ttl,
- &keyrdata, &tuple);
- check_result(result, "dns_difftuple_create");
+ INSIST(nxt.len < sizeof(bitmap));
- dns_diff_append(&diff, &tuple);
+ dns_diff_init(mctx, &diff);
+ result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL, name,
+ rdataset->ttl, &rdata, &tuple);
+ check_result(result, "dns_difftuple_create");
+ dns_diff_append(&diff, &tuple);
+
+ memset(bitmap, 0, sizeof(bitmap));
+ memcpy(bitmap, nxt.typebits, nxt.len);
+ set_bit(bitmap, type, val);
+ nxt.typebits = bitmap;
+ nxt.len = len;
+ isc_buffer_init(&b, nxtdata, sizeof(nxtdata));
+ result = dns_rdata_fromstruct(&newrdata, rdata.rdclass,
+ dns_rdatatype_nxt, &nxt, &b);
+ check_result(result, "dns_rdata_fromstruct");
- result = dns_diff_apply(&diff, db, version);
- check_result(result, "dns_diff_apply");
+ result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
+ rdataset->ttl, &newrdata,
+ &tuple);
+ check_result(result, "dns_difftuple_create");
+ dns_diff_append(&diff, &tuple);
- dns_diff_clear(&diff);
+ result = dns_diff_apply(&diff, gdb, gversion);
+ check_result(result, "dns_difftuple_apply");
+ dns_diff_clear(&diff);
+ }
+ dns_rdata_freestruct(&nxt);
}
static void
dns_rdataset_t rdataset;
dns_rdatasetiter_t *rdsiter;
isc_boolean_t isdelegation = ISC_FALSE;
- isc_boolean_t childkey = ISC_FALSE;
+ isc_boolean_t hasds = ISC_FALSE;
isc_boolean_t atorigin;
- isc_boolean_t neednullkey = ISC_FALSE;
dns_diff_t diff;
char namestr[DNS_NAME_FORMATSIZE];
isdelegation = ISC_TRUE;
/*
- * If this is a delegation point, determine if we need to generate
- * a null key.
+ * If this is a delegation point, look for a DS set.
*/
if (isdelegation) {
- dns_rdataset_t keyset;
- dns_ttl_t nullkeyttl;
+ dns_rdataset_t dsset;
- childkey = haschildkey(name);
- neednullkey = ISC_TRUE;
- nullkeyttl = zonettl;
-
- dns_rdataset_init(&keyset);
- result = dns_db_findrdataset(gdb, node, gversion,
- dns_rdatatype_key, 0, 0, &keyset,
- NULL);
- if (result == ISC_R_SUCCESS && childkey) {
- if (hasnullkey(&keyset)) {
- fatal("%s has both a signedkey file and "
- "null keys in the zone. Aborting.",
- namestr);
- }
- vbprintf(2, "child key for %s found\n", namestr);
- neednullkey = ISC_FALSE;
- dns_rdataset_disassociate(&keyset);
- }
- else if (result == ISC_R_SUCCESS) {
- if (hasnullkey(&keyset))
- neednullkey = ISC_FALSE;
- nullkeyttl = keyset.ttl;
- dns_rdataset_disassociate(&keyset);
- } else if (childkey) {
- vbprintf(2, "child key for %s found\n", namestr);
- neednullkey = ISC_FALSE;
+ dns_rdataset_init(&dsset);
+ result = loadds(name, &dsset);
+ if (result == ISC_R_SUCCESS) {
+ result = dns_db_addrdataset(gdb, node, gversion, 0,
+ &dsset, 0, NULL);
+ check_result(result, "dns_db_deleterdataset");
+ hasds = ISC_TRUE;
+ dns_rdataset_disassociate(&dsset);
}
-
- if (neednullkey)
- createnullkey(gdb, gversion, name, nullkeyttl);
}
/*
if (rdataset.type == dns_rdatatype_sig)
goto skip;
- /*
- * If this is a KEY set at the apex, look for a signedkey file.
- */
- if (atorigin && rdataset.type == dns_rdatatype_key) {
- importparentsig(&diff, name, &rdataset);
- goto skip;
- }
-
/*
* If this name is a delegation point, skip all records
- * except an NXT set and a KEY set containing a null key.
+ * except NXT and DS sets.
*/
if (isdelegation) {
- if (!(rdataset.type == dns_rdatatype_nxt ||
- (rdataset.type == dns_rdatatype_key &&
- hasnullkey(&rdataset))))
+ if (rdataset.type != dns_rdatatype_nxt &&
+ rdataset.type != dns_rdatatype_ds)
goto skip;
}
if (rdataset.type == dns_rdatatype_nxt) {
if (!nokeys)
- nxt_setbit(&rdataset, dns_rdatatype_sig);
- if (neednullkey)
- nxt_setbit(&rdataset, dns_rdatatype_key);
+ nxt_setbit(name, &rdataset, dns_rdatatype_sig,
+ 1);
+ if (hasds)
+ nxt_setbit(name, &rdataset, dns_rdatatype_ds,
+ 1);
}
signset(&diff, node, name, &rdataset);
for (i = 0; i < nkeys; i++) {
signer_key_t *key;
- key = newkeystruct(keys[i], ISC_FALSE);
+ key = newkeystruct(keys[i], ISC_FALSE, ISC_FALSE);
ISC_LIST_APPEND(keylist, key, link);
}
dns_db_detachnode(db, &node);
goto next;
}
- key = newkeystruct(pubkey, ISC_FALSE);
+ key = newkeystruct(pubkey, ISC_FALSE, ISC_FALSE);
ISC_LIST_APPEND(keylist, key, link);
next:
result = dns_rdataset_next(&rdataset);
dns_db_closeversion(db, ¤tversion, ISC_FALSE);
}
+static void
+writekeyset(void) {
+ char namestr[DNS_NAME_FORMATSIZE];
+ isc_buffer_t namebuf;
+ unsigned int filenamelen;
+ char *keyfile;
+ signer_key_t *key;
+ unsigned char keybuf[DST_KEY_MAXSIZE];
+ dns_diff_t diff;
+ dns_difftuple_t *tuple = NULL;
+ dns_db_t *db = NULL;
+ dns_dbversion_t *version = NULL;
+ dns_rdata_t rdata;
+ isc_buffer_t b;
+ isc_region_t r;
+ isc_result_t result;
+
+ isc_buffer_init(&namebuf, namestr, sizeof(namestr));
+ result = dns_name_tofilenametext(gorigin, ISC_FALSE, &namebuf);
+ check_result(result, "dns_name_tofilenametext");
+ isc_buffer_putuint8(&namebuf, 0);
+ filenamelen = strlen("keyset-") + strlen(namestr);
+ if (directory != NULL)
+ filenamelen += strlen(directory) + 1;
+ keyfile = isc_mem_get(mctx, filenamelen + 1);
+ if (keyfile == NULL)
+ fatal("out of memory");
+ if (directory != NULL)
+ sprintf(keyfile, "%s/", directory);
+ else
+ keyfile[0] = 0;
+ strcat(keyfile, "keyset-");
+ strcat(keyfile, namestr);
+
+ dns_diff_init(mctx, &diff);
+
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link))
+ {
+ if (!key->keysigning)
+ continue;
+ dns_rdata_init(&rdata);
+ isc_buffer_init(&b, keybuf, sizeof(keybuf));
+ result = dst_key_todns(key->key, &b);
+ check_result(result, "dst_key_todns");
+ isc_buffer_usedregion(&b, &r);
+ dns_rdata_fromregion(&rdata, gclass, dns_rdatatype_key, &r);
+ result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, gorigin,
+ zonettl, &rdata, &tuple);
+ check_result(result, "dns_difftuple_create");
+ dns_diff_append(&diff, &tuple);
+ }
+
+ result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
+ gclass, 0, NULL, &db);
+ check_result(result, "dns_db_create");
+
+ result = dns_db_newversion(db, &version);
+ check_result(result, "dns_db_newversion");
+
+ result = dns_diff_apply(&diff, db, version);
+ check_result(result, "dns_diff_apply");
+ dns_diff_clear(&diff);
+
+ result = dns_master_dump(mctx, db, version, masterstyle, keyfile);
+ check_result(result, "dns_master_dump");
+
+ isc_mem_put(mctx, keyfile, filenamelen + 1);
+
+ dns_db_closeversion(db, &version, ISC_FALSE);
+ dns_db_detach(&db);
+}
+
static void
print_time(FILE *fp) {
time_t currenttime;
fprintf(stderr, "\t-t:\t");
fprintf(stderr, "print statistics\n");
fprintf(stderr, "\t-n ncpus (number of cpus present)\n");
+ fprintf(stderr, "\t-k key_signing_key\n");
fprintf(stderr, "\n");
int i, ch;
char *startstr = NULL, *endstr = NULL, *classname = NULL;
char *origin = NULL, *file = NULL, *output = NULL;
+ char *dskeyfile[MAXDSKEYS];
+ int ndskeys = 0;
char *endp;
isc_time_t timer_start, timer_finish;
signer_key_t *key;
isc_boolean_t free_output = ISC_FALSE;
int tempfilelen;
dns_rdataclass_t rdclass;
+ dns_db_t *udb = NULL;
isc_task_t **tasks = NULL;
masterstyle = &dns_master_style_explicitttl;
dns_result_register();
while ((ch = isc_commandline_parse(argc, argv,
- "c:s:e:i:v:o:f:ahpr:td:n:S"))
+ "c:s:e:i:v:o:f:ahpr:td:n:Sk:"))
!= -1) {
switch (ch) {
case 'c':
masterstyle = &dns_master_style_simple;
break;
+ case 'k':
+ if (ndskeys == MAXDSKEYS)
+ fatal("too many key-signing keys specified");
+ dskeyfile[ndskeys++] = isc_commandline_argument;
+ break;
+
case 'h':
default:
usage();
argc -= 1;
argv += 1;
+ if (origin == NULL)
+ origin = file;
+
if (output == NULL) {
free_output = ISC_TRUE;
output = isc_mem_allocate(mctx,
sprintf(output, "%s.signed", file);
}
- if (origin == NULL)
- origin = file;
-
gdb = NULL;
TIME_NOW(&timer_start);
loadzone(file, origin, rdclass, &gdb);
gorigin = dns_db_origin(gdb);
+ gclass = dns_db_class(gdb);
zonettl = soattl();
ISC_LIST_INIT(keylist);
key = ISC_LIST_HEAD(keylist);
while (key != NULL) {
key->isdefault = ISC_TRUE;
+ if (ndskeys == 0)
+ key->keysigning = ISC_TRUE;
key = ISC_LIST_NEXT(key, link);
}
} else {
key = ISC_LIST_NEXT(key, link);
}
if (key == NULL) {
- key = newkeystruct(newkey, ISC_TRUE);
+ isc_boolean_t iskeysigning = ISC_FALSE;
+ if (ndskeys == 0)
+ iskeysigning = ISC_TRUE;
+ key = newkeystruct(newkey, ISC_TRUE,
+ iskeysigning);
ISC_LIST_APPEND(keylist, key, link);
} else
dst_key_free(&newkey);
loadzonepubkeys(gdb);
}
+ for (i = 0; i < ndskeys; i++) {
+ dst_key_t *newkey = NULL;
+
+ result = dst_key_fromnamedfile(dskeyfile[i],
+ DST_TYPE_PUBLIC |
+ DST_TYPE_PRIVATE,
+ mctx, &newkey);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot load key %s: %s", dskeyfile[i],
+ isc_result_totext(result));
+
+ key = ISC_LIST_HEAD(keylist);
+ while (key != NULL) {
+ dst_key_t *dkey = key->key;
+ if (dst_key_id(dkey) == dst_key_id(newkey) &&
+ dst_key_alg(dkey) == dst_key_alg(newkey) &&
+ dns_name_equal(dst_key_name(dkey),
+ dst_key_name(newkey)))
+ {
+ key->keysigning = ISC_TRUE;
+ dst_key_free(&dkey);
+ key->key = newkey;
+ break;
+ }
+ key = ISC_LIST_NEXT(key, link);
+ }
+ if (key == NULL) {
+ key = newkeystruct(newkey, ISC_FALSE, ISC_TRUE);
+ ISC_LIST_APPEND(keylist, key, link);
+ }
+ }
+
if (ISC_LIST_EMPTY(keylist)) {
fprintf(stderr, "%s: warning: No keys specified or found\n",
program);
nxtify();
+ if (!nokeys)
+ writekeyset();
+
tempfilelen = strlen(output) + 20;
tempfile = isc_mem_get(mctx, tempfilelen);
if (tempfile == NULL)
isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *));
postsign();
+ if (udb != NULL) {
+ dumpdb(udb);
+ dns_db_detach(&udb);
+ }
+
result = isc_stdio_close(fp);
check_result(result, "isc_stdio_close");
removefile = ISC_FALSE;
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.219 2002/03/28 04:03:50 marka Exp $ */
+/* $Id: query.c,v 1.220 2002/06/17 04:01:08 marka Exp $ */
#include <config.h>
}
}
+static void
+query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node) {
+ dns_name_t *rname;
+ dns_rdataset_t *rdataset, *sigrdataset;
+ isc_result_t result;
+
+ CTRACE("query_addds");
+ rname = NULL;
+ rdataset = NULL;
+ sigrdataset = NULL;
+
+ /*
+ * We'll need some resources...
+ */
+ rdataset = query_newrdataset(client);
+ sigrdataset = query_newrdataset(client);
+ if (rdataset == NULL || sigrdataset == NULL)
+ return;
+
+ /*
+ * Look for the DS record, which may or may not be present.
+ */
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0,
+ client->now, rdataset, sigrdataset);
+ /*
+ * If we didn't find it, look for an NXT. */
+ if (result == ISC_R_NOTFOUND)
+ result = dns_db_findrdataset(db, node, NULL,
+ dns_rdatatype_nxt, 0, client->now,
+ rdataset, sigrdataset);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
+ goto cleanup;
+ if (!dns_rdataset_isassociated(rdataset) ||
+ !dns_rdataset_isassociated(sigrdataset))
+ goto cleanup;
+
+ /*
+ * We've already added the NS record, so if the name's not there,
+ * we have other problems. Use this name rather than calling
+ * query_addrrset().
+ */
+ result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ rname = NULL;
+ dns_message_currentname(client->message, DNS_SECTION_AUTHORITY,
+ &rname);
+ result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ ISC_LIST_APPEND(rname->list, rdataset, link);
+ ISC_LIST_APPEND(rname->list, sigrdataset, link);
+ rdataset = NULL;
+ sigrdataset = NULL;
+
+ cleanup:
+ if (rdataset != NULL)
+ query_putrdataset(client, &rdataset);
+ if (sigrdataset != NULL)
+ query_putrdataset(client, &sigrdataset);
+}
+
static void
query_resume(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
return (result);
}
-static inline isc_result_t
-query_findparentkey(ns_client_t *client, dns_name_t *name,
- dns_zone_t **zonep, dns_db_t **dbp,
- dns_dbversion_t **versionp, dns_dbnode_t **nodep,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
-{
- dns_db_t *pdb;
- dns_dbnode_t *pnode;
- dns_dbversion_t *pversion;
- dns_rdataset_t prdataset, psigrdataset;
- dns_rdataset_t *psigrdatasetp;
- isc_result_t result;
- dns_zone_t *pzone;
- isc_boolean_t is_zone;
- dns_fixedname_t pfoundname;
-
- /*
- * 'name' is at a zone cut. Try to find a KEY for 'name' in
- * the deepest ancestor zone of 'name' (if any). If it exists,
- * update *zonep, *dbp, *nodep, rdataset, and sigrdataset and
- * return ISC_R_SUCCESS. If not, leave them alone and return a
- * non-success status.
- */
-
- pzone = NULL;
- pdb = NULL;
- pnode = NULL;
- pversion = NULL;
- dns_rdataset_init(&prdataset);
- if (sigrdataset != NULL)
- dns_rdataset_init(&psigrdataset);
- is_zone = ISC_FALSE;
- dns_fixedname_init(&pfoundname);
-
- result = query_getdb(client, name, DNS_GETDB_NOEXACT,
- &pzone, &pdb, &pversion, &is_zone);
- if (result != ISC_R_SUCCESS)
- goto cleanup;
- if (!is_zone) {
- result = ISC_R_FAILURE;
- goto cleanup;
- }
-
- if (sigrdataset != NULL)
- psigrdatasetp = &psigrdataset;
- else
- psigrdatasetp = NULL;
- result = dns_db_find(pdb, name, pversion, dns_rdatatype_key,
- client->query.dboptions,
- client->now, &pnode,
- dns_fixedname_name(&pfoundname),
- &prdataset, psigrdatasetp);
- if (result == ISC_R_SUCCESS) {
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- dns_rdataset_clone(&prdataset, rdataset);
- if (sigrdataset != NULL) {
- if (dns_rdataset_isassociated(sigrdataset))
- dns_rdataset_disassociate(sigrdataset);
- if (dns_rdataset_isassociated(&psigrdataset))
- dns_rdataset_clone(&psigrdataset, sigrdataset);
- }
- if (*nodep != NULL)
- dns_db_detachnode(*dbp, nodep);
- *nodep = pnode;
- pnode = NULL;
- *versionp = pversion;
- if (*dbp != NULL)
- dns_db_detach(dbp);
- *dbp = pdb;
- pdb = NULL;
- if (*zonep != NULL)
- dns_zone_detach(zonep);
- *zonep = pzone;
- pzone = NULL;
- }
-
- cleanup:
- if (dns_rdataset_isassociated(&prdataset))
- dns_rdataset_disassociate(&prdataset);
- if (sigrdataset != NULL && dns_rdataset_isassociated(&psigrdataset))
- dns_rdataset_disassociate(&psigrdataset);
- if (pnode != NULL)
- dns_db_detachnode(pdb, &pnode);
- if (pdb != NULL)
- dns_db_detach(&pdb);
- if (pzone != NULL)
- dns_zone_detach(&pzone);
-
- return (result);
-}
-
#define MAX_RESTARTS 16
#define QUERY_ERROR(r) \
dns_zone_t *zone;
dns_rdata_cname_t cname;
dns_rdata_dname_t dname;
+ unsigned int options;
CTRACE("query_find");
/*
* First we must find the right database.
*/
- result = query_getdb(client, client->query.qname, 0, &zone, &db,
+ options = 0;
+ if (dns_rdatatype_atparent(qtype) &&
+ !dns_name_equal(client->query.qname, dns_rootname))
+ options |= DNS_GETDB_NOEXACT;
+ result = query_getdb(client, client->query.qname, options, &zone, &db,
&version, &is_zone);
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_REFUSED)
client->query.dboptions, client->now,
&node, fname, rdataset, sigrdataset);
- /*
- * We interrupt our normal query processing to bring you this special
- * case...
- *
- * RFC 2535 (DNSSEC), section 2.3.4, discusses various special
- * cases that can occur at delegation points.
- *
- * One of these cases is that the NULL KEY for an unsecure zone
- * may occur in the delegating zone instead of in the delegated zone.
- * If we're authoritative for both zones, we need to look for the
- * key in the delegator if we didn't find it in the delegatee. If
- * we didn't do this, a client doing DNSSEC validation could fail
- * because it couldn't get the NULL KEY.
- */
- if (type == dns_rdatatype_key &&
- is_zone &&
- result == DNS_R_NXRRSET &&
- !dns_db_issecure(db) &&
- dns_name_equal(client->query.qname, dns_db_origin(db))) {
- /*
- * We're looking for a KEY at the top of an unsecure zone,
- * and we didn't find it.
- */
- result = query_findparentkey(client, client->query.qname,
- &zone, &db, &version, &node,
- rdataset, sigrdataset);
- if (result == ISC_R_SUCCESS) {
- /*
- * We found the parent KEY.
- *
- * zone, db, version, node, rdataset, and sigrdataset
- * have all been updated to refer to the parent's
- * data. We will resume query processing as if
- * we had looked for the KEY in the parent zone in
- * the first place.
- *
- * We need to set fname correctly. We do this here
- * instead of in query_findparentkey() because
- * dns_name_copy() can fail (though it shouldn't
- * ever do so since we should have enough space).
- */
- result = dns_name_copy(client->query.qname,
- fname, NULL);
- if (result != ISC_R_SUCCESS) {
- QUERY_ERROR(DNS_R_SERVFAIL);
- goto cleanup;
- }
- } else {
- /*
- * We couldn't find the KEY in a parent zone.
- * Continue with processing of the original
- * results of dns_db_find().
- */
- result = DNS_R_NXRRSET;
- }
- }
-
resume:
CTRACE("query_find: resume");
switch (result) {
&rdataset, sigrdatasetp,
dbuf, DNS_SECTION_AUTHORITY);
client->query.gluedb = NULL;
+ if (WANTDNSSEC(client) && dns_db_issecure(db))
+ query_addds(client, db, node);
} else {
/*
* We might have a better answer or delegation
/*
* Recurse!
*/
+ /* XXXBEW look at this? */
if (type == dns_rdatatype_key)
result = query_recurse(client, qtype,
NULL, NULL);
client->query.gluedb = NULL;
client->query.attributes &=
~NS_QUERYATTR_CACHEGLUEOK;
+ if (WANTDNSSEC(client) &&
+ !dns_rdataset_isassociated(sigrdataset))
+ query_addds(client, db, node);
}
}
goto cleanup;
/*
* Add NXT record if we found one.
*/
- if (dns_rdataset_isassociated(rdataset)) {
- if (WANTDNSSEC(client))
+ if (WANTDNSSEC(client)) {
+ if (dns_rdataset_isassociated(rdataset))
query_addrrset(client, &fname, &rdataset,
&sigrdataset,
NULL, DNS_SECTION_AUTHORITY);
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: conf.sh.in,v 1.23 2001/08/01 19:00:58 gson Exp $
+# $Id: conf.sh.in,v 1.24 2002/06/17 04:01:10 marka Exp $
#
# Common configuration data for system tests, to be sourced into
NSUPDATE=$TOP/bin/nsupdate/nsupdate
KEYGEN=$TOP/bin/dnssec/dnssec-keygen
SIGNER=$TOP/bin/dnssec/dnssec-signzone
-KEYSIGNER=$TOP/bin/dnssec/dnssec-signkey
-KEYSETTOOL=$TOP/bin/dnssec/dnssec-makekeyset
# The "stress" test is not run by default since it creates enough
# load on the machine to make it unusable to other users.
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: sign.sh,v 1.13 2001/09/17 17:42:04 bwelling Exp $
+# $Id: sign.sh,v 1.14 2002/06/17 04:01:12 marka Exp $
SYSTEMTESTTOP=../..
. $SYSTEMTESTTOP/conf.sh
infile=root.db.in
zonefile=root.db
-keyname=`$KEYGEN -r $RANDFILE -a RSA -b 768 -n zone $zone`
-
(cd ../ns2 && sh sign.sh )
cp ../ns2/keyset-example. .
-$KEYSIGNER -r $RANDFILE keyset-example. $keyname > /dev/null
-
-cat signedkey-example. >> ../ns2/example.db.signed
-
-$KEYSETTOOL -r $RANDFILE -t 3600 $keyname > /dev/null
+keyname=`$KEYGEN -r $RANDFILE -a RSA -b 768 -n zone $zone`
cat $infile $keyname.key > $zonefile
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: sign.sh,v 1.19 2002/02/20 03:33:55 marka Exp $
+# $Id: sign.sh,v 1.20 2002/06/17 04:01:14 marka Exp $
SYSTEMTESTTOP=../..
. $SYSTEMTESTTOP/conf.sh
infile=example.db.in
zonefile=example.db
-keyname=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone`
-
-# Have the child generate a zone key and pass it to us,
-# sign it, and pass it back
+# Have the child generate a zone key and pass it to us.
( cd ../ns3 && sh sign.sh )
for subdomain in secure bogus dynamic
do
cp ../ns3/keyset-$subdomain.example. .
-
- $KEYSIGNER -r $RANDFILE keyset-$subdomain.example. $keyname > /dev/null
-
- # This will leave two copies of the child's zone key in the signed db file;
- # that shouldn't cause any problems.
- cat signedkey-$subdomain.example. >>../ns3/$subdomain.example.db.signed
done
-$KEYSETTOOL -r $RANDFILE -t 3600 $keyname > /dev/null
+keyname1=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone`
+keyname2=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone`
-cat $infile $keyname.key >$zonefile
+cat $infile $keyname1.key $keyname2.key >$zonefile
-$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -r $RANDFILE -o $zone -k $keyname1 $zonefile $keyname2 > /dev/null
# Sign the privately secure file
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: sign.sh,v 1.16 2002/02/20 03:33:59 marka Exp $
+# $Id: sign.sh,v 1.17 2002/06/17 04:01:15 marka Exp $
RANDFILE=../random.data
keyname=`$KEYGEN -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
-$KEYSETTOOL -r $RANDFILE -t 3600 $keyname.key > /dev/null
-
cat $infile $keyname.key >$zonefile
$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
keyname=`$KEYGEN -r $RANDFILE -a RSA -b 768 -n zone $zone`
-$KEYSETTOOL -r $RANDFILE -t 3600 $keyname.key > /dev/null
-
cat $infile $keyname.key >$zonefile
$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
keyname=`$KEYGEN -r $RANDFILE -a RSA -b 768 -n zone $zone`
-$KEYSETTOOL -r $RANDFILE -t 3600 $keyname.key > /dev/null
-
cat $infile $keyname.key >$zonefile
$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
keyname=`$KEYGEN -r $RANDFILE -a RSA -b 768 -n zone $zone`
-$KEYSETTOOL -r $RANDFILE -t 3600 $keyname.key > /dev/null
-
cat $infile $keyname.key >$zonefile
$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: tests.sh,v 1.39 2002/02/20 03:33:50 marka Exp $
+# $Id: tests.sh,v 1.40 2002/06/17 04:01:11 marka Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
rm -f dig.out.*
-DIGOPTS="+tcp +noadd +nosea +nostat +noquest +nocmd +dnssec -p 5300"
+DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p 5300"
# Check the example. domain
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
+echo "I:checking that insecurity proofs fail with a misconfigured trusted key ($n)"
+ret=0
+$DIG $DIGOPTS a.insecure.example. a @10.53.0.5 > dig.out.ns5.test$n || ret=1
+grep "SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
echo "I:checking that validation fails when key record is missing ($n)"
ret=0
$DIG $DIGOPTS a.b.keyless.example. a @10.53.0.4 > dig.out.ns4.test$n || ret=1
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.129 2002/03/07 06:29:36 marka Exp $
+# $Id: Makefile.in,v 1.130 2002/06/17 04:01:17 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
OBJS = a6.@O@ acl.@O@ adb.@O@ byaddr.@O@ \
cache.@O@ callbacks.@O@ compress.@O@ \
db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
- dnssec.@O@ forward.@O@ journal.@O@ keytable.@O@ \
+ dnssec.@O@ ds.@O@ forward.@O@ journal.@O@ keytable.@O@ \
lib.@O@ log.@O@ lookup.@O@ \
master.@O@ masterdump.@O@ message.@O@ \
name.@O@ ncache.@O@ nxt.@O@ order.@O@ peer.@O@ \
SRCS = a6.c acl.c adb.c byaddr.c \
cache.c callbacks.c compress.c \
db.c dbiterator.c dbtable.c diff.c dispatch.c \
- dnssec.c forward.c journal.c keytable.c \
+ dnssec.c ds.c forward.c journal.c keytable.c \
lib.c log.c lookup.c \
master.c masterdump.c message.c \
name.c ncache.c nxt.c order.c peer.c \
--- /dev/null
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ds.c,v 1.2 2002/06/17 04:01:18 marka Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <isc/buffer.h>
+#include <isc/region.h>
+#include <isc/sha1.h>
+#include <isc/util.h>
+
+#include <dns/ds.h>
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdatastruct.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
+isc_result_t
+dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
+ unsigned int digest_type, unsigned char *buffer,
+ dns_rdata_t *rdata)
+{
+ isc_sha1_t sha1;
+ dns_fixedname_t fname;
+ dns_name_t *name;
+ unsigned char digest[ISC_SHA1_DIGESTLENGTH];
+ isc_region_t r;
+ isc_buffer_t b;
+ dns_rdata_ds_t ds;
+
+ if (digest_type != DNS_DSDIGEST_SHA1)
+ return (ISC_R_NOTIMPLEMENTED);
+
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ (void)dns_name_downcase(owner, name, NULL);
+
+ memset(buffer, 0, DNS_DS_BUFFERSIZE);
+ isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE);
+
+ isc_sha1_init(&sha1);
+ dns_name_toregion(name, &r);
+ isc_sha1_update(&sha1, r.base, r.length);
+ dns_rdata_toregion(key, &r);
+ INSIST(r.length >= 4);
+ isc_sha1_update(&sha1, r.base, r.length);
+ isc_sha1_final(&sha1, digest);
+
+ ds.mctx = NULL;
+ ds.common.rdclass = key->rdclass;
+ ds.common.rdtype = dns_rdatatype_ds;
+ ds.algorithm = r.base[3];
+ ds.key_tag = dst_region_computeid(&r, ds.algorithm);
+ ds.digest_type = DNS_DSDIGEST_SHA1;
+ ds.length = ISC_SHA1_DIGESTLENGTH;
+ ds.digest = digest;
+
+ return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
+ &ds, &b));
+}
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.45 2001/11/09 23:09:29 bwelling Exp $
+# $Id: Makefile.in,v 1.46 2002/06/17 04:01:28 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
HEADERS = a6.h acl.h adb.h byaddr.h cache.h callbacks.h \
cert.h compress.h \
db.h dbiterator.h dbtable.h diff.h dispatch.h \
- dnssec.h events.h fixedname.h journal.h keyflags.h \
+ dnssec.h ds.h events.h fixedname.h journal.h keyflags.h \
keytable.h keyvalues.h lib.h log.h master.h masterdump.h \
message.h name.h ncache.h \
nxt.h peer.h rbt.h rcode.h \
--- /dev/null
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ds.h,v 1.2 2002/06/17 04:01:29 marka Exp $ */
+
+#ifndef DNS_DS_H
+#define DNS_DS_H 1
+
+#include <isc/lang.h>
+
+#include <dns/types.h>
+
+#define DNS_DSDIGEST_SHA1 (1)
+
+/*
+ * Assuming SHA-1 digest type.
+ */
+#define DNS_DS_BUFFERSIZE (24)
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
+ unsigned int digest_type, unsigned char *buffer,
+ dns_rdata_t *rdata);
+/*
+ * Build the rdata of a DS record.
+ *
+ * Requires:
+ * key Points to a valid DNS KEY record.
+ * buffer Points to a temporary buffer of at least
+ * DNS_DS_BUFFERSIZE bytes.
+ * rdata Points to an initialized dns_rdata_t.
+ *
+ * Ensures:
+ * *rdata Contains a valid DS rdata. The 'data' member refers
+ * to 'buffer'.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_DS_H */
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdata.h,v 1.54 2002/02/20 03:34:36 marka Exp $ */
+/* $Id: rdata.h,v 1.55 2002/06/17 04:01:31 marka Exp $ */
#ifndef DNS_RDATA_H
#define DNS_RDATA_H 1
*
*/
+isc_boolean_t
+dns_rdatatype_atparent(dns_rdatatype_t type);
+/*
+ * Return true iff rdata of type 'type' should appear at the parent of
+ * a zone cut.
+ *
+ * Requires:
+ * 'type' is a valid rdata type.
+ *
+ */
+
unsigned int
dns_rdatatype_attributes(dns_rdatatype_t rdtype);
/*
#define DNS_RDATATYPEATTR_QUESTIONONLY 0x00000080U
/* is META, and can NOT be in a question section */
#define DNS_RDATATYPEATTR_NOTQUESTION 0x00000100U
+/* Is present at zone cuts in the parent, not the child */
+#define DNS_RDATATYPEATTR_ATPARENT 0x00000200U
dns_rdatatype_t
dns_rdata_covers(dns_rdata_t *rdata);
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.h,v 1.88 2002/03/14 18:34:46 bwelling Exp $ */
+/* $Id: result.h,v 1.89 2002/06/17 04:01:32 marka Exp $ */
#ifndef DNS_RESULT_H
#define DNS_RESULT_H 1
#define DNS_R_FROZEN (ISC_RESULTCLASS_DNS + 81)
#define DNS_R_UNKNOWNFLAG (ISC_RESULTCLASS_DNS + 82)
#define DNS_R_EXPECTEDRESPONSE (ISC_RESULTCLASS_DNS + 83)
+#define DNS_R_NOVALIDDS (ISC_RESULTCLASS_DNS + 84)
-#define DNS_R_NRESULTS 84 /* Number of results */
+#define DNS_R_NRESULTS 85 /* Number of results */
/*
* DNS wire format rcodes.
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.h,v 1.20 2001/09/14 20:53:33 gson Exp $ */
+/* $Id: validator.h,v 1.21 2002/06/17 04:01:33 marka Exp $ */
#ifndef DNS_VALIDATOR_H
#define DNS_VALIDATOR_H 1
unsigned int attributes;
dns_validatorevent_t * event;
dns_fetch_t * fetch;
- dns_validator_t * keyvalidator;
- dns_validator_t * authvalidator;
+ dns_validator_t * subvalidator;
+ dns_validator_t * parent;
dns_keytable_t * keytable;
dns_keynode_t * keynode;
dst_key_t * key;
dns_rdataset_t * currentset;
isc_boolean_t seensig;
dns_rdataset_t * keyset;
+ dns_rdataset_t * dsset;
+ dns_rdataset_t * soaset;
dns_rdataset_t frdataset;
dns_rdataset_t fsigrdataset;
+ dns_fixedname_t fname;
ISC_LINK(dns_validator_t) link;
};
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.175 2002/05/28 05:49:20 marka Exp $ */
+/* $Id: rbtdb.c,v 1.176 2002/06/17 04:01:20 marka Exp $ */
/*
* Principal Author: Bob Halley
*/
if (node->find_callback &&
(node != search.rbtdb->origin_node ||
- IS_STUB(search.rbtdb)))
+ IS_STUB(search.rbtdb)) &&
+ !dns_rdatatype_atparent(type))
maybe_zonecut = ISC_TRUE;
}
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdata.c,v 1.171 2002/03/27 23:31:32 marka Exp $ */
+/* $Id: rdata.c,v 1.172 2002/06/17 04:01:21 marka Exp $ */
#include <config.h>
#include <ctype.h>
return (ISC_FALSE);
}
+isc_boolean_t
+dns_rdatatype_atparent(dns_rdatatype_t type) {
+ if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0)
+ return (ISC_TRUE);
+ return (ISC_FALSE);
+}
+
isc_boolean_t
dns_rdataclass_ismeta(dns_rdataclass_t rdclass) {
REQUIRE(rdclass < 65536);
--- /dev/null
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ds_43.c,v 1.2 2002/06/17 04:01:35 marka Exp $ */
+
+/* draft-ietf-dnsext-delegation-signer-05.txt */
+
+#ifndef RDATA_GENERIC_DS_43_C
+#define RDATA_GENERIC_DS_43_C
+
+#define RRTYPE_DS_ATTRIBUTES (DNS_RDATATYPEATTR_ATPARENT)
+
+static inline isc_result_t
+fromtext_ds(ARGS_FROMTEXT) {
+ isc_token_t token;
+
+ REQUIRE(type == 43);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(origin);
+ UNUSED(downcase);
+ UNUSED(callbacks);
+
+ /*
+ * Key tag.
+ */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xffff)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint16_tobuffer(token.value.as_ulong, target));
+
+ /*
+ * Algorithm.
+ */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xff)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint8_tobuffer(token.value.as_ulong, target));
+
+ /*
+ * Digest type.
+ */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xff)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint8_tobuffer(token.value.as_ulong, target));
+ type = token.value.as_ulong;
+
+ /*
+ * Digest.
+ */
+ return (isc_hex_tobuffer(lexer, target, -1));
+}
+
+static inline isc_result_t
+totext_ds(ARGS_TOTEXT) {
+ isc_region_t sr;
+ char buf[sizeof("64000 ")];
+ unsigned int n;
+
+ REQUIRE(rdata->type == 43);
+ REQUIRE(rdata->length != 0);
+
+ UNUSED(tctx);
+
+ dns_rdata_toregion(rdata, &sr);
+
+ /*
+ * Key tag.
+ */
+ n = uint16_fromregion(&sr);
+ isc_region_consume(&sr, 2);
+ sprintf(buf, "%u ", n);
+ RETERR(str_totext(buf, target));
+
+ /*
+ * Algorithm.
+ */
+ n = uint8_fromregion(&sr);
+ isc_region_consume(&sr, 1);
+ sprintf(buf, "%u ", n);
+ RETERR(str_totext(buf, target));
+
+ /*
+ * Digest type.
+ */
+ n = uint8_fromregion(&sr);
+ isc_region_consume(&sr, 1);
+ sprintf(buf, "%u", n);
+ RETERR(str_totext(buf, target));
+
+ /*
+ * Digest.
+ */
+ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
+ RETERR(str_totext(" (", target));
+ RETERR(str_totext(tctx->linebreak, target));
+ RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target));
+ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
+ RETERR(str_totext(" )", target));
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+fromwire_ds(ARGS_FROMWIRE) {
+ isc_region_t sr;
+
+ REQUIRE(type == 43);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(dctx);
+ UNUSED(downcase);
+
+ isc_buffer_activeregion(source, &sr);
+ if (sr.length < 4)
+ return (ISC_R_UNEXPECTEDEND);
+
+ isc_buffer_forward(source, sr.length);
+ return (mem_tobuffer(target, sr.base, sr.length));
+}
+
+static inline isc_result_t
+towire_ds(ARGS_TOWIRE) {
+ isc_region_t sr;
+
+ REQUIRE(rdata->type == 43);
+ REQUIRE(rdata->length != 0);
+
+ UNUSED(cctx);
+
+ dns_rdata_toregion(rdata, &sr);
+ return (mem_tobuffer(target, sr.base, sr.length));
+}
+
+static inline int
+compare_ds(ARGS_COMPARE) {
+ isc_region_t r1;
+ isc_region_t r2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 43);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+ return (isc_region_compare(&r1, &r2));
+}
+
+static inline isc_result_t
+fromstruct_ds(ARGS_FROMSTRUCT) {
+ dns_rdata_ds_t *ds = source;
+
+ REQUIRE(type == 43);
+ REQUIRE(source != NULL);
+ REQUIRE(ds->common.rdtype == type);
+ REQUIRE(ds->common.rdclass == rdclass);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ RETERR(uint16_tobuffer(ds->key_tag, target));
+ RETERR(uint8_tobuffer(ds->algorithm, target));
+ RETERR(uint8_tobuffer(ds->digest_type, target));
+
+ return (mem_tobuffer(target, ds->digest, ds->length));
+}
+
+static inline isc_result_t
+tostruct_ds(ARGS_TOSTRUCT) {
+ dns_rdata_ds_t *ds = target;
+ isc_region_t region;
+
+ REQUIRE(rdata->type == 43);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length != 0);
+
+ ds->common.rdclass = rdata->rdclass;
+ ds->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&ds->common, link);
+
+ dns_rdata_toregion(rdata, ®ion);
+
+ ds->key_tag = uint16_fromregion(®ion);
+ isc_region_consume(®ion, 2);
+ ds->algorithm = uint8_fromregion(®ion);
+ isc_region_consume(®ion, 1);
+ ds->digest_type = uint8_fromregion(®ion);
+ isc_region_consume(®ion, 1);
+ ds->length = region.length;
+
+ ds->digest = mem_maybedup(mctx, region.base, region.length);
+ if (ds->digest == NULL)
+ return (ISC_R_NOMEMORY);
+
+ ds->mctx = mctx;
+ return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_ds(ARGS_FREESTRUCT) {
+ dns_rdata_ds_t *ds = source;
+
+ REQUIRE(ds != NULL);
+ REQUIRE(ds->common.rdtype == 43);
+
+ if (ds->mctx == NULL)
+ return;
+
+ if (ds->digest != NULL)
+ isc_mem_free(ds->mctx, ds->digest);
+ ds->mctx = NULL;
+}
+
+static inline isc_result_t
+additionaldata_ds(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == 43);
+
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_ds(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 43);
+
+ dns_rdata_toregion(rdata, &r);
+
+ return ((digest)(arg, &r));
+}
+
+#endif /* RDATA_GENERIC_DS_43_C */
--- /dev/null
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ds_43.h,v 1.2 2002/06/17 04:01:37 marka Exp $ */
+
+/* draft-ietf-dnsext-delegation-signer-05.txt */
+#ifndef GENERIC_DS_43_H
+#define GENERIC_DS_43_H 1
+
+typedef struct dns_rdata_ds {
+ dns_rdatacommon_t common;
+ isc_mem_t *mctx;
+ isc_uint16_t key_tag;
+ isc_uint8_t algorithm;
+ isc_uint8_t digest_type;
+ isc_uint16_t length;
+ unsigned char *digest;
+} dns_rdata_ds_t;
+
+#endif /* GENERIC_DS_43_H */
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.242 2002/05/27 06:30:24 marka Exp $ */
+/* $Id: resolver.c,v 1.243 2002/06/17 04:01:24 marka Exp $ */
#include <config.h>
* nameservers, and we're not in forward-only mode,
* so find the best nameservers to use.
*/
- if (type == dns_rdatatype_key)
+ if (dns_rdatatype_atparent(type))
findoptions |= DNS_DBFIND_NOEXACT;
dns_fixedname_init(&qdomain);
result = dns_view_findzonecut(res->view, name,
{
isc_result_t result;
dns_message_t *message;
- dns_name_t *name, *qname, *ns_name, *soa_name;
+ dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name;
dns_rdataset_t *rdataset, *ns_rdataset;
isc_boolean_t done, aa, negative_response;
dns_rdatatype_t type;
ns_name = NULL;
ns_rdataset = NULL;
soa_name = NULL;
+ ds_name = NULL;
result = dns_message_firstname(message, section);
while (!done && result == ISC_R_SUCCESS) {
name = NULL;
return (DNS_R_FORMERR);
soa_name = name;
}
- negative_response = ISC_TRUE;
- name->attributes |=
- DNS_NAMEATTR_NCACHE;
- rdataset->attributes |=
- DNS_RDATASETATTR_NCACHE;
+ /*
+ * This is wrong, but maybe it'll
+ * work for now.
+ */
+ if (ns_name == NULL) {
+ negative_response = ISC_TRUE;
+ name->attributes |=
+ DNS_NAMEATTR_NCACHE;
+ rdataset->attributes |=
+ DNS_RDATASETATTR_NCACHE;
+ } else {
+ name->attributes |=
+ DNS_NAMEATTR_CACHE;
+ rdataset->attributes |=
+ DNS_RDATASETATTR_CACHE;
+ }
if (aa)
rdataset->trust =
dns_trust_authauthority;
* No additional data needs to be
* marked.
*/
+ } else if (type == dns_rdatatype_ds) {
+ /*
+ * DS or SIG DS.
+ *
+ * These should only be here if
+ * this is a referral, and there
+ * should only be one DS.
+ */
+ if (negative_response)
+ return (DNS_R_FORMERR);
+ if (rdataset->type ==
+ dns_rdatatype_ds) {
+ if (ds_name != NULL &&
+ name != ds_name)
+ return (DNS_R_FORMERR);
+ ds_name = name;
+ }
+ name->attributes |=
+ DNS_NAMEATTR_CACHE;
+ rdataset->attributes |=
+ DNS_RDATASETATTR_CACHE;
+ if (aa)
+ rdataset->trust =
+ dns_trust_authauthority;
+ else
+ rdataset->trust =
+ dns_trust_additional;
}
}
}
isc_time_t tnow, *finish;
dns_adbaddrinfo_t *addrinfo;
unsigned int options;
+ unsigned int findoptions;
REQUIRE(VALID_QUERY(query));
fctx = query->fctx;
fctx_done(fctx, DNS_R_SERVFAIL);
return;
}
+ findoptions = 0;
+ if (dns_rdatatype_atparent(fctx->type))
+ findoptions |= DNS_DBFIND_NOEXACT;
result = dns_view_findzonecut(fctx->res->view,
&fctx->domain,
fname,
- now, 0, ISC_TRUE,
+ now, findoptions,
+ ISC_TRUE,
&fctx->nameservers,
NULL);
if (result != ISC_R_SUCCESS) {
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.c,v 1.98 2002/03/14 18:34:44 bwelling Exp $ */
+/* $Id: result.c,v 1.99 2002/06/17 04:01:25 marka Exp $ */
#include <config.h>
"obsolete", /* 80 DNS_R_OBSOLETE */
"already frozen", /* 81 DNS_R_FROZEN */
"unknown flag", /* 82 DNS_R_UNKNOWNFLAG */
- "expected a response" /* 83 DNS_R_EXPECTEDRESPONSE */
+ "expected a response", /* 83 DNS_R_EXPECTEDRESPONSE */
+ "no valid DS" /* 84 DNS_R_NOVALIDDS */
};
static const char *rcode_text[DNS_R_NRCODERESULTS] = {
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.104 2002/04/29 23:50:24 marka Exp $ */
+/* $Id: validator.c,v 1.105 2002/06/17 04:01:26 marka Exp $ */
#include <config.h>
#include <isc/util.h>
#include <dns/db.h>
+#include <dns/ds.h>
#include <dns/dnssec.h>
#include <dns/events.h>
#include <dns/keytable.h>
#define VALATTR_SHUTDOWN 0x01
#define VALATTR_FOUNDNONEXISTENCE 0x02
#define VALATTR_TRIEDVERIFY 0x04
+#define VALATTR_NEGATIVE 0x08
+#define VALATTR_INSECURITY 0x10
#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
static void
-nullkeyvalidated(isc_task_t *task, isc_event_t *event);
-
-static isc_boolean_t
-containsnullkey(dns_validator_t *val, dns_rdataset_t *rdataset);
+destroy(dns_validator_t *val);
static isc_result_t
get_dst_key(dns_validator_t *val, dns_rdata_sig_t *siginfo,
static isc_result_t
validate(dns_validator_t *val, isc_boolean_t resume);
+static isc_result_t
+validatezonekey(dns_validator_t *val, isc_boolean_t resume);
+
static isc_result_t
nxtvalidate(dns_validator_t *val, isc_boolean_t resume);
validator_log(dns_validator_t *val, int level, const char *fmt, ...)
ISC_FORMAT_PRINTF(3, 4);
+static void
+validator_logcreate(dns_validator_t *val,
+ dns_name_t *name, dns_rdatatype_t type,
+ const char *caller, const char *operation);
+
static void
validator_done(dns_validator_t *val, isc_result_t result) {
isc_task_t *task;
isc_task_sendanddetach(&task, (isc_event_t **)&val->event);
}
+static inline isc_boolean_t
+exit_check(dns_validator_t *val) {
+ /*
+ * Caller must be holding the lock.
+ */
+ if (!SHUTDOWN(val))
+ return (ISC_FALSE);
+
+ INSIST(val->event == NULL);
+
+ if (val->fetch != NULL || val->subvalidator != NULL)
+ return (ISC_FALSE);
+
+ return (ISC_TRUE);
+}
+
static void
auth_nonpending(dns_message_t *message) {
isc_result_t result;
dns_fetchevent_t *devent;
dns_validator_t *val;
dns_rdataset_t *rdataset;
+ isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
val->keyset = &val->frdataset;
}
result = validate(val, ISC_TRUE);
- if (result != DNS_R_WAIT) {
+ if (result != DNS_R_WAIT)
validator_done(val, result);
- goto out;
- }
} else {
validator_log(val, ISC_LOG_DEBUG(3),
"fetch_callback_validator: got %s",
else
validator_done(val, DNS_R_NOVALIDKEY);
}
-
- out:
+ want_destroy = exit_check(val);
UNLOCK(&val->lock);
- /*
- * Free stuff from the event.
- */
- if (dns_rdataset_isassociated(&val->frdataset) &&
- val->keyset != &val->frdataset)
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
+ if (want_destroy)
+ destroy(val);
}
static void
-fetch_callback_nullkey(isc_task_t *task, isc_event_t *event) {
+dsfetched(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *devent;
dns_validator_t *val;
- dns_rdataset_t *rdataset, *sigrdataset;
+ dns_rdataset_t *rdataset;
+ isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
devent = (dns_fetchevent_t *)event;
val = devent->ev_arg;
rdataset = &val->frdataset;
- sigrdataset = &val->fsigrdataset;
eresult = devent->result;
+ isc_event_free(&event);
dns_resolver_destroyfetch(&val->fetch);
INSIST(val->event != NULL);
- validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_nullkey");
-
+ validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched");
LOCK(&val->lock);
if (eresult == ISC_R_SUCCESS) {
- if (!containsnullkey(val, rdataset)) {
- /*
- * No null key.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "found a keyset, no null key");
- result = proveunsecure(val, ISC_TRUE);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- else {
- /*
- * Don't free rdataset & sigrdataset, since
- * they'll be freed in nullkeyvalidated.
- */
- isc_event_free(&event);
- UNLOCK(&val->lock);
- return;
- }
- } else {
- validator_log(val, ISC_LOG_DEBUG(3),
- "found a keyset with a null key");
- if (rdataset->trust >= dns_trust_secure) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "insecurity proof succeeded");
- val->event->rdataset->trust = dns_trust_answer;
- validator_done(val, ISC_R_SUCCESS);
- } else if (!dns_rdataset_isassociated(sigrdataset)) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "insecurity proof failed");
- validator_done(val, DNS_R_NOTINSECURE);
- } else {
- dns_name_t *tname;
- tname = dns_fixedname_name(&devent->foundname);
- result = dns_validator_create(val->view, tname,
- dns_rdatatype_key,
- rdataset,
- sigrdataset, NULL,
- 0, val->task,
- nullkeyvalidated,
- val,
- &val->keyvalidator);
- if (result != ISC_R_SUCCESS)
- validator_done(val, result);
- /*
- * Don't free rdataset & sigrdataset, since
- * they'll be freed in nullkeyvalidated.
- */
- isc_event_free(&event);
- UNLOCK(&val->lock);
- return;
- }
- }
- } else if (eresult == DNS_R_NCACHENXDOMAIN ||
- eresult == DNS_R_NCACHENXRRSET ||
- eresult == DNS_R_NXDOMAIN ||
- eresult == DNS_R_NXRRSET)
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dsset with trust %d", rdataset->trust);
+ val->dsset = &val->frdataset;
+ result = validatezonekey(val, ISC_TRUE);
+ if (result != DNS_R_WAIT)
+ validator_done(val, result);
+ } else if (eresult == DNS_R_NXRRSET ||
+ eresult == DNS_R_NCACHENXRRSET)
{
- /*
- * No keys.
- */
- validator_log(val, ISC_LOG_DEBUG(3), "no keys found");
- result = proveunsecure(val, ISC_TRUE);
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "falling back to insecurity proof");
+ val->attributes |= VALATTR_INSECURITY;
+ result = proveunsecure(val, ISC_FALSE);
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
validator_log(val, ISC_LOG_DEBUG(3),
- "fetch_callback_nullkey: got %s",
+ "dsfetched: got %s",
isc_result_totext(eresult));
if (eresult == ISC_R_CANCELED)
validator_done(val, eresult);
else
- validator_done(val, DNS_R_NOVALIDKEY);
+ validator_done(val, DNS_R_NOVALIDDS);
}
+ want_destroy = exit_check(val);
UNLOCK(&val->lock);
+ if (want_destroy)
+ destroy(val);
+}
+
+/*
+ * XXX there's too much duplicated code here.
+ */
+static void
+dsfetched2(isc_task_t *task, isc_event_t *event) {
+ dns_fetchevent_t *devent;
+ dns_validator_t *val;
+ dns_rdataset_t *rdataset;
+ isc_boolean_t want_destroy;
+ isc_result_t result;
+ isc_result_t eresult;
+
+ UNUSED(task);
+ INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
+ devent = (dns_fetchevent_t *)event;
+ val = devent->ev_arg;
+ rdataset = &val->frdataset;
+ eresult = devent->result;
- /*
- * Free stuff from the event.
- */
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
isc_event_free(&event);
+ dns_resolver_destroyfetch(&val->fetch);
+
+ INSIST(val->event != NULL);
+
+ validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2");
+ LOCK(&val->lock);
+ if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NCACHENXRRSET) {
+ /*
+ * There is no DS. We're done.
+ */
+ val->event->rdataset->trust = dns_trust_answer;
+ validator_done(val, ISC_R_SUCCESS);
+ } else if (eresult == ISC_R_SUCCESS ||
+ eresult == DNS_R_NXDOMAIN ||
+ eresult == DNS_R_NCACHENXDOMAIN)
+ {
+ /*
+ * Either there is a DS or this is not a zone cut. Continue.
+ */
+ result = proveunsecure(val, ISC_TRUE);
+ if (result != DNS_R_WAIT)
+ validator_done(val, result);
+ } else {
+ if (eresult == ISC_R_CANCELED)
+ validator_done(val, eresult);
+ else
+ validator_done(val, DNS_R_NOVALIDDS);
+ }
+ want_destroy = exit_check(val);
+ UNLOCK(&val->lock);
+ if (want_destroy)
+ destroy(val);
}
static void
keyvalidated(isc_task_t *task, isc_event_t *event) {
dns_validatorevent_t *devent;
dns_validator_t *val;
+ isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
eresult = devent->result;
isc_event_free(&event);
+ dns_validator_destroy(&val->subvalidator);
INSIST(val->event != NULL);
if (val->frdataset.trust >= dns_trust_secure)
(void) get_dst_key(val, val->siginfo, &val->frdataset);
result = validate(val, ISC_TRUE);
- if (result != DNS_R_WAIT) {
+ if (result != DNS_R_WAIT)
validator_done(val, result);
- goto out;
- }
} else {
validator_log(val, ISC_LOG_DEBUG(3),
"keyvalidated: got %s",
isc_result_totext(eresult));
validator_done(val, eresult);
}
- out:
+ want_destroy = exit_check(val);
+ UNLOCK(&val->lock);
+ if (want_destroy)
+ destroy(val);
+}
+
+static void
+dsvalidated(isc_task_t *task, isc_event_t *event) {
+ dns_validatorevent_t *devent;
+ dns_validator_t *val;
+ isc_boolean_t want_destroy;
+ isc_result_t result;
+ isc_result_t eresult;
+
+ UNUSED(task);
+ INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
+
+ devent = (dns_validatorevent_t *)event;
+ val = devent->ev_arg;
+ eresult = devent->result;
+
+ isc_event_free(&event);
+ dns_validator_destroy(&val->subvalidator);
+
+ INSIST(val->event != NULL);
+ validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated");
+ LOCK(&val->lock);
+ if (eresult == ISC_R_SUCCESS) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dsset with trust %d", val->frdataset.trust);
+ if ((val->attributes & VALATTR_INSECURITY) != 0)
+ result = proveunsecure(val, ISC_TRUE);
+ else
+ result = validatezonekey(val, ISC_TRUE);
+ if (result != DNS_R_WAIT)
+ validator_done(val, result);
+ } else {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dsvalidated: got %s",
+ isc_result_totext(eresult));
+ validator_done(val, eresult);
+ }
+ want_destroy = exit_check(val);
UNLOCK(&val->lock);
- dns_validator_destroy(&val->keyvalidator);
- /*
- * Free stuff from the event.
- */
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
+ if (want_destroy)
+ destroy(val);
}
static isc_boolean_t
dns_validatorevent_t *devent;
dns_validator_t *val;
dns_rdataset_t *rdataset, *sigrdataset;
+ isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
sigrdataset = devent->sigrdataset;
val = devent->ev_arg;
eresult = devent->result;
- dns_validator_destroy(&val->authvalidator);
+ dns_validator_destroy(&val->subvalidator);
INSIST(val->event != NULL);
validator_log(val, ISC_LOG_DEBUG(3),
"authvalidated: got %s",
isc_result_totext(eresult));
- result = nxtvalidate(val, ISC_TRUE);
- if (result != DNS_R_WAIT)
+ if (result == ISC_R_CANCELED)
validator_done(val, result);
+ else {
+ result = nxtvalidate(val, ISC_TRUE);
+ if (result != DNS_R_WAIT)
+ validator_done(val, result);
+ }
} else {
if (rdataset->type == dns_rdatatype_nxt &&
nxtprovesnonexistence(val, devent->name, rdataset,
if (result != DNS_R_WAIT)
validator_done(val, result);
}
+ want_destroy = exit_check(val);
UNLOCK(&val->lock);
+ if (want_destroy)
+ destroy(val);
/*
* Free stuff from the event.
negauthvalidated(isc_task_t *task, isc_event_t *event) {
dns_validatorevent_t *devent;
dns_validator_t *val;
+ isc_boolean_t want_destroy;
isc_result_t eresult;
UNUSED(task);
val = devent->ev_arg;
eresult = devent->result;
isc_event_free(&event);
- dns_validator_destroy(&val->authvalidator);
+ dns_validator_destroy(&val->subvalidator);
INSIST(val->event != NULL);
isc_result_totext(eresult));
validator_done(val, eresult);
}
+ want_destroy = exit_check(val);
UNLOCK(&val->lock);
+ if (want_destroy)
+ destroy(val);
+}
- /*
- * Free stuff from the event.
- */
+static inline isc_result_t
+view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
if (dns_rdataset_isassociated(&val->frdataset))
dns_rdataset_disassociate(&val->frdataset);
-}
-
-static void
-nullkeyvalidated(isc_task_t *task, isc_event_t *event) {
- dns_validatorevent_t *devent;
- dns_validator_t *val;
- isc_result_t result;
- isc_result_t eresult;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
-
- devent = (dns_validatorevent_t *)event;
- val = devent->ev_arg;
- eresult = devent->result;
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_disassociate(&val->fsigrdataset);
- dns_name_free(devent->name, val->view->mctx);
- isc_mem_put(val->view->mctx, devent->name, sizeof(dns_name_t));
- dns_validator_destroy(&val->keyvalidator);
- isc_event_free(&event);
+ if (val->view->zonetable == NULL)
+ return (ISC_R_CANCELED);
+ return (dns_view_simplefind(val->view, name, type, 0,
+ DNS_DBFIND_PENDINGOK, ISC_FALSE,
+ &val->frdataset, &val->fsigrdataset));
+}
- INSIST(val->event != NULL);
+static inline isc_boolean_t
+check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
+ dns_validator_t *parent;
- validator_log(val, ISC_LOG_DEBUG(3), "in nullkeyvalidated");
- LOCK(&val->lock);
- if (eresult == ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "proved that name is in an unsecure domain");
- validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");
- val->event->rdataset->trust = dns_trust_answer;
- validator_done(val, ISC_R_SUCCESS);
- } else {
- result = proveunsecure(val, ISC_TRUE);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
+ for (parent = val->parent; parent != NULL; parent = parent->parent) {
+ if (parent->event != NULL &&
+ parent->event->type == type &&
+ dns_name_equal(parent->event->name, name))
+ {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "continuing validation would lead to "
+ "deadlock: aborting validation");
+ return (ISC_TRUE);
+ }
}
- UNLOCK(&val->lock);
+ return (ISC_FALSE);
+}
- /*
- * Free stuff from the event.
- */
+static inline isc_result_t
+create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
+ isc_taskaction_t callback, const char *caller)
+{
if (dns_rdataset_isassociated(&val->frdataset))
dns_rdataset_disassociate(&val->frdataset);
if (dns_rdataset_isassociated(&val->fsigrdataset))
dns_rdataset_disassociate(&val->fsigrdataset);
+
+ if (check_deadlock(val, name, type))
+ return (DNS_R_NOVALIDSIG);
+
+ validator_logcreate(val, name, type, caller, "fetch");
+ return (dns_resolver_createfetch(val->view->resolver, name, type,
+ NULL, NULL, NULL, 0,
+ val->event->ev_sender,
+ callback, val,
+ &val->frdataset,
+ &val->fsigrdataset,
+ &val->fetch));
}
-/*
- * Try to find a null zone key among those in 'rdataset'. If found, build
- * a dst_key_t for it and point val->key at it.
- */
-static isc_boolean_t
-containsnullkey(dns_validator_t *val, dns_rdataset_t *rdataset) {
+static inline isc_result_t
+create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+ isc_taskaction_t action, const char *caller)
+{
isc_result_t result;
- dst_key_t *key = NULL;
- isc_buffer_t b;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_boolean_t found = ISC_FALSE;
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- return (ISC_FALSE);
- while (result == ISC_R_SUCCESS && !found) {
- dns_rdataset_current(rdataset, &rdata);
- isc_buffer_init(&b, rdata.data, rdata.length);
- isc_buffer_add(&b, rdata.length);
- key = NULL;
- /*
- * The key name is unimportant, so we can avoid any name/text
- * conversion.
- */
- result = dst_key_fromdns(dns_rootname, rdata.rdclass, &b,
- val->view->mctx, &key);
- if (result != ISC_R_SUCCESS)
- continue;
- if (dst_key_isnullkey(key))
- found = ISC_TRUE;
- dst_key_free(&key);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(rdataset);
- }
- return (found);
+ if (check_deadlock(val, name, type))
+ return (DNS_R_NOVALIDSIG);
+
+ validator_logcreate(val, name, type, caller, "validator");
+ result = dns_validator_create(val->view, name, type,
+ rdataset, sigrdataset, NULL, 0,
+ val->task, action, val,
+ &val->subvalidator);
+ if (result == ISC_R_SUCCESS)
+ val->subvalidator->parent = val;
+ return (result);
}
/*
namereln != dns_namereln_equal)
return (DNS_R_CONTINUE);
- /*
- * Is the key used for the signature a security root?
- */
- INSIST(val->keynode == NULL);
- result = dns_keytable_findkeynode(val->keytable,
- &siginfo->signer,
- siginfo->algorithm, siginfo->keyid,
- &val->keynode);
- if (result == ISC_R_SUCCESS) {
+ if (namereln == dns_namereln_equal) {
/*
- * The key is a security root.
+ * If this is a self-signed keyset, it must not be a zone key
+ * (since get_key is not called from validatezonekey).
*/
- val->key = dns_keynode_key(val->keynode);
- return (ISC_R_SUCCESS);
- }
+ if (val->event->rdataset->type == dns_rdatatype_key)
+ return (DNS_R_CONTINUE);
- /*
- * A key set may not be self-signed unless the signing key is a
- * security root. We don't want a KEY RR to authenticate
- * itself, so we ignore the signature if it was not made by
- * an ancestor of the KEY or a preconfigured key.
- */
- if (val->event->rdataset->type == dns_rdatatype_key &&
- namereln == dns_namereln_equal)
- {
- validator_log(val, ISC_LOG_DEBUG(3),
- "keyset was self-signed but not preconfigured");
- return (DNS_R_CONTINUE);
+ /*
+ * Records appearing in the parent zone at delegation
+ * points cannot be self-signed.
+ */
+ if (dns_rdatatype_atparent(val->event->rdataset->type))
+ return (DNS_R_CONTINUE);
}
/*
* Do we know about this key?
*/
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- result = dns_view_simplefind(val->view, &siginfo->signer,
- dns_rdatatype_key, 0,
- DNS_DBFIND_PENDINGOK, ISC_FALSE,
- &val->frdataset, &val->fsigrdataset);
+ result = view_find(val, &siginfo->signer, dns_rdatatype_key);
if (result == ISC_R_SUCCESS) {
/*
* We have an rrset for the given keyname.
/*
* We know the key but haven't validated it yet.
*/
- result = dns_validator_create(val->view,
- &siginfo->signer,
- dns_rdatatype_key,
- &val->frdataset,
- &val->fsigrdataset,
- NULL,
- 0,
- val->task,
- keyvalidated,
- val,
- &val->keyvalidator);
+ result = create_validator(val, &siginfo->signer,
+ dns_rdatatype_key,
+ &val->frdataset,
+ &val->fsigrdataset,
+ keyvalidated,
+ "get_key");
if (result != ISC_R_SUCCESS)
return (result);
return (DNS_R_WAIT);
/*
* We don't know anything about this key.
*/
- val->fetch = NULL;
- result = dns_resolver_createfetch(val->view->resolver,
- &siginfo->signer,
- dns_rdatatype_key,
- NULL, NULL, NULL, 0,
- val->event->ev_sender,
- fetch_callback_validator,
- val,
- &val->frdataset,
- &val->fsigrdataset,
- &val->fetch);
+ result = create_fetch(val, &siginfo->signer, dns_rdatatype_key,
+ fetch_callback_validator, "get_key");
if (result != ISC_R_SUCCESS)
return (result);
return (DNS_R_WAIT);
return (result);
}
+static dns_keytag_t
+compute_keytag(dns_rdata_t *rdata, dns_rdata_key_t *key) {
+ isc_region_t r;
+
+ dns_rdata_toregion(rdata, &r);
+ return (dst_region_computeid(&r, key->algorithm));
+}
+
/*
- * If the rdataset being validated is a key set, is each key a security root?
+ * Is this keyset self-signed?
*/
static isc_boolean_t
-issecurityroot(dns_validator_t *val) {
- dns_name_t *name;
- dns_rdataset_t *rdataset;
- isc_mem_t *mctx;
+isselfsigned(dns_validator_t *val) {
+ dns_rdataset_t *rdataset, *sigrdataset;
dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_t sigrdata = DNS_RDATA_INIT;
+ dns_rdata_key_t key;
+ dns_rdata_sig_t sig;
+ dns_keytag_t keytag;
isc_result_t result;
- dns_keynode_t *keynode, *nextnode;
- dst_key_t *key, *secrootkey;
- isc_boolean_t match = ISC_FALSE;
- name = val->event->name;
rdataset = val->event->rdataset;
- mctx = val->view->mctx;
+ sigrdataset = val->event->sigrdataset;
+
+ INSIST(rdataset->type == dns_rdatatype_key);
for (result = dns_rdataset_first(rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(rdataset))
{
- dns_rdataset_current(rdataset, &rdata);
- key = NULL;
- result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &key);
dns_rdata_reset(&rdata);
- if (result != ISC_R_SUCCESS)
- continue;
- keynode = NULL;
- result = dns_keytable_findkeynode(
- val->keytable, name,
- (dns_secalg_t)dst_key_alg(key),
- dst_key_id(key),
- &keynode);
-
- match = ISC_FALSE;
- while (result == ISC_R_SUCCESS) {
- secrootkey = dns_keynode_key(keynode);
- if (dst_key_compare(key, secrootkey)) {
- match = ISC_TRUE;
- dns_keytable_detachkeynode(val->keytable,
- &keynode);
- break;
- }
- nextnode = NULL;
- result = dns_keytable_findnextkeynode(val->keytable,
- keynode,
- &nextnode);
- dns_keytable_detachkeynode(val->keytable, &keynode);
- }
+ dns_rdataset_current(rdataset, &rdata);
+ (void)dns_rdata_tostruct(&rdata, &key, NULL);
+ keytag = compute_keytag(&rdata, &key);
+ for (result = dns_rdataset_first(sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(sigrdataset))
+ {
+ dns_rdata_reset(&sigrdata);
+ dns_rdataset_current(sigrdataset, &sigrdata);
+ (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
- dst_key_free(&key);
- if (!match)
- return (ISC_FALSE);
+ if (sig.algorithm == key.algorithm &&
+ sig.keyid == keytag)
+ return (ISC_TRUE);
+ }
}
- return (match);
+ return (ISC_FALSE);
+}
+
+static isc_result_t
+verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata) {
+ isc_result_t result;
+
+ val->attributes |= VALATTR_TRIEDVERIFY;
+ result = dns_dnssec_verify(val->event->name, val->event->rdataset,
+ key, ISC_FALSE, val->view->mctx, rdata);
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "verify rdataset: %s",
+ isc_result_totext(result));
+ return (result);
}
/*
- * Attempts positive response validation.
+ * Attempts positive response validation of a normal RRset.
*
* Returns:
* ISC_R_SUCCESS Validation completed successfully
event = val->event;
- /*
- * If this is a security root, it's ok.
- */
- if (val->event->type == dns_rdatatype_key && !resume) {
- dns_fixedname_t fsecroot;
- dns_name_t *secroot;
-
- dns_fixedname_init(&fsecroot);
- secroot = dns_fixedname_name(&fsecroot);
- result = dns_keytable_finddeepestmatch(val->keytable,
- val->event->name,
- secroot);
- if (result == ISC_R_SUCCESS &&
- dns_name_equal(val->event->name, secroot) &&
- issecurityroot(val))
- {
- val->event->rdataset->trust = dns_trust_secure;
- return (ISC_R_SUCCESS);
- }
- }
-
if (resume) {
/*
* We already have a sigrdataset.
}
do {
- val->attributes |= VALATTR_TRIEDVERIFY;
- result = dns_dnssec_verify(event->name,
- event->rdataset,
- val->key, ISC_FALSE,
- val->view->mctx, &rdata);
- validator_log(val, ISC_LOG_DEBUG(3),
- "verify rdataset: %s",
- isc_result_totext(result));
+ result = verify(val, val->key, &rdata);
if (result == ISC_R_SUCCESS)
break;
if (val->keynode != NULL) {
return (DNS_R_NOVALIDSIG);
}
+/*
+ * Attempts positive response validation of an RRset containing zone keys.
+ *
+ * Returns:
+ * ISC_R_SUCCESS Validation completed successfully
+ * DNS_R_WAIT Validation has started but is waiting
+ * for an event.
+ * Other return codes are possible and all indicate failure.
+ */
+static isc_result_t
+validatezonekey(dns_validator_t *val, isc_boolean_t resume) {
+ isc_result_t result;
+ dns_validatorevent_t *event;
+ dns_rdataset_t trdataset;
+ dns_rdata_t dsrdata = DNS_RDATA_INIT;
+ dns_rdata_t newdsrdata = DNS_RDATA_INIT;
+ dns_rdata_t keyrdata = DNS_RDATA_INIT;
+ dns_rdata_t sigrdata = DNS_RDATA_INIT;
+ unsigned char dsbuf[DNS_DS_BUFFERSIZE];
+ dns_keytag_t keytag;
+ dns_rdata_ds_t ds;
+ dns_rdata_key_t key;
+ dns_rdata_sig_t sig;
+ dst_key_t *dstkey;
+
+ UNUSED(resume);
+
+ /*
+ * Caller must be holding the validator lock.
+ */
+
+ event = val->event;
+
+ if (val->dsset == NULL) {
+ /*
+ * First, see if this key was signed by a trusted key.
+ */
+ for (result = dns_rdataset_first(val->event->sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(val->event->sigrdataset))
+ {
+ dns_keynode_t *keynode = NULL, *nextnode = NULL;
+
+ dns_rdata_reset(&sigrdata);
+ dns_rdataset_current(val->event->sigrdataset,
+ &sigrdata);
+ (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
+ result = dns_keytable_findkeynode(val->keytable,
+ val->event->name,
+ sig.algorithm,
+ sig.keyid,
+ &keynode);
+ while (result == ISC_R_SUCCESS) {
+ dstkey = dns_keynode_key(keynode);
+ result = verify(val, dstkey, &sigrdata);
+ if (result == ISC_R_SUCCESS) {
+ dns_keytable_detachkeynode(val->keytable,
+ &keynode);
+ break;
+ }
+ result = dns_keytable_findnextkeynode(
+ val->keytable,
+ keynode,
+ &nextnode);
+ dns_keytable_detachkeynode(val->keytable,
+ &keynode);
+ keynode = nextnode;
+ }
+ if (result == ISC_R_SUCCESS) {
+ event->rdataset->trust = dns_trust_secure;
+ event->sigrdataset->trust = dns_trust_secure;
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "signed by trusted key; "
+ "marking as secure");
+ return (result);
+ }
+ }
+
+ /*
+ * If this is the root name and there was no trusted key,
+ * give up, since there's no DS at the root.
+ */
+ if (dns_name_equal(event->name, dns_rootname)) {
+ if ((val->attributes & VALATTR_TRIEDVERIFY) != 0)
+ return (DNS_R_NOVALIDSIG);
+ else
+ return (DNS_R_NOVALIDDS);
+ }
+
+ /*
+ * Otherwise, try to find the DS record.
+ */
+ result = view_find(val, val->event->name, dns_rdatatype_ds);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * We have DS records.
+ */
+ val->dsset = &val->frdataset;
+ if (val->frdataset.trust == dns_trust_pending &&
+ dns_rdataset_isassociated(&val->fsigrdataset))
+ {
+ result = create_validator(val,
+ val->event->name,
+ dns_rdatatype_ds,
+ &val->frdataset,
+ &val->fsigrdataset,
+ dsvalidated,
+ "validatezonekey");
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ return (DNS_R_WAIT);
+ } else if (val->frdataset.trust == dns_trust_pending) {
+ /*
+ * There should never be an unsigned DS.
+ */
+ dns_rdataset_disassociate(&val->frdataset);
+ validator_log(val, ISC_LOG_DEBUG(2),
+ "unsigned DS record");
+ return (DNS_R_NOVALIDSIG);
+ } else
+ result = ISC_R_SUCCESS;
+ } else if (result == ISC_R_NOTFOUND) {
+ /*
+ * We don't have the DS. Find it.
+ */
+ result = create_fetch(val, val->event->name,
+ dns_rdatatype_ds, dsfetched,
+ "validatezonekey");
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ return (DNS_R_WAIT);
+ } else if (result == DNS_R_NCACHENXDOMAIN ||
+ result == DNS_R_NCACHENXRRSET ||
+ result == DNS_R_NXDOMAIN ||
+ result == DNS_R_NXRRSET)
+ {
+ /*
+ * The DS does not exist.
+ */
+ if (dns_rdataset_isassociated(&val->frdataset))
+ dns_rdataset_disassociate(&val->frdataset);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_disassociate(&val->fsigrdataset);
+ validator_log(val, ISC_LOG_DEBUG(2), "no DS record");
+ return (DNS_R_NOVALIDSIG);
+ }
+ }
+
+ /*
+ * We have a DS set.
+ */
+ INSIST(val->dsset != NULL);
+
+ if (val->dsset->trust < dns_trust_secure) {
+ val->event->rdataset->trust = dns_trust_answer;
+ val->event->sigrdataset->trust = dns_trust_answer;
+ return (ISC_R_SUCCESS);
+ }
+
+ /*
+ * Look through the DS record and find the keys that can sign the
+ * key set and the matching signature. For each such key, attempt
+ * verification.
+ */
+
+ for (result = dns_rdataset_first(val->dsset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(val->dsset))
+ {
+ dns_rdata_reset(&dsrdata);
+ dns_rdataset_current(val->dsset, &dsrdata);
+ (void)dns_rdata_tostruct(&dsrdata, &ds, NULL);
+
+ dns_rdataset_init(&trdataset);
+ dns_rdataset_clone(val->event->rdataset, &trdataset);
+
+ for (result = dns_rdataset_first(&trdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&trdataset))
+ {
+ dns_rdata_reset(&keyrdata);
+ dns_rdataset_current(&trdataset, &keyrdata);
+ (void)dns_rdata_tostruct(&keyrdata, &key, NULL);
+ keytag = compute_keytag(&keyrdata, &key);
+ if (ds.key_tag != keytag ||
+ ds.algorithm != key.algorithm)
+ continue;
+ dns_rdata_reset(&newdsrdata);
+ result = dns_ds_buildrdata(val->event->name,
+ &keyrdata, ds.digest_type,
+ dsbuf, &newdsrdata);
+ if (result != ISC_R_SUCCESS)
+ continue;
+ if (dns_rdata_compare(&dsrdata, &newdsrdata) == 0)
+ break;
+ }
+ if (result != ISC_R_SUCCESS) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "no KEY matching DS");
+ continue;
+ }
+
+ for (result = dns_rdataset_first(val->event->sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(val->event->sigrdataset))
+ {
+ dns_rdata_reset(&sigrdata);
+ dns_rdataset_current(val->event->sigrdataset,
+ &sigrdata);
+ (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
+ if (ds.key_tag == sig.keyid &&
+ ds.algorithm == sig.algorithm)
+ break;
+ }
+ if (result != ISC_R_SUCCESS) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "no SIG matching DS key");
+ continue;
+ }
+
+ dstkey = NULL;
+ result = dns_dnssec_keyfromrdata(val->event->name,
+ &keyrdata,
+ val->view->mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS)
+ /*
+ * This really shouldn't happen, but...
+ */
+ continue;
+
+ result = verify(val, dstkey, &sigrdata);
+ dst_key_free(&dstkey);
+ dns_rdataset_disassociate(&trdataset);
+ if (result == ISC_R_SUCCESS)
+ break;
+ }
+ if (result == ISC_R_SUCCESS) {
+ event->rdataset->trust = dns_trust_secure;
+ event->sigrdataset->trust = dns_trust_secure;
+ validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
+ return (result);
+ } else
+ return (DNS_R_NOVALIDSIG);
+}
+
+/*
+ * Starts a positive response validation.
+ *
+ * Returns:
+ * ISC_R_SUCCESS Validation completed successfully
+ * DNS_R_WAIT Validation has started but is waiting
+ * for an event.
+ * Other return codes are possible and all indicate failure.
+ */
+static isc_result_t
+start_positive_validation(dns_validator_t *val) {
+ /*
+ * If this is not a key, go straight into validate().
+ */
+ if (val->event->type != dns_rdatatype_key || !isselfsigned(val))
+ return (validate(val, ISC_FALSE));
+
+ return (validatezonekey(val, ISC_FALSE));
+}
static isc_result_t
nxtvalidate(dns_validator_t *val, isc_boolean_t resume) {
dns_message_t *message = val->event->message;
isc_result_t result;
- if (!resume) {
+ if (!resume)
result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
- if (result != ISC_R_SUCCESS)
- validator_done(val, ISC_R_NOTFOUND);
- } else {
+ else {
result = ISC_R_SUCCESS;
validator_log(val, ISC_LOG_DEBUG(3), "resuming nxtvalidate");
}
if (rdataset->type == dns_rdatatype_sig)
continue;
+ if (rdataset->type == dns_rdatatype_soa)
+ val->soaset = rdataset;
+
for (sigrdataset = ISC_LIST_HEAD(name->list);
sigrdataset != NULL;
sigrdataset = ISC_LIST_NEXT(sigrdataset,
dns_rdatatype_soa))
continue;
}
- val->authvalidator = NULL;
val->currentset = rdataset;
- result = dns_validator_create(val->view, name,
- rdataset->type,
- rdataset,
- sigrdataset,
- NULL, 0,
- val->task,
- authvalidated,
- val,
- &val->authvalidator);
+ result = create_validator(val, name, rdataset->type,
+ rdataset, sigrdataset,
+ authvalidated,
+ "nxtvalidate");
if (result != ISC_R_SUCCESS)
return (result);
return (DNS_R_WAIT);
if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS;
if (result != ISC_R_SUCCESS)
- validator_done(val, result);
+ return (result);
if ((val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0) {
- if (!val->seensig) {
- result = dns_validator_create(val->view, name,
- dns_rdatatype_soa,
- &val->frdataset,
- NULL, NULL, 0,
- val->task,
- negauthvalidated,
- val,
- &val->authvalidator);
+ if (!val->seensig && val->soaset != NULL) {
+ result = create_validator(val, name, dns_rdatatype_soa,
+ val->soaset, NULL,
+ negauthvalidated,
+ "nxtvalidate");
if (result != ISC_R_SUCCESS)
return (result);
return (DNS_R_WAIT);
static isc_result_t
proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
isc_result_t result;
- dns_fixedname_t secroot, tfname;
+ dns_fixedname_t secroot;
dns_name_t *tname;
dns_fixedname_init(&secroot);
- dns_fixedname_init(&tfname);
result = dns_keytable_finddeepestmatch(val->keytable,
val->event->name,
dns_fixedname_name(&secroot));
else if (result != ISC_R_SUCCESS)
return (result);
- /*
- * If this is a security root, it's ok.
- */
- if (val->event->type == dns_rdatatype_key &&
- dns_name_equal(val->event->name, dns_fixedname_name(&secroot)) &&
- issecurityroot(val))
- {
- val->event->rdataset->trust = dns_trust_secure;
- return (ISC_R_SUCCESS);
- }
-
if (!resume)
val->labels = dns_name_depth(dns_fixedname_name(&secroot)) + 1;
else {
char namebuf[DNS_NAME_FORMATSIZE];
if (val->labels == dns_name_depth(val->event->name)) {
- if (val->event->type == dns_rdatatype_key)
- break;
tname = val->event->name;
} else {
- tname = dns_fixedname_name(&tfname);
+ dns_fixedname_init(&val->fname);
+ tname = dns_fixedname_name(&val->fname);
result = dns_name_splitatdepth(val->event->name,
val->labels,
NULL, tname);
dns_name_format(tname, namebuf, sizeof(namebuf));
validator_log(val, ISC_LOG_DEBUG(3),
- "looking for null keyset at '%s'",
+ "checking existence of DS at '%s'",
namebuf);
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
-
- result = dns_view_simplefind(val->view, tname,
- dns_rdatatype_key, 0,
- DNS_DBFIND_PENDINGOK, ISC_FALSE,
- &val->frdataset,
- &val->fsigrdataset);
- if (result == ISC_R_SUCCESS) {
- dns_name_t *fname = NULL;
-
- if (!dns_rdataset_isassociated(&val->fsigrdataset)) {
- result = DNS_R_NOTINSECURE;
+ result = view_find(val, tname, dns_rdatatype_ds);
+ if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
+ /*
+ * There is no DS. We're hopefully done.
+ */
+ if (val->frdataset.trust < dns_trust_secure) {
+ /*
+ * This shouldn't happen, since the negative
+ * response should have been validated. Since
+ * there's no way of validating existing
+ * negative response blobs, give up.
+ */
+ result = DNS_R_NOVALIDSIG;
goto out;
}
- validator_log(val, ISC_LOG_DEBUG(3),
- "found keyset, looking for null key");
- if (!containsnullkey(val, &val->frdataset))
+ val->event->rdataset->trust = dns_trust_answer;
+ return (ISC_R_SUCCESS);
+ } else if (result == ISC_R_SUCCESS) {
+ /*
+ * There is a DS here. Verify that it's secure and
+ * continue.
+ */
+ if (val->frdataset.trust >= dns_trust_secure)
continue;
-
- if (val->frdataset.trust >= dns_trust_secure) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "insecurity proof succeeded");
- val->event->rdataset->trust = dns_trust_answer;
- result = ISC_R_SUCCESS;
- goto out;
- }
-
- fname = isc_mem_get(val->view->mctx, sizeof(*fname));
- if (fname == NULL)
- return (ISC_R_NOMEMORY);
- dns_name_init(fname, NULL);
- result = dns_name_dup(tname, val->view->mctx, fname);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(val->view->mctx, fname,
- sizeof(*fname));
- result = ISC_R_NOMEMORY;
+ else if (!dns_rdataset_isassociated(&val->fsigrdataset))
+ {
+ result = DNS_R_NOVALIDSIG;
goto out;
}
-
- result = dns_validator_create(val->view,
- fname,
- dns_rdatatype_key,
- &val->frdataset,
- &val->fsigrdataset,
- NULL,
- 0,
- val->task,
- nullkeyvalidated,
- val,
- &val->keyvalidator);
+ result = create_validator(val, tname, dns_rdatatype_ds,
+ &val->frdataset,
+ &val->fsigrdataset,
+ dsvalidated,
+ "proveunsecure");
if (result != ISC_R_SUCCESS)
goto out;
return (DNS_R_WAIT);
+ } else if (result == DNS_R_NXDOMAIN ||
+ result == DNS_R_NCACHENXDOMAIN)
+ {
+ /*
+ * This is not a zone cut. Assuming things are
+ * as expected, continue.
+ */
+ if (!dns_rdataset_isassociated(&val->frdataset)) {
+ /*
+ * There should be an NXT here, since we
+ * are still in a secure zone.
+ */
+ result = DNS_R_NOVALIDNXT;
+ goto out;
+ } else if (val->frdataset.trust < dns_trust_secure) {
+ /*
+ * This shouldn't happen, since the negative
+ * response should have been validated. Since
+ * there's no way of validating existing
+ * negative response blobs, give up.
+ */
+ result = DNS_R_NOVALIDSIG;
+ goto out;
+ }
+ continue;
} else if (result == ISC_R_NOTFOUND) {
- val->fetch = NULL;
- result = dns_resolver_createfetch(val->view->resolver,
- tname,
- dns_rdatatype_key,
- NULL, NULL, NULL, 0,
- val->event->ev_sender,
- fetch_callback_nullkey,
- val,
- &val->frdataset,
- &val->fsigrdataset,
- &val->fetch);
+ /*
+ * We don't know anything about the DS. Find it.
+ */
+ result = create_fetch(val, tname, dns_rdatatype_ds,
+ dsfetched2, "proveunsecure");
if (result != ISC_R_SUCCESS)
goto out;
return (DNS_R_WAIT);
- } else if (result == DNS_R_NCACHENXDOMAIN ||
- result == DNS_R_NCACHENXRRSET ||
- result == DNS_R_NXDOMAIN ||
- result == DNS_R_NXRRSET)
- {
- continue;
- } else
- goto out;
+ }
}
validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
- return (DNS_R_NOTINSECURE); /* Didn't find a null key */
+ return (DNS_R_NOTINSECURE); /* Couldn't complete insecurity proof */
out:
if (dns_rdataset_isassociated(&val->frdataset))
validator_start(isc_task_t *task, isc_event_t *event) {
dns_validator_t *val;
dns_validatorevent_t *vevent;
+ isc_boolean_t want_destroy = ISC_FALSE;
isc_result_t result = ISC_R_FAILURE;
UNUSED(task);
validator_log(val, ISC_LOG_DEBUG(3),
"attempting positive response validation");
- result = validate(val, ISC_FALSE);
+ INSIST(dns_rdataset_isassociated(val->event->rdataset));
+ INSIST(dns_rdataset_isassociated(val->event->sigrdataset));
+ result = start_positive_validation(val);
if (result == DNS_R_NOVALIDSIG &&
(val->attributes & VALATTR_TRIEDVERIFY) == 0)
{
saved_result = result;
validator_log(val, ISC_LOG_DEBUG(3),
"falling back to insecurity proof");
+ val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, ISC_FALSE);
if (result == DNS_R_NOTINSECURE)
result = saved_result;
* This is either an unsecure subdomain or a response from
* a broken server.
*/
+ INSIST(dns_rdataset_isassociated(val->event->rdataset));
validator_log(val, ISC_LOG_DEBUG(3),
"attempting insecurity proof");
+ val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, ISC_FALSE);
} else if (val->event->rdataset == NULL &&
val->event->sigrdataset == NULL)
validator_log(val, ISC_LOG_DEBUG(3),
"attempting negative response validation");
+ val->attributes |= VALATTR_NEGATIVE;
result = nxtvalidate(val, ISC_FALSE);
} else {
/*
INSIST(0);
}
- if (result != DNS_R_WAIT)
+ if (result != DNS_R_WAIT) {
+ want_destroy = exit_check(val);
validator_done(val, result);
+ }
UNLOCK(&val->lock);
+ if (want_destroy)
+ destroy(val);
}
isc_result_t
val->options = options;
val->attributes = 0;
val->fetch = NULL;
- val->keyvalidator = NULL;
- val->authvalidator = NULL;
+ val->subvalidator = NULL;
+ val->parent = NULL;
val->keytable = NULL;
dns_keytable_attach(val->view->secroots, &val->keytable);
val->keynode = NULL;
val->labels = 0;
val->currentset = NULL;
val->keyset = NULL;
+ val->dsset = NULL;
+ val->soaset = NULL;
val->seensig = ISC_FALSE;
dns_rdataset_init(&val->frdataset);
dns_rdataset_init(&val->fsigrdataset);
if (validator->fetch != NULL)
dns_resolver_cancelfetch(validator->fetch);
- if (validator->keyvalidator != NULL)
- dns_validator_cancel(validator->keyvalidator);
-
- if (validator->authvalidator != NULL)
- dns_validator_cancel(validator->authvalidator);
+ if (validator->subvalidator != NULL)
+ dns_validator_cancel(validator->subvalidator);
}
UNLOCK(&validator->lock);
}
dst_key_free(&val->key);
if (val->keytable != NULL)
dns_keytable_detach(&val->keytable);
- if (val->keyvalidator != NULL)
- dns_validator_destroy(&val->keyvalidator);
- if (val->authvalidator != NULL)
- dns_validator_destroy(&val->authvalidator);
+ if (val->subvalidator != NULL)
+ dns_validator_destroy(&val->subvalidator);
mctx = val->view->mctx;
if (val->siginfo != NULL)
isc_mem_put(mctx, val->siginfo, sizeof(*val->siginfo));
LOCK(&val->lock);
- REQUIRE(val->event == NULL);
-
+ val->attributes |= VALATTR_SHUTDOWN;
validator_log(val, ISC_LOG_DEBUG(3), "dns_validator_destroy");
- val->attributes |= VALATTR_SHUTDOWN;
- if (val->fetch == NULL && val->keyvalidator == NULL &&
- val->authvalidator == NULL)
- want_destroy = ISC_TRUE;
+ want_destroy = exit_check(val);
UNLOCK(&val->lock);
DNS_LOGMODULE_VALIDATOR, level, fmt, ap);
va_end(ap);
}
+
+static void
+validator_logcreate(dns_validator_t *val,
+ dns_name_t *name, dns_rdatatype_t type,
+ const char *caller, const char *operation)
+{
+ char namestr[DNS_NAME_FORMATSIZE];
+ char typestr[DNS_RDATATYPE_FORMATSIZE];
+
+ dns_name_format(name, namestr, sizeof(namestr));
+ dns_rdatatype_format(type, typestr, sizeof(typestr));
+ validator_log(val, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s",
+ caller, operation, namestr, typestr);
+}
-# $Id: version,v 1.27 2001/08/30 05:02:20 marka Exp $
+# $Id: version,v 1.28 2002/06/17 04:00:59 marka Exp $
#
# This file must follow /bin/sh rules. It is imported directly via
# configure.