diff --git a/ChangeLog b/ChangeLog index 3ca53b2e..5133ba7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ -* 2018-??-??: Version 1.4.3 +* 2018-12-??: Version 1.5.0 + * ZONEMD rr-type * getdns_query queries for addresses when a query name without a type is given. * RFE #408: Fetching of trust anchors will be retried diff --git a/configure.ac b/configure.ac index 31d75a20..2c40affb 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,7 @@ sinclude(./m4/acx_getaddrinfo.m4) sinclude(./m4/ax_check_compile_flag.m4) sinclude(./m4/pkg.m4) -AC_INIT([getdns], [1.4.3], [team@getdnsapi.net], [getdns], [https://getdnsapi.net]) +AC_INIT([getdns], [1.5.0], [team@getdnsapi.net], [getdns], [https://getdnsapi.net]) # Autoconf 2.70 will have set up runstatedir. 2.69 is frequently (Debian) # patched to do the same, but frequently (MacOS) not. So add a with option @@ -63,13 +63,13 @@ AC_ARG_WITH([current-date], [CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"]) AC_SUBST(GETDNS_VERSION, ["AC_PACKAGE_VERSION$RELEASE_CANDIDATE"]) -AC_SUBST(GETDNS_NUMERIC_VERSION, [0x010402c1]) +AC_SUBST(GETDNS_NUMERIC_VERSION, [0x0104ffc1]) AC_SUBST(API_VERSION, ["December 2015"]) AC_SUBST(API_NUMERIC_VERSION, [0x07df0c00]) GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRENT_DATE for the $API_VERSION version of the API" AC_DEFINE_UNQUOTED([STUBBY_PACKAGE], ["stubby"], [Stubby package]) -AC_DEFINE_UNQUOTED([STUBBY_PACKAGE_STRING], ["0.2.3$STUBBY_RELEASE_CANDIDATE"], [Stubby package string]) +AC_DEFINE_UNQUOTED([STUBBY_PACKAGE_STRING], ["0.2.4$STUBBY_RELEASE_CANDIDATE"], [Stubby package string]) # Library version # --------------- @@ -106,7 +106,8 @@ AC_DEFINE_UNQUOTED([STUBBY_PACKAGE_STRING], ["0.2.3$STUBBY_RELEASE_CANDIDATE"], # getdns-1.4.0 had libversion 10:0:0 # getdns-1.4.1 had libversion 10:1:0 # getdns-1.4.2 has libversion 10:2:0 -GETDNS_LIBVERSION=10:2:0 +# getdns-1.5.0 will have libversion 11:0:1 +GETDNS_LIBVERSION=11:0:1 AC_SUBST(GETDNS_COMPILATION_COMMENT) AC_SUBST(GETDNS_LIBVERSION) diff --git a/src/anchor.c b/src/anchor.c index 950176a7..afdf1bf1 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -703,7 +703,7 @@ static uint8_t *tas_validate(struct mem_funcs *mf, success = NULL; } } else - DEBUG_ANCHOR("Could not allocate space for " + DEBUG_ANCHOR("Cannot allocate space for " "trust anchors\n"); } else { success = tas; @@ -736,57 +736,71 @@ void _getdns_context_equip_with_anchor( if ((r = getdns_context_get_trust_anchors_verify_CA( context, &verify_CA))) - DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify" - " CA: \"%s\"\n", __FUNC__ - , getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot get trust anchor verify CA: \"%s\"\n" + , getdns_get_errorstr_by_id(r)); else if (!verify_CA || !*verify_CA) - DEBUG_ANCHOR("NOTICE: Trust anchor verification explicitely " + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO + , "Trust anchor verification explicitely " "disabled by empty verify CA\n"); else if ((r = getdns_context_get_trust_anchors_verify_email( context, &verify_email))) - DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify email " - "address: \"%s\"\n", __FUNC__ - , getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot get trust anchor verify email address: " + "\"%s\"\n", getdns_get_errorstr_by_id(r)); else if (!verify_email || !*verify_email) - DEBUG_ANCHOR("NOTICE: Trust anchor verification explicitely " + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO + , "Trust anchor verification explicitely " "disabled by empty verify email\n"); else if (!(xml_data = _getdns_context_get_priv_file(context, "root-anchors.xml", xml_spc, sizeof(xml_spc), &xml_len))) - DEBUG_ANCHOR("DEBUG %s(): root-anchors.xml not present\n" - , __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG + , "root-anchors.xml not present\n"); else if (!(p7s_data = _getdns_context_get_priv_file(context, "root-anchors.p7s", p7s_spc, sizeof(p7s_spc), &p7s_len))) - DEBUG_ANCHOR("DEBUG %s(): root-anchors.p7s not present\n" - , __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO + , "root-anchors.xml not present\n"); else if (!(xml = BIO_new_mem_buf(xml_data, xml_len))) - DEBUG_ANCHOR("ERROR %s(): Failed allocating xml BIO\n" - , __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Failed allocating xml BIO\n"); else if (!(p7s = BIO_new_mem_buf(p7s_data, p7s_len))) - DEBUG_ANCHOR("ERROR %s(): Failed allocating p7s BIO\n" - , __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Failed allocating p7s BIO\n"); else if (!(crt = BIO_new_mem_buf((void *)verify_CA, -1))) - DEBUG_ANCHOR("ERROR %s(): Failed allocating crt BIO\n" - , __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Failed allocating crt BIO\n"); else if (!(x = PEM_read_bio_X509(crt, NULL, 0, NULL))) - DEBUG_ANCHOR("ERROR %s(): Parsing builtin certificate\n" - , __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot parse builtin certificate\n"); else if (!(store = X509_STORE_new())) - DEBUG_ANCHOR("ERROR %s(): Failed allocating store\n" - , __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Failed allocating X509 store\n"); else if (!X509_STORE_add_cert(store, x)) - DEBUG_ANCHOR("ERROR %s(): Adding certificate to store\n" - , __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot add certificate to X509 store\n"); else if (_getdns_verify_p7sig(xml, p7s, store, verify_email)) { uint8_t ta_spc[sizeof(context->trust_anchors_spc)]; @@ -799,15 +813,21 @@ void _getdns_context_equip_with_anchor( if (!_getdns_parse_xml_trust_anchors_buf(&gbuf, now_ms, (char *)xml_data, xml_len)) - DEBUG_ANCHOR("Failed to parse trust anchor XML data"); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Failed to parse trust anchor XML data\n"); + else if ((ta_len = gldns_buffer_position(&gbuf)) > sizeof(ta_spc)) { if ((ta = GETDNS_XMALLOC(context->mf, uint8_t, ta_len))) { gldns_buffer_init_frm_data(&gbuf, ta, gldns_buffer_position(&gbuf)); if (!_getdns_parse_xml_trust_anchors_buf( &gbuf, now_ms, (char *)xml_data, xml_len)) { - DEBUG_ANCHOR("Failed to re-parse trust" - " anchor XML data"); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR + , GETDNS_LOG_ERR + , "Error re-parsing trust " + "anchor XML data\n"); GETDNS_FREE(context->mf, ta); } else { context->trust_anchors = ta; @@ -816,7 +836,11 @@ void _getdns_context_equip_with_anchor( _getdns_ta_notify_dnsreqs(context); } } else - DEBUG_ANCHOR("Could not allocate space for XML file"); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR + , GETDNS_LOG_ERR + , "Cannot allocate space for " + "XML file"); } else { (void)memcpy(context->trust_anchors_spc, ta_spc, ta_len); context->trust_anchors = context->trust_anchors_spc; @@ -828,7 +852,9 @@ void _getdns_context_equip_with_anchor( (void *)context->trust_anchors, (int)context->trust_anchors_len); } else { - DEBUG_ANCHOR("Verifying trust-anchors failed!\n"); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Verifying trust-anchors XML failed!\n"); } if (store) X509_STORE_free(store); if (x) X509_free(x); @@ -855,10 +881,8 @@ static const char tas_write_xml_p7s_buf[] = "\r\n"; -#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG static inline const char * rt_str(uint16_t rt) { return rt == GETDNS_RRTYPE_A ? "A" : rt == GETDNS_RRTYPE_AAAA ? "AAAA" : "?"; } -#endif static int tas_busy(tas_connection *a) { @@ -905,7 +929,8 @@ static void tas_success(getdns_context *context, tas_connection *a) tas_cleanup(context, a); tas_cleanup(context, other); - DEBUG_ANCHOR("Successfully fetched new trust anchors\n"); + _getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO + , "Successfully fetched new trust anchors\n"); context->trust_anchors_source = GETDNS_TASRC_XML; _getdns_ta_notify_dnsreqs(context); } @@ -913,22 +938,26 @@ static void tas_success(getdns_context *context, tas_connection *a) static void tas_fail(getdns_context *context, tas_connection *a) { tas_connection *other = &context->a == a ? &context->aaaa : &context->a; -#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG uint16_t rt = &context->a == a ? GETDNS_RRTYPE_A : GETDNS_RRTYPE_AAAA; - uint16_t ort = rt == GETDNS_RRTYPE_A ? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A; -#endif + tas_cleanup(context, a); if (!tas_busy(other)) { - DEBUG_ANCHOR("Fatal error fetching trust anchor: " + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Fatal error fetching trust anchor: " "%s connection failed too\n", rt_str(rt)); context->trust_anchors_source = GETDNS_TASRC_FAILED; context->trust_anchors_backoff_expiry = _getdns_get_now_ms() + context->trust_anchors_backoff_time; _getdns_ta_notify_dnsreqs(context); } else - DEBUG_ANCHOR("%s connection failed, waiting for %s\n" - , rt_str(rt), rt_str(ort)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING + , "%s connection failed, waiting for %s\n" + , rt_str(rt) + , rt_str( rt == GETDNS_RRTYPE_A + ? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A)); } static void tas_connect(getdns_context *context, tas_connection *a); @@ -960,7 +989,9 @@ static void tas_timeout_cb(void *userarg) a = &context->a; else a = &context->aaaa; - DEBUG_ANCHOR("Trust anchor fetch timeout\n"); + _getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING + , "Trust anchor fetch timeout\n"); + GETDNS_CLEAR_EVENT(a->loop, &a->event); tas_next(context, a); } @@ -976,7 +1007,9 @@ static void tas_reconnect_cb(void *userarg) a = &context->a; else a = &context->aaaa; - DEBUG_ANCHOR("Waiting for second document timeout. Reconnecting...\n"); + _getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG + , "Waiting for second document timeout. Reconnecting...\n"); + GETDNS_CLEAR_EVENT(a->loop, &a->event); close(a->fd); a->fd = -1; @@ -991,8 +1024,6 @@ static void tas_read_cb(void *userarg); static void tas_write_cb(void *userarg); static void tas_doc_read(getdns_context *context, tas_connection *a) { - DEBUG_ANCHOR("doc (size: %d)\n", (int)a->tcp.read_buf_len); - assert(a->tcp.read_pos == a->tcp.read_buf + a->tcp.read_buf_len); assert(context); @@ -1021,18 +1052,20 @@ static void tas_doc_read(getdns_context *context, tas_connection *a) if ((r = getdns_context_get_trust_anchors_verify_CA( context, (const char **)&verify_CA.data))) - DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify" - " CA: \"%s\"\n", __FUNC__ - , getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot get trust anchor verify CA: " + "\"%s\"\n", getdns_get_errorstr_by_id(r)); else if (!(verify_CA.size = strlen((const char *)verify_CA.data))) ; /* pass */ else if ((r = getdns_context_get_trust_anchors_verify_email( context, &verify_email))) - DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify" - " email address: \"%s\"\n", __FUNC__ - , getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot get trust anchor verify email: " + "\"%s\"\n", getdns_get_errorstr_by_id(r)); else if (!(tas = tas_validate(&context->mf, &a->xml, &p7s_bd, &verify_CA, verify_email, &now_ms, tas, &tas_len))) @@ -1157,7 +1190,11 @@ static void tas_read_cb(void *userarg) DEBUG_ANCHOR("i: %d, n: %d, doc_len: %d\n" , (int)i, (int)n, doc_len); if (!doc) - DEBUG_ANCHOR("Memory error"); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR + , GETDNS_LOG_ERR + , "Memory error while reading " + "trust anchor\n"); else { ssize_t surplus = n - i; @@ -1204,7 +1241,11 @@ static void tas_read_cb(void *userarg) } else if (_getdns_socketerror_wants_retry()) return; - DEBUG_ANCHOR("Read error: %d %s\n", (int)n, _getdns_errnostr()); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error while receiving trust anchor: %s\n" + , _getdns_errnostr()); + GETDNS_CLEAR_EVENT(a->loop, &a->event); tas_next(context, a); } @@ -1254,7 +1295,9 @@ static void tas_write_cb(void *userarg) } else if (_getdns_socketerror_wants_retry()) return; - DEBUG_ANCHOR("Write error: %s\n", _getdns_errnostr()); + _getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error while sending to trust anchor site: %s\n" + , _getdns_errnostr()); GETDNS_CLEAR_EVENT(a->loop, &a->event); tas_next(context, a); } @@ -1293,9 +1336,7 @@ static getdns_return_t _getdns_get_tas_url_hostname( static void tas_connect(getdns_context *context, tas_connection *a) { -#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG char a_buf[40]; -#endif int r; #ifdef HAVE_FCNTL @@ -1311,15 +1352,19 @@ static void tas_connect(getdns_context *context, tas_connection *a) tas_next(context, a); return; } - DEBUG_ANCHOR("Initiating connection to %s\n" - , inet_ntop(( a->req->request_type == GETDNS_RRTYPE_A - ? AF_INET : AF_INET6) - , a->rr->rr_i.rr_type + 10, a_buf, sizeof(a_buf))); + + _getdns_log( &context->log, GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG + , "Setting op connection to: %s\n" + , inet_ntop( ( a->req->request_type == GETDNS_RRTYPE_A + ? AF_INET : AF_INET6) + , a->rr->rr_i.rr_type + 10 + , a_buf, sizeof(a_buf))); if ((a->fd = socket(( a->req->request_type == GETDNS_RRTYPE_A ? AF_INET : AF_INET6), SOCK_STREAM, IPPROTO_TCP)) == -1) { - DEBUG_ANCHOR("Error creating socket: %s\n", - _getdns_errnostr()); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error creating socket: %s\n", _getdns_errnostr()); tas_next(context, a); return; } @@ -1370,9 +1415,11 @@ static void tas_connect(getdns_context *context, tas_connection *a) } if ((R = _getdns_get_tas_url_hostname( context, tas_hostname, &path))) { - DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname" - ": \"%s\"", __FUNC__ - , getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot get hostname from trust anchor " + "url: \"%s\"\n" + , getdns_get_errorstr_by_id(r)); goto error; } hostname_len = strlen(tas_hostname); @@ -1380,8 +1427,10 @@ static void tas_connect(getdns_context *context, tas_connection *a) tas_hostname[--hostname_len] = '\0'; path_len = strlen(path); if (path_len < 4) { - DEBUG_ANCHOR("ERROR %s(): path of tas_url \"%s\" too " - "small\n", __FUNC__, path); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Trust anchor path \"%s\" too small\n" + , path); goto error; } if (a->state == TAS_RETRY_GET_PS7) { @@ -1394,8 +1443,10 @@ static void tas_connect(getdns_context *context, tas_connection *a) fmt = tas_write_xml_p7s_buf; } if (!(write_buf = GETDNS_XMALLOC(context->mf, char, buf_sz))) { - DEBUG_ANCHOR("ERROR %s(): Could not allocate write " - "buffer\n", __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot allocate write buffer for " + "sending to trust anchor host\n"); goto error; } if (a->state == TAS_RETRY_GET_PS7) { @@ -1429,8 +1480,10 @@ static void tas_connect(getdns_context *context, tas_connection *a) DEBUG_ANCHOR("Scheduled write with event\n"); return; } else - DEBUG_ANCHOR("Connect error: %s\n", _getdns_errnostr()); - + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error connecting to trust anchor host: %s\n " + , _getdns_errnostr()); error: tas_next(context, a); } @@ -1444,7 +1497,10 @@ static void tas_happy_eyeballs_cb(void *userarg) if (tas_fetching(&context->aaaa)) return; else { - DEBUG_ANCHOR("AAAA came too late, clearing Happy Eyeballs timer\n"); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG + , "Too late reception of AAAA for trust anchor " + "host for Happy Eyeballs\n"); GETDNS_CLEAR_EVENT(context->a.loop, &context->a.event); tas_connect(context, &context->a); } @@ -1463,28 +1519,31 @@ static void _tas_hostname_lookup_cb(getdns_dns_req *dnsreq) &a->rrset_spc, a->req->response, a->req->response_len); if (!a->rrset) { -#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG char tas_hostname[256] = ""; (void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL); - DEBUG_ANCHOR("%s lookup for %s returned no response\n" + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG + , "%s lookup for %s returned no response\n" , rt_str(a->req->request_type), tas_hostname); -#endif + } else if (a->req->response_len < dnsreq->name_len + 12 || !_getdns_dname_equal(a->req->response + 12, dnsreq->name) || a->rrset->rr_type != a->req->request_type) { -#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG char tas_hostname[256] = ""; (void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL); - DEBUG_ANCHOR("%s lookup for %s returned wrong response\n" + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG + , "%s lookup for %s returned wrong response\n" , rt_str(a->req->request_type), tas_hostname); -#endif + } else if (!(a->rr = _getdns_rrtype_iter_init(&a->rr_spc, a->rrset))) { -#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG char tas_hostname[256] = ""; (void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL); - DEBUG_ANCHOR("%s lookup for %s returned no addresses\n" + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG + , "%s lookup for %s returned no addresses\n" , rt_str(a->req->request_type), tas_hostname); -#endif + } else { tas_connection *other = a == &context->a ? &context->aaaa : &context->a; @@ -1494,8 +1553,9 @@ static void _tas_hostname_lookup_cb(getdns_dns_req *dnsreq) ; /* pass */ else if (a == &context->a && tas_busy(other)) { - DEBUG_ANCHOR("Postponing connection initiation: " - "Happy Eyeballs\n"); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG + , "Waiting 25ms for AAAA to arrive\n"); GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 25, getdns_eventloop_event_init(&a->event, a->req->owner, NULL, NULL, tas_happy_eyeballs_cb)); @@ -1522,38 +1582,47 @@ void _getdns_start_fetching_ta( const char *verify_email; if ((r = _getdns_get_tas_url_hostname(context, tas_hostname, NULL))) { - DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname" - ": \"%s\"", __FUNC__ - , getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot get hostname from trust anchor url: " + "\"%s\"\n", getdns_get_errorstr_by_id(r)); return; } else if ((r = getdns_context_get_trust_anchors_verify_CA( context, &verify_CA))) { - DEBUG_ANCHOR("ERROR %s(): Could not get verify CA" - ": \"%s\"", __FUNC__ - , getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot get trust anchor verify CA: \"%s\"\n" + , getdns_get_errorstr_by_id(r)); return; } else if (!verify_CA || !*verify_CA) { - DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely " + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO + , "Trust anchor verification explicitely " "disabled by empty verify CA\n"); return; } else if ((r = getdns_context_get_trust_anchors_verify_email( context, &verify_email))) { - DEBUG_ANCHOR("ERROR %s(): Could not get verify email address" - ": \"%s\"", __FUNC__ - , getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Cannot get trust anchor verify email: \"%s\"\n" + , getdns_get_errorstr_by_id(r)); return; } else if (!verify_email || !*verify_email) { - DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely " - "disabled by empty verify email address\n"); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO + , "Trust anchor verification explicitely " + "disabled by empty verify email\n"); return; } else if (!_getdns_context_can_write_appdata(context)) { - DEBUG_ANCHOR("NOTICE %s(): Not fetching TA, because " - "non writeable appdata directory\n", __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING + , "Not fetching TA, because " + "non writeable appdata directory\n"); return; } DEBUG_ANCHOR("Hostname: %s\n", tas_hostname); @@ -1561,34 +1630,36 @@ void _getdns_start_fetching_ta( loop == &context->sync_eventloop.loop ? "" : "a"); scheduled = 0; -#if 1 context->a.state = TAS_LOOKUP_ADDRESSES; if ((r = _getdns_general_loop(context, loop, tas_hostname, GETDNS_RRTYPE_A, no_dnssec_checking_disabled_opportunistic, context, &context->a.req, NULL, _tas_hostname_lookup_cb))) { - DEBUG_ANCHOR("Error scheduling A lookup for %s: %s\n" - , tas_hostname, getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING + , "Error scheduling A lookup for %s: %s\n" + , tas_hostname, getdns_get_errorstr_by_id(r)); } else scheduled += 1; -#endif -#if 1 context->aaaa.state = TAS_LOOKUP_ADDRESSES; if ((r = _getdns_general_loop(context, loop, tas_hostname, GETDNS_RRTYPE_AAAA, no_dnssec_checking_disabled_opportunistic, context, &context->aaaa.req, NULL, _tas_hostname_lookup_cb))) { - DEBUG_ANCHOR("Error scheduling AAAA lookup for %s: %s\n" - , tas_hostname, getdns_get_errorstr_by_id(r)); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING + , "Error scheduling AAAA lookup for %s: %s\n" + , tas_hostname, getdns_get_errorstr_by_id(r)); } else scheduled += 1; -#endif if (!scheduled) { - DEBUG_ANCHOR("Fatal error fetching trust anchor: Unable to " - "schedule address requests for %s\n" - , tas_hostname); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_WARNING + , "Error scheduling address lookups for %s\n" + , tas_hostname); + context->trust_anchors_source = GETDNS_TASRC_FAILED; if (now_ms) { if (*now_ms == 0) *now_ms = _getdns_get_now_ms(); @@ -1713,7 +1784,10 @@ static void _getdns_context_read_root_ksk(getdns_context *context) buf_sz *= 2; } if (!(buf = GETDNS_XMALLOC(context->mf, uint8_t, buf_sz))) { - DEBUG_ANCHOR("ERROR %s(): Memory error\n", __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error allocating memory to read " + "root.key\n"); break;; } ptr = buf; @@ -1798,8 +1872,10 @@ _getdns_context_update_root_ksk( break; } if (str_buf != str_spc) { - DEBUG_ANCHOR("ERROR %s(): Buffer size determination " - "error\n", __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error determining buffer size for root " + "KSK\n"); if (str_buf) GETDNS_FREE(context->mf, str_buf); @@ -1807,11 +1883,13 @@ _getdns_context_update_root_ksk( } if (!(str_pos = str_buf = GETDNS_XMALLOC( context->mf, char, (str_sz = sizeof(str_spc) - remaining) + 1))) { - DEBUG_ANCHOR("ERROR %s(): Memory error\n", __FUNC__); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error allocating memory to read " + "root KSK\n"); return; } remaining = str_sz + 1; - DEBUG_ANCHOR("Retrying with buf size: %d\n", remaining); }; /* Write presentation format DNSKEY rrset to "root.key" file */ @@ -1886,17 +1964,21 @@ _getdns_context_update_root_ksk( break; } if (!ta) { - DEBUG_ANCHOR("NOTICE %s(): Key with id %d " - "*not* found in TA.\n" - "\"root-anchors.xml\" need " - "updating.\n", __FUNC__ + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR + , GETDNS_LOG_NOTICE + , "Key with id %d not found in TA; " + "\"root-anchors.xml\" needs to be " + "updated.\n" , context->root_ksk.ids[i]); context->trust_anchors_source = GETDNS_TASRC_XML_UPDATE; break; } - DEBUG_ANCHOR("DEBUG %s(): Key with id %d found in TA\n" - , __FUNC__, context->root_ksk.ids[i]); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_DEBUG + , "Key with id %d found in TA\n" + , context->root_ksk.ids[i]); } } if (str_buf && str_buf != str_spc) diff --git a/src/const-info.c b/src/const-info.c index f6f0d18b..ebff80a4 100644 --- a/src/const-info.c +++ b/src/const-info.c @@ -124,7 +124,11 @@ static struct const_info consts_info[] = { { 1402, "GETDNS_TLS1_1", GETDNS_TLS1_1_TEXT }, { 1403, "GETDNS_TLS1_2", GETDNS_TLS1_2_TEXT }, { 1404, "GETDNS_TLS1_3", GETDNS_TLS1_3_TEXT }, - { 4096, "GETDNS_LOG_UPSTREAM_STATS", GETDNS_LOG_UPSTREAM_STATS_TEXT }, + { 8192, "GETDNS_LOG_SYS_STUB", GETDNS_LOG_SYS_STUB_TEXT }, + { 12288, "GETDNS_LOG_UPSTREAM_STATS", GETDNS_LOG_UPSTREAM_STATS_TEXT }, + { 16384, "GETDNS_LOG_SYS_RECURSING", GETDNS_LOG_SYS_RECURSING_TEXT }, + { 24576, "GETDNS_LOG_SYS_RESOLVING", GETDNS_LOG_SYS_RESOLVING_TEXT }, + { 32768, "GETDNS_LOG_SYS_ANCHOR", GETDNS_LOG_SYS_ANCHOR_TEXT }, }; static int const_info_cmp(const void *a, const void *b) @@ -225,7 +229,11 @@ static struct const_name_info consts_name_info[] = { { "GETDNS_LOG_ERR", 3 }, { "GETDNS_LOG_INFO", 6 }, { "GETDNS_LOG_NOTICE", 5 }, - { "GETDNS_LOG_UPSTREAM_STATS", 4096 }, + { "GETDNS_LOG_SYS_ANCHOR", 32768 }, + { "GETDNS_LOG_SYS_RECURSING", 16384 }, + { "GETDNS_LOG_SYS_RESOLVING", 24576 }, + { "GETDNS_LOG_SYS_STUB", 8192 }, + { "GETDNS_LOG_UPSTREAM_STATS", 12288 }, { "GETDNS_LOG_WARNING", 4 }, { "GETDNS_NAMESPACE_DNS", 500 }, { "GETDNS_NAMESPACE_LOCALNAMES", 501 }, @@ -376,6 +384,7 @@ static struct const_name_info consts_name_info[] = { { "GETDNS_RRTYPE_URI", 256 }, { "GETDNS_RRTYPE_WKS", 11 }, { "GETDNS_RRTYPE_X25", 19 }, + { "GETDNS_RRTYPE_ZONEMD", 63 }, { "GETDNS_SSL3", 1400 }, { "GETDNS_TLS1", 1401 }, { "GETDNS_TLS1_1", 1402 }, diff --git a/src/context.c b/src/context.c index b1b36231..aaea6d59 100644 --- a/src/context.c +++ b/src/context.c @@ -127,15 +127,15 @@ typedef struct host_name_addrs { } host_name_addrs; -/* If changing these lists also remember to +/* If changing these lists also remember to change the value of GETDNS_UPSTREAM_TRANSPORTS */ -static getdns_transport_list_t +static getdns_transport_list_t getdns_upstream_transports[GETDNS_UPSTREAM_TRANSPORTS] = { GETDNS_TRANSPORT_TCP, GETDNS_TRANSPORT_TLS, }; -static in_port_t +static in_port_t getdns_port_array[GETDNS_UPSTREAM_TRANSPORTS] = { GETDNS_PORT_DNS, GETDNS_PORT_DNS_OVER_TLS @@ -183,22 +183,23 @@ _getdns_strdup2(const struct mem_funcs *mfs, const getdns_bindata *s) } #ifdef USE_WINSOCK -/* For windows, the CA trust store is not read by openssl. +/* For windows, the CA trust store is not read by openssl. Add code to open the trust store using wincrypt API and add the root certs into openssl trust store */ -static int -add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) +static int +add_WIN_cacerts_to_openssl_store(getdns_context *ctxt, SSL_CTX* tls_ctx) { HCERTSTORE hSystemStore; PCCERT_CONTEXT pTargetCert = NULL; - - DEBUG_STUB("%s %-35s: %s\n", STUB_DEBUG_SETUP_TLS, __FUNC__, - "Adding Windows certificates from system root store to CA store"); + + _getdns_log(&ctxt->log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_DEBUG + , "%s: %s\n", STUB_DEBUG_SETUP_TLS, + , "Adding Windows certificates from system root store to CA store") + ; /* load just once per context lifetime for this version of getdns TODO: dynamically update CA trust changes as they are available */ - if (!tls_ctx) - return 0; + assert(tls_ctx); /* Call wincrypt's CertOpenStore to open the CA root store. */ @@ -206,50 +207,69 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) CERT_STORE_PROV_SYSTEM, 0, 0, - /* NOTE: mingw does not have this const: replace with 1 << 16 from code + /* NOTE: mingw does not have this const: replace with 1 << 16 from code CERT_SYSTEM_STORE_CURRENT_USER, */ 1 << 16, L"root")) == 0) { + _getdns_log(&ctxt->log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s\n", STUB_DEBUG_SETUP_TLS + , "Could not CertOpenStore()"); return 0; } X509_STORE* store = SSL_CTX_get_cert_store(tls_ctx); - if (!store) + if (!store) { + _getdns_log(&ctxt->log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s\n", STUB_DEBUG_SETUP_TLS + , "Could not SSL_CTX_get_cert_store()"); return 0; + } /* failure if the CA store is empty or the call fails */ if ((pTargetCert = CertEnumCertificatesInStore( - hSystemStore, pTargetCert)) == 0) { - DEBUG_STUB("%s %-35s: %s\n", STUB_DEBUG_SETUP_TLS, __FUNC__, - "CA certificate store for Windows is empty."); - return 0; + hSystemStore, pTargetCert)) == 0) { + _getdns_log(&ctxt->log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_NOTICE + , "%s: %s\n", STUB_DEBUG_SETUP_TLS + , "CA certificate store for Windows is empty."); + return 0; } /* iterate over the windows cert store and add to openssl store */ - do + do { - X509 *cert1 = d2i_X509(NULL, + X509 *cert1 = d2i_X509(NULL, (const unsigned char **)&pTargetCert->pbCertEncoded, pTargetCert->cbCertEncoded); if (!cert1) { /* return error if a cert fails */ - DEBUG_STUB("%s %-35s: %s %d:%s\n", STUB_DEBUG_SETUP_TLS, __FUNC__, - "Unable to parse certificate in memory", - ERR_get_error(), ERR_error_string(ERR_get_error(), NULL)); + _getdns_log(&ctxt->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR, + , "%s: %s %d:%s\n" + , STUB_DEBUG_SETUP_TLS + , "Unable to parse certificate in memory" + , ERR_get_error() + , ERR_error_string(ERR_get_error(), NULL)); return 0; } else { /* return error if a cert add to store fails */ if (X509_STORE_add_cert(store, cert1) == 0) { unsigned long error = ERR_peek_last_error(); - + /* Ignore error X509_R_CERT_ALREADY_IN_HASH_TABLE which means the - * certificate is already in the store. */ + * certificate is already in the store. */ if(ERR_GET_LIB(error) != ERR_LIB_X509 || ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) { - DEBUG_STUB("%s %-35s: %s %d:%s\n", STUB_DEBUG_SETUP_TLS, __FUNC__, - "Error adding certificate", ERR_get_error(), - ERR_error_string(ERR_get_error(), NULL)); + _getdns_log(&ctxt->log + , GETDNS_LOG_SYS_STUB + , GETDNS_LOG_ERR + , "%s: %s %d:%s\n" + , STUB_DEBUG_SETUP_TLS + , "Error adding certificate" + , ERR_get_error() + , ERR_error_string( ERR_get_error() + , NULL) + ); X509_free(cert1); return 0; } @@ -264,12 +284,18 @@ add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) CertFreeCertificateContext(pTargetCert); if (hSystemStore) { - if (!CertCloseStore( - hSystemStore, 0)) + if (!CertCloseStore(hSystemStore, 0)) { + _getdns_log(&ctxt->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s\n", STUB_DEBUG_SETUP_TLS + , "Could not CertCloseStore()"); return 0; + } } - DEBUG_STUB("%s %-35s: %s\n", STUB_DEBUG_SETUP_TLS, __FUNC__, - "Completed adding Windows certificates to CA store successfully"); + _getdns_log(&ctxt->log, GETDNS_LOG_SYS_STUB, GETDNS_LOG_INFO + , "%s: %s\n", STUB_DEBUG_SETUP_TLS + , "Completed adding Windows certificates to CA store successfully") + ; return 1; } #endif @@ -304,16 +330,15 @@ static void destroy_local_host(_getdns_rbnode_t * node, void *arg) * TODO: Determine from OS */ static getdns_return_t -create_default_namespaces(struct getdns_context *context) +create_default_namespaces(getdns_context *context) { - context->namespaces = GETDNS_XMALLOC(context->my_mf, getdns_namespace_t, 2); - if(context->namespaces == NULL) - return GETDNS_RETURN_GENERIC_ERROR; + if (!( context->namespaces + = GETDNS_XMALLOC(context->my_mf, getdns_namespace_t, 2))) + return GETDNS_RETURN_MEMORY_ERROR; context->namespaces[0] = GETDNS_NAMESPACE_LOCALNAMES; context->namespaces[1] = GETDNS_NAMESPACE_DNS; context->namespace_count = 2; - return GETDNS_RETURN_GOOD; } @@ -321,11 +346,11 @@ create_default_namespaces(struct getdns_context *context) * Helper to get default transports. */ static getdns_return_t -create_default_dns_transports(struct getdns_context *context) +create_default_dns_transports(getdns_context *context) { - context->dns_transports = GETDNS_XMALLOC(context->my_mf, getdns_transport_list_t, 2); - if(context->dns_transports == NULL) - return GETDNS_RETURN_GENERIC_ERROR; + if (!( context->dns_transports + = GETDNS_XMALLOC(context->my_mf, getdns_transport_list_t, 2))) + return GETDNS_RETURN_MEMORY_ERROR; context->dns_transports[0] = GETDNS_TRANSPORT_UDP; context->dns_transports[1] = GETDNS_TRANSPORT_TCP; @@ -389,7 +414,7 @@ local_host_cmp(const void *id1, const void *id2) } /** return 0 on success */ -static int +static getdns_return_t add_local_host(getdns_context *context, getdns_dict *address, const char *str) { uint8_t host_name[256]; @@ -398,9 +423,10 @@ add_local_host(getdns_context *context, getdns_dict *address, const char *str) getdns_bindata *address_type; int hnas_found = 0; getdns_list **addrs; + getdns_return_t r; if (gldns_str2wire_dname_buf(str, host_name, &host_name_len)) - return -1; + return GETDNS_RETURN_BAD_DOMAIN_NAME; canonicalize_dname(host_name); @@ -409,7 +435,7 @@ add_local_host(getdns_context *context, getdns_dict *address, const char *str) if (!(hnas = (host_name_addrs *)GETDNS_XMALLOC(context->mf, uint8_t, sizeof(host_name_addrs) + host_name_len))) - return -1; + return GETDNS_RETURN_MEMORY_ERROR; hnas->ipv4addrs = NULL; hnas->ipv6addrs = NULL; @@ -419,35 +445,33 @@ add_local_host(getdns_context *context, getdns_dict *address, const char *str) } else hnas_found = 1; - if (getdns_dict_get_bindata(address, "address_type", &address_type) || - - address_type->size < 4 || - - !(addrs = address_type->data[3] == '4'? &hnas->ipv4addrs + if ((r = getdns_dict_get_bindata(address,"address_type",&address_type)) + || address_type->size < 4 + || !(addrs = address_type->data[3] == '4'? &hnas->ipv4addrs : address_type->data[3] == '6'? &hnas->ipv4addrs : NULL)) { if (!hnas_found) GETDNS_FREE(context->mf, hnas); - return -1; + return r ? r : GETDNS_RETURN_WRONG_TYPE_REQUESTED; } if (!*addrs && !(*addrs = getdns_list_create_with_context(context))) { if (!hnas_found) GETDNS_FREE(context->mf, hnas); - return -1; + return GETDNS_RETURN_MEMORY_ERROR; } - if (_getdns_list_append_this_dict(*addrs, address)) { + if ((r = _getdns_list_append_this_dict(*addrs, address))) { if (!hnas_found) { getdns_list_destroy(*addrs); GETDNS_FREE(context->mf, hnas); } - return -1; + return r; } else if (!hnas_found) (void)_getdns_rbtree_insert(&context->local_hosts, &hnas->node); - return 0; + return GETDNS_RETURN_GOOD; } static getdns_dict * -sockaddr_dict(getdns_context *context, struct sockaddr *sa) +sockaddr_dict(const getdns_context *context, struct sockaddr *sa) { getdns_dict *address = getdns_dict_create_with_context(context); char addrstr[1024], *b; @@ -565,7 +589,7 @@ getdns_return_t getdns_context_set_hosts(getdns_context *context, const char *hosts) { /* enough space in buf for longest allowed domain name */ - char buf[1024]; + char buf[2048]; char *pos = buf, prev_c, *start_of_word = NULL; FILE *in; int start_of_line = 1; @@ -577,7 +601,7 @@ getdns_context_set_hosts(getdns_context *context, const char *hosts) if (!(in = fopen(hosts, "r"))) return GETDNS_RETURN_IO_ERROR; - (void)strlcpy(context->fchg_hosts.fn, hosts, _GETDNS_PATH_MAX); + (void) strlcpy(context->fchg_hosts.fn, hosts, _GETDNS_PATH_MAX); (void) memset(&context->fchg_hosts.prevstat, 0, sizeof(struct stat)); context->fchg_hosts.changes = GETDNS_FCHG_NOCHANGES; context->fchg_hosts.errors = GETDNS_FCHG_NOERROR; @@ -591,7 +615,7 @@ getdns_context_set_hosts(getdns_context *context, const char *hosts) /* Break out of for to read more */ for (;;) { /* Skip whitespace */ - while (*pos == ' ' || *pos == '\f' + while (*pos == ' ' || *pos == '\f' || *pos == '\t' || *pos == '\v') pos++; @@ -630,7 +654,7 @@ getdns_context_set_hosts(getdns_context *context, const char *hosts) *pos = '\0'; if (start_of_line) { start_of_line = 0; - if (address) + if (address) getdns_dict_destroy(address); if (!(address = str_addr_dict(context, start_of_word))) @@ -669,7 +693,7 @@ read_more: ; } getdns_return_t -getdns_context_get_hosts(getdns_context *context, const char **hosts) +getdns_context_get_hosts(const getdns_context *context, const char **hosts) { if (!context || !hosts) return GETDNS_RETURN_INVALID_PARAMETER; @@ -685,39 +709,22 @@ upstreams_create(getdns_context *context, size_t size) getdns_upstreams *r = (void *) GETDNS_XMALLOC(context->mf, char, sizeof(getdns_upstreams) + sizeof(getdns_upstream) * size); - r->mf = context->mf; - r->referenced = 1; - r->count = 0; - r->current_udp = 0; - r->current_stateful = 0; - r->max_backoff_value = context->max_backoff_value; - r->tls_backoff_time = context->tls_backoff_time; - r->tls_connection_retries = context->tls_connection_retries; - r->log = context->log; + + if (r) { + r->mf = context->mf; + r->referenced = 1; + r->count = 0; + r->current_udp = 0; + r->current_stateful = 0; + r->max_backoff_value = context->max_backoff_value; + r->tls_backoff_time = context->tls_backoff_time; + r->tls_connection_retries = context->tls_connection_retries; + r->log = context->log; + } return r; } -#if defined(USE_DANESSL) && defined(STUB_DEBUG) && STUB_DEBUG -static void _stub_debug_print_openssl_errors(void) -{ - unsigned long err; - char buffer[1024]; - const char *file; - const char *data; - int line; - int flags; - - while ((err = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { - ERR_error_string_n(err, buffer, sizeof(buffer)); - if (flags & ERR_TXT_STRING) - DEBUG_STUB("DEBUG OpenSSL Error: %s:%s:%d:%s\n", buffer, file, line, data); - else - DEBUG_STUB("DEBUG OpenSSL Error: %s:%s:%d\n", buffer, file, line); - } -} -#endif - void _getdns_upstreams_dereference(getdns_upstreams *upstreams) { @@ -760,9 +767,6 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams) if (upstream->tls_obj != NULL) { SSL_shutdown(upstream->tls_obj); #ifdef USE_DANESSL -# if defined(STUB_DEBUG) && STUB_DEBUG - _stub_debug_print_openssl_errors(); -# endif DANESSL_cleanup(upstream->tls_obj); #endif SSL_free(upstream->tls_obj); @@ -789,22 +793,6 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams) GETDNS_FREE(upstreams->mf, upstreams); } -void _getdns_upstream_log(getdns_upstream *upstream, uint64_t system, - getdns_loglevel_type level, const char *fmt, ...) -{ - va_list args; - - if (!upstream || !upstream->upstreams || !upstream->upstreams->log.func - || !(upstream->upstreams->log.system & system) - || level > upstream->upstreams->log.level) - return; - - va_start(args, fmt); - upstream->upstreams->log.func( - upstream->upstreams->log.userarg, system, level, fmt, args); - va_end(args); -} - static void upstream_backoff(getdns_upstream *upstream) { upstream->conn_state = GETDNS_CONN_BACKOFF; @@ -837,8 +825,8 @@ static void _getdns_upstream_reset(getdns_upstream *upstream) { /* Back off connections that never got up service at all (probably no - TCP service or incompatible TLS version/cipher). - Leave choice between working upstreams to the stub. + TCP service or incompatible TLS version/cipher). + Leave choice between working upstreams to the stub. This back-off should be time based for TLS according to RFC7858. For now, use the same basis if we simply can't get TCP service either.*/ /* [TLS1]TODO: This arbitrary logic at the moment - review and improve!*/ @@ -852,16 +840,16 @@ _getdns_upstream_reset(getdns_upstream *upstream) && upstream->total_responses == 0) || (upstream->conn_completed >= conn_retries && - upstream->total_responses == 0 && + upstream->total_responses == 0 && upstream->total_timeouts > GETDNS_TRANSPORT_FAIL_MULT)) { upstream_backoff(upstream); } /* If we didn't backoff it would be nice to reset the conn_backoff_interval - if the upstream is working well again otherwise it would get stuck at the + if the upstream is working well again otherwise it would get stuck at the tls_backoff_time forever... How about */ - if (upstream->conn_state != GETDNS_CONN_BACKOFF && + if (upstream->conn_state != GETDNS_CONN_BACKOFF && upstream->responses_received > 1) upstream->conn_backoff_interval = 1; @@ -881,9 +869,6 @@ _getdns_upstream_reset(getdns_upstream *upstream) if (upstream->tls_obj != NULL) { SSL_shutdown(upstream->tls_obj); #ifdef USE_DANESSL -# if defined(STUB_DEBUG) && STUB_DEBUG - _stub_debug_print_openssl_errors(); -# endif DANESSL_cleanup(upstream->tls_obj); #endif SSL_free(upstream->tls_obj); @@ -1047,7 +1032,7 @@ upstream_init(getdns_upstream *upstream, upstream->addr_len = ai->ai_addrlen; (void) memcpy(&upstream->addr, ai->ai_addr, ai->ai_addrlen); - inet_ntop(upstream->addr.ss_family, upstream_addr(upstream), + inet_ntop(upstream->addr.ss_family, upstream_addr(upstream), upstream->addr_str, INET6_ADDRSTRLEN); /* How is this upstream doing on connections? */ @@ -1143,7 +1128,7 @@ static int get_dns_suffix_windows(getdns_list *suffix, char* domain) { returnStatus = RegQueryValueEx(hKey, TEXT("SearchList"), 0, &dwType,(LPBYTE)&lszValue, &dwSize); - if (returnStatus == ERROR_SUCCESS) + if (returnStatus == ERROR_SUCCESS) { if ((strlen(lszValue)) > 0) { parse = lszValue; @@ -1209,7 +1194,7 @@ set_os_defaults_windows(getdns_context *context) info = (FIXED_INFO *)malloc(sizeof(FIXED_INFO)); if (info == NULL) - return GETDNS_RETURN_GENERIC_ERROR; + return GETDNS_RETURN_MEMORY_ERROR; if ((info_err = GetNetworkParams(info, &buflen)) == ERROR_BUFFER_OVERFLOW) { free(info); @@ -1389,7 +1374,8 @@ getdns_context_set_resolvconf(getdns_context *context, const char *resolvconf) #endif getdns_return_t -getdns_context_get_resolvconf(getdns_context *context, const char **resolvconf) +getdns_context_get_resolvconf( + const getdns_context *context, const char **resolvconf) { if (!context || !resolvconf) return GETDNS_RETURN_INVALID_PARAMETER; @@ -1482,11 +1468,11 @@ static char const * const _getdns_default_trust_anchors_verify_CA = static char const * const _getdns_default_trust_anchors_verify_email = "dnssec@iana.org"; -static char const * const _getdns_default_tls_cipher_list = +static char const * const _getdns_default_tls_cipher_list = "TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:" "TLS13-CHACHA20-POLY1305-SHA256:EECDH+AESGCM:EECDH+CHACHA20"; -static char const * const _getdns_default_tls_ciphersuites = +static char const * const _getdns_default_tls_ciphersuites = "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"; /* @@ -1683,7 +1669,7 @@ getdns_context_create_with_extended_memory_functions( result->edns_maximum_udp_payload_size = -1; if ((r = create_default_dns_transports(result))) goto error; - result->tls_auth = GETDNS_AUTHENTICATION_NONE; + result->tls_auth = GETDNS_AUTHENTICATION_NONE; result->tls_auth_min = GETDNS_AUTHENTICATION_NONE; result->round_robin_upstreams = 0; result->tls_backoff_time = 3600; @@ -1733,7 +1719,7 @@ getdns_context_create_with_extended_memory_functions( #endif // resolv.conf does not exist on Windows, handle differently -#ifndef USE_WINSOCK +#ifndef USE_WINSOCK if ((set_from_os & 1)) { (void) getdns_context_set_resolvconf(result, GETDNS_FN_RESOLVCONF); (void) getdns_context_set_hosts(result, GETDNS_FN_HOSTS); @@ -1913,7 +1899,8 @@ getdns_context_set_update_callback(getdns_context *context, void *userarg, } getdns_return_t -getdns_context_get_update_callback(getdns_context *context, void **userarg, +getdns_context_get_update_callback(const getdns_context *context, + void **userarg, void (**cb)(getdns_context *, getdns_context_code_t, void *)) { if (!context || !userarg || !cb) @@ -1941,20 +1928,6 @@ getdns_context_set_logfunc(getdns_context *context, void *userarg, return GETDNS_RETURN_GOOD; } -void _getdns_context_log(getdns_context *context, uint64_t system, - getdns_loglevel_type level, const char *fmt, ...) -{ - va_list args; - - if (!context || !context->log.func || !(context->log.system & system) - || level > context->log.level) - return; - - va_start(args, fmt); - context->log.func(context->log.userarg, system, level, fmt, args); - va_end(args); -} - #ifdef HAVE_LIBUNBOUND /* * Helpers to set options on the unbound ctx @@ -2252,7 +2225,7 @@ set_ub_dns_transport(struct getdns_context* context) { break; } } - if (fallback == 0) + if (fallback == 0) /* Use TLS if it is the only thing.*/ set_ub_string_opt(context, "ssl-upstream:", "yes"); break; @@ -2359,7 +2332,7 @@ getdns_context_set_tls_authentication(getdns_context *context, getdns_tls_authentication_t value) { RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - if (value != GETDNS_AUTHENTICATION_NONE && + if (value != GETDNS_AUTHENTICATION_NONE && value != GETDNS_AUTHENTICATION_REQUIRED) { return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; } @@ -2395,7 +2368,7 @@ getdns_context_set_round_robin_upstreams(getdns_context *context, uint8_t value) * before the upstream which has previously timed out will be tried again. * @see getdns_context_get_max_backoff_value * @param[in] context The context to configure - * @param[in[ value Number of messages sent to other upstreams before + * @param[in[ value Number of messages sent to other upstreams before * retrying the upstream which had timed out. * @return GETDNS_RETURN_GOOD on success * @return GETDNS_RETURN_INVALID_PARAMETER if context is null. @@ -3105,7 +3078,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context, dict, "tls_auth_name", &tls_auth_name)) == GETDNS_RETURN_GOOD) { if (tls_auth_name->size >= sizeof(upstream->tls_auth_name)) { - /* tls_auth_name's are + /* tls_auth_name's are * domain names in presentation * format and, taking escaping * into account, should not @@ -3147,7 +3120,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context, (void) getdns_dict_get_bindata( dict, "tls_curves_list", &tls_curves_list); if (tls_curves_list) { - upstream->tls_curves_list = + upstream->tls_curves_list = _getdns_strdup2(&upstreams->mf , tls_curves_list); } else @@ -3553,18 +3526,36 @@ ub_setup_stub(struct ub_ctx *ctx, getdns_context *context) getdns_upstream *upstream; char addr[1024]; getdns_upstreams *upstreams = context->upstreams; + int r; - (void) ub_ctx_set_fwd(ctx, NULL); + if ((r = ub_ctx_set_fwd(ctx, NULL))) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_WARNING + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP + , "Error while clearing forwarding modus on unbound context" + , ub_strerror(r)); + } for (i = 0; i < upstreams->count; i++) { upstream = &upstreams->upstreams[i]; - /*[TLS]: Use only the TLS subset of upstreams when TLS is the only thing - * used. All other cases must currently fallback to TCP for libunbound.*/ + /* [TLS]: Use only the TLS subset of upstreams when TLS is the + * only thing used. All other cases must currently fallback to + * TCP for libunbound.*/ if (context->dns_transports[0] == GETDNS_TRANSPORT_TLS && context->dns_transport_count ==1 && upstream->transport != GETDNS_TRANSPORT_TLS) continue; upstream_ntop_buf(upstream, addr, 1024); - ub_ctx_set_fwd(ctx, addr); + if ((r = ub_ctx_set_fwd(ctx, addr))) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_WARNING + , "%s: %s '%s' (%s)\n" + , STUB_DEBUG_SETUP + , "Error while setting up unbound context for " + "forwarding to" + , addr + , ub_strerror(r)); + } } /* Allow lookups of: @@ -3634,8 +3625,16 @@ ub_setup_recursing(struct ub_ctx *ctx, getdns_context *context) { _getdns_rr_iter rr_spc, *rr; char ta_str[8192]; + int r; - (void) ub_ctx_set_fwd(ctx, NULL); + if ((r = ub_ctx_set_fwd(ctx, NULL))) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_RECURSING, GETDNS_LOG_WARNING + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP + , "Error while clearing forwarding modus on unbound context" + , ub_strerror(r)); + } if (!context->unbound_ta_set && context->trust_anchors) { for ( rr = _getdns_rr_iter_init( &rr_spc , context->trust_anchors @@ -3644,7 +3643,17 @@ ub_setup_recursing(struct ub_ctx *ctx, getdns_context *context) (void) gldns_wire2str_rr_buf((UNCONST_UINT8_p)rr->pos, rr->nxt - rr->pos, ta_str, sizeof(ta_str)); - (void) ub_ctx_add_ta(ctx, ta_str); + if ((r = ub_ctx_add_ta(ctx, ta_str))) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_RECURSING + , GETDNS_LOG_WARNING + , "%s: %s '%s' (%s)\n" + , STUB_DEBUG_SETUP + , "Error while equiping unbound context " + "with trust anchor" + , ta_str + , ub_strerror(r)); + } } context->unbound_ta_set = 1; } @@ -3659,8 +3668,15 @@ _getdns_ns_dns_setup(struct getdns_context *context) switch (context->resolution_type) { case GETDNS_RESOLUTION_STUB: - if (!context->upstreams || !context->upstreams->count) - return GETDNS_RETURN_GENERIC_ERROR; + if (!context->upstreams || !context->upstreams->count) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s\n" + , STUB_DEBUG_SETUP + , "Stub resolution requested, but no upstreams " + "configured"); + return GETDNS_RETURN_BAD_CONTEXT; + } #ifdef STUB_NATIVE_DNSSEC # ifdef DNSSEC_ROADBLOCK_AVOIDANCE # ifdef HAVE_LIBUNBOUND @@ -3685,6 +3701,12 @@ _getdns_ns_dns_setup(struct getdns_context *context) return GETDNS_RETURN_NOT_IMPLEMENTED; #endif } + _getdns_log(&context->log + , GETDNS_LOG_SYS_RESOLVING + , GETDNS_LOG_ERR + , "%s: %s (%d)\n", STUB_DEBUG_SETUP + , "Unknown resolution type: " + , context->resolution_type); return GETDNS_RETURN_BAD_CONTEXT; } @@ -3692,19 +3714,23 @@ getdns_return_t _getdns_context_prepare_for_resolution(getdns_context *context) { getdns_return_t r; + char ssl_err[256]; + int osr; - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); + assert(context); if (context->destroying) return GETDNS_RETURN_BAD_CONTEXT; /* Transport can in theory be set per query in stub mode */ - if (context->resolution_type == GETDNS_RESOLUTION_STUB && + if (context->resolution_type == GETDNS_RESOLUTION_STUB && tls_is_in_transports_list(context) == 1) { /* Check minimum require authentication level*/ - if (tls_only_is_in_transports_list(context) == 1 && + if (tls_only_is_in_transports_list(context) == 1 && context->tls_auth == GETDNS_AUTHENTICATION_REQUIRED) { context->tls_auth_min = GETDNS_AUTHENTICATION_REQUIRED; - /* TODO: If no auth data provided for any upstream, fail here */ + /* TODO: If no auth data provided for any upstream, + * fail here + */ } else { context->tls_auth_min = GETDNS_AUTHENTICATION_NONE; @@ -3718,22 +3744,52 @@ _getdns_context_prepare_for_resolution(getdns_context *context) # else context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method()); # endif - if(context->tls_ctx == NULL) + if(context->tls_ctx == NULL) { + ERR_error_string_n( ERR_get_error() + , ssl_err, sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Error creating TLS context" + , ssl_err); return GETDNS_RETURN_BAD_CONTEXT; + } # if defined(HAVE_DECL_SSL_SET_MIN_PROTO_VERSION) \ && HAVE_DECL_SSL_SET_MIN_PROTO_VERSION if (!SSL_CTX_set_min_proto_version(context->tls_ctx, - _getdns_tls_version2openssl_version(context->tls_min_version))) { + _getdns_tls_version2openssl_version( + context->tls_min_version))) { SSL_CTX_free(context->tls_ctx); context->tls_ctx = NULL; + ERR_error_string_n( ERR_get_error() + , ssl_err, sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Error configuring TLS context with " + "minimum TLS version" + , ssl_err); return GETDNS_RETURN_BAD_CONTEXT; } if (context->tls_max_version && !SSL_CTX_set_max_proto_version(context->tls_ctx, - _getdns_tls_version2openssl_version(context->tls_max_version))) { + _getdns_tls_version2openssl_version( + context->tls_max_version))) { SSL_CTX_free(context->tls_ctx); context->tls_ctx = NULL; + ERR_error_string_n( ERR_get_error() + , ssl_err, sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Error configuring TLS context with " + "maximum TLS version" + , ssl_err); + return GETDNS_RETURN_BAD_CONTEXT; } # else @@ -3741,71 +3797,181 @@ _getdns_context_prepare_for_resolution(getdns_context *context) if (( context->tls_min_version && context->tls_min_version != GETDNS_TLS1_2) || context->tls_max_version) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s\n" + , STUB_DEBUG_SETUP_TLS + , "This version of OpenSSL does not " + "support setting of mimum or maximum " + "TLS versions"); return GETDNS_RETURN_NOT_IMPLEMENTED; } # endif # endif - /* Be strict and only use the cipher suites recommended in RFC7525 - Unless we later fallback to opportunistic. */ + /* Be strict and only use the cipher suites recommended + * in RFC7525 Unless we later fallback to opportunistic. + */ if (!SSL_CTX_set_cipher_list(context->tls_ctx, - context->tls_cipher_list ? context->tls_cipher_list - : _getdns_default_tls_cipher_list)) + context->tls_cipher_list + ? context->tls_cipher_list + : _getdns_default_tls_cipher_list)) { + ERR_error_string_n( ERR_get_error() + , ssl_err, sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Error configuring TLS context with " + "cipher list" + , ssl_err); + return GETDNS_RETURN_BAD_CONTEXT; + } # ifdef HAVE_SSL_CTX_SET_CIPHERSUITES if (!SSL_CTX_set_ciphersuites(context->tls_ctx, - context->tls_ciphersuites ? context->tls_ciphersuites - : _getdns_default_tls_ciphersuites)) + context->tls_ciphersuites + ? context->tls_ciphersuites + : _getdns_default_tls_ciphersuites)) { + ERR_error_string_n( ERR_get_error() + , ssl_err, sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Error configuring TLS context with " + "cipher suites" + , ssl_err); + return GETDNS_RETURN_BAD_CONTEXT; -# else - if (context->tls_ciphersuites) - return GETDNS_RETURN_NOT_IMPLEMENTED; -# endif -# if defined(HAVE_DECL_SSL_CTX_SET1_CURVES_LIST) && HAVE_DECL_SSL_CTX_SET1_CURVES_LIST - if (context->tls_curves_list && - !SSL_CTX_set1_curves_list(context->tls_ctx, context->tls_curves_list)) - return GETDNS_RETURN_BAD_CONTEXT; -# else - if (context->tls_curves_list) - return GETDNS_RETURN_NOT_IMPLEMENTED; -# endif - /* For strict authentication, we must have local root certs available - Set up is done only when the tls_ctx is created (per getdns_context)*/ - if ((context->tls_ca_file || context->tls_ca_path) && - SSL_CTX_load_verify_locations(context->tls_ctx - , context->tls_ca_file, context->tls_ca_path)) - ; /* pass */ -# ifndef USE_WINSOCK - else if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) { -# else - else if (!add_WIN_cacerts_to_openssl_store(context->tls_ctx)) { -# endif /* USE_WINSOCK */ - if (context->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED) - return GETDNS_RETURN_BAD_CONTEXT; } +# else + if (context->tls_ciphersuites) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s\n" + , STUB_DEBUG_SETUP_TLS + , "This version of OpenSSL does not " + "support configuring cipher suites"); + return GETDNS_RETURN_NOT_IMPLEMENTED; + } +# endif +# if defined(HAVE_DECL_SSL_CTX_SET1_CURVES_LIST) \ + && HAVE_DECL_SSL_CTX_SET1_CURVES_LIST + if (context->tls_curves_list && + !SSL_CTX_set1_curves_list(context->tls_ctx, + context->tls_curves_list)) { + ERR_error_string_n( ERR_get_error() + , ssl_err, sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Error configuring TLS context with " + "curves list" + , ssl_err); + return GETDNS_RETURN_BAD_CONTEXT; + } +# else + if (context->tls_curves_list) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s\n" + , STUB_DEBUG_SETUP_TLS + , "This version of OpenSSL does not " + "support configuring curves list"); + return GETDNS_RETURN_NOT_IMPLEMENTED; + } +# endif + /* For strict authentication, we must have local root + * certs available. Set up is done only when the tls_ctx + * is created (per getdns_context) + */ + osr = 0; + if (context->tls_ca_file || context->tls_ca_path) { + osr = SSL_CTX_load_verify_locations( + context->tls_ctx + , context->tls_ca_file + , context->tls_ca_path ); + if (!osr) { + ERR_error_string_n( ERR_get_error() + , ssl_err + , sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB + , GETDNS_LOG_WARNING + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Could not load verify locations" + , ssl_err); + } else { + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB + , GETDNS_LOG_DEBUG + , "%s: %s\n" + , STUB_DEBUG_SETUP_TLS + , "Verify locations loaded"); + } + } + if (osr) + ; /* verify locations loaded: pass */ +# ifndef USE_WINSOCK + else if (!SSL_CTX_set_default_verify_paths( + context->tls_ctx) && +# else + else if (!add_WIN_cacerts_to_openssl_store( + context, context->tls_ctx) && +# endif /* USE_WINSOCK */ + context->tls_auth_min + == GETDNS_AUTHENTICATION_REQUIRED) { + ERR_error_string_n( ERR_get_error() + , ssl_err, sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB + , GETDNS_LOG_ERR + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Authentication is needed but no default " + "verify location could be loaded" + , ssl_err); + return GETDNS_RETURN_BAD_CONTEXT; + } + # if defined(HAVE_SSL_CTX_DANE_ENABLE) -# if defined(STUB_DEBUG) && STUB_DEBUG - int osr = -# else - (void) -# endif - SSL_CTX_dane_enable(context->tls_ctx); - DEBUG_STUB("%s %-35s: DEBUG: SSL_CTX_dane_enable() -> %d\n" - , STUB_DEBUG_SETUP_TLS, __FUNC__, osr); + if (!SSL_CTX_dane_enable(context->tls_ctx)) { + ERR_error_string_n( ERR_get_error() + , ssl_err, sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_WARNING + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Could not enable DANE on TLX context" + , ssl_err); + } # elif defined(USE_DANESSL) -# if defined(STUB_DEBUG) && STUB_DEBUG - int osr = -# else - (void) -# endif - DANESSL_CTX_init(context->tls_ctx); - DEBUG_STUB("%s %-35s: DEBUG: DANESSL_CTX_init() -> %d\n" - , STUB_DEBUG_SETUP_TLS, __FUNC__, osr); + if (!DANESSL_CTX_init(context->tls_ctx)) { + ERR_error_string_n( ERR_get_error() + , ssl_err, sizeof(ssl_err)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_WARNING + , "%s: %s (%s)\n" + , STUB_DEBUG_SETUP_TLS + , "Could not enable DANE on TLX context" + , ssl_err); + } # endif #else /* HAVE_TLS_v1_2 */ - if (tls_only_is_in_transports_list(context) == 1) - return GETDNS_RETURN_BAD_CONTEXT; - /* A null tls_ctx will make TLS fail and fallback to the other - transports will kick-in.*/ + if (tls_only_is_in_transports_list(context) == 1) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s\n" + , STUB_DEBUG_SETUP_TLS + , "This version of OpenSSL does not " + "support authenticated TLS"); + return GETDNS_RETURN_NOT_IMPLEMENTED; + } + /* A null tls_ctx will make TLS fail and fallback to + * the other transports will kick-in. + */ #endif /* HAVE_TLS_v1_2 */ } } @@ -3813,10 +3979,16 @@ _getdns_context_prepare_for_resolution(getdns_context *context) /* Block use of TLS ONLY in recursive mode as it won't work */ /* Note: If TLS is used in recursive mode this will try TLS on port * 53 so it is blocked here. */ - if (context->resolution_type == GETDNS_RESOLUTION_RECURSING && - tls_only_is_in_transports_list(context) == 1) - return GETDNS_RETURN_BAD_CONTEXT; - + if (context->resolution_type == GETDNS_RESOLUTION_RECURSING + && tls_only_is_in_transports_list(context) == 1) { + _getdns_log(&context->log + , GETDNS_LOG_SYS_STUB, GETDNS_LOG_ERR + , "%s: %s\n" + , STUB_DEBUG_SETUP_TLS + , "TLS only transport is not supported for the recursing " + "resolution type"); + return GETDNS_RETURN_NOT_IMPLEMENTED; + } if (context->resolution_type_set == context->resolution_type) /* already set and no config changes * have caused this to be bad. @@ -3827,8 +3999,6 @@ _getdns_context_prepare_for_resolution(getdns_context *context) * the spec calls for us to treat the namespace list as ordered * so we need to respect that order */ - - r = _getdns_ns_dns_setup(context); if (r == GETDNS_RETURN_GOOD) context->resolution_type_set = context->resolution_type; @@ -3887,7 +4057,7 @@ _getdns_bindata_destroy(struct mem_funcs *mfs, /* TODO: Remove next_timeout argument from getdns_context_get_num_pending_requests */ uint32_t -getdns_context_get_num_pending_requests(getdns_context* context, +getdns_context_get_num_pending_requests(const getdns_context* context, struct timeval* next_timeout) { (void)next_timeout; @@ -3961,7 +4131,8 @@ getdns_context_set_eventloop(getdns_context* context, getdns_eventloop* loop) } getdns_return_t -getdns_context_get_eventloop(getdns_context *context, getdns_eventloop **loop) +getdns_context_get_eventloop( + const getdns_context *context, getdns_eventloop **loop) { if (!context || !loop) return GETDNS_RETURN_INVALID_PARAMETER; @@ -3974,9 +4145,9 @@ getdns_context_get_eventloop(getdns_context *context, getdns_eventloop **loop) return GETDNS_RETURN_GOOD; } -static size_t _getdns_get_appdata(getdns_context *context, char *path); +static size_t _getdns_get_appdata(const getdns_context *context, char *path); static getdns_dict* -_get_context_settings(getdns_context* context) +_get_context_settings(const getdns_context* context) { getdns_dict *result = getdns_dict_create_with_context(context); getdns_list *list; @@ -4188,7 +4359,7 @@ error: } getdns_dict* -getdns_context_get_api_information(getdns_context* context) +getdns_context_get_api_information(const getdns_context* context) { getdns_dict* result; getdns_dict* settings; @@ -4232,7 +4403,7 @@ getdns_context_get_api_information(getdns_context* context) #ifdef HAVE_OPENSSL_VERSION && ! getdns_dict_util_set_string( result, "openssl_version_string", OpenSSL_version(OPENSSL_VERSION)) - + && ! getdns_dict_util_set_string( result, "openssl_cflags", OpenSSL_version(OPENSSL_CFLAGS)) @@ -4300,7 +4471,7 @@ _getdns_context_local_namespace_resolve( getdns_context *context = dnsreq->context; host_name_addrs *hnas; uint8_t lookup[256]; - getdns_list empty_list = { 0, 0, NULL, { NULL, {{ NULL, NULL, NULL }}}}; + getdns_list empty_list = { 0, 0, NULL, { NULL, {{ NULL,NULL,NULL}}}}; getdns_bindata bindata; getdns_list *jaa; size_t i; @@ -4311,9 +4482,10 @@ _getdns_context_local_namespace_resolve( int ipv6 = dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_AAAA || (dnsreq->netreqs[1] && dnsreq->netreqs[1]->request_type == GETDNS_RRTYPE_AAAA); + getdns_return_t r; if (!ipv4 && !ipv6) - return GETDNS_RETURN_GENERIC_ERROR; + return GETDNS_RETURN_WRONG_TYPE_REQUESTED; /*Do the lookup*/ (void)memcpy(lookup, dnsreq->name, dnsreq->name_len); @@ -4321,59 +4493,61 @@ _getdns_context_local_namespace_resolve( if (!(hnas = (host_name_addrs *) _getdns_rbtree_search(&context->local_hosts, lookup))) - return GETDNS_RETURN_GENERIC_ERROR; + return GETDNS_RETURN_NO_SUCH_DICT_NAME; if (!hnas->ipv4addrs && (!ipv6 || !hnas->ipv6addrs)) - return GETDNS_RETURN_GENERIC_ERROR; + return GETDNS_RETURN_NO_SUCH_DICT_NAME; if (!hnas->ipv6addrs && (!ipv4 || !hnas->ipv4addrs)) - return GETDNS_RETURN_GENERIC_ERROR; + return GETDNS_RETURN_NO_SUCH_DICT_NAME; if (!(*response = getdns_dict_create_with_context(context))) - return GETDNS_RETURN_GENERIC_ERROR; + return GETDNS_RETURN_MEMORY_ERROR; bindata.size = dnsreq->name_len; bindata.data = dnsreq->name; - if (getdns_dict_set_bindata(*response, "canonical_name", &bindata)) + if ((r = getdns_dict_set_bindata(*response,"canonical_name",&bindata))) goto error; empty_list.mf = context->mf; - if (getdns_dict_set_list(*response, "replies_full", &empty_list)) + if ((r = getdns_dict_set_list(*response, "replies_full", &empty_list))) goto error; - if (getdns_dict_set_list(*response, "replies_tree", &empty_list)) + if ((r = getdns_dict_set_list(*response, "replies_tree", &empty_list))) goto error; - if (getdns_dict_set_int(*response, "status", GETDNS_RESPSTATUS_GOOD)) + if ((r=getdns_dict_set_int(*response,"status",GETDNS_RESPSTATUS_GOOD))) goto error; if (!ipv4 || !hnas->ipv4addrs) { - if (getdns_dict_set_list(*response, - "just_address_answers", hnas->ipv6addrs)) + if ((r = getdns_dict_set_list(*response, + "just_address_answers", hnas->ipv6addrs))) goto error; return GETDNS_RETURN_GOOD; } else if (!ipv6 || !hnas->ipv6addrs) { - if (getdns_dict_set_list(*response, - "just_address_answers", hnas->ipv4addrs)) + if ((r = getdns_dict_set_list(*response, + "just_address_answers", hnas->ipv4addrs))) goto error; return GETDNS_RETURN_GOOD; } - if (!(jaa = getdns_list_create_with_context(context))) + if (!(jaa = getdns_list_create_with_context(context))) { + r = GETDNS_RETURN_MEMORY_ERROR; goto error; + } for (i = 0; !getdns_list_get_dict(hnas->ipv4addrs, i, &addr); i++) - if (_getdns_list_append_dict(jaa, addr)) + if ((r = _getdns_list_append_dict(jaa, addr))) break; for (i = 0; !getdns_list_get_dict(hnas->ipv6addrs, i, &addr); i++) - if (_getdns_list_append_dict(jaa, addr)) + if ((r = _getdns_list_append_dict(jaa, addr))) break; - if (!_getdns_dict_set_this_list(*response, "just_address_answers", jaa)) + if (!(r = _getdns_dict_set_this_list(*response, "just_address_answers", jaa))) return GETDNS_RETURN_GOOD; else getdns_list_destroy(jaa); error: getdns_dict_destroy(*response); - return GETDNS_RETURN_GENERIC_ERROR; + return r; } struct mem_funcs * @@ -4383,197 +4557,117 @@ priv_getdns_context_mf(getdns_context *context) } /** begin getters **/ + +#define CONTEXT_GETTER2(NAME,TYPE,VALUE) \ + getdns_return_t \ + getdns_context_get_ ## NAME ( \ + const getdns_context *context, TYPE *value) \ + { if (!context || !value) return GETDNS_RETURN_INVALID_PARAMETER \ + ; *value = context-> VALUE; return GETDNS_RETURN_GOOD; } + +#define CONTEXT_GETTER(NAME,TYPE) CONTEXT_GETTER2(NAME,TYPE,NAME) + +CONTEXT_GETTER(resolution_type, getdns_resolution_t) + getdns_return_t -getdns_context_get_resolution_type(getdns_context *context, - getdns_resolution_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->resolution_type; - return GETDNS_RETURN_GOOD; +getdns_context_get_namespaces(const getdns_context *context, + size_t* namespace_count, getdns_namespace_t **namespaces) +{ + if (!context || !namespace_count || !namespaces) + return GETDNS_RETURN_INVALID_PARAMETER; + *namespace_count = context->namespace_count; + if (!context->namespace_count) { + *namespaces = NULL; + return GETDNS_RETURN_GOOD; + } + // use normal malloc here so users can do normal free + *namespaces = malloc( + context->namespace_count * sizeof(getdns_namespace_t)); + memcpy(*namespaces, context->namespaces, + context->namespace_count * sizeof(getdns_namespace_t)); + return GETDNS_RETURN_GOOD; } getdns_return_t -getdns_context_get_namespaces(getdns_context *context, - size_t* namespace_count, getdns_namespace_t **namespaces) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(namespace_count, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(namespaces, GETDNS_RETURN_INVALID_PARAMETER); - *namespace_count = context->namespace_count; - if (!context->namespace_count) { - *namespaces = NULL; - return GETDNS_RETURN_GOOD; - } - // use normal malloc here so users can do normal free - *namespaces = malloc(context->namespace_count * sizeof(getdns_namespace_t)); - memcpy(*namespaces, context->namespaces, - context->namespace_count * sizeof(getdns_namespace_t)); - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_dns_transport(getdns_context *context, - getdns_transport_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - int count = context->dns_transport_count; - getdns_transport_list_t *transports = context->dns_transports; - if (!count) - return GETDNS_RETURN_WRONG_TYPE_REQUESTED; - - /* Best effort mapping for backwards compatibility*/ - if (transports[0] == GETDNS_TRANSPORT_UDP) { - if (count == 1) - *value = GETDNS_TRANSPORT_UDP_ONLY; - else if (count == 2 && transports[1] == GETDNS_TRANSPORT_TCP) - *value = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP; - else - return GETDNS_RETURN_WRONG_TYPE_REQUESTED; - } - if (transports[0] == GETDNS_TRANSPORT_TCP) { - if (count == 1) - *value = GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN; - } - if (transports[0] == GETDNS_TRANSPORT_TLS) { - if (count == 1) - *value = GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN; - else if (count == 2 && transports[1] == GETDNS_TRANSPORT_TCP) - *value = GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN; - else - return GETDNS_RETURN_WRONG_TYPE_REQUESTED; - } - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_dns_transport_list(getdns_context *context, - size_t* transport_count, getdns_transport_list_t **transports) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(transport_count, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(transports, GETDNS_RETURN_INVALID_PARAMETER); - *transport_count = context->dns_transport_count; - if (!context->dns_transport_count) { - *transports = NULL; - return GETDNS_RETURN_GOOD; - } - // use normal malloc here so users can do normal free - *transports = malloc(context->dns_transport_count * sizeof(getdns_transport_list_t)); - memcpy(*transports, context->dns_transports, - context->dns_transport_count * sizeof(getdns_transport_list_t)); - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_tls_authentication(getdns_context *context, - getdns_tls_authentication_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->tls_auth; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_round_robin_upstreams(getdns_context *context, - uint8_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->round_robin_upstreams; - return GETDNS_RETURN_GOOD; -} - -/** - * Get the maximum number of messages that can be sent to other upstreams - * before the upstream which has previously timed out will be tried again. - * @see getdns_context_set_max_backoff_value - * @param[in] context The context from which to get the setting - * @param[out] value Number of messages sent to other upstreams before - * retrying the upstream which had timed out. - * @return GETDNS_RETURN_GOOD on success - * @return GETDNS_RETURN_INVALID_PARAMETER if context is null. - */ -getdns_return_t -getdns_context_get_max_backoff_value(getdns_context *context, - uint16_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->max_backoff_value; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_tls_backoff_time(getdns_context *context, - uint16_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->tls_backoff_time; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_tls_connection_retries(getdns_context *context, - uint16_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->tls_connection_retries; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_limit_outstanding_queries(getdns_context *context, - uint16_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->limit_outstanding_queries; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_timeout(getdns_context *context, uint64_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->timeout; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_idle_timeout(getdns_context *context, uint64_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->idle_timeout; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_follow_redirects( - getdns_context *context, getdns_redirects_t* value) +getdns_context_get_dns_transport( + const getdns_context *context, getdns_transport_t* value) { if (!context || !value) return GETDNS_RETURN_INVALID_PARAMETER; - *value = context->follow_redirects; - return GETDNS_RETURN_NOT_IMPLEMENTED; + + if (context->dns_transport_count == 0) + return GETDNS_RETURN_WRONG_TYPE_REQUESTED; + + /* Best effort mapping for backwards compatibility*/ + if (context->dns_transports[0] == GETDNS_TRANSPORT_UDP) { + if (context->dns_transport_count == 1) + *value = GETDNS_TRANSPORT_UDP_ONLY; + else if (context->dns_transport_count == 2 + && context->dns_transports[1] == GETDNS_TRANSPORT_TCP) + *value = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP; + else + return GETDNS_RETURN_WRONG_TYPE_REQUESTED; + } + if (context->dns_transports[0] == GETDNS_TRANSPORT_TCP) { + if (context->dns_transport_count == 1) + *value = GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN; + } + if (context->dns_transports[0] == GETDNS_TRANSPORT_TLS) { + if (context->dns_transport_count == 1) + *value = GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN; + else if (context->dns_transport_count == 2 + && context->dns_transports[1] == GETDNS_TRANSPORT_TCP) + *value = GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN; + else + return GETDNS_RETURN_WRONG_TYPE_REQUESTED; + } + return GETDNS_RETURN_GOOD; } getdns_return_t -getdns_context_get_dns_root_servers(getdns_context *context, - getdns_list **value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = NULL; - if (context->dns_root_servers) - return _getdns_list_copy(context->dns_root_servers, value); - return GETDNS_RETURN_GOOD; +getdns_context_get_dns_transport_list(const getdns_context *context, + size_t* transport_count, getdns_transport_list_t **transports) +{ + if (!context || !transport_count || !transports) + return GETDNS_RETURN_INVALID_PARAMETER; + *transport_count = context->dns_transport_count; + if (!context->dns_transport_count) { + *transports = NULL; + return GETDNS_RETURN_GOOD; + } + // use normal malloc here so users can do normal free + *transports = malloc( + context->dns_transport_count * sizeof(getdns_transport_list_t)); + memcpy(*transports, context->dns_transports, + context->dns_transport_count * sizeof(getdns_transport_list_t)); + return GETDNS_RETURN_GOOD; } -getdns_return_t -getdns_context_get_append_name(getdns_context *context, - getdns_append_name_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->append_name; - return GETDNS_RETURN_GOOD; -} +CONTEXT_GETTER2(tls_authentication, getdns_tls_authentication_t, tls_auth) +CONTEXT_GETTER(round_robin_upstreams , uint8_t) +CONTEXT_GETTER(max_backoff_value , uint16_t) +CONTEXT_GETTER(tls_backoff_time , uint16_t) +CONTEXT_GETTER(tls_connection_retries , uint16_t) +CONTEXT_GETTER(limit_outstanding_queries , uint16_t) +CONTEXT_GETTER(timeout , uint64_t) +CONTEXT_GETTER(idle_timeout , uint64_t) +CONTEXT_GETTER(follow_redirects , getdns_redirects_t) getdns_return_t -getdns_context_get_suffix(getdns_context *context, getdns_list **value) +getdns_context_get_dns_root_servers( + const getdns_context *context, getdns_list **value) +{ + if (!context || !value) return GETDNS_RETURN_INVALID_PARAMETER; + if (context->dns_root_servers) + return _getdns_list_copy(context->dns_root_servers, value); + *value = NULL; + return GETDNS_RETURN_GOOD; +} + +CONTEXT_GETTER(append_name , getdns_append_name_t) + +getdns_return_t +getdns_context_get_suffix(const getdns_context *context, getdns_list **value) { size_t dname_len; const uint8_t *dname; @@ -4611,10 +4705,9 @@ getdns_context_get_suffix(getdns_context *context, getdns_list **value) getdns_return_t getdns_context_get_dnssec_trust_anchors( - getdns_context *context, getdns_list **value) + const getdns_context *context, getdns_list **value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); + if (!context || !value) return GETDNS_RETURN_INVALID_PARAMETER; if (context->trust_anchors) { if ((*value = getdns_list_create_with_context(context))) @@ -4630,17 +4723,17 @@ getdns_context_get_dnssec_trust_anchors( } getdns_return_t -getdns_context_get_dnssec_allowed_skew(getdns_context *context, - uint32_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->dnssec_allowed_skew; - return GETDNS_RETURN_GOOD; +getdns_context_get_dnssec_allowed_skew( + const getdns_context *context, uint32_t* value) +{ + if (!context || !value) return GETDNS_RETURN_INVALID_PARAMETER; + *value = context->dnssec_allowed_skew; + return GETDNS_RETURN_GOOD; } getdns_return_t -getdns_context_get_upstream_recursive_servers(getdns_context *context, - getdns_list **upstreams_r) +getdns_context_get_upstream_recursive_servers( + const getdns_context *context, getdns_list **upstreams_r) { size_t i; getdns_list *upstreams; @@ -4766,55 +4859,20 @@ getdns_context_get_upstream_recursive_servers(getdns_context *context, } getdns_return_t -getdns_context_get_edns_maximum_udp_payload_size(getdns_context *context, - uint16_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->edns_maximum_udp_payload_size == -1 ? 0 - : context->edns_maximum_udp_payload_size; - return GETDNS_RETURN_GOOD; +getdns_context_get_edns_maximum_udp_payload_size( + const getdns_context *context, uint16_t* value) +{ + if (!context || !value) return GETDNS_RETURN_INVALID_PARAMETER; + *value = context->edns_maximum_udp_payload_size == -1 ? 0 + : context->edns_maximum_udp_payload_size; + return GETDNS_RETURN_GOOD; } -getdns_return_t -getdns_context_get_edns_extended_rcode(getdns_context *context, - uint8_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->edns_extended_rcode; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_edns_version(getdns_context *context, uint8_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->edns_version; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_edns_do_bit(getdns_context *context, uint8_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->edns_do_bit; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_edns_client_subnet_private(getdns_context *context, uint8_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->edns_client_subnet_private; - return GETDNS_RETURN_GOOD; -} - -getdns_return_t -getdns_context_get_tls_query_padding_blocksize(getdns_context *context, uint16_t* value) { - RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER); - *value = context->tls_query_padding_blocksize; - return GETDNS_RETURN_GOOD; -} +CONTEXT_GETTER(edns_extended_rcode , uint8_t) +CONTEXT_GETTER(edns_version , uint8_t) +CONTEXT_GETTER(edns_do_bit , uint8_t) +CONTEXT_GETTER(edns_client_subnet_private , uint8_t) +CONTEXT_GETTER(tls_query_padding_blocksize, uint16_t) static int _streq(const getdns_bindata *name, const char *str) { @@ -5076,7 +5134,7 @@ getdns_context_config(getdns_context *context, const getdns_dict *config_dict) return r; } -static size_t _getdns_get_appdata(getdns_context *context, char *path) +static size_t _getdns_get_appdata(const getdns_context *context, char *path) { size_t len = 0; @@ -5090,12 +5148,15 @@ static size_t _getdns_get_appdata(getdns_context *context, char *path) } else if (! SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path))) - DEBUG_ANCHOR("ERROR %s(): Could not get %%AppData%% directory\n" - , __FUNC__); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_NOTICE + , "Could not get %%AppData%% directory\n"); - else if ((len = strlen(path)) + sizeof(APPDATA_SUBDIR) + 2 >= _GETDNS_PATH_MAX) - DEBUG_ANCHOR("ERROR %s(): Home path too long for appdata\n" - , __FUNC__); + else if ((len = strlen(path)) + + sizeof(APPDATA_SUBDIR) + 2 >= _GETDNS_PATH_MAX) + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Path name for appdata directory too long\n"); #else # define SLASHTOK '/' # define APPDATA_SUBDIR ".getdns" @@ -5107,12 +5168,14 @@ static size_t _getdns_get_appdata(getdns_context *context, char *path) len = strlen(path); } else if (!(home = p ? p->pw_dir : getenv("HOME"))) - DEBUG_ANCHOR("ERROR %s(): Could not get home directory\n" - , __FUNC__); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_NOTICE + , "Unable to determine home directory location\n"); else if ((len = strlen(home)) + sizeof(APPDATA_SUBDIR) + 2 >= _GETDNS_PATH_MAX) - DEBUG_ANCHOR("ERROR %s(): Home path too long for appdata\n" - , __FUNC__); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Path name for appdata directory too long\n"); else if (!strcpy(path, home)) ; /* strcpy returns path always */ @@ -5137,8 +5200,10 @@ static size_t _getdns_get_appdata(getdns_context *context, char *path) mkdir(path, 0755) #endif && errno != EEXIST) - DEBUG_ANCHOR("ERROR %s(): Could not mkdir %s: %s\n" - , __FUNC__, path, strerror(errno)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "mkdir(\"%s\") failed: %s\n" + , path, _getdns_errnostr()); else { path[len++] = SLASHTOK; path[len ] = '\0'; @@ -5149,36 +5214,31 @@ static size_t _getdns_get_appdata(getdns_context *context, char *path) return 0; } -FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn) +FILE *_getdns_context_get_priv_fp( + const getdns_context *context, const char *fn) { char path[_GETDNS_PATH_MAX]; FILE *f = NULL; size_t len = _getdns_get_appdata(context, path); - (void) context; -/* - * Commented out to enable fallback to current directory - * - * if (!(len = _getdns_get_appdata(context, path))) - * DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n" - * , __FUNC__); - * - * else - */ if (len + strlen(fn) >= sizeof(path)) - DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Path name for appdata directory too long\n"); + else if (!strcpy(path + len, fn)) ; /* strcpy returns path + len always */ else if (!(f = fopen(path, "r"))) - DEBUG_ANCHOR("ERROR %s(): Opening \"%s\": %s\n" - , __FUNC__, path, strerror(errno)); - + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO + , "Error opening \"%s\": %s\n" + , path, _getdns_errnostr()); return f; } -uint8_t *_getdns_context_get_priv_file(getdns_context *context, +uint8_t *_getdns_context_get_priv_file(const getdns_context *context, const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz) { FILE *f = NULL; @@ -5192,20 +5252,26 @@ uint8_t *_getdns_context_get_priv_file(getdns_context *context, return buf; } else if (fseek(f, 0, SEEK_END) < 0) - DEBUG_ANCHOR("ERROR %s(): Determining size of \"%s\": %s\n" - , __FUNC__, fn, strerror(errno)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error determining size of \"%s\": %s\n" + , fn, _getdns_errnostr()); else if (!(buf = GETDNS_XMALLOC( context->mf, uint8_t, (buf_len = ftell(f) + 1)))) - DEBUG_ANCHOR("ERROR %s(): Allocating %d memory for \"%s\"\n" - , __FUNC__, (int)buf_len, fn); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error allocating %d bytes of memory for \"%s\"\n" + , (int)buf_len, fn); else { rewind(f); if ((*file_sz = fread(buf, 1, buf_len, f)) >= buf_len || !feof(f)) { GETDNS_FREE(context->mf, buf); - DEBUG_ANCHOR("ERROR %s(): Reading \"%s\": %s\n" - , __FUNC__, fn, strerror(errno)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error reding \"%s\": %s\n" + , fn, _getdns_errnostr()); } else { buf[*file_sz] = 0; @@ -5227,46 +5293,51 @@ int _getdns_context_write_priv_file(getdns_context *context, FILE *f = NULL; size_t len = _getdns_get_appdata(context, path); -/* - * Commented out to enable fallback to current directory - * - * if (!(len = _getdns_get_appdata(context, path))) - * DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n" - * , __FUNC__); - * - * else - */ if (len + 6 >= sizeof(tmpfn) || len + strlen(fn) >= sizeof(path)) - DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__); - + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Application data filename \"%s\" too long\n" + , fn); else if (snprintf(tmpfn, sizeof(tmpfn), "%sXXXXXX", path) < 0) - DEBUG_ANCHOR("ERROR %s(): Creating temporary filename template: \"%s\"\n" - , __FUNC__, tmpfn); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error creating temporary file template \"%s\"\n" + , tmpfn); else if (!strcpy(path + len, fn)) ; /* strcpy returns path + len always */ else if ((fd = mkstemp(tmpfn)) < 0) - DEBUG_ANCHOR("ERROR %s(): Creating temporary file \"%s\": %s\n" - , __FUNC__, tmpfn, strerror(errno)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_INFO + , "Could not create temporary file \"%s\": %s\n" + , tmpfn, _getdns_errnostr()); else if (!(f = fdopen(fd, "w"))) - DEBUG_ANCHOR("ERROR %s(): Opening temporary file: %s\n" - , __FUNC__, strerror(errno)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error opening temporary file \"%s\": %s\n" + , tmpfn, _getdns_errnostr()); else if (fwrite(content->data, 1, content->size, f) < content->size) - DEBUG_ANCHOR("ERROR %s(): Writing temporary file: %s\n" - , __FUNC__, strerror(errno)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error writing to temporary file \"%s\": %s\n" + , tmpfn, _getdns_errnostr()); else if (fclose(f) < 0) - DEBUG_ANCHOR("ERROR %s(): Closing temporary file: %s\n" - , __FUNC__, strerror(errno)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error closing temporary file \"%s\": %s\n" + , tmpfn, _getdns_errnostr()); else if (rename(tmpfn, path) < 0) - DEBUG_ANCHOR("ERROR %s(): Renaming temporary file: %s\n" - , __FUNC__, strerror(errno)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error renaming temporary file \"%s\" to \"%s\"" + ": %s\n", tmpfn, path, _getdns_errnostr()); else { context->can_write_appdata = PROP_ABLE; return 1; @@ -5300,26 +5371,21 @@ int _getdns_context_can_write_appdata(getdns_context *context) return 0; len = _getdns_get_appdata(context, path); -/* - * Commented out to enable fallback to current directory - * - * - * if (!(len = _getdns_get_appdata(context, path))) - * DEBUG_ANCHOR("ERROR %s(): Could not get application data path\n" - * , __FUNC__); - * - * else - */ + if (len + strlen(test_fn) >= sizeof(path)) - DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Application data too long \"%s\" + \"%s\"\n" + , path, test_fn); else if (!strcpy(path + len, test_fn)) ; /* strcpy returns path + len always */ else if (unlink(path) < 0) - DEBUG_ANCHOR("ERROR %s(): Unlinking write test file \"%s\": %s\n" - , __FUNC__, path, strerror(errno)); - + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Error unlinking write test file: \"%s\": %s\n" + , path, _getdns_errnostr()); return 1; } @@ -5363,7 +5429,7 @@ getdns_context_set_trust_anchors_url( getdns_return_t getdns_context_get_trust_anchors_url( - getdns_context *context, const char **url) + const getdns_context *context, const char **url) { if (!context || !url) return GETDNS_RETURN_INVALID_PARAMETER; @@ -5393,7 +5459,7 @@ getdns_context_set_trust_anchors_verify_CA( getdns_return_t getdns_context_get_trust_anchors_verify_CA( - getdns_context *context, const char **verify_CA) + const getdns_context *context, const char **verify_CA) { if (!verify_CA) return GETDNS_RETURN_INVALID_PARAMETER; @@ -5423,7 +5489,7 @@ getdns_context_set_trust_anchors_verify_email( getdns_return_t getdns_context_get_trust_anchors_verify_email( - getdns_context *context, const char **verify_email) + const getdns_context *context, const char **verify_email) { if (!verify_email) return GETDNS_RETURN_INVALID_PARAMETER; @@ -5449,16 +5515,7 @@ getdns_context_set_trust_anchors_backoff_time( return GETDNS_RETURN_GOOD; } -getdns_return_t -getdns_context_get_trust_anchors_backoff_time( - getdns_context *context, uint64_t *backoff_time) -{ - if (!backoff_time) - return GETDNS_RETURN_INVALID_PARAMETER; - - *backoff_time = context->trust_anchors_backoff_time; - return GETDNS_RETURN_GOOD; -} +CONTEXT_GETTER(trust_anchors_backoff_time , uint64_t) getdns_return_t getdns_context_set_appdata_dir( @@ -5487,26 +5544,36 @@ getdns_context *_getdns_context_get_sys_ctxt( &context->sys_ctxt, 1, context->mf.mf_arg, context->mf.mf.ext.malloc, context->mf.mf.ext.realloc, context->mf.mf.ext.free))) - DEBUG_ANCHOR("Could not create system context: %s\n" + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Could not create system context: %s\n" , getdns_get_errorstr_by_id(r)); #ifndef USE_WINSOCK else if (*context->fchg_resolvconf.fn && (r = getdns_context_set_resolvconf( context->sys_ctxt, context->fchg_resolvconf.fn))) - DEBUG_ANCHOR("Could initialize system context with resolvconf " - "\"%s\": %s\n", context->fchg_resolvconf.fn - , getdns_get_errorstr_by_id(r)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Could not initialize system context with " + "resolvconf \"%s\": %s\n" + , context->fchg_resolvconf.fn + , getdns_get_errorstr_by_id(r)); #endif else if (*context->fchg_hosts.fn && (r = getdns_context_set_hosts( context->sys_ctxt, context->fchg_hosts.fn))) - DEBUG_ANCHOR("Could initialize system context with hosts " - "\"%s\": %s\n", context->fchg_resolvconf.fn - , getdns_get_errorstr_by_id(r)); + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Could not initialize system context with " + "hosts \"%s\": %s\n" + , context->fchg_hosts.fn + , getdns_get_errorstr_by_id(r)); else if ((r = getdns_context_set_eventloop( context->sys_ctxt, loop))) - DEBUG_ANCHOR("Could not configure %ssynchronous loop " + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Could not configure %ssynchronous loop " "with system context: %s\n" , ( loop == &context->sync_eventloop.loop ? "" : "a" ) @@ -5514,7 +5581,9 @@ getdns_context *_getdns_context_get_sys_ctxt( else if ((r = getdns_context_set_resolution_type( context->sys_ctxt, GETDNS_RESOLUTION_STUB))) - DEBUG_ANCHOR("Could not configure system context for " + _getdns_log(&context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_ERR + , "Could not configure system context for " "stub resolver: %s\n" , getdns_get_errorstr_by_id(r)); else @@ -5538,15 +5607,7 @@ getdns_context_set_tls_ca_path(getdns_context *context, const char *tls_ca_path) return GETDNS_RETURN_GOOD; } -getdns_return_t -getdns_context_get_tls_ca_path(getdns_context *context, const char **tls_ca_path) -{ - if (!context || !tls_ca_path) - return GETDNS_RETURN_INVALID_PARAMETER; - - *tls_ca_path = context->tls_ca_path; - return GETDNS_RETURN_GOOD; -} +CONTEXT_GETTER(tls_ca_path , const char *) getdns_return_t getdns_context_set_tls_ca_file(getdns_context *context, const char *tls_ca_file) @@ -5561,15 +5622,7 @@ getdns_context_set_tls_ca_file(getdns_context *context, const char *tls_ca_file) return GETDNS_RETURN_GOOD; } -getdns_return_t -getdns_context_get_tls_ca_file(getdns_context *context, const char **tls_ca_file) -{ - if (!context || !tls_ca_file) - return GETDNS_RETURN_INVALID_PARAMETER; - - *tls_ca_file = context->tls_ca_file; - return GETDNS_RETURN_GOOD; -} +CONTEXT_GETTER(tls_ca_file , const char *) getdns_return_t getdns_context_set_tls_cipher_list( @@ -5589,7 +5642,7 @@ getdns_context_set_tls_cipher_list( getdns_return_t getdns_context_get_tls_cipher_list( - getdns_context *context, const char **tls_cipher_list) + const getdns_context *context, const char **tls_cipher_list) { if (!context || !tls_cipher_list) return GETDNS_RETURN_INVALID_PARAMETER; @@ -5618,7 +5671,7 @@ getdns_context_set_tls_ciphersuites( getdns_return_t getdns_context_get_tls_ciphersuites( - getdns_context *context, const char **tls_ciphersuites) + const getdns_context *context, const char **tls_ciphersuites) { if (!context || !tls_ciphersuites) return GETDNS_RETURN_INVALID_PARAMETER; @@ -5650,15 +5703,7 @@ getdns_context_set_tls_curves_list( #endif } -getdns_return_t -getdns_context_get_tls_curves_list( - getdns_context *context, const char **tls_curves_list) -{ - if (!context || !tls_curves_list) - return GETDNS_RETURN_INVALID_PARAMETER; - *tls_curves_list = context->tls_curves_list; - return GETDNS_RETURN_GOOD; -} +CONTEXT_GETTER(tls_curves_list , const char *) getdns_return_t getdns_context_set_tls_min_version( @@ -5671,15 +5716,7 @@ getdns_context_set_tls_min_version( return GETDNS_RETURN_GOOD; } -getdns_return_t -getdns_context_get_tls_min_version( - getdns_context *context, getdns_tls_version_t *tls_min_version) -{ - if (!context || !tls_min_version) - return GETDNS_RETURN_INVALID_PARAMETER; - *tls_min_version = context->tls_min_version; - return GETDNS_RETURN_GOOD; -} +CONTEXT_GETTER(tls_min_version , getdns_tls_version_t) getdns_return_t getdns_context_set_tls_max_version( @@ -5692,14 +5729,6 @@ getdns_context_set_tls_max_version( return GETDNS_RETURN_GOOD; } -getdns_return_t -getdns_context_get_tls_max_version( - getdns_context *context, getdns_tls_version_t *tls_max_version) -{ - if (!context || !tls_max_version) - return GETDNS_RETURN_INVALID_PARAMETER; - *tls_max_version = context->tls_max_version; - return GETDNS_RETURN_GOOD; -} +CONTEXT_GETTER(tls_max_version , getdns_tls_version_t) /* context.c */ diff --git a/src/context.h b/src/context.h index ef16855e..72b9d9d2 100644 --- a/src/context.h +++ b/src/context.h @@ -127,7 +127,7 @@ const getdns_tsig_info *_getdns_get_tsig_info(getdns_tsig_algo tsig_alg); /* for doing public key pinning of TLS-capable upstreams: */ typedef struct sha256_pin { - char pin[SHA256_DIGEST_LENGTH]; + uint8_t pin[SHA256_DIGEST_LENGTH]; struct sha256_pin *next; } sha256_pin_t; @@ -502,11 +502,38 @@ struct getdns_context { #endif /* HAVE_MDNS_SUPPORT */ }; /* getdns_context */ -void _getdns_upstream_log(getdns_upstream *upstream, uint64_t system, - getdns_loglevel_type level, const char *fmt, ...); +static inline int _getdns_check_log(const getdns_log_config *log, + uint64_t system, getdns_loglevel_type level) +{ assert(log) +; return log->func && (log->system & system) && level <= log->level; } -void _getdns_context_log(getdns_context *context, uint64_t system, - getdns_loglevel_type level, const char *fmt, ...); +static inline void _getdns_log(const getdns_log_config *log, + uint64_t system, getdns_loglevel_type level, const char *fmt, ...) +{ + va_list args; + + if (!_getdns_check_log(log, system, level)) + return; + + va_start(args, fmt); + log->func(log->userarg, system, level, fmt, args); + va_end(args); +} + +static inline void _getdns_upstream_log(const getdns_upstream *up, + uint64_t system, getdns_loglevel_type level, const char *fmt, ...) +{ + va_list args; + + if (!up || !up->upstreams + || !_getdns_check_log(&up->upstreams->log, system, level)) + return; + + va_start(args, fmt); + up->upstreams->log.func( + up->upstreams->log.userarg, system, level, fmt, args); + va_end(args); +} /** internal functions **/ @@ -563,8 +590,9 @@ void _getdns_upstreams_dereference(getdns_upstreams *upstreams); void _getdns_upstream_shutdown(getdns_upstream *upstream); -FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn); -uint8_t *_getdns_context_get_priv_file(getdns_context *context, +FILE *_getdns_context_get_priv_fp( + const getdns_context *context, const char *fn); +uint8_t *_getdns_context_get_priv_file(const getdns_context *context, const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz); int _getdns_context_write_priv_file(getdns_context *context, diff --git a/src/dict.c b/src/dict.c index 02d3f20f..d2ce53a9 100644 --- a/src/dict.c +++ b/src/dict.c @@ -434,7 +434,7 @@ getdns_dict_create_with_memory_functions(void *(*malloc)(size_t), /*-------------------------- getdns_dict_create_with_context */ struct getdns_dict * -getdns_dict_create_with_context(struct getdns_context *context) +getdns_dict_create_with_context(const getdns_context *context) { if (context) return getdns_dict_create_with_extended_memory_functions( @@ -655,7 +655,8 @@ getdns_dict_set_bindata( /*---------------------------------------- getdns_dict_set_bindata */ getdns_return_t -getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value) +getdns_dict_util_set_string(getdns_dict *dict, + const char *name, const char *value) { getdns_item *item; getdns_bindata *newbindata; diff --git a/src/dnssec.c b/src/dnssec.c index dc0da14a..d4f6aff3 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -523,7 +523,7 @@ static void val_chain_sched(chain_head *head, const uint8_t *dname); static void val_chain_sched_ds(chain_head *head, const uint8_t *dname); static void val_chain_sched_signer(chain_head *head, _getdns_rrsig_iter *rrsig); -static chain_head *add_rrset2val_chain(struct mem_funcs *mf, +static chain_head *add_rrset2val_chain(const struct mem_funcs *mf, chain_head **chain_p, _getdns_rrset *rrset, getdns_network_req *netreq) { chain_head *head; @@ -788,7 +788,7 @@ static int is_synthesized_cname(_getdns_rrset *cname) * When a SOA query was successful, a query for DS will follow for that * owner name. */ -static void add_pkt2val_chain(struct mem_funcs *mf, +static void add_pkt2val_chain(const struct mem_funcs *mf, chain_head **chain_p, uint8_t *pkt, size_t pkt_len, getdns_network_req *netreq) { @@ -850,7 +850,7 @@ static void add_pkt2val_chain(struct mem_funcs *mf, * checked eventually. * But only if we know the question of course... */ -static void add_question2val_chain(struct mem_funcs *mf, +static void add_question2val_chain(const struct mem_funcs *mf, chain_head **chain_p, uint8_t *pkt, size_t pkt_len, const uint8_t *qname, uint16_t qtype, uint16_t qclass, getdns_network_req *netreq) @@ -1364,8 +1364,9 @@ static int _rr_iter_rdata_cmp(const void *a, const void *b) * nc_name will be set to the next closer (within rrset->name). */ #define VAL_RRSET_SPC_SZ 256 -static int _getdns_verify_rrsig(struct mem_funcs *mf, - _getdns_rrset *rrset, _getdns_rrsig_iter *rrsig, _getdns_rrtype_iter *key, const uint8_t **nc_name) +static int _getdns_verify_rrsig(const struct mem_funcs *mf, + _getdns_rrset *rrset, _getdns_rrsig_iter *rrsig, _getdns_rrtype_iter *key, + const uint8_t **nc_name) { int r; int to_skip; @@ -1683,8 +1684,9 @@ static int check_dates(time_t now, int32_t skew, int32_t exp, int32_t inc) /* Returns whether dnskey signed rrset. If the rrset was a valid wildcard * expansion, nc_name will point to the next closer part of the name in rrset. */ -static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew, - _getdns_rrtype_iter *dnskey, _getdns_rrset *rrset, const uint8_t **nc_name) +static int dnskey_signed_rrset(const struct mem_funcs *mf, time_t now, + uint32_t skew, _getdns_rrtype_iter *dnskey, _getdns_rrset *rrset, + const uint8_t **nc_name) { _getdns_rrsig_iter rrsig_spc, *rrsig; _getdns_rdf_iter rdf_spc, *rdf; @@ -1752,7 +1754,7 @@ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew, } /* Returns whether a dnskey for keyset signed a non wildcard rrset. */ -static int a_key_signed_rrset_no_wc(struct mem_funcs *mf, time_t now, +static int a_key_signed_rrset_no_wc(const struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *keyset, _getdns_rrset *rrset) { _getdns_rrtype_iter dnskey_spc, *dnskey; @@ -1780,13 +1782,13 @@ static int a_key_signed_rrset_no_wc(struct mem_funcs *mf, time_t now, return 0; } -static int find_nsec_covering_name( - struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *dnskey, +static int find_nsec_covering_name(const struct mem_funcs *mf, + time_t now, uint32_t skew, _getdns_rrset *dnskey, _getdns_rrset *rrset, const uint8_t *name, int *opt_out); /* Returns whether a dnskey for keyset signed rrset. */ -static int a_key_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew, - _getdns_rrset *keyset, _getdns_rrset *rrset) +static int a_key_signed_rrset(const struct mem_funcs *mf, time_t now, + uint32_t skew, _getdns_rrset *keyset, _getdns_rrset *rrset) { _getdns_rrtype_iter dnskey_spc, *dnskey; const uint8_t *nc_name; /* Initialized by dnskey_signed_rrset() */ @@ -1827,7 +1829,7 @@ static int a_key_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew, /* Returns whether a DS in ds_set matches a dnskey in dnskey_set which in turn * signed the dnskey set. */ -static int ds_authenticates_keys(struct mem_funcs *mf, +static int ds_authenticates_keys(const struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *ds_set, _getdns_rrset *dnskey_set) { _getdns_rrtype_iter dnskey_spc, *dnskey; @@ -2112,8 +2114,8 @@ static int nsec3_covers_name( } } -static int find_nsec_covering_name( - struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *dnskey, +static int find_nsec_covering_name(const struct mem_funcs *mf, time_t now, + uint32_t skew, _getdns_rrset *dnskey, _getdns_rrset *rrset, const uint8_t *name, int *opt_out) { _getdns_rrset_iter i_spc, *i; @@ -2215,7 +2217,7 @@ static int find_nsec_covering_name( } static int nsec3_find_next_closer( - struct mem_funcs *mf, time_t now, uint32_t skew, + const struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *dnskey, _getdns_rrset *rrset, const uint8_t *nc_name, int *opt_out) { @@ -2267,7 +2269,7 @@ static int nsec3_find_next_closer( * verifying key: it returns keytag + NSEC3_ITERATION_COUNT_HIGH (0x20000) */ static int key_proves_nonexistance( - struct mem_funcs *mf, time_t now, uint32_t skew, + const struct mem_funcs *mf, time_t now, uint32_t skew, _getdns_rrset *keyset, _getdns_rrset *rrset, int *opt_out) { _getdns_rrset nsec_rrset, *cover, *ce; @@ -2571,7 +2573,7 @@ static int key_proves_nonexistance( * non-existence of a DS along the path is proofed, and SECURE otherwise. */ static int chain_node_get_trusted_keys( - struct mem_funcs *mf, time_t now, uint32_t skew, + const struct mem_funcs *mf, time_t now, uint32_t skew, chain_node *node, _getdns_rrset *ta, _getdns_rrset **keys) { int s, keytag; @@ -2714,7 +2716,7 @@ static int chain_node_get_trusted_keys( * For this first a secure keyset is looked up, with which the keyset is * evaluated. */ -static int chain_head_validate_with_ta(struct mem_funcs *mf, +static int chain_head_validate_with_ta(const struct mem_funcs *mf, time_t now, uint32_t skew, chain_head *head, _getdns_rrset *ta) { _getdns_rrset *keys; @@ -2801,8 +2803,8 @@ static int chain_head_validate_with_ta(struct mem_funcs *mf, /* The DNSSEC status of the rrset in head is evaluated by trying the trust * anchors in tas in turn. The best outcome counts. */ -static int chain_head_validate(struct mem_funcs *mf, time_t now, uint32_t skew, - chain_head *head, _getdns_rrset_iter *tas) +static int chain_head_validate(const struct mem_funcs *mf, time_t now, + uint32_t skew, chain_head *head, _getdns_rrset_iter *tas) { _getdns_rrset_iter *i; _getdns_rrset *ta, dnskey_ta, ds_ta; @@ -2951,7 +2953,7 @@ static void chain_clear_netreq_dnssec_status(chain_head *chain) * processing each head in turn. The worst outcome is the dnssec status for * the whole. */ -static int chain_validate_dnssec(struct mem_funcs *mf, +static int chain_validate_dnssec(const struct mem_funcs *mf, time_t now, uint32_t skew, chain_head *chain, _getdns_rrset_iter *tas) { int s = GETDNS_DNSSEC_INDETERMINATE, t; @@ -3287,7 +3289,6 @@ static void check_chain_complete(chain_head *chain) } else if (_getdns_bogus(dnsreq)) { _getdns_rrsig_iter rrsig_spc; - DEBUG_ANCHOR("Request was bogus!\n"); if ((head = chain) && (node = _to_the_root(head->parent)) /* The root DNSKEY rrset */ @@ -3300,7 +3301,9 @@ static void check_chain_complete(chain_head *chain) && _getdns_rrsig_iter_init(&rrsig_spc, &node->dnskey) ){ - DEBUG_ANCHOR("root DNSKEY set was bogus!\n"); + _getdns_log( &context->log + , GETDNS_LOG_SYS_ANCHOR, GETDNS_LOG_NOTICE + , "root DNSKEY set was bogus!\n"); if (!dnsreq->waiting_for_ta) { uint64_t now_ms = 0; @@ -3481,7 +3484,7 @@ void _getdns_ta_notify_dnsreqs(getdns_context *context) getdns_network_req *netreq, **netreq_p; int r = GETDNS_RETURN_GOOD; - (void) _getdns_context_prepare_for_resolution(context); + (void) _getdns_context_prepare_for_resolution(context); *dnsreq_p = dnsreq->ta_notify; for ( netreq_p = dnsreq->netreqs @@ -3606,7 +3609,7 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq) *****************************************************************************/ -static int wire_validate_dnssec(struct mem_funcs *mf, +static int wire_validate_dnssec(const struct mem_funcs *mf, time_t now, uint32_t skew, uint8_t *to_val, size_t to_val_len, uint8_t *support, size_t support_len, uint8_t *tas, size_t tas_len) { @@ -3688,9 +3691,9 @@ static int wire_validate_dnssec(struct mem_funcs *mf, * */ getdns_return_t -getdns_validate_dnssec2(getdns_list *records_to_validate, - getdns_list *support_records, - getdns_list *trust_anchors, +getdns_validate_dnssec2(const getdns_list *records_to_validate, + const getdns_list *support_records, + const getdns_list *trust_anchors, time_t now, uint32_t skew) { uint8_t to_val_buf[4096], *to_val, @@ -3702,7 +3705,7 @@ getdns_validate_dnssec2(getdns_list *records_to_validate, tas_len = sizeof(tas_buf); int r = GETDNS_RETURN_MEMORY_ERROR; - struct mem_funcs *mf; + const struct mem_funcs *mf; size_t i; getdns_dict *reply; @@ -3783,9 +3786,9 @@ exit_free_support: getdns_return_t -getdns_validate_dnssec(getdns_list *records_to_validate, - getdns_list *support_records, - getdns_list *trust_anchors) +getdns_validate_dnssec(const getdns_list *records_to_validate, + const getdns_list *support_records, + const getdns_list *trust_anchors) { return getdns_validate_dnssec2(records_to_validate, support_records, trust_anchors, time(NULL), 0); diff --git a/src/general.c b/src/general.c index f3170072..cb923187 100644 --- a/src/general.c +++ b/src/general.c @@ -243,7 +243,6 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) #if defined(REQ_DEBUG) && REQ_DEBUG debug_req("getting validation chain for ", *dns_req->netreqs); #endif - DEBUG_ANCHOR("Valchain lookup\n"); _getdns_get_validation_chain(dns_req); } else _getdns_call_user_callback( diff --git a/src/getdns/getdns.h.in b/src/getdns/getdns.h.in index aa7ae128..5e4873b5 100644 --- a/src/getdns/getdns.h.in +++ b/src/getdns/getdns.h.in @@ -416,6 +416,7 @@ typedef enum getdns_callback_type_t { #define GETDNS_RRTYPE_CDNSKEY 60 #define GETDNS_RRTYPE_OPENPGPKEY 61 #define GETDNS_RRTYPE_CSYNC 62 +#define GETDNS_RRTYPE_ZONEMD 63 #define GETDNS_RRTYPE_SPF 99 #define GETDNS_RRTYPE_UINFO 100 #define GETDNS_RRTYPE_UID 101 @@ -743,7 +744,7 @@ getdns_list *getdns_list_create(); * used to create and initialize the list. * @return pointer to an allocated list, NULL if insufficient memory */ -getdns_list *getdns_list_create_with_context(getdns_context *context); +getdns_list *getdns_list_create_with_context(const getdns_context *context); /** * create a new list with no items, creating and initializing it with the @@ -863,7 +864,7 @@ getdns_dict *getdns_dict_create(); * used to create and initialize the dict. * @return pointer to an allocated dict, NULL if insufficient memory */ -getdns_dict *getdns_dict_create_with_context(getdns_context *context); +getdns_dict *getdns_dict_create_with_context(const getdns_context *context); /** * create a new dict with no items, creating and initializing it with the @@ -1032,7 +1033,7 @@ getdns_general(getdns_context *context, uint16_t request_type, const getdns_dict *extensions, void *userarg, - getdns_transaction_t * transaction_id, getdns_callback_t callbackfn); + getdns_transaction_t *transaction_id, getdns_callback_t callbackfn); /** * retrieve address assigned to a DNS name @@ -1050,7 +1051,7 @@ getdns_address(getdns_context *context, const char *name, const getdns_dict *extensions, void *userarg, - getdns_transaction_t * transaction_id, getdns_callback_t callbackfn); + getdns_transaction_t *transaction_id, getdns_callback_t callbackfn); /** * retrieve hostname assigned to an IP address @@ -1068,7 +1069,7 @@ getdns_hostname(getdns_context *context, const getdns_dict *address, const getdns_dict *extensions, void *userarg, - getdns_transaction_t * transaction_id, getdns_callback_t callbackfn); + getdns_transaction_t *transaction_id, getdns_callback_t callbackfn); /** * retrieve a service assigned to a DNS name @@ -1086,7 +1087,7 @@ getdns_service(getdns_context *context, const char *name, const getdns_dict *extensions, void *userarg, - getdns_transaction_t * transaction_id, getdns_callback_t callbackfn); + getdns_transaction_t *transaction_id, getdns_callback_t callbackfn); /** @} */ @@ -1341,9 +1342,8 @@ char *getdns_convert_alabel_to_ulabel(const char *alabel); * depending on the validation status. */ getdns_return_t -getdns_validate_dnssec(getdns_list *to_validate, - getdns_list *support_records, - getdns_list *trust_anchors); +getdns_validate_dnssec(const getdns_list *to_validate, + const getdns_list *support_records, const getdns_list *trust_anchors); /** * Get the default list of trust anchor records that is used by the library @@ -1816,7 +1816,7 @@ getdns_context_set_extended_memory_functions(getdns_context *context, * object with getdns_dict_destroy. */ getdns_dict* -getdns_context_get_api_information(getdns_context* context); +getdns_context_get_api_information(const getdns_context *context); /** @} */ diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index f1b2af36..a11b52ea 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -361,7 +361,7 @@ struct getdns_eventloop_vmt { * @return GETDNS_RETURN_INVALID_PARAMETER when context or eventloop were NULL. */ getdns_return_t -getdns_context_set_eventloop(getdns_context* context, +getdns_context_set_eventloop(getdns_context *context, getdns_eventloop *eventloop); /** @@ -377,7 +377,7 @@ getdns_context_set_eventloop(getdns_context* context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or evenloop were NULL */ getdns_return_t -getdns_context_get_eventloop(getdns_context* context, +getdns_context_get_eventloop(const getdns_context *context, getdns_eventloop **eventloop); /** @@ -557,8 +557,18 @@ typedef enum getdns_loglevel_type { #define GETDNS_LOG_INFO_TEXT "Informational message" #define GETDNS_LOG_DEBUG_TEXT "Debug-level message" -#define GETDNS_LOG_UPSTREAM_STATS 4096 +#define GETDNS_LOG_UPSTREAM_STATS 0x3000 #define GETDNS_LOG_UPSTREAM_STATS_TEXT "Log messages about upstream statistics" +#define GETDNS_LOG_SYS_STUB 0x2000 +#define GETDNS_LOG_SYS_STUB_TEXT "Log messages about stub resolving" +#define GETDNS_LOG_SYS_RECURSING 0x4000 +#define GETDNS_LOG_SYS_RECURSING_TEXT "Log messages about recursive resolving" +#define GETDNS_LOG_SYS_RESOLVING 0x6000 +#define GETDNS_LOG_SYS_RESOLVING_TEXT "Log messages about resolving" +#define GETDNS_LOG_SYS_ANCHOR 0x8000 +#define GETDNS_LOG_SYS_ANCHOR_TEXT "Log messages about fetching trust anchors" + + typedef void (*getdns_logfunc_type) (void *userarg, uint64_t log_systems, getdns_loglevel_type, const char *, va_list ap); @@ -847,7 +857,7 @@ getdns_context_set_tls_min_version( */ getdns_return_t getdns_context_get_tls_min_version( - getdns_context *context, getdns_tls_version_t *min_version); + const getdns_context *context, getdns_tls_version_t *min_version); /** * Configure context for maximum supported TLS version. @@ -877,7 +887,7 @@ getdns_context_set_tls_max_version( */ getdns_return_t getdns_context_get_tls_max_version( - getdns_context *context, getdns_tls_version_t *max_version); + const getdns_context *context, getdns_tls_version_t *max_version); /** * Get the current resolution type setting from this context. @@ -890,8 +900,8 @@ getdns_context_get_tls_max_version( * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_resolution_type(getdns_context *context, - getdns_resolution_t* value); +getdns_context_get_resolution_type(const getdns_context *context, + getdns_resolution_t *value); /** * Get a copy of the namespaces list setting from this context. @@ -905,8 +915,8 @@ getdns_context_get_resolution_type(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when any of the arguments was NULL. */ getdns_return_t -getdns_context_get_namespaces(getdns_context *context, - size_t* namespace_count, getdns_namespace_t **namespaces); +getdns_context_get_namespaces(const getdns_context *context, + size_t *namespace_count, getdns_namespace_t **namespaces); /** * Get what transports are used for DNS lookups. @@ -919,8 +929,8 @@ getdns_context_get_namespaces(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when any of the arguments was NULL. */ getdns_return_t -getdns_context_get_dns_transport(getdns_context *context, - getdns_transport_t* value); +getdns_context_get_dns_transport(const getdns_context *context, + getdns_transport_t *value); /** * Get a copy of the transports list setting from this context. @@ -935,8 +945,8 @@ getdns_context_get_dns_transport(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when any of the arguments was NULL. */ getdns_return_t -getdns_context_get_dns_transport_list(getdns_context *context, - size_t* transport_count, getdns_transport_list_t **transports); +getdns_context_get_dns_transport_list(const getdns_context *context, + size_t *transport_count, getdns_transport_list_t **transports); /** * Get the current limit for outstanding queries setting from this context. @@ -947,8 +957,8 @@ getdns_context_get_dns_transport_list(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or limit was NULL. */ getdns_return_t -getdns_context_get_limit_outstanding_queries(getdns_context *context, - uint16_t* limit); +getdns_context_get_limit_outstanding_queries(const getdns_context *context, + uint16_t *limit); /** * Get the current number of milliseconds the API will wait for request @@ -961,7 +971,7 @@ getdns_context_get_limit_outstanding_queries(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or limit was NULL. */ getdns_return_t -getdns_context_get_timeout(getdns_context *context, uint64_t* timeout); +getdns_context_get_timeout(const getdns_context *context, uint64_t *timeout); /** * Get the current number of milliseconds the API will leave an idle TCP or TLS @@ -975,7 +985,8 @@ getdns_context_get_timeout(getdns_context *context, uint64_t* timeout); * @return GETDNS_RETURN_INVALID_PARAMETER when context or timeout was NULL. */ getdns_return_t -getdns_context_get_idle_timeout(getdns_context *context, uint64_t* timeout); +getdns_context_get_idle_timeout( + const getdns_context *context, uint64_t *timeout); /** * Get the setting that says whether or not DNS queries follow redirects. @@ -987,8 +998,8 @@ getdns_context_get_idle_timeout(getdns_context *context, uint64_t* timeout); * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_follow_redirects(getdns_context *context, - getdns_redirects_t* value); +getdns_context_get_follow_redirects(const getdns_context *context, + getdns_redirects_t *value); /** * Get a copy of the list of addresses in use for looking up top-level domains @@ -1005,7 +1016,7 @@ getdns_context_get_follow_redirects(getdns_context *context, * @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated */ getdns_return_t -getdns_context_get_dns_root_servers(getdns_context *context, +getdns_context_get_dns_root_servers(const getdns_context *context, getdns_list **addresses); /** @@ -1023,8 +1034,8 @@ getdns_context_get_dns_root_servers(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_append_name(getdns_context *context, - getdns_append_name_t* value); +getdns_context_get_append_name(const getdns_context *context, + getdns_append_name_t *value); /** * Get a copy of the list of suffixes to be appended based on the value off the @@ -1040,7 +1051,7 @@ getdns_context_get_append_name(getdns_context *context, * @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated */ getdns_return_t -getdns_context_get_suffix(getdns_context *context, getdns_list **value); +getdns_context_get_suffix(const getdns_context *context, getdns_list **value); /** * Get a copy of the list of DNSSEC trust anchors in use by context. @@ -1055,7 +1066,7 @@ getdns_context_get_suffix(getdns_context *context, getdns_list **value); * @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated */ getdns_return_t -getdns_context_get_dnssec_trust_anchors(getdns_context *context, +getdns_context_get_dnssec_trust_anchors(const getdns_context *context, getdns_list **value); /** @@ -1069,8 +1080,8 @@ getdns_context_get_dnssec_trust_anchors(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_dnssec_allowed_skew(getdns_context *context, - uint32_t* value); +getdns_context_get_dnssec_allowed_skew(const getdns_context *context, + uint32_t *value); /** * Get a copy of the list of upstream that will be targeted in stub resolution @@ -1086,7 +1097,7 @@ getdns_context_get_dnssec_allowed_skew(getdns_context *context, * @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated */ getdns_return_t -getdns_context_get_upstream_recursive_servers(getdns_context *context, +getdns_context_get_upstream_recursive_servers(const getdns_context *context, getdns_list **upstream_list); /** @@ -1101,8 +1112,8 @@ getdns_context_get_upstream_recursive_servers(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_edns_maximum_udp_payload_size(getdns_context *context, - uint16_t* value); +getdns_context_get_edns_maximum_udp_payload_size(const getdns_context *context, + uint16_t *value); /** * Get the rcode advertised in an EDNS0 OPT record setting from context @@ -1113,8 +1124,8 @@ getdns_context_get_edns_maximum_udp_payload_size(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_edns_extended_rcode(getdns_context *context, - uint8_t* value); +getdns_context_get_edns_extended_rcode(const getdns_context *context, + uint8_t *value); /** * Get the version advertised in an EDNS0 OPT record setting from context @@ -1125,7 +1136,7 @@ getdns_context_get_edns_extended_rcode(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_edns_version(getdns_context *context, uint8_t* value); +getdns_context_get_edns_version(const getdns_context *context, uint8_t *value); /** * Get the DO bit advertised in an EDNS0 OPT record setting from context @@ -1137,7 +1148,7 @@ getdns_context_get_edns_version(getdns_context *context, uint8_t* value); * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_edns_do_bit(getdns_context *context, uint8_t* value); +getdns_context_get_edns_do_bit(const getdns_context *context, uint8_t *value); /** * Get whether queries with this context will have the EDNS Client Subnet @@ -1150,7 +1161,8 @@ getdns_context_get_edns_do_bit(getdns_context *context, uint8_t* value); * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_edns_client_subnet_private(getdns_context *context, uint8_t* value); +getdns_context_get_edns_client_subnet_private(const getdns_context *context, + uint8_t *value); /** * Get the blocksize that will be used to pad outgoing queries over TLS. @@ -1162,7 +1174,8 @@ getdns_context_get_edns_client_subnet_private(getdns_context *context, uint8_t* * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_tls_query_padding_blocksize(getdns_context *context, uint16_t* value); +getdns_context_get_tls_query_padding_blocksize( + const getdns_context *context, uint16_t *value); /** * Get whether the upstream needs to be authenticated with DNS over TLS. @@ -1180,8 +1193,8 @@ getdns_context_get_tls_query_padding_blocksize(getdns_context *context, uint16_t * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_tls_authentication(getdns_context *context, - getdns_tls_authentication_t* value); +getdns_context_get_tls_authentication(const getdns_context *context, + getdns_tls_authentication_t *value); /** * Get whether the context is configured to round robin queries over the available @@ -1193,8 +1206,8 @@ getdns_context_get_tls_authentication(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_round_robin_upstreams(getdns_context *context, - uint8_t* value); +getdns_context_get_round_robin_upstreams(const getdns_context *context, + uint8_t *value); /** * Get the amount of seconds a TLS connection should not be tried with @@ -1208,8 +1221,8 @@ getdns_context_get_round_robin_upstreams(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_tls_backoff_time(getdns_context *context, - uint16_t* value); +getdns_context_get_tls_backoff_time(const getdns_context *context, + uint16_t *value); /** * Get the number of times getdns retries to setup DNS over TLS with a @@ -1223,8 +1236,8 @@ getdns_context_get_tls_backoff_time(getdns_context *context, * @return GETDNS_RETURN_INVALID_PARAMETER when context or value was NULL. */ getdns_return_t -getdns_context_get_tls_connection_retries(getdns_context *context, - uint16_t* value); +getdns_context_get_tls_connection_retries(const getdns_context *context, + uint16_t *value); /** * Get the currently registered callback function and user defined argument @@ -1241,7 +1254,8 @@ getdns_context_get_tls_connection_retries(getdns_context *context, * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t -getdns_context_get_update_callback(getdns_context *context, void **userarg, +getdns_context_get_update_callback(const getdns_context *context, + void **userarg, void (**value) (getdns_context *, getdns_context_code_t, void *)); @@ -1295,7 +1309,7 @@ getdns_context_get_update_callback(getdns_context *context, void **userarg, */ getdns_return_t getdns_context_get_trust_anchors_url( - getdns_context *context, const char **url); + const getdns_context *context, const char **url); /** * Gets the public certificate for the Certificate Authority with which to @@ -1314,7 +1328,7 @@ getdns_context_get_trust_anchors_url( */ getdns_return_t getdns_context_get_trust_anchors_verify_CA( - getdns_context *context, const char **verify_CA); + const getdns_context *context, const char **verify_CA); /** * Gets the email address for the Subject of the signer's certificate from the @@ -1331,7 +1345,7 @@ getdns_context_get_trust_anchors_verify_CA( */ getdns_return_t getdns_context_get_trust_anchors_verify_email( - getdns_context *context, const char **verify_email); + const getdns_context *context, const char **verify_email); /** * Get the amount of milliseconds the trust anchors will not be tried to be @@ -1345,7 +1359,7 @@ getdns_context_get_trust_anchors_verify_email( */ getdns_return_t getdns_context_get_trust_anchors_backoff_time( - getdns_context *context, uint64_t *value); + const getdns_context *context, uint64_t *value); /** * Get the value with which the context's upstream recursive servers @@ -1358,7 +1372,8 @@ getdns_context_get_trust_anchors_backoff_time( * @return GETDNS_RETURN_GOOD when successful and error code otherwise. */ getdns_return_t -getdns_context_get_resolvconf(getdns_context *context, const char **resolvconf); +getdns_context_get_resolvconf( + const getdns_context *context, const char **resolvconf); /** * Get the value with which the context's GETDNS_NAMESPACE_LOCALNAMES namespace @@ -1371,7 +1386,8 @@ getdns_context_get_resolvconf(getdns_context *context, const char **resolvconf); * @return GETDNS_RETURN_GOOD when successful and error code otherwise. */ getdns_return_t -getdns_context_get_hosts(getdns_context *context, const char **hosts); +getdns_context_get_hosts( + const getdns_context *context, const char **hosts); /** * Get the location of the directory for CA certificates for verification @@ -1385,7 +1401,8 @@ getdns_context_get_hosts(getdns_context *context, const char **hosts); * @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL. */ getdns_return_t -getdns_context_get_tls_ca_path(getdns_context *context, const char **tls_ca_path); +getdns_context_get_tls_ca_path( + const getdns_context *context, const char **tls_ca_path); /** * Get the file location with CA certificates for verification purposes. @@ -1398,7 +1415,8 @@ getdns_context_get_tls_ca_path(getdns_context *context, const char **tls_ca_path * @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL. */ getdns_return_t -getdns_context_get_tls_ca_file(getdns_context *context, const char **tls_ca_file); +getdns_context_get_tls_ca_file( + const getdns_context *context, const char **tls_ca_file); /** * Get the list of available ciphers for authenticated TLS upstreams. @@ -1410,7 +1428,7 @@ getdns_context_get_tls_ca_file(getdns_context *context, const char **tls_ca_file */ getdns_return_t getdns_context_get_tls_cipher_list( - getdns_context *context, const char **cipher_list); + const getdns_context *context, const char **cipher_list); /** * Get the configured available TLS1.3 ciphersuited for authenticated TLS @@ -1423,7 +1441,7 @@ getdns_context_get_tls_cipher_list( */ getdns_return_t getdns_context_get_tls_ciphersuites( - getdns_context *context, const char **ciphersuites); + const getdns_context *context, const char **ciphersuites); /** * Get the supported curves list if one has been set earlier. @@ -1438,7 +1456,7 @@ getdns_context_get_tls_ciphersuites( */ getdns_return_t getdns_context_get_tls_curves_list( - getdns_context *context, const char **curves_list); + const getdns_context *context, const char **curves_list); /** @} */ @@ -1526,7 +1544,8 @@ const char *getdns_get_errorstr_by_id(uint16_t err); * @return GETDNS_RETURN_MEMORY_ERROR when the copy could not be allocated */ getdns_return_t -getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value); +getdns_dict_util_set_string( + getdns_dict *dict, const char *name, const char *value); /** * Get the string associated with the speicifed name. The string should not @@ -1539,7 +1558,8 @@ getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value); * @return GETDNS_RETURN_NO_SUCH_DICT_NAME if dict is invalid or name does not exist */ getdns_return_t -getdns_dict_util_get_string(getdns_dict * dict, char *name, char **result); +getdns_dict_util_get_string( + const getdns_dict * dict, const char *name, char **result); /** @} */ @@ -1580,9 +1600,9 @@ getdns_dict_util_get_string(getdns_dict * dict, char *name, char **result); * return code. */ getdns_return_t -getdns_validate_dnssec2(getdns_list *to_validate, - getdns_list *support_records, - getdns_list *trust_anchors, +getdns_validate_dnssec2(const getdns_list *to_validate, + const getdns_list *support_records, + const getdns_list *trust_anchors, time_t validation_time, uint32_t skew); @@ -1625,9 +1645,9 @@ getdns_validate_dnssec2(getdns_list *to_validate, * @param str the pinning string to parse * @return a dict created from ctx, or NULL if the string did not match. */ -getdns_dict* getdns_pubkey_pin_create_from_string( - getdns_context* context, - const char* str); +getdns_dict *getdns_pubkey_pin_create_from_string( + const getdns_context *context, + const char *str); /** @@ -1644,8 +1664,8 @@ getdns_dict* getdns_pubkey_pin_create_from_string( * @return GETDNS_RETURN_GOOD if the pinset passes the sanity check. */ getdns_return_t getdns_pubkey_pinset_sanity_check( - const getdns_list* pinset, - getdns_list* errorlist); + const getdns_list *pinset, + getdns_list *errorlist); /** @} */ @@ -2293,7 +2313,7 @@ getdns_context_set_listen_addresses( */ getdns_return_t getdns_reply(getdns_context *context, - getdns_dict *reply, getdns_transaction_t request_id); + const getdns_dict *reply, getdns_transaction_t request_id); /** @} @@ -2317,7 +2337,7 @@ getdns_return_t getdns_strerror(getdns_return_t err, char *buf, size_t buflen); * WARNING! Do not use this function. This function will be removed in * future versions of getdns. */ -getdns_return_t getdns_context_process_async(getdns_context* context); +getdns_return_t getdns_context_process_async(getdns_context *context); /** * Return the number of pending requests and the point of time of the next @@ -2325,8 +2345,8 @@ getdns_return_t getdns_context_process_async(getdns_context* context); * WARNING! Do not use this function. This function will be removed in * future versions of getdns. */ -uint32_t getdns_context_get_num_pending_requests(getdns_context* context, - struct timeval* next_timeout); +uint32_t getdns_context_get_num_pending_requests(const getdns_context *context, + struct timeval *next_timeout); /** * Detach the eventloop from the context. Resets the context with the default @@ -2351,7 +2371,7 @@ getdns_context_detach_eventloop(getdns_context *context); * @return GETDNS_RETURN_GOOD on success * @return GETDNS_RETURN_INVALID_PARAMETER if context is NULL */ -getdns_return_t getdns_context_set_use_threads(getdns_context* context, +getdns_return_t getdns_context_set_use_threads(getdns_context *context, int use_threads); /** @} diff --git a/src/gldns/rrdef.c b/src/gldns/rrdef.c index 52e9cf3b..9f27a5a1 100644 --- a/src/gldns/rrdef.c +++ b/src/gldns/rrdef.c @@ -150,6 +150,9 @@ static const gldns_rdf_type type_openpgpkey_wireformat[] = { static const gldns_rdf_type type_csync_wireformat[] = { GLDNS_RDF_TYPE_INT32, GLDNS_RDF_TYPE_INT16, GLDNS_RDF_TYPE_NSEC }; +static const gldns_rdf_type type_zonemd_wireformat[] = { + GLDNS_RDF_TYPE_INT32, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_INT8, GLDNS_RDF_TYPE_HEX +}; /* nsec3 is some vars, followed by same type of data of nsec */ static const gldns_rdf_type type_nsec3_wireformat[] = { /* GLDNS_RDF_TYPE_NSEC3_VARS, GLDNS_RDF_TYPE_NSEC3_NEXT_OWNER, GLDNS_RDF_TYPE_NSEC*/ @@ -372,7 +375,8 @@ static gldns_rr_descriptor rdata_field_descriptors[] = { {GLDNS_RR_TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1, type_openpgpkey_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 }, /* 62 */ {GLDNS_RR_TYPE_CSYNC, "CSYNC", 3, 3, type_csync_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 }, -{GLDNS_RR_TYPE_NULL, "TYPE63", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 }, + /* 63 */ + {GLDNS_RR_TYPE_ZONEMD, "ZONEMD", 4, 4, type_zonemd_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 }, {GLDNS_RR_TYPE_NULL, "TYPE64", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 }, {GLDNS_RR_TYPE_NULL, "TYPE65", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 }, {GLDNS_RR_TYPE_NULL, "TYPE66", 1, 1, type_0_wireformat, GLDNS_RDF_TYPE_NONE, GLDNS_RR_NO_COMPRESS, 0 }, diff --git a/src/gldns/rrdef.h b/src/gldns/rrdef.h index ecbf0749..a11984b3 100644 --- a/src/gldns/rrdef.h +++ b/src/gldns/rrdef.h @@ -195,6 +195,7 @@ enum gldns_enum_rr_type GLDNS_RR_TYPE_CDNSKEY = 60, /** RFC 7344 */ GLDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */ GLDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */ + GLDNS_RR_TYPE_ZONEMD = 63, /* draft-wessels-dns-zone-digest */ GLDNS_RR_TYPE_SPF = 99, /* RFC 4408 */ diff --git a/src/list.c b/src/list.c index c7bd476b..555a847f 100644 --- a/src/list.c +++ b/src/list.c @@ -418,7 +418,7 @@ getdns_list_create_with_memory_functions(void *(*malloc)(size_t), /*-------------------------- getdns_list_create_with_context */ struct getdns_list * -getdns_list_create_with_context(struct getdns_context *context) +getdns_list_create_with_context(const getdns_context *context) { if (context) return getdns_list_create_with_extended_memory_functions( diff --git a/src/mk-const-info.c.sh b/src/mk-const-info.c.sh index 5915bc85..26c2f626 100755 --- a/src/mk-const-info.c.sh +++ b/src/mk-const-info.c.sh @@ -14,7 +14,7 @@ cat > const-info.c << END_OF_HEAD static struct const_info consts_info[] = { { -1, NULL, "/* */" }, END_OF_HEAD -gawk '/^[ ]+GETDNS_[A-Z0-9_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%7d", $3); consts[key] = $1; }/^#define GETDNS_[A-Z0-9_]+[ ]+[0-9]+/ && !/^#define GETDNS_RRTYPE/ && !/^#define GETDNS_RRCLASS/ && !/^#define GETDNS_OPCODE/ && !/^#define GETDNS_RCODE/ && !/_TEXT/{ key = sprintf("%7d", $3); consts[key] = $2; }/^#define GETDNS_[A-Z0-9_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%7d", $4); consts[key] = $2; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ "val", \""name"\", "name"_TEXT },"}}' getdns/getdns_extra.h.in getdns/getdns.h.in const-info.h| sed 's/,,/,/g' >> const-info.c +gawk --non-decimal-data '/^[ ]+GETDNS_[A-Z0-9_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%7d", $3); consts[key] = $1; }/^#define GETDNS_[A-Z0-9_]+[ ]+(0[xX][0-9a-fA-F]+|[0-9]+)/ && !/^#define GETDNS_RRTYPE/ && !/^#define GETDNS_RRCLASS/ && !/^#define GETDNS_OPCODE/ && !/^#define GETDNS_RCODE/ && !/_TEXT/{ key = sprintf("%7d", $3); consts[key] = $2; }/^#define GETDNS_[A-Z0-9_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%7d", $4); consts[key] = $2; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ "val", \""name"\", "name"_TEXT },"}}' getdns/getdns_extra.h.in getdns/getdns.h.in const-info.h| sed 's/,,/,/g' >> const-info.c cat >> const-info.c << END_OF_TAIL }; @@ -49,7 +49,7 @@ getdns_get_errorstr_by_id(uint16_t err) static struct const_name_info consts_name_info[] = { END_OF_TAIL -gawk '/^[ ]+GETDNS_[A-Z0-9_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%d", $3); consts[$1] = key; }/^#define GETDNS_[A-Z0-9_]+[ ]+[0-9]+/ && !/_TEXT/{ key = sprintf("%d", $3); consts[$2] = key; }/^#define GETDNS_[A-Z0-9_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%d", $4); consts[$2] = key; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ \""val"\", "name" },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in const-info.h| sed 's/,,/,/g' >> const-info.c +gawk --non-decimal-data '/^[ ]+GETDNS_[A-Z0-9_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%d", $3); consts[$1] = key; }/^#define GETDNS_[A-Z0-9_]+[ ]+(0[xX][0-9a-fA-F]+|[0-9]+)/ && !/_TEXT/{ key = sprintf("%d", $3); consts[$2] = key; }/^#define GETDNS_[A-Z0-9_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%d", $4); consts[$2] = key; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ \""val"\", "name" },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in const-info.h| sed 's/,,/,/g' >> const-info.c cat >> const-info.c << END_OF_TAIL }; diff --git a/src/pubkey-pinning.c b/src/pubkey-pinning.c index 1b9674fd..e7aae2f7 100644 --- a/src/pubkey-pinning.c +++ b/src/pubkey-pinning.c @@ -55,6 +55,7 @@ #include #include "context.h" #include "util-internal.h" +#include "gldns/parseutil.h" #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) #define X509_STORE_CTX_get0_untrusted(store) store->untrusted @@ -92,16 +93,15 @@ static const getdns_bindata sha256 = { It is the caller's responsibility to call getdns_dict_destroy when it is no longer needed. */ -getdns_dict* getdns_pubkey_pin_create_from_string( - getdns_context* context, - const char* str) +getdns_dict *getdns_pubkey_pin_create_from_string( + const getdns_context *context, const char *str) { BIO *bio = NULL; size_t i; uint8_t buf[SHA256_DIGEST_LENGTH]; char inbuf[B64_ENCODED_SHA256_LENGTH + 1]; getdns_bindata value = { .size = SHA256_DIGEST_LENGTH, .data = buf }; - getdns_dict* out = NULL; + getdns_dict *out = NULL; /* we only do sha256 right now, make sure this is well-formed */ if (!str || strncmp(PIN_PREFIX, str, PIN_PREFIX_LENGTH)) @@ -270,7 +270,7 @@ _getdns_get_pubkey_pinset_from_list(const getdns_list *pinset_list, } getdns_return_t -_getdns_get_pubkey_pinset_list(getdns_context *ctx, +_getdns_get_pubkey_pinset_list(const getdns_context *ctx, const sha256_pin_t *pinset_in, getdns_list **pinset_list) { @@ -378,20 +378,20 @@ _getdns_associate_upstream_with_SSL(SSL *ssl, } getdns_return_t -_getdns_verify_pinset_match(const sha256_pin_t *pinset, - X509_STORE_CTX *store) +_getdns_verify_pinset_match(const getdns_upstream *upstream, + const sha256_pin_t *pinset, X509_STORE_CTX *store) { - getdns_return_t ret = GETDNS_RETURN_GENERIC_ERROR; X509 *x, *prev = NULL; + char x_name_spc[1024], *x_name, prev_name_spc[1024]; int i, len; unsigned char raw[4096]; unsigned char *next; unsigned char buf[sizeof(pinset->pin)]; const sha256_pin_t *p; - if (pinset == NULL || store == NULL) - return GETDNS_RETURN_GENERIC_ERROR; - + assert(pinset); + assert(store); + /* start at the base of the chain (the end-entity cert) and * make sure that some valid element of the chain does match * the pinset. */ @@ -407,29 +407,74 @@ _getdns_verify_pinset_match(const sha256_pin_t *pinset, /* TODO: how do we handle raw public keys? */ - for (i = 0; i < sk_X509_num(X509_STORE_CTX_get0_untrusted(store)); i++, prev = x) { - + for ( i = 0 + ; i < sk_X509_num(X509_STORE_CTX_get0_untrusted(store)) + ; i++, prev = x) { x = sk_X509_value(X509_STORE_CTX_get0_untrusted(store), i); -#if defined(STUB_DEBUG) && STUB_DEBUG - DEBUG_STUB("%s %-35s: Name of cert: %d ", - STUB_DEBUG_SETUP_TLS, __FUNC__, i); - X509_NAME_print_ex_fp(stderr, X509_get_subject_name(x), 1, XN_FLAG_ONELINE); - fprintf(stderr, "\n"); -#endif + x_name = NULL; + + if (upstream->upstreams + && _getdns_check_log(&upstream->upstreams->log, + GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG)) { + + x_name = X509_NAME_oneline( X509_get_subject_name(x) + , x_name_spc + , sizeof(x_name_spc)); + _getdns_upstream_log( upstream + , GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG + , "%-40s : Verifying pinsets with cert: %d %s\n" + , upstream->addr_str, i, x_name); + } if (i > 0) { - /* we ensure that "prev" is signed by "x" */ + /* we ensure that "prev" is signed by "x" */ EVP_PKEY *pkey = X509_get_pubkey(x); int verified; + if (!pkey) { - DEBUG_STUB("%s %-35s: Could not get pubkey from cert %d (%p)\n", - STUB_DEBUG_SETUP_TLS, __FUNC__, i, (void*)x); + if (!upstream->upstreams + || !_getdns_check_log( + &upstream->upstreams->log + , GETDNS_LOG_UPSTREAM_STATS + , GETDNS_LOG_ERR + )) + return GETDNS_RETURN_GENERIC_ERROR; + + if (!x_name) + x_name = X509_NAME_oneline( + X509_get_subject_name(x) + , x_name_spc, sizeof(x_name_spc)); + _getdns_upstream_log( upstream + , GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR + , "%-40s : Could not get pubkey from cert " + "cert: %d %s\n" + , upstream->addr_str, i, x_name); return GETDNS_RETURN_GENERIC_ERROR; } verified = X509_verify(prev, pkey); EVP_PKEY_free(pkey); if (!verified) { - DEBUG_STUB("%s %-35s: cert %d (%p) was not signed by cert %d\n", - STUB_DEBUG_SETUP_TLS, __FUNC__, i-1, (void*)prev, i); + if (!upstream->upstreams + || !_getdns_check_log( + &upstream->upstreams->log + , GETDNS_LOG_UPSTREAM_STATS + , GETDNS_LOG_ERR + )) + return GETDNS_RETURN_GENERIC_ERROR; + + if (!x_name) + x_name = X509_NAME_oneline( + X509_get_subject_name(x) + , x_name_spc, sizeof(x_name_spc)); + _getdns_upstream_log( upstream + , GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR + , "%-40s : Cert: %d %swas not signed " + "by cert %d %s\n", upstream->addr_str + , i - 1 + , X509_NAME_oneline( + X509_get_subject_name(prev) + , prev_name_spc + , sizeof(prev_name_spc) ) + , i, x_name); return GETDNS_RETURN_GENERIC_ERROR; } } @@ -437,31 +482,85 @@ _getdns_verify_pinset_match(const sha256_pin_t *pinset, /* digest the cert with sha256 */ len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), NULL); if (len > (int)sizeof(raw)) { - DEBUG_STUB("%s %-35s: Pubkey %d is larger than %"PRIsz" octets\n", - STUB_DEBUG_SETUP_TLS, __FUNC__, i, sizeof(raw)); + if (!upstream->upstreams + || !_getdns_check_log( &upstream->upstreams->log + , GETDNS_LOG_UPSTREAM_STATS + , GETDNS_LOG_WARNING )) + continue; + + if (!x_name) + x_name = X509_NAME_oneline( + X509_get_subject_name(x) + , x_name_spc, sizeof(x_name_spc)); + _getdns_upstream_log( upstream + , GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING + , "%-40s : Skipping cert %d %s, because pubkey is " + "larger than buffer size (%"PRIsz" octets)\n" + , upstream->addr_str, i, x_name, sizeof(raw)); continue; } next = raw; i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &next); if (next - raw != len) { - DEBUG_STUB("%s %-35s: Pubkey %d claimed it needed %d octets, really needed %"PRIsz"\n", - STUB_DEBUG_SETUP_TLS, __FUNC__, i, len, next - raw); + if (!upstream->upstreams + || !_getdns_check_log( &upstream->upstreams->log + , GETDNS_LOG_UPSTREAM_STATS + , GETDNS_LOG_WARNING )) + continue; + + if (!x_name) + x_name = X509_NAME_oneline( + X509_get_subject_name(x) + , x_name_spc, sizeof(x_name_spc)); + _getdns_upstream_log( upstream + , GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_WARNING + , "%-40s : Skipping cert %d %s, because pubkey si" + "ze %"PRIsz" differs from earlier reported %d\n" + , upstream->addr_str, i, x_name, next - raw, len); continue; } SHA256(raw, len, buf); /* compare it */ - for (p = pinset; p; p = p->next) - if (0 == memcmp(buf, p->pin, sizeof(p->pin))) { - DEBUG_STUB("%s %-35s: Pubkey %d matched pin %p (%"PRIsz")\n", - STUB_DEBUG_SETUP_TLS, __FUNC__, i, (void*)p, sizeof(p->pin)); - return GETDNS_RETURN_GOOD; - } else - DEBUG_STUB("%s %-35s: Pubkey %d did not match pin %p\n", - STUB_DEBUG_SETUP_TLS, __FUNC__, i, (void*)p); - } + for (p = pinset; p; p = p->next) { + char pin_str[1024]; + + if (x_name) /* only when debugging */ + gldns_b64_ntop( p->pin , sizeof(p->pin) + , pin_str, sizeof(pin_str) ); - return ret; + if (0 == memcmp(buf, p->pin, sizeof(p->pin))) { + if (!upstream->upstreams + || !_getdns_check_log( + &upstream->upstreams->log + , GETDNS_LOG_UPSTREAM_STATS + , GETDNS_LOG_INFO)) + return GETDNS_RETURN_GOOD; + + if (!x_name) { + x_name = X509_NAME_oneline( + X509_get_subject_name(x) + , x_name_spc, sizeof(x_name_spc)); + gldns_b64_ntop( p->pin , sizeof(p->pin) + , pin_str + , sizeof(pin_str) ); + } + _getdns_upstream_log( upstream + , GETDNS_LOG_UPSTREAM_STATS + , GETDNS_LOG_INFO + , "%-40s : Pubkey of cert %d %s matched " + "pin %s\n", upstream->addr_str + , i, x_name, pin_str); + return GETDNS_RETURN_GOOD; + } + _getdns_upstream_log( upstream + , GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG + , "%-40s : Pubkey of cert %d %s did not match" + " pin %s\n", upstream->addr_str + , i, x_name, pin_str); + } + } + return GETDNS_RETURN_GENERIC_ERROR; } /* pubkey-pinning.c */ diff --git a/src/pubkey-pinning.h b/src/pubkey-pinning.h index 894ccf00..a17ecb61 100644 --- a/src/pubkey-pinning.h +++ b/src/pubkey-pinning.h @@ -44,7 +44,7 @@ _getdns_get_pubkey_pinset_from_list(const getdns_list *pinset_list, /* create a getdns_list version of the pinset */ getdns_return_t -_getdns_get_pubkey_pinset_list(getdns_context *ctx, +_getdns_get_pubkey_pinset_list(const getdns_context *ctx, const sha256_pin_t *pinset_in, getdns_list **pinset_list); @@ -61,8 +61,8 @@ _getdns_associate_upstream_with_SSL(SSL *ssl, getdns_upstream *upstream); getdns_return_t -_getdns_verify_pinset_match(const sha256_pin_t *pinset, - X509_STORE_CTX *store); +_getdns_verify_pinset_match(const getdns_upstream *upstream, + const sha256_pin_t *pinset, X509_STORE_CTX *store); #endif /* pubkey-pinning.h */ diff --git a/src/rr-dict.c b/src/rr-dict.c index ab0c2b82..79fb7bcc 100644 --- a/src/rr-dict.c +++ b/src/rr-dict.c @@ -613,6 +613,11 @@ static _getdns_rdata_def csync_rdata[] = { { "serial" , GETDNS_RDF_I4 , NULL }, { "flags" , GETDNS_RDF_I2 , NULL }, { "type_bit_maps" , GETDNS_RDF_X , NULL }}; +static _getdns_rdata_def zonemd_rdata[] = { + { "serial" , GETDNS_RDF_I4 , NULL }, + { "digest_type" , GETDNS_RDF_I1 , NULL }, + { "reserved" , GETDNS_RDF_I1 , NULL }, + { "digest" , GETDNS_RDF_X , NULL }}; static _getdns_rdata_def spf_rdata[] = { { "text" , GETDNS_RDF_S_M , NULL }}; static _getdns_rdata_def nid_rdata[] = { @@ -723,9 +728,9 @@ static _getdns_rr_def _getdns_rr_defs[] = { { "TALINK", talink_rdata, ALEN( talink_rdata) }, { "CDS", ds_rdata, ALEN( ds_rdata) }, { "CDNSKEY", dnskey_rdata, ALEN( dnskey_rdata) }, - { "OPENPGPKEY", openpgpkey_rdata, ALEN(openpgpkey_rdata) }, /* 61 - */ - { "CSYNC", csync_rdata, ALEN( csync_rdata) }, /* - 62 */ - { NULL, NULL, 0 }, + { "OPENPGPKEY", openpgpkey_rdata, ALEN(openpgpkey_rdata) }, + { "CSYNC", csync_rdata, ALEN( csync_rdata) }, + { "ZONEMD", zonemd_rdata, ALEN( zonemd_rdata) }, /* - 63 */ { NULL, NULL, 0 }, { NULL, NULL, 0 }, { NULL, NULL, 0 }, diff --git a/src/server.c b/src/server.c index a6d4008e..3736a6f2 100644 --- a/src/server.c +++ b/src/server.c @@ -287,8 +287,8 @@ _getdns_cancel_reply(getdns_context *context, connection *conn) } getdns_return_t -getdns_reply( - getdns_context *context, getdns_dict *reply, getdns_transaction_t request_id) +getdns_reply(getdns_context *context, + const getdns_dict *reply, getdns_transaction_t request_id) { /* TODO: Check request_id at context->outbound_requests */ connection *conn = (connection *)(intptr_t)request_id; diff --git a/src/stub.c b/src/stub.c index 7dfcf1cb..d7af6eb4 100644 --- a/src/stub.c +++ b/src/stub.c @@ -887,7 +887,8 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* Deal with the pinset validation */ if (upstream->tls_pubkey_pinset) - pinset_ret = _getdns_verify_pinset_match(upstream->tls_pubkey_pinset, ctx); + pinset_ret = _getdns_verify_pinset_match( + upstream, upstream->tls_pubkey_pinset, ctx); if (pinset_ret != GETDNS_RETURN_GOOD) { DEBUG_STUB("%s %-35s: FD: %d, WARNING: Pinset validation failure!\n", @@ -2402,9 +2403,9 @@ upstream_find_for_netreq(getdns_network_req *netreq) return fd; } /* Handle better, will give generic error*/ - DEBUG_STUB("%s %-35s: MSG: %p No valid upstream! \n", STUB_DEBUG_SCHEDULE, __FUNC__, (void*)netreq); - _getdns_context_log(netreq->owner->context, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR, - " *FAILURE* no valid transports or upstreams available!\n"); + _getdns_log(&netreq->owner->context->log + , GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR + , " *FAILURE* no valid transports or upstreams available!\n"); return -1; } diff --git a/src/test/check_getdns_address.h b/src/test/check_getdns_address.h index f898bdd8..10e4b7b2 100644 --- a/src/test/check_getdns_address.h +++ b/src/test/check_getdns_address.h @@ -192,7 +192,7 @@ CONTEXT_CREATE(TRUE); EVENT_BASE_CREATE; - ASSERT_RC(getdns_address(context, "localhost", NULL, + ASSERT_RC(getdns_address(context, "localhost.", NULL, &fn_ref, &transaction_id, callbackfn), GETDNS_RETURN_GOOD, "Return code from getdns_address()"); diff --git a/src/test/check_getdns_address_sync.h b/src/test/check_getdns_address_sync.h index f9e6b97d..07f8408f 100644 --- a/src/test/check_getdns_address_sync.h +++ b/src/test/check_getdns_address_sync.h @@ -127,7 +127,7 @@ CONTEXT_CREATE(TRUE); - ASSERT_RC(getdns_address_sync(context, "localhost", NULL, &response), + ASSERT_RC(getdns_address_sync(context, "localhost.", NULL, &response), GETDNS_RETURN_GOOD, "Return code from getdns_address_sync()"); EXTRACT_LOCAL_RESPONSE; diff --git a/src/test/check_getdns_common.c b/src/test/check_getdns_common.c index af894be5..192ab661 100644 --- a/src/test/check_getdns_common.c +++ b/src/test/check_getdns_common.c @@ -70,6 +70,7 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e * If it is absent, do not try to decompose the replies_tree, because the * answer most likely came not from DNS. */ + ex_response->response = response; have_answer_type = getdns_dict_get_int(response, "answer_type", &ex_response->top_answer_type) == GETDNS_RETURN_GOOD; @@ -233,11 +234,14 @@ void assert_address_in_answer(struct extracted_response *ex_response, int a, int */ void assert_address_in_just_address_answers(struct extracted_response *ex_response) { - size_t length; + size_t length = 0; + char *resp_str = ""; ASSERT_RC(getdns_list_get_length(ex_response->just_address_answers, &length), GETDNS_RETURN_GOOD, "Failed to extract \"just_address_answers\" length"); - - ck_assert_msg(length > 0, "Expected \"just_address_answers\" length > 0, got %d", length); + + if (length == 0) resp_str = getdns_pretty_print_dict(ex_response->response); + ck_assert_msg(length > 0, "Expected \"just_address_answers\" length > 0, got %d\n%s", length, resp_str); + if (length == 0) free(resp_str); } /* diff --git a/src/test/check_getdns_common.h b/src/test/check_getdns_common.h index 6fb3b555..c9691b59 100644 --- a/src/test/check_getdns_common.h +++ b/src/test/check_getdns_common.h @@ -41,6 +41,7 @@ struct extracted_response { uint32_t top_answer_type; + struct getdns_dict *response; struct getdns_bindata *top_canonical_name; struct getdns_list *just_address_answers; struct getdns_list *replies_full; diff --git a/src/util-internal.c b/src/util-internal.c index 0eaf3435..45fd2fda 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -54,7 +54,8 @@ getdns_return_t -getdns_dict_util_get_string(getdns_dict * dict, char *name, char **result) +getdns_dict_util_get_string(const getdns_dict *dict, + const char *name, char **result) { struct getdns_bindata *bindata = NULL; if (!result) { @@ -1454,7 +1455,7 @@ _getdns_validate_dname(const char* dname) { } /* _getdns_validate_dname */ -static void _getdns_reply2wire_buf(gldns_buffer *buf, getdns_dict *reply) +static void _getdns_reply2wire_buf(gldns_buffer *buf, const getdns_dict *reply) { getdns_dict *rr_dict, *q_dict, *h_dict; getdns_list *section; @@ -1510,7 +1511,7 @@ static void _getdns_reply2wire_buf(gldns_buffer *buf, getdns_dict *reply) } } -static void _getdns_list2wire_buf(gldns_buffer *buf, getdns_list *l) +static void _getdns_list2wire_buf(gldns_buffer *buf, const getdns_list *l) { getdns_dict *rr_dict; size_t i, pkt_start; @@ -1548,8 +1549,8 @@ static void _getdns_list2wire_buf(gldns_buffer *buf, getdns_list *l) gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, ancount); } -uint8_t *_getdns_list2wire( - getdns_list *l, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf) +uint8_t *_getdns_list2wire(const getdns_list *l, + uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf) { gldns_buffer gbuf; size_t sz; @@ -1569,8 +1570,8 @@ uint8_t *_getdns_list2wire( return buf; } -uint8_t *_getdns_reply2wire( - getdns_dict *r, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf) +uint8_t *_getdns_reply2wire(const getdns_dict *r, + uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf) { gldns_buffer gbuf; size_t sz; @@ -1590,7 +1591,7 @@ uint8_t *_getdns_reply2wire( return buf; } -void _getdns_wire2list(uint8_t *pkt, size_t pkt_len, getdns_list *l) +void _getdns_wire2list(const uint8_t *pkt, size_t pkt_len, getdns_list *l) { _getdns_rr_iter rr_spc, *rr; getdns_dict *rr_dict; diff --git a/src/util-internal.h b/src/util-internal.h index 529ebce0..d512a9d2 100644 --- a/src/util-internal.h +++ b/src/util-internal.h @@ -147,17 +147,18 @@ _getdns_rr_iter2rr_dict_canonical( struct mem_funcs *mf, _getdns_rr_iter *i, uint32_t *orig_ttl); struct getdns_dns_req; -struct getdns_dict *_getdns_create_getdns_response(struct getdns_dns_req *completed_request); +struct getdns_dict *_getdns_create_getdns_response( + struct getdns_dns_req *completed_request); getdns_return_t _getdns_validate_dname(const char* dname); -uint8_t *_getdns_list2wire( - getdns_list *l, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf); +uint8_t *_getdns_list2wire(const getdns_list *l, + uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf); -uint8_t *_getdns_reply2wire( - getdns_dict *r, uint8_t *buf, size_t *buf_len, struct mem_funcs *mf); +uint8_t *_getdns_reply2wire(const getdns_dict *r, + uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf); -void _getdns_wire2list(uint8_t *pkt, size_t pkt_len, getdns_list *l); +void _getdns_wire2list(const uint8_t *pkt, size_t pkt_len, getdns_list *l); /** @@ -218,19 +219,46 @@ INLINE uint64_t _getdns_ms_until_expiry2(uint64_t expires, uint64_t *now_ms) return *now_ms >= expires ? 0 : expires - *now_ms; } -# if defined(HAVE_DECL_SSL_SET_MIN_PROTO_VERSION) && HAVE_DECL_SSL_SET_MIN_PROTO_VERSION +#if defined(HAVE_DECL_SSL_SET_MIN_PROTO_VERSION) \ + && HAVE_DECL_SSL_SET_MIN_PROTO_VERSION + INLINE int _getdns_tls_version2openssl_version(getdns_tls_version_t v) { switch (v) { +# ifdef SSL3_VERSION case GETDNS_SSL3 : return SSL3_VERSION; +# endif +# ifdef TLS1_VERSION case GETDNS_TLS1 : return TLS1_VERSION; +# endif +# ifdef TLS1_1_VERSION case GETDNS_TLS1_1: return TLS1_1_VERSION; +# endif +# ifdef TLS1_2_VERSION case GETDNS_TLS1_2: return TLS1_2_VERSION; +# endif +# ifdef TLS1_3_VERSION case GETDNS_TLS1_3: return TLS1_3_VERSION; - default : return TLS_MAX_VERSION; +# endif + default : +# if defined(TLS_MAX_VERSION) + return TLS_MAX_VERSION; +# elif defined(TLS1_3_VERSION) + return TLS1_3_VERSION; +# elif defined(TLS1_2_VERSION) + return TLS1_2_VERSION; +# elif defined(TLS1_1_VERSION) + return TLS1_1_VERSION; +# elif defined(TLS1_VERSION) + return TLS1_VERSION; +# elif defined(SSL3_VERSION) + return SSL3_VERSION; +# else + return -1; +# endif } } -# endif +#endif #endif /* util-internal.h */ diff --git a/stubby b/stubby index 8fb853ac..919b7d91 160000 --- a/stubby +++ b/stubby @@ -1 +1 @@ -Subproject commit 8fb853ac8d6148fd9b53fdcbc107ecd375071ec5 +Subproject commit 919b7d914ca618f4a843464d5825383f45809f3e