mirror of https://github.com/getdnsapi/getdns.git
dnssec_status & dnssec_return_only_secure exts.
This commit is contained in:
parent
edf1da405f
commit
b6c9b25fc7
|
@ -132,12 +132,7 @@ handle_network_request_error(getdns_network_req * netreq, int err)
|
||||||
static void
|
static void
|
||||||
handle_dns_request_complete(getdns_dns_req * dns_req)
|
handle_dns_request_complete(getdns_dns_req * dns_req)
|
||||||
{
|
{
|
||||||
uint32_t ret_chain_ext = GETDNS_EXTENSION_FALSE;
|
if (is_extension_set(dns_req->extensions, "dnssec_return_validation_chain"))
|
||||||
getdns_return_t r = getdns_dict_get_int(dns_req->extensions,
|
|
||||||
"dnssec_return_validation_chain", &ret_chain_ext);
|
|
||||||
|
|
||||||
if (r == GETDNS_RETURN_GOOD && ret_chain_ext == GETDNS_EXTENSION_TRUE)
|
|
||||||
|
|
||||||
priv_getdns_get_validation_chain(dns_req);
|
priv_getdns_get_validation_chain(dns_req);
|
||||||
else
|
else
|
||||||
priv_getdns_call_user_callback(
|
priv_getdns_call_user_callback(
|
||||||
|
|
|
@ -116,8 +116,6 @@ dns_req_new(struct getdns_context *context,
|
||||||
|
|
||||||
getdns_dns_req *result = NULL;
|
getdns_dns_req *result = NULL;
|
||||||
getdns_network_req *req = NULL;
|
getdns_network_req *req = NULL;
|
||||||
getdns_return_t r;
|
|
||||||
uint32_t both = GETDNS_EXTENSION_FALSE;
|
|
||||||
|
|
||||||
result = GETDNS_MALLOC(context->mf, getdns_dns_req);
|
result = GETDNS_MALLOC(context->mf, getdns_dns_req);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
|
@ -150,12 +148,9 @@ dns_req_new(struct getdns_context *context,
|
||||||
result->first_req = req;
|
result->first_req = req;
|
||||||
|
|
||||||
/* tack on A or AAAA if needed */
|
/* tack on A or AAAA if needed */
|
||||||
r = getdns_dict_get_int(extensions,
|
if (is_extension_set(extensions, "return_both_v4_and_v6") &&
|
||||||
GETDNS_STR_EXTENSION_RETURN_BOTH_V4_AND_V6, &both);
|
(request_type == GETDNS_RRTYPE_A ||
|
||||||
if (r == GETDNS_RETURN_GOOD &&
|
request_type == GETDNS_RRTYPE_AAAA)) {
|
||||||
both == GETDNS_EXTENSION_TRUE &&
|
|
||||||
(request_type == GETDNS_RRTYPE_A
|
|
||||||
|| request_type == GETDNS_RRTYPE_AAAA)) {
|
|
||||||
|
|
||||||
uint16_t next_req_type =
|
uint16_t next_req_type =
|
||||||
(request_type ==
|
(request_type ==
|
||||||
|
|
|
@ -360,7 +360,7 @@ add_only_addresses(struct getdns_list * addrs, ldns_rr_list * rr_list)
|
||||||
|
|
||||||
static struct getdns_dict *
|
static struct getdns_dict *
|
||||||
create_reply_dict(struct getdns_context *context, getdns_network_req * req,
|
create_reply_dict(struct getdns_context *context, getdns_network_req * req,
|
||||||
struct getdns_list * just_addrs)
|
struct getdns_list * just_addrs, int *nanswers)
|
||||||
{
|
{
|
||||||
/* turn a packet into this glorious structure
|
/* turn a packet into this glorious structure
|
||||||
*
|
*
|
||||||
|
@ -401,18 +401,45 @@ create_reply_dict(struct getdns_context *context, getdns_network_req * req,
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int r = 0;
|
getdns_return_t r = 0;
|
||||||
ldns_pkt *reply = req->result;
|
ldns_pkt *reply = req->result;
|
||||||
ldns_rr_list *rr_list = NULL;
|
ldns_rr_list *rr_list = NULL;
|
||||||
ldns_rr *question = NULL;
|
ldns_rr *question = NULL;
|
||||||
struct getdns_dict *subdict = NULL;
|
struct getdns_dict *subdict = NULL;
|
||||||
struct getdns_list *sublist = NULL;
|
struct getdns_list *sublist = NULL;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* info (bools) about dns_req */
|
||||||
|
int dnssec_return_status;
|
||||||
|
int dnssec_return_only_secure;
|
||||||
|
int do_dnssec;
|
||||||
|
|
||||||
|
/* info (bool) about network_req */
|
||||||
|
int include_answers;
|
||||||
|
int rrsig_in_answer;
|
||||||
|
|
||||||
struct getdns_dict *result = getdns_dict_create_with_context(context);
|
struct getdns_dict *result = getdns_dict_create_with_context(context);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
assert(nanswers);
|
||||||
|
|
||||||
|
dnssec_return_status = is_extension_set(req->owner->extensions,
|
||||||
|
"dnssec_return_status");
|
||||||
|
dnssec_return_only_secure = is_extension_set(req->owner->extensions,
|
||||||
|
"dnssec_return_only_secure");
|
||||||
|
do_dnssec = ( dnssec_return_status || dnssec_return_only_secure ) &&
|
||||||
|
context->has_ta;
|
||||||
|
dnssec_return_status = dnssec_return_status || dnssec_return_only_secure ||
|
||||||
|
is_extension_set(req->owner->extensions,
|
||||||
|
"dnssec_return_validation_chain");
|
||||||
|
|
||||||
|
include_answers = ! do_dnssec /* No DNSSEC, include answer.*/
|
||||||
|
|| req->secure /* Always include secure answers. */
|
||||||
|
|| (! dnssec_return_only_secure /* And insecure answers (ext.), */
|
||||||
|
&& ! req->bogus); /* unless it is bogus. */
|
||||||
|
|
||||||
/* header */
|
/* header */
|
||||||
do {
|
do {
|
||||||
subdict = create_reply_header_dict(context, reply);
|
subdict = create_reply_header_dict(context, reply);
|
||||||
|
@ -435,16 +462,29 @@ create_reply_dict(struct getdns_context *context, getdns_network_req * req,
|
||||||
|
|
||||||
/* answers */
|
/* answers */
|
||||||
rr_list = ldns_pkt_answer(reply);
|
rr_list = ldns_pkt_answer(reply);
|
||||||
sublist = create_list_from_rr_list(context, rr_list);
|
rrsig_in_answer = 0;
|
||||||
|
for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++)
|
||||||
|
if (LDNS_RR_TYPE_RRSIG ==
|
||||||
|
ldns_rr_get_type(ldns_rr_list_rr(rr_list, i))) {
|
||||||
|
rrsig_in_answer = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (include_answers) {
|
||||||
|
*nanswers += ldns_rr_list_rr_count(rr_list);
|
||||||
|
sublist = create_list_from_rr_list(context, rr_list);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sublist = getdns_list_create_with_context(context);
|
||||||
|
|
||||||
r = getdns_dict_set_list(result, GETDNS_STR_KEY_ANSWER, sublist);
|
r = getdns_dict_set_list(result, GETDNS_STR_KEY_ANSWER, sublist);
|
||||||
getdns_list_destroy(sublist);
|
getdns_list_destroy(sublist);
|
||||||
if (r != GETDNS_RETURN_GOOD) {
|
if (r != GETDNS_RETURN_GOOD) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((req->request_type == GETDNS_RRTYPE_A ||
|
if (include_answers && just_addrs &&
|
||||||
req->request_type == GETDNS_RRTYPE_AAAA) &&
|
(req->request_type == GETDNS_RRTYPE_A ||
|
||||||
just_addrs != NULL) {
|
req->request_type == GETDNS_RRTYPE_AAAA)) {
|
||||||
/* add to just addrs */
|
/* add to just addrs */
|
||||||
r = add_only_addresses(just_addrs, rr_list);
|
r = add_only_addresses(just_addrs, rr_list);
|
||||||
if (r != GETDNS_RETURN_GOOD) {
|
if (r != GETDNS_RETURN_GOOD) {
|
||||||
|
@ -488,10 +528,15 @@ create_reply_dict(struct getdns_context *context, getdns_network_req * req,
|
||||||
if (r != GETDNS_RETURN_GOOD)
|
if (r != GETDNS_RETURN_GOOD)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
r = getdns_dict_set_int(result, "dnssec_status",
|
if (! dnssec_return_status)
|
||||||
( req->secure ? GETDNS_DNSSEC_SECURE
|
break;
|
||||||
: req->bogus ? GETDNS_DNSSEC_BOGUS : GETDNS_DNSSEC_INSECURE ));
|
|
||||||
|
|
||||||
|
r = getdns_dict_set_int(result, "dnssec_status",
|
||||||
|
( req->secure ? GETDNS_DNSSEC_SECURE
|
||||||
|
: req->bogus ? GETDNS_DNSSEC_BOGUS
|
||||||
|
: rrsig_in_answer &&
|
||||||
|
context->has_ta ? GETDNS_DNSSEC_INDETERMINATE
|
||||||
|
: GETDNS_DNSSEC_INSECURE ));
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
|
@ -524,8 +569,8 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
completed_request->context);
|
completed_request->context);
|
||||||
getdns_network_req *netreq = completed_request->first_req;
|
getdns_network_req *netreq = completed_request->first_req;
|
||||||
char *canonical_name = NULL;
|
char *canonical_name = NULL;
|
||||||
|
getdns_return_t r = 0;
|
||||||
int r = 0;
|
int nanswers = 0, all_secure = 1;
|
||||||
|
|
||||||
if (completed_request->first_req->request_class == GETDNS_RRTYPE_A ||
|
if (completed_request->first_req->request_class == GETDNS_RRTYPE_A ||
|
||||||
completed_request->first_req->request_class ==
|
completed_request->first_req->request_class ==
|
||||||
|
@ -534,12 +579,6 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
completed_request->context);
|
completed_request->context);
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
r = getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS,
|
|
||||||
GETDNS_RESPSTATUS_GOOD);
|
|
||||||
if (r != GETDNS_RETURN_GOOD) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
canonical_name = get_canonical_name(completed_request->name);
|
canonical_name = get_canonical_name(completed_request->name);
|
||||||
r = getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM,
|
r = getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM,
|
||||||
canonical_name);
|
canonical_name);
|
||||||
|
@ -555,6 +594,9 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (netreq && r == GETDNS_RETURN_GOOD) {
|
while (netreq && r == GETDNS_RETURN_GOOD) {
|
||||||
|
|
||||||
|
all_secure = all_secure && netreq->secure;
|
||||||
|
|
||||||
struct getdns_bindata full_data;
|
struct getdns_bindata full_data;
|
||||||
full_data.data = NULL;
|
full_data.data = NULL;
|
||||||
full_data.size = 0;
|
full_data.size = 0;
|
||||||
|
@ -569,7 +611,7 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
/* reply tree */
|
/* reply tree */
|
||||||
struct getdns_dict *reply = create_reply_dict(
|
struct getdns_dict *reply = create_reply_dict(
|
||||||
completed_request->context, netreq, just_addrs);
|
completed_request->context, netreq, just_addrs, &nanswers);
|
||||||
r = getdns_list_add_item(replies_tree, &idx);
|
r = getdns_list_add_item(replies_tree, &idx);
|
||||||
if (r != GETDNS_RETURN_GOOD) {
|
if (r != GETDNS_RETURN_GOOD) {
|
||||||
getdns_dict_destroy(reply);
|
getdns_dict_destroy(reply);
|
||||||
|
@ -618,6 +660,19 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
||||||
r = getdns_dict_set_list(result, GETDNS_STR_KEY_JUST_ADDRS,
|
r = getdns_dict_set_list(result, GETDNS_STR_KEY_JUST_ADDRS,
|
||||||
just_addrs);
|
just_addrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dnssec_return_only_secure = is_extension_set(
|
||||||
|
completed_request->extensions, "dnssec_return_only_secure");
|
||||||
|
|
||||||
|
r = getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS,
|
||||||
|
dnssec_return_only_secure
|
||||||
|
&& ! all_secure ? GETDNS_RESPSTATUS_NO_SECURE_ANSWERS
|
||||||
|
: nanswers == 0 ? GETDNS_RESPSTATUS_NO_NAME
|
||||||
|
: GETDNS_RESPSTATUS_GOOD);
|
||||||
|
if (r != GETDNS_RETURN_GOOD) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
|
@ -779,4 +834,17 @@ validate_dname(const char* dname) {
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
} /* validate_dname */
|
} /* validate_dname */
|
||||||
|
|
||||||
|
int
|
||||||
|
is_extension_set(struct getdns_dict *extensions, const char *extension)
|
||||||
|
{
|
||||||
|
getdns_return_t r;
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
if (! extensions)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = getdns_dict_get_int(extensions, extension, &value);
|
||||||
|
return r == GETDNS_RETURN_GOOD && value == GETDNS_EXTENSION_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* util-internal.c */
|
/* util-internal.c */
|
||||||
|
|
|
@ -134,4 +134,6 @@ getdns_return_t validate_extensions(struct getdns_dict * extensions);
|
||||||
struct getdns_list *
|
struct getdns_list *
|
||||||
create_list_from_rr_list(struct getdns_context *context, ldns_rr_list * rr_list);
|
create_list_from_rr_list(struct getdns_context *context, ldns_rr_list * rr_list);
|
||||||
|
|
||||||
|
int is_extension_set(struct getdns_dict *extensions, const char *extension);
|
||||||
|
|
||||||
/* util-internal.h */
|
/* util-internal.h */
|
||||||
|
|
Loading…
Reference in New Issue