mirror of https://github.com/getdnsapi/getdns.git
dnssec_return_validation_chain with stub resolving
This commit is contained in:
parent
f1a9c1a464
commit
d2345285a6
126
src/dnssec.c
126
src/dnssec.c
|
@ -49,6 +49,7 @@
|
||||||
#include "rr-dict.h"
|
#include "rr-dict.h"
|
||||||
#include "gldns/str2wire.h"
|
#include "gldns/str2wire.h"
|
||||||
#include "gldns/wire2str.h"
|
#include "gldns/wire2str.h"
|
||||||
|
#include "general.h"
|
||||||
|
|
||||||
void priv_getdns_call_user_callback(getdns_dns_req *, struct getdns_dict *);
|
void priv_getdns_call_user_callback(getdns_dns_req *, struct getdns_dict *);
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ struct chain_response {
|
||||||
int sec;
|
int sec;
|
||||||
char *bogus;
|
char *bogus;
|
||||||
struct validation_chain *chain;
|
struct validation_chain *chain;
|
||||||
int unbound_id;
|
getdns_transaction_t transaction_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chain_link {
|
struct chain_link {
|
||||||
|
@ -181,10 +182,12 @@ static void callback_on_complete_chain(struct validation_chain *chain)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ub_chain_response_callback(void *arg, int err, struct ub_result* ub_res)
|
chain_response_callback(struct getdns_dns_req *dns_req)
|
||||||
{
|
{
|
||||||
struct chain_response *response = (struct chain_response *) arg;
|
struct chain_response *response =
|
||||||
getdns_context *context = response->chain->dns_req->context;
|
(struct chain_response *) dns_req->user_pointer;
|
||||||
|
getdns_context *context = dns_req->context;
|
||||||
|
getdns_network_req **netreq_p, *netreq;
|
||||||
priv_getdns_rr_iter rr_iter_storage, *rr_iter;
|
priv_getdns_rr_iter rr_iter_storage, *rr_iter;
|
||||||
priv_getdns_rdf_iter rdf_storage, *rdf;
|
priv_getdns_rdf_iter rdf_storage, *rdf;
|
||||||
gldns_pkt_section section;
|
gldns_pkt_section section;
|
||||||
|
@ -193,52 +196,54 @@ ub_chain_response_callback(void *arg, int err, struct ub_result* ub_res)
|
||||||
getdns_list *keys;
|
getdns_list *keys;
|
||||||
size_t nkeys;
|
size_t nkeys;
|
||||||
|
|
||||||
response->err = err;
|
if (dns_req == NULL ||
|
||||||
response->sec = ub_res ? ub_res->secure : 0;
|
|
||||||
response->bogus = ub_res ? ub_res->why_bogus : NULL;
|
|
||||||
|
|
||||||
if (ub_res == NULL || ub_res->answer_packet == NULL ||
|
|
||||||
!(keys = getdns_list_create_with_context(context)))
|
!(keys = getdns_list_create_with_context(context)))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
for ( rr_iter = priv_getdns_rr_iter_init(&rr_iter_storage
|
for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++) {
|
||||||
, ub_res->answer_packet
|
for ( rr_iter = priv_getdns_rr_iter_init(&rr_iter_storage
|
||||||
, ub_res->answer_len)
|
, netreq->response
|
||||||
; rr_iter
|
, netreq->response_len)
|
||||||
; rr_iter = priv_getdns_rr_iter_next(rr_iter)
|
; rr_iter
|
||||||
) {
|
; rr_iter = priv_getdns_rr_iter_next(rr_iter)
|
||||||
section = priv_getdns_rr_iter_section(rr_iter);
|
) {
|
||||||
if (section != GLDNS_SECTION_ANSWER)
|
section = priv_getdns_rr_iter_section(rr_iter);
|
||||||
continue;
|
if (section != GLDNS_SECTION_ANSWER)
|
||||||
|
continue;
|
||||||
|
|
||||||
rr_type = gldns_read_uint16(rr_iter->rr_type);
|
rr_type = gldns_read_uint16(rr_iter->rr_type);
|
||||||
|
|
||||||
if (rr_type == GETDNS_RRTYPE_DS ||
|
if (rr_type == GETDNS_RRTYPE_DS ||
|
||||||
rr_type == GETDNS_RRTYPE_DNSKEY) {
|
rr_type == GETDNS_RRTYPE_DNSKEY) {
|
||||||
if (!(rr_dict = priv_getdns_rr_iter2rr_dict(context, rr_iter)))
|
if (!(rr_dict = priv_getdns_rr_iter2rr_dict(
|
||||||
|
context, rr_iter)))
|
||||||
|
continue;
|
||||||
|
if (getdns_list_append_dict(keys, rr_dict))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rr_type != GETDNS_RRTYPE_RRSIG)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(rdf = priv_getdns_rdf_iter_init(
|
||||||
|
&rdf_storage, rr_iter)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
type_covered = gldns_read_uint16(rdf->pos);
|
||||||
|
if (type_covered == GETDNS_RRTYPE_DS) {
|
||||||
|
if ((rdf = priv_getdns_rdf_iter_init_at(
|
||||||
|
&rdf_storage, rr_iter, 7)))
|
||||||
|
launch_chain_link_lookup(
|
||||||
|
response->chain, rdf);
|
||||||
|
|
||||||
|
} else if (type_covered != GETDNS_RRTYPE_DNSKEY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(rr_dict = priv_getdns_rr_iter2rr_dict(
|
||||||
|
context, rr_iter)))
|
||||||
continue;
|
continue;
|
||||||
if (getdns_list_append_dict(keys, rr_dict))
|
if (getdns_list_append_dict(keys, rr_dict))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rr_type != GETDNS_RRTYPE_RRSIG)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(rdf = priv_getdns_rdf_iter_init(&rdf_storage, rr_iter)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
type_covered = gldns_read_uint16(rdf->pos);
|
|
||||||
if (type_covered == GETDNS_RRTYPE_DS) {
|
|
||||||
if ((rdf = priv_getdns_rdf_iter_init_at(
|
|
||||||
&rdf_storage, rr_iter, 7)))
|
|
||||||
launch_chain_link_lookup(response->chain, rdf);
|
|
||||||
|
|
||||||
} else if (type_covered != GETDNS_RRTYPE_DNSKEY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(rr_dict = priv_getdns_rr_iter2rr_dict(context, rr_iter)))
|
|
||||||
continue;
|
|
||||||
if (getdns_list_append_dict(keys, rr_dict))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (getdns_list_get_length(keys, &nkeys))
|
if (getdns_list_get_length(keys, &nkeys))
|
||||||
getdns_list_destroy(keys);
|
getdns_list_destroy(keys);
|
||||||
|
@ -248,32 +253,47 @@ ub_chain_response_callback(void *arg, int err, struct ub_result* ub_res)
|
||||||
else
|
else
|
||||||
response->result = keys;
|
response->result = keys;
|
||||||
|
|
||||||
ub_resolve_free(ub_res);
|
|
||||||
|
|
||||||
done: if (response->err == 0 && response->result == NULL)
|
done: if (response->err == 0 && response->result == NULL)
|
||||||
response->err = -1;
|
response->err = -1;
|
||||||
|
if (dns_req) {
|
||||||
|
getdns_context_clear_outbound_request(dns_req);
|
||||||
|
dns_req_free(dns_req);
|
||||||
|
}
|
||||||
callback_on_complete_chain(response->chain);
|
callback_on_complete_chain(response->chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chain_response_init(
|
static void chain_response_init(
|
||||||
struct validation_chain *chain, struct chain_response *response)
|
struct validation_chain *chain, struct chain_response *response)
|
||||||
{
|
{
|
||||||
response->err = 0;
|
response->err = 0;
|
||||||
response->result = NULL;
|
response->result = NULL;
|
||||||
response->sec = 0;
|
response->sec = 0;
|
||||||
response->bogus = NULL;
|
response->bogus = NULL;
|
||||||
response->chain = chain;
|
response->chain = chain;
|
||||||
response->unbound_id = -1;
|
response->transaction_id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
resolve(char* name, int rrtype, struct chain_response *response)
|
resolve(char* name, int rrtype, struct chain_response *response)
|
||||||
{
|
{
|
||||||
return ub_resolve_async(
|
getdns_return_t r;
|
||||||
response->chain->dns_req->context->unbound_ctx,
|
getdns_dict *extensions;
|
||||||
name, rrtype, GETDNS_RRCLASS_IN, response,
|
|
||||||
ub_chain_response_callback, &response->unbound_id);
|
if (!(extensions = getdns_dict_create_with_context(
|
||||||
|
response->chain->dns_req->context)))
|
||||||
|
return GETDNS_RETURN_MEMORY_ERROR;
|
||||||
|
|
||||||
|
if (!(r = getdns_dict_set_int(extensions,
|
||||||
|
"dnssec_ok_checking_disabled", GETDNS_EXTENSION_TRUE)))
|
||||||
|
|
||||||
|
r = priv_getdns_general_loop(response->chain->dns_req->context,
|
||||||
|
response->chain->dns_req->loop, name, rrtype, extensions,
|
||||||
|
response, &response->transaction_id, NULL,
|
||||||
|
chain_response_callback);
|
||||||
|
|
||||||
|
getdns_dict_destroy(extensions);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -91,7 +91,9 @@ priv_getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
||||||
else if (netreq->response_len > 0)
|
else if (netreq->response_len > 0)
|
||||||
results_found = 1;
|
results_found = 1;
|
||||||
|
|
||||||
if (! results_found)
|
if (dns_req->internal_cb)
|
||||||
|
dns_req->internal_cb(dns_req);
|
||||||
|
else if (! results_found)
|
||||||
priv_getdns_call_user_callback(dns_req, NULL);
|
priv_getdns_call_user_callback(dns_req, NULL);
|
||||||
else if (dns_req->dnssec_return_validation_chain
|
else if (dns_req->dnssec_return_validation_chain
|
||||||
#ifdef STUB_NATIVE_DNSSEC
|
#ifdef STUB_NATIVE_DNSSEC
|
||||||
|
@ -172,7 +174,7 @@ static getdns_return_t
|
||||||
getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||||
void *userarg, getdns_transaction_t *transaction_id,
|
void *userarg, getdns_transaction_t *transaction_id,
|
||||||
getdns_callback_t callbackfn, int usenamespaces)
|
getdns_callback_t callbackfn, internal_cb_t internal_cb, int usenamespaces)
|
||||||
{
|
{
|
||||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||||
getdns_network_req *netreq, **netreq_p;
|
getdns_network_req *netreq, **netreq_p;
|
||||||
|
@ -180,7 +182,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
getdns_dict *localnames_response;
|
getdns_dict *localnames_response;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (!context || !name || !callbackfn)
|
if (!context || !name || (!callbackfn && !internal_cb))
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
if ((r = validate_dname(name)))
|
if ((r = validate_dname(name)))
|
||||||
|
@ -200,6 +202,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
|
|
||||||
req->user_pointer = userarg;
|
req->user_pointer = userarg;
|
||||||
req->user_callback = callbackfn;
|
req->user_callback = callbackfn;
|
||||||
|
req->internal_cb = internal_cb;
|
||||||
|
|
||||||
if (transaction_id)
|
if (transaction_id)
|
||||||
*transaction_id = req->trans_id;
|
*transaction_id = req->trans_id;
|
||||||
|
@ -252,11 +255,11 @@ getdns_return_t
|
||||||
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||||
void *userarg, getdns_transaction_t *transaction_id,
|
void *userarg, getdns_transaction_t *transaction_id,
|
||||||
getdns_callback_t callback)
|
getdns_callback_t callback, internal_cb_t internal_cb)
|
||||||
{
|
{
|
||||||
return getdns_general_ns(context, loop,
|
return getdns_general_ns(context, loop,
|
||||||
name, request_type, extensions,
|
name, request_type, extensions,
|
||||||
userarg, transaction_id, callback, 0);
|
userarg, transaction_id, callback, internal_cb, 0);
|
||||||
|
|
||||||
} /* getdns_general_loop */
|
} /* getdns_general_loop */
|
||||||
|
|
||||||
|
@ -279,7 +282,7 @@ priv_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
|
|
||||||
r = getdns_general_ns(context, loop,
|
r = getdns_general_ns(context, loop,
|
||||||
name, GETDNS_RRTYPE_A, extensions,
|
name, GETDNS_RRTYPE_A, extensions,
|
||||||
userarg, transaction_id, callback, 1);
|
userarg, transaction_id, callback, NULL, 1);
|
||||||
|
|
||||||
if (cleanup_extensions)
|
if (cleanup_extensions)
|
||||||
getdns_dict_destroy(extensions);
|
getdns_dict_destroy(extensions);
|
||||||
|
@ -370,7 +373,7 @@ priv_getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
retval = priv_getdns_general_loop(context, loop, name, req_type,
|
retval = priv_getdns_general_loop(context, loop, name, req_type,
|
||||||
extensions, userarg, transaction_id, callback);
|
extensions, userarg, transaction_id, callback, NULL);
|
||||||
return retval;
|
return retval;
|
||||||
} /* getdns_hostname_loop */
|
} /* getdns_hostname_loop */
|
||||||
|
|
||||||
|
@ -380,7 +383,7 @@ priv_getdns_service_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
getdns_transaction_t * transaction_id, getdns_callback_t callback)
|
getdns_transaction_t * transaction_id, getdns_callback_t callback)
|
||||||
{
|
{
|
||||||
return getdns_general_ns(context, loop, name, GETDNS_RRTYPE_SRV,
|
return getdns_general_ns(context, loop, name, GETDNS_RRTYPE_SRV,
|
||||||
extensions, userarg, transaction_id, callback, 1);
|
extensions, userarg, transaction_id, callback, NULL, 1);
|
||||||
} /* getdns_service_loop */
|
} /* getdns_service_loop */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -395,7 +398,7 @@ getdns_general(getdns_context *context,
|
||||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
return priv_getdns_general_loop(context, context->extension,
|
return priv_getdns_general_loop(context, context->extension,
|
||||||
name, request_type, extensions,
|
name, request_type, extensions,
|
||||||
userarg, transaction_id, callback);
|
userarg, transaction_id, callback, NULL);
|
||||||
|
|
||||||
} /* getdns_general */
|
} /* getdns_general */
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ getdns_return_t
|
||||||
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
priv_getdns_general_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||||
void *userarg, getdns_transaction_t *transaction_id,
|
void *userarg, getdns_transaction_t *transaction_id,
|
||||||
getdns_callback_t callbackfn);
|
getdns_callback_t callbackfn, internal_cb_t internal_cb);
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
priv_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
priv_getdns_address_loop(getdns_context *context, getdns_eventloop *loop,
|
||||||
|
|
|
@ -207,8 +207,12 @@ dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
= is_extension_set(extensions, "dnssec_return_only_secure");
|
= is_extension_set(extensions, "dnssec_return_only_secure");
|
||||||
int dnssec_return_validation_chain
|
int dnssec_return_validation_chain
|
||||||
= is_extension_set(extensions, "dnssec_return_validation_chain");
|
= is_extension_set(extensions, "dnssec_return_validation_chain");
|
||||||
|
int dnssec_ok_checking_disabled
|
||||||
|
= is_extension_set(extensions, "dnssec_ok_checking_disabled");
|
||||||
|
|
||||||
int dnssec_extension_set = dnssec_return_status
|
int dnssec_extension_set = dnssec_return_status
|
||||||
|| dnssec_return_only_secure || dnssec_return_validation_chain;
|
|| dnssec_return_only_secure || dnssec_return_validation_chain
|
||||||
|
|| dnssec_ok_checking_disabled;;
|
||||||
|
|
||||||
uint32_t edns_do_bit;
|
uint32_t edns_do_bit;
|
||||||
int edns_maximum_udp_payload_size;
|
int edns_maximum_udp_payload_size;
|
||||||
|
|
|
@ -86,7 +86,7 @@ priv_getdns_rr_iter_init(priv_getdns_rr_iter *i, uint8_t *pkt, size_t pkt_len)
|
||||||
{
|
{
|
||||||
assert(i);
|
assert(i);
|
||||||
|
|
||||||
if (pkt_len < GLDNS_HEADER_SIZE + 5) {
|
if (!pkt || pkt_len < GLDNS_HEADER_SIZE + 5) {
|
||||||
i->pos = NULL;
|
i->pos = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ getdns_general_sync(getdns_context *context, const char *name,
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if ((r = priv_getdns_general_loop(context, &loop.loop.loop, name,
|
if ((r = priv_getdns_general_loop(context, &loop.loop.loop, name,
|
||||||
request_type, extensions, &loop, NULL, getdns_sync_cb))) {
|
request_type, extensions, &loop, NULL, getdns_sync_cb, NULL))) {
|
||||||
|
|
||||||
getdns_sync_loop_cleanup(&loop);
|
getdns_sync_loop_cleanup(&loop);
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -108,6 +108,7 @@ struct getdns_upstream;
|
||||||
struct getdns_dns_req;
|
struct getdns_dns_req;
|
||||||
struct getdns_network_req;
|
struct getdns_network_req;
|
||||||
|
|
||||||
|
typedef void (*internal_cb_t)(struct getdns_dns_req *dns_req);
|
||||||
|
|
||||||
#define MF_PLAIN ((void *)&plain_mem_funcs_user_arg)
|
#define MF_PLAIN ((void *)&plain_mem_funcs_user_arg)
|
||||||
extern void *plain_mem_funcs_user_arg;
|
extern void *plain_mem_funcs_user_arg;
|
||||||
|
@ -238,6 +239,12 @@ typedef struct getdns_dns_req {
|
||||||
int dnssec_return_only_secure;
|
int dnssec_return_only_secure;
|
||||||
int dnssec_return_validation_chain;
|
int dnssec_return_validation_chain;
|
||||||
|
|
||||||
|
/* Internally used by return_validation_chain */
|
||||||
|
int dnssec_ok_checking_disabled;
|
||||||
|
|
||||||
|
/* internally scheduled request */
|
||||||
|
internal_cb_t internal_cb;
|
||||||
|
|
||||||
/* event loop */
|
/* event loop */
|
||||||
getdns_eventloop *loop;
|
getdns_eventloop *loop;
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
static getdns_extension_format extformats[] = {
|
static getdns_extension_format extformats[] = {
|
||||||
{"add_opt_parameters", t_dict},
|
{"add_opt_parameters", t_dict},
|
||||||
{"add_warning_for_bad_dns", t_int},
|
{"add_warning_for_bad_dns", t_int},
|
||||||
|
{"dnssec_ok_checking_disabled", t_int},
|
||||||
{"dnssec_return_only_secure", t_int},
|
{"dnssec_return_only_secure", t_int},
|
||||||
{"dnssec_return_status", t_int},
|
{"dnssec_return_status", t_int},
|
||||||
{"dnssec_return_validation_chain", t_int},
|
{"dnssec_return_validation_chain", t_int},
|
||||||
|
|
Loading…
Reference in New Issue