From c1f51815baf43d6c35d8c97f4d12e9708b395aca Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 30 Nov 2018 14:20:12 +0100 Subject: [PATCH] RFE #408: "dnssec" extension requiring DNSSEC When this extension is set, GETDNS_DNSSEC_INDETERMINATE status will no longer be returned. --- ChangeLog | 5 ++++- src/context.c | 6 ++++++ src/context.h | 1 + src/dict.c | 1 + src/general.c | 4 ++++ src/request-internal.c | 7 ++++++- src/tools/getdns_query.c | 1 + src/types-internal.h | 1 + src/util-internal.c | 12 +++++++++--- 9 files changed, 33 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ba1508e..f5626102 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,7 @@ -* 2018-0?-??: Version 1.4.3 +* 2018-??-??: Version 1.4.3 + * RFE #408: A "dnssec" extension that requires DNSSEC + verification. When this extension is set, Indeterminate + DNSSEC status will noging be returned. * Issue #410: Unspecified ownership of get_api_information() * Fix for DNSSEC bug in finding most specific key when trust anchor proves non-existance of one of the labels diff --git a/src/context.c b/src/context.c index 6dcbe489..51ef96c2 100644 --- a/src/context.c +++ b/src/context.c @@ -1655,6 +1655,7 @@ getdns_context_create_with_extended_memory_functions( result->header = NULL; result->add_opt_parameters = NULL; result->add_warning_for_bad_dns = 0; + result->dnssec = 0; result->dnssec_return_all_statuses = 0; result->dnssec_return_full_validation_chain = 0; result->dnssec_return_only_secure = 0; @@ -4129,6 +4130,10 @@ _get_context_settings(getdns_context* context) result, "dnssec_return_full_validation_chain", context->dnssec_return_full_validation_chain ? GETDNS_EXTENSION_TRUE : GETDNS_EXTENSION_FALSE); + (void)getdns_dict_set_int( + result, "dnssec", + context->dnssec ? GETDNS_EXTENSION_TRUE : GETDNS_EXTENSION_FALSE); + (void)getdns_dict_set_int( result, "dnssec_return_only_secure", context->dnssec_return_only_secure ? GETDNS_EXTENSION_TRUE @@ -4974,6 +4979,7 @@ _getdns_context_config_setting(getdns_context *context, /**** ****/ /**************************************/ EXTENSION_SETTING_BOOL(add_warning_for_bad_dns) + EXTENSION_SETTING_BOOL(dnssec) EXTENSION_SETTING_BOOL(dnssec_return_all_statuses) EXTENSION_SETTING_BOOL(dnssec_return_full_validation_chain) EXTENSION_SETTING_BOOL(dnssec_return_only_secure) diff --git a/src/context.h b/src/context.h index 29890928..c0080930 100644 --- a/src/context.h +++ b/src/context.h @@ -442,6 +442,7 @@ struct getdns_context { getdns_dict *header; getdns_dict *add_opt_parameters; unsigned add_warning_for_bad_dns : 1; + unsigned dnssec : 1; unsigned dnssec_return_all_statuses : 1; unsigned dnssec_return_full_validation_chain : 1; unsigned dnssec_return_only_secure : 1; diff --git a/src/dict.c b/src/dict.c index 3a454516..02d3f20f 100644 --- a/src/dict.c +++ b/src/dict.c @@ -1083,6 +1083,7 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent, /* extensions */ strcmp(item->node.key, "add_warning_for_bad_dns") == 0 || + strcmp(item->node.key, "dnssec") == 0 || strcmp(item->node.key, "dnssec_return_all_statuses") == 0 || strcmp(item->node.key, "dnssec_return_full_validation_chain") == 0 || strcmp(item->node.key, "dnssec_return_only_secure") == 0 || diff --git a/src/general.c b/src/general.c index 9de1d510..2cfec678 100644 --- a/src/general.c +++ b/src/general.c @@ -218,12 +218,14 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) && !dns_req->avoid_dnssec_roadblocks && (dns_req->dnssec_return_status || dns_req->dnssec_return_only_secure || + dns_req->dnssec || dns_req->dnssec_return_all_statuses )) #endif || ( dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING && (dns_req->dnssec_return_status || dns_req->dnssec_return_only_secure || + dns_req->dnssec || dns_req->dnssec_return_all_statuses) && _getdns_bogus(dns_req)) )) { @@ -423,6 +425,7 @@ _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms) if ( context->resolution_type == GETDNS_RESOLUTION_RECURSING || dns_req->dnssec_return_status || dns_req->dnssec_return_only_secure + || dns_req->dnssec || dns_req->dnssec_return_all_statuses || dns_req->dnssec_return_validation_chain) { #endif @@ -503,6 +506,7 @@ validate_extensions(const getdns_dict * extensions) static getdns_extension_format extformats[] = { {"add_opt_parameters" , t_dict, 1}, {"add_warning_for_bad_dns" , t_int , 1}, + {"dnssec" , t_int , 1}, {"dnssec_return_all_statuses" , t_int , 1}, {"dnssec_return_full_validation_chain", t_int , 1}, {"dnssec_return_only_secure" , t_int , 1}, diff --git a/src/request-internal.c b/src/request-internal.c index 46c77e05..c94038b7 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -702,6 +702,9 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, const char *name, uint16_t request_type, const getdns_dict *extensions, uint64_t *now_ms) { + int dnssec = is_extension_set( + extensions, "dnssec", + context->dnssec); int dnssec_return_status = is_extension_set( extensions, "dnssec_return_status", context->dnssec_return_status); @@ -728,7 +731,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, || is_extension_set(extensions, "dnssec_roadblock_avoidance", context->dnssec_roadblock_avoidance); #endif - int dnssec_extension_set = dnssec_return_status + int dnssec_extension_set = dnssec || dnssec_return_status || dnssec_return_only_secure || dnssec_return_all_statuses || dnssec_return_validation_chain || dnssec_return_full_validation_chain @@ -776,6 +779,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, int opportunistic = 0; if (extensions == no_dnssec_checking_disabled_opportunistic) { + dnssec = 0; dnssec_return_status = 0; dnssec_return_only_secure = 0; dnssec_return_all_statuses = 0; @@ -956,6 +960,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, result->context = context; result->loop = loop; result->trans_id = (uint64_t) (intptr_t) result; + result->dnssec = dnssec; result->dnssec_return_status = dnssec_return_status; result->dnssec_return_only_secure = dnssec_return_only_secure; result->dnssec_return_all_statuses = dnssec_return_all_statuses; diff --git a/src/tools/getdns_query.c b/src/tools/getdns_query.c index 3102ce1a..1ee253b7 100644 --- a/src/tools/getdns_query.c +++ b/src/tools/getdns_query.c @@ -183,6 +183,7 @@ print_usage(FILE *out, const char *progname) fprintf(out, "\ntsig spec: [:]:\n"); fprintf(out, "\nextensions:\n"); fprintf(out, "\t+add_warning_for_bad_dns\n"); + fprintf(out, "\t+dnssec\n"); fprintf(out, "\t+dnssec_return_status\n"); fprintf(out, "\t+dnssec_return_only_secure\n"); fprintf(out, "\t+dnssec_return_all_statuses\n"); diff --git a/src/types-internal.h b/src/types-internal.h index e36b1f60..12489e9c 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -299,6 +299,7 @@ typedef struct getdns_dns_req { unsigned suffix_appended : 1; /* request extensions */ + unsigned dnssec : 1; unsigned dnssec_return_status : 1; unsigned dnssec_return_only_secure : 1; unsigned dnssec_return_all_statuses : 1; diff --git a/src/util-internal.c b/src/util-internal.c index 0bceb002..2deefba0 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -1133,7 +1133,8 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request) if (!(result = getdns_dict_create_with_context(context))) return NULL; - dnssec_return_status = completed_request->dnssec_return_status || + dnssec_return_status = completed_request->dnssec || + completed_request->dnssec_return_status || completed_request->dnssec_return_only_secure || completed_request->dnssec_return_all_statuses #ifdef DNSSEC_ROADBLOCK_AVOIDANCE @@ -1210,6 +1211,9 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request) else if (completed_request->dnssec_return_only_secure && netreq->dnssec_status != GETDNS_DNSSEC_SECURE) continue; + else if (completed_request->dnssec && + netreq->dnssec_status == GETDNS_DNSSEC_INDETERMINATE) + continue; else if (netreq->tsig_status == GETDNS_DNSSEC_BOGUS) continue; } @@ -1287,9 +1291,11 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request) if (getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS, completed_request->request_timed_out || nreplies == 0 ? GETDNS_RESPSTATUS_ALL_TIMEOUT : - completed_request->dnssec_return_only_secure && nsecure == 0 && ninsecure > 0 + ( completed_request->dnssec_return_only_secure + || completed_request->dnssec ) && nsecure == 0 && ninsecure > 0 ? GETDNS_RESPSTATUS_NO_SECURE_ANSWERS : - completed_request->dnssec_return_only_secure && nsecure == 0 && nbogus > 0 + ( completed_request->dnssec_return_only_secure + || completed_request->dnssec ) && nsecure == 0 && nbogus > 0 ? GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS : nanswers == 0 ? GETDNS_RESPSTATUS_NO_NAME : GETDNS_RESPSTATUS_GOOD))