validator.c revision 6098d364b690cb9dabf96e9664c4689c8559bd2e
8a99b24dbe8e0e713f226f4696bfa215b38ad3c6Tinderbox User * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Copyright (C) 2000-2003 Internet Software Consortium.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and/or distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * copyright notice and this permission notice appear in all copies.
609f86163a9e80aa5ce0db79b67ee0b6e2a34b34Tatuya JINMEI 神明達哉 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
8f7cae3d7b0c122c3b17e8409bbb80005433acd2Brian Wellington * PERFORMANCE OF THIS SOFTWARE.
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington/* $Id: validator.c,v 1.162 2008/09/24 02:46:22 marka Exp $ */
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * Basic processing sequences.
8327c62a49a2487d29a37acbed6b602e629fc0eeAndreas Gustafsson * \li When called with rdataset and sigrdataset:
8327c62a49a2487d29a37acbed6b602e629fc0eeAndreas Gustafsson * validator_start -> validate -> proveunsecure -> startfinddlvsep ->
8327c62a49a2487d29a37acbed6b602e629fc0eeAndreas Gustafsson * dlv_validator_start -> validator_start -> validate -> proveunsecure
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * validator_start -> validate -> nsecvalidate (secure wildcard answer)
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * \li When called with rdataset, sigrdataset and with DNS_VALIDATOR_DLV:
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * validator_start -> startfinddlvsep -> dlv_validator_start ->
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * validator_start -> validate -> proveunsecure
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson * \li When called with rdataset:
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * validator_start -> proveunsecure -> startfinddlvsep ->
3b1a5821011c91c3d30dc08b9dc2a4148ba77bb0Mark Andrews * dlv_validator_start -> validator_start -> proveunsecure
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * \li When called with rdataset and with DNS_VALIDATOR_DLV:
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * validator_start -> startfinddlvsep -> dlv_validator_start ->
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * validator_start -> proveunsecure
8582a1e113c13886ccbd1b534d6c240315767be6Bob Halley * \li When called without a rdataset:
8582a1e113c13886ccbd1b534d6c240315767be6Bob Halley * validator_start -> nsecvalidate -> proveunsecure -> startfinddlvsep ->
edcd1247ad7e81bb8b430e610d9718f64c70f05dDavid Lawrence * dlv_validator_start -> validator_start -> nsecvalidate -> proveunsecure
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * Note: there isn't a case for DNS_VALIDATOR_DLV here as we want nsecvalidate()
edcd1247ad7e81bb8b430e610d9718f64c70f05dDavid Lawrence * to always validate the authority section even when it does not contain
c55dd77de4ce71b858afb291e44577b51be8b780Mark Andrews * signatures.
c55dd77de4ce71b858afb291e44577b51be8b780Mark Andrews * validator_start: determines what type of validation to do.
edcd1247ad7e81bb8b430e610d9718f64c70f05dDavid Lawrence * validate: attempts to perform a positive validation.
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * proveunsecure: attempts to prove the answer comes from a unsecure zone.
c90f5e8d1edbd5c277f2ee320167a12a30ba7c7bMichael Graff * nsecvalidate: attempts to prove a negative response.
edcd1247ad7e81bb8b430e610d9718f64c70f05dDavid Lawrence * startfinddlvsep: starts the DLV record lookup.
c90f5e8d1edbd5c277f2ee320167a12a30ba7c7bMichael Graff * dlv_validator_start: resets state and restarts the lookup using the
b31c8af1d9778ce006c7375394b5f4e5e00405bfAndreas Gustafsson * DLV RRset found by startfinddlvsep.
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson#define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson#define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson#define VALATTR_SHUTDOWN 0x0001 /*%< Shutting down. */
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson#define VALATTR_CANCELED 0x0002 /*%< Cancelled. */
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson#define VALATTR_TRIEDVERIFY 0x0004 /*%< We have found a key and
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson * have attempted a verify. */
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson#define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson#define VALATTR_DLVTRIED 0x0020 /*%< Looked for a DLV record. */
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson * NSEC proofs to be looked for.
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson * NSEC proofs that have been found.
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson#define VALATTR_FOUNDNOWILDCARD 0x00002000
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson#define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson#define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
44fee668021c7ceef4ee1c848031d883a508b359James Brister#define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
44fee668021c7ceef4ee1c848031d883a508b359James Brister#define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington#define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
44fee668021c7ceef4ee1c848031d883a508b359James Bristerget_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
44613d4d868ed5e73a1132280880f0699af56733Evan Huntvalidate(dns_validator_t *val, isc_boolean_t resume);
44613d4d868ed5e73a1132280880f0699af56733Evan Huntnsecvalidate(dns_validator_t *val, isc_boolean_t resume);
44613d4d868ed5e73a1132280880f0699af56733Evan Huntproveunsecure(dns_validator_t *val, isc_boolean_t have_ds,
44613d4d868ed5e73a1132280880f0699af56733Evan Huntvalidator_logv(dns_validator_t *val, isc_logcategory_t *category,
ee80f4506479e189ca1320eb87ac89188c5a7848Mark Andrews isc_logmodule_t *module, int level, const char *fmt, va_list ap)
ee80f4506479e189ca1320eb87ac89188c5a7848Mark Andrewsvalidator_log(dns_validator_t *val, int level, const char *fmt, ...)
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson const char *caller, const char *operation);
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafssondlv_validatezonekey(dns_validator_t *val);
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafssondlv_validator_start(dns_validator_t *val);
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafssonfinddlvsep(dns_validator_t *val, isc_boolean_t resume);
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafssonstartfinddlvsep(dns_validator_t *val, dns_name_t *unsecure);
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson * Mark the RRsets as a answer.
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellingtonstatic inline void
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson val->event->rdataset->trust = dns_trust_answer;
1d9ab721315555ac75e7d4f57585323909283688Andreas Gustafsson val->event->sigrdataset->trust = dns_trust_answer;
1d9ab721315555ac75e7d4f57585323909283688Andreas Gustafssonvalidator_done(dns_validator_t *val, isc_result_t result) {
44613d4d868ed5e73a1132280880f0699af56733Evan Hunt * Caller must be holding the lock.
44613d4d868ed5e73a1132280880f0699af56733Evan Hunt isc_task_sendanddetach(&task, (isc_event_t **)&val->event);
3b4405aba93729eead9f8f006d426f24fc4c3d78Mark Andrews * Caller must be holding the lock.
3b4405aba93729eead9f8f006d426f24fc4c3d78Mark Andrews if (val->fetch != NULL || val->subvalidator != NULL)
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson * Look in the NSEC record returned from a DS query to see if there is
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson * a NS RRset at this name. If it is found we are at a delegation point.
5542df09597c479be604da0ece8271cbc6fd9c4aDavid Lawrenceisdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley unsigned int length;
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley REQUIRE(dbresult == DNS_R_NXRRSET || dbresult == DNS_R_NCACHENXRRSET);
89d03d4715120fd0c968775bf0724b5a2a647539Mark Andrews result = dns_ncache_getrdataset(rdataset, name,
return (found);
if (order == 0) {
return (found);
return (ISC_TRUE);
return (found);
if (want_destroy)
if (want_destroy)
ISC_TRUE);
if (want_destroy)
if (want_destroy)
if (want_destroy)
static isc_result_t
int order;
return (result);
if (order < 0) {
return (ISC_R_IGNORE);
if (order == 0) {
if (!atparent) {
return (ISC_R_IGNORE);
return (ISC_R_IGNORE);
*data);
return (ISC_R_SUCCESS);
return (ISC_R_IGNORE);
return (ISC_R_IGNORE);
return (result);
if (order == 0) {
return (ISC_R_IGNORE);
return (ISC_R_IGNORE);
return (ISC_R_SUCCESS);
return (result);
return (ISC_R_SUCCESS);
static isc_result_t
int order;
int scope;
unsigned int length;
unsigned int qlabels;
unsigned int zlabels;
return (result);
return (result);
return (ISC_R_IGNORE);
zlabels--;
return (ISC_R_IGNORE);
return (ISC_R_IGNORE);
return (ISC_R_SUCCESS);
return (ISC_R_IGNORE);
return (result);
return (ISC_R_IGNORE);
return (ISC_R_IGNORE);
if (!atparent) {
return (ISC_R_IGNORE);
return (ISC_R_IGNORE);
return (ISC_R_SUCCESS);
return (ISC_R_IGNORE);
if (order == 0 &&
return (ISC_R_IGNORE);
if (order == 0) {
sizeof(namebuf));
namebuf);
return (answer);
sizeof(namebuf));
namebuf);
*optout =
qlabels--;
if (qlabels > 0)
return (answer);
== ISC_R_SUCCESS)
if (!exists) {
if (want_destroy)
static inline isc_result_t
unsigned int options;
return (ISC_R_CANCELED);
goto notfound;
goto notfound;
goto notfound;
goto notfound;
goto notfound;
goto notfound;
goto notfound;
return (result);
return (ISC_R_NOTFOUND);
static inline isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
static inline isc_result_t
return (DNS_R_NOVALIDSIG);
static inline isc_result_t
return (DNS_R_NOVALIDSIG);
return (result);
static isc_result_t
isc_buffer_t b;
goto failure;
goto failure;
if (foundold)
return (ISC_R_SUCCESS);
return (result);
static isc_result_t
unsigned int nlabels;
int order;
return (DNS_R_CONTINUE);
return (DNS_R_CONTINUE);
return (DNS_R_CONTINUE);
return (result);
return (DNS_R_WAIT);
return (result);
return (DNS_R_WAIT);
return (result);
static dns_keytag_t
isc_region_t r;
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
static isc_result_t
goto again;
return (result);
static isc_result_t
if (resume) {
return (ISC_R_NOMEMORY);
return (result);
if (!resume) {
return (result);
return (DNS_R_MUSTBESECURE);
return (ISC_R_SUCCESS);
&nextnode);
!= ISC_R_SUCCESS)
return (DNS_R_NOVALIDSIG);
return (result);
return (result);
return (DNS_R_NOVALIDSIG);
static isc_result_t
&sigrdata);
&keyrdata,
&dstkey);
return (result);
return (DNS_R_MUSTBESECURE);
return (ISC_R_SUCCESS);
return (DNS_R_NOVALIDSIG);
static isc_result_t
&sigrdata);
&keynode);
&keynode);
&nextnode);
&keynode);
return (result);
return (DNS_R_NOVALIDSIG);
return (DNS_R_NOVALIDDS);
if (atsep) {
sizeof(namebuf));
namebuf);
return (DNS_R_NOVALIDKEY);
return (result);
return (DNS_R_WAIT);
return (DNS_R_NOVALIDSIG);
return (result);
return (DNS_R_WAIT);
return (DNS_R_NOVALIDSIG);
return (DNS_R_MUSTBESECURE);
return (ISC_R_SUCCESS);
&sigrdata);
&keyrdata,
&dstkey);
return (result);
return (DNS_R_MUSTBESECURE);
return (ISC_R_SUCCESS);
return (DNS_R_NOVALIDSIG);
static isc_result_t
static isc_result_t
return (ISC_R_SUCCESS);
== ISC_R_SUCCESS)
name;
if (!exists)
name;
return (ISC_R_SUCCESS);
name;
if (!exists)
name;
return (ISC_R_SUCCESS);
return (result);
static isc_result_t
NULL);
return (result);
return (ISC_R_SUCCESS);
if (setclosest)
if (unknown)
if (optout)
NULL);
return (result);
return (result);
static isc_result_t
if (!resume)
if (resume) {
link))
return (result);
return (result);
return (DNS_R_WAIT);
return (result);
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
return (DNS_R_NOVALIDNSEC);
return (result);
return (ISC_R_SUCCESS);
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
sizeof(namebuf));
namebuf);
if (want_destroy)
static isc_result_t
namebuf);
return (DNS_R_MUSTBESECURE);
return (ISC_R_SUCCESS);
return (result);
sizeof(namebuf));
return (DNS_R_WAIT);
static isc_result_t
unsigned int labels;
if (!resume) {
return (DNS_R_MUSTBESECURE);
if (labels == 0)
return (ISC_R_NOTFOUND);
dlvsep);
if (labels == 0)
return (ISC_R_NOTFOUND);
return (DNS_R_NOVALIDSIG);
namebuf);
return (DNS_R_NOVALIDSIG);
return (ISC_R_SUCCESS);
return (result);
return (DNS_R_WAIT);
return (result);
if (labels == 0)
return (ISC_R_NOTFOUND);
static isc_result_t
goto out;
return (ISC_R_SUCCESS);
return (result);
if (!resume) {
namebuf);
goto out;
namebuf);
goto out;
goto out;
namebuf);
goto out;
return (DNS_R_WAIT);
goto out;
return (DNS_R_MUSTBESECURE);
return (ISC_R_SUCCESS);
goto out;
goto out;
goto out;
goto out;
goto out;
return (DNS_R_WAIT);
goto out;
goto out;
goto out;
return (DNS_R_WAIT);
out:
return (result);
INSIST(0);
if (want_destroy)
return (ISC_R_NOMEMORY);
sizeof(dns_validatorevent_t));
goto cleanup_val;
goto cleanup_event;
return (ISC_R_SUCCESS);
return (result);
if (want_destroy)
sizeof(typebuf));