mirror of https://github.com/getdnsapi/getdns.git
Configurable zero configuration DNSSEC parameters
This commit is contained in:
parent
8aa46b305d
commit
8f3ce9af35
306
src/anchor.c
306
src/anchor.c
|
@ -50,35 +50,6 @@
|
|||
#include "rr-iter.h"
|
||||
#include "util-internal.h"
|
||||
|
||||
#define P7SIGNER "dnssec@iana.org"
|
||||
|
||||
/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */
|
||||
static char _getdns_builtin_cert[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
|
||||
"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
|
||||
"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
|
||||
"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
|
||||
"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
|
||||
"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
|
||||
"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
|
||||
"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
|
||||
"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
|
||||
"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
|
||||
"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
|
||||
"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
|
||||
"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
|
||||
"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
|
||||
"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
|
||||
"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
|
||||
"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
|
||||
"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
|
||||
"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static getdns_bindata _getdns_builtin_cert_bd =
|
||||
{ sizeof(_getdns_builtin_cert) - 1, (void *)_getdns_builtin_cert};
|
||||
|
||||
/* get key usage out of its extension, returns 0 if no key_usage extension */
|
||||
static unsigned long
|
||||
_getdns_get_usage_of_ex(X509* cert)
|
||||
|
@ -585,7 +556,7 @@ static ta_iter *ta_iter_init(ta_iter *ta, const char *doc, size_t doc_len)
|
|||
return ta_iter_next(ta);
|
||||
}
|
||||
|
||||
uint16_t _getdns_parse_xml_trust_anchors_buf(
|
||||
static uint16_t _getdns_parse_xml_trust_anchors_buf(
|
||||
gldns_buffer *gbuf, time_t now, char *xml_data, size_t xml_len)
|
||||
{
|
||||
ta_iter ta_spc, *ta;
|
||||
|
@ -750,18 +721,35 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now)
|
|||
uint8_t xml_spc[4096], *xml_data;
|
||||
uint8_t p7s_spc[4096], *p7s_data = NULL;
|
||||
size_t xml_len, p7s_len;
|
||||
const char *verify_email = NULL;
|
||||
const char *verify_CA = NULL;
|
||||
getdns_return_t r;
|
||||
|
||||
BIO *xml = NULL, *p7s = NULL, *crt = NULL;
|
||||
X509 *x = NULL;
|
||||
X509_STORE *store = NULL;
|
||||
|
||||
if (!(xml_data = _getdns_context_get_priv_file(context,
|
||||
if ((r = getdns_context_get_trust_anchor_verify_CA(
|
||||
context, ".", &verify_CA)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify"
|
||||
" CA: \"%s\"\n", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
|
||||
else if ((r = getdns_context_get_trust_anchor_verify_email(
|
||||
context, ".", &verify_email)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify email "
|
||||
"address: \"%s\"\n", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
|
||||
else if (!(xml_data = _getdns_context_get_priv_file(context,
|
||||
"root-anchors.xml", xml_spc, sizeof(xml_spc), &xml_len)))
|
||||
; /* pass */
|
||||
DEBUG_ANCHOR("DEBUG %s(): root-anchors.xml not present\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if (!(p7s_data = _getdns_context_get_priv_file(context,
|
||||
"root-anchors.p7s", p7s_spc, sizeof(p7s_spc), &p7s_len)))
|
||||
; /* pass */
|
||||
DEBUG_ANCHOR("DEBUG %s(): root-anchors.p7s not present\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if (!(xml = BIO_new_mem_buf(xml_data, xml_len)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Failed allocating xml BIO\n"
|
||||
|
@ -770,8 +758,8 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now)
|
|||
else if (!(p7s = BIO_new_mem_buf(p7s_data, p7s_len)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Failed allocating p7s BIO\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if (!(crt = BIO_new_mem_buf((void *)_getdns_builtin_cert, -1)))
|
||||
|
||||
else if (!(crt = BIO_new_mem_buf((void *)verify_CA, -1)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Failed allocating crt BIO\n"
|
||||
, __FUNC__);
|
||||
|
||||
|
@ -787,7 +775,7 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now)
|
|||
DEBUG_ANCHOR("ERROR %s(): Adding certificate to store\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if (_getdns_verify_p7sig(xml, p7s, store, "dnssec@iana.org")) {
|
||||
else if (_getdns_verify_p7sig(xml, p7s, store, verify_email)) {
|
||||
uint8_t ta_spc[sizeof(context->trust_anchors_spc)];
|
||||
size_t ta_len;
|
||||
uint8_t *ta = NULL;
|
||||
|
@ -837,17 +825,17 @@ void _getdns_context_equip_with_anchor(getdns_context *context, time_t now)
|
|||
GETDNS_FREE(context->mf, p7s_data);
|
||||
}
|
||||
|
||||
static const uint8_t tas_write_p7s_buf[] =
|
||||
"GET /root-anchors/root-anchors.p7s HTTP/1.1\r\n"
|
||||
"Host: data.iana.org\r\n"
|
||||
static const char tas_write_p7s_buf[] =
|
||||
"GET %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"\r\n";
|
||||
|
||||
static const uint8_t tas_write_xml_p7s_buf[] =
|
||||
"GET /root-anchors/root-anchors.xml HTTP/1.1\r\n"
|
||||
"Host: data.iana.org\r\n"
|
||||
static const char tas_write_xml_p7s_buf[] =
|
||||
"GET %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"\r\n"
|
||||
"GET /root-anchors/root-anchors.p7s HTTP/1.1\r\n"
|
||||
"Host: data.iana.org\r\n"
|
||||
"GET %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"\r\n";
|
||||
|
||||
|
||||
|
@ -888,6 +876,8 @@ static void tas_cleanup(getdns_context *context, tas_connection *a)
|
|||
tas_rinse(context, a);
|
||||
if (a->req)
|
||||
_getdns_context_cancel_request(a->req->owner);
|
||||
if (a->http)
|
||||
GETDNS_FREE(context->mf, (void *)a->http);
|
||||
(void) memset(a, 0, sizeof(*a));
|
||||
a->fd = -1;
|
||||
}
|
||||
|
@ -1004,14 +994,33 @@ static void tas_doc_read(getdns_context *context, tas_connection *a)
|
|||
getdns_bindata p7s_bd;
|
||||
uint8_t *tas = context->trust_anchors_spc;
|
||||
size_t tas_len = sizeof(context->trust_anchors_spc);
|
||||
const char *verify_email = NULL;
|
||||
getdns_bindata verify_CA;
|
||||
getdns_return_t r;
|
||||
|
||||
p7s_bd.data = a->tcp.read_buf;
|
||||
p7s_bd.size = a->tcp.read_buf_len;
|
||||
tas = tas_validate(&context->mf, &a->xml, &p7s_bd,
|
||||
&_getdns_builtin_cert_bd, "dnssec@iana.org",
|
||||
time(NULL), tas, &tas_len);
|
||||
|
||||
if (tas) {
|
||||
if ((r = getdns_context_get_trust_anchor_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));
|
||||
|
||||
else if (!(verify_CA.size = strlen((const char *)verify_CA.data)))
|
||||
; /* pass */
|
||||
|
||||
else if ((r = getdns_context_get_trust_anchor_verify_email(
|
||||
context, ".", &verify_email)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Getting trust anchor verify"
|
||||
" email address: \"%s\"\n", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
|
||||
else if (!(tas = tas_validate(&context->mf, &a->xml, &p7s_bd,
|
||||
&verify_CA, verify_email, time(NULL), tas, &tas_len)))
|
||||
; /* pass */
|
||||
|
||||
else {
|
||||
context->trust_anchors = tas;
|
||||
context->trust_anchors_len = tas_len;
|
||||
_getdns_context_write_priv_file(
|
||||
|
@ -1019,8 +1028,9 @@ static void tas_doc_read(getdns_context *context, tas_connection *a)
|
|||
_getdns_context_write_priv_file(
|
||||
context, "root-anchors.p7s", &p7s_bd);
|
||||
tas_success(context, a);
|
||||
} else
|
||||
tas_fail(context, a);
|
||||
return;
|
||||
}
|
||||
tas_fail(context, a);
|
||||
return;
|
||||
}
|
||||
/* First try to read signatures immediately */
|
||||
|
@ -1220,6 +1230,38 @@ static void tas_write_cb(void *userarg)
|
|||
tas_next(context, a);
|
||||
}
|
||||
|
||||
static getdns_return_t _getdns_get_tas_url_hostname(
|
||||
getdns_context *context, char *hostname, const char **path)
|
||||
{
|
||||
getdns_return_t r;
|
||||
const char *url;
|
||||
char *next_slash;
|
||||
size_t s;
|
||||
|
||||
if ((r = getdns_context_get_trust_anchor_url(context, ".", &url)))
|
||||
return r;
|
||||
|
||||
if ((next_slash = strchr(url + 7 /* "http://" */, '/'))) {
|
||||
if (next_slash - url - 7 > 254)
|
||||
return GETDNS_RETURN_NO_SUCH_LIST_ITEM;
|
||||
if (path)
|
||||
*path = next_slash;
|
||||
strncpy(hostname, url + 7, next_slash - url - 7);
|
||||
hostname[next_slash - url - 7] = 0;
|
||||
} else {
|
||||
if (path)
|
||||
*path = url + strlen(url);
|
||||
strncpy(hostname, url + 7, 254);
|
||||
hostname[254] = 0;
|
||||
}
|
||||
s = strlen(hostname);
|
||||
if (s && s < 255 && hostname[s - 1] != '.') {
|
||||
hostname[s] = '.';
|
||||
hostname[s+1] = '\0';
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static void tas_connect(getdns_context *context, tas_connection *a)
|
||||
{
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
|
@ -1281,16 +1323,74 @@ static void tas_connect(getdns_context *context, tas_connection *a)
|
|||
r = connect(a->fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
}
|
||||
if (r == 0 || (r == -1 && (_getdns_EINPROGRESS ||
|
||||
_getdns_EWOULDBLOCK))) {
|
||||
_getdns_EWOULDBLOCK))) {
|
||||
char tas_hostname[256];
|
||||
const char *path = "", *fmt;
|
||||
getdns_return_t R;
|
||||
char *write_buf;
|
||||
size_t buf_sz, path_len, hostname_len;
|
||||
|
||||
a->state += 1;
|
||||
if (a->state == TAS_RETRY_GET_PS7) {
|
||||
a->tcp.write_buf = tas_write_p7s_buf;
|
||||
a->tcp.write_buf_len = sizeof(tas_write_p7s_buf) - 1;
|
||||
} else {
|
||||
a->tcp.write_buf = tas_write_xml_p7s_buf;
|
||||
a->tcp.write_buf_len = sizeof(tas_write_xml_p7s_buf) - 1;
|
||||
if (a->http) {
|
||||
GETDNS_FREE(context->mf, (void *)a->http);
|
||||
a->http = NULL;
|
||||
a->tcp.write_buf = NULL;
|
||||
a->tcp.write_buf_len = 0;
|
||||
a->tcp.written = 0;
|
||||
}
|
||||
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));
|
||||
goto error;
|
||||
}
|
||||
hostname_len = strlen(tas_hostname);
|
||||
if (hostname_len > 0 && tas_hostname[hostname_len - 1] == '.')
|
||||
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);
|
||||
goto error;
|
||||
}
|
||||
if (a->state == TAS_RETRY_GET_PS7) {
|
||||
buf_sz = sizeof(tas_write_p7s_buf)
|
||||
+ 1 * (hostname_len - 2) + 1 * (path_len - 2) + 1;
|
||||
fmt = tas_write_p7s_buf;
|
||||
} else {
|
||||
buf_sz = sizeof(tas_write_xml_p7s_buf)
|
||||
+ 2 * (hostname_len - 2) + 2 * (path_len - 2) + 1;
|
||||
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__);
|
||||
goto error;
|
||||
}
|
||||
if (a->state == TAS_RETRY_GET_PS7) {
|
||||
(void) snprintf( write_buf, buf_sz, fmt
|
||||
, path, tas_hostname);
|
||||
write_buf[4 + path_len - 3] =
|
||||
write_buf[4 + path_len - 3] == 'X' ? 'P' : 'p';
|
||||
write_buf[4 + path_len - 2] = '7';
|
||||
write_buf[4 + path_len - 1] =
|
||||
write_buf[4 + path_len - 1] == 'L' ? 'S' : 's';
|
||||
} else {
|
||||
(void) snprintf( write_buf, buf_sz, fmt
|
||||
, path, tas_hostname
|
||||
, path, tas_hostname);
|
||||
write_buf[29 + hostname_len + 2 * path_len - 3] =
|
||||
write_buf[29 + hostname_len + 2 * path_len - 3] == 'X'
|
||||
? 'P' : 'p';
|
||||
write_buf[29 + hostname_len + 2 * path_len - 2] = '7';
|
||||
write_buf[29 + hostname_len + 2 * path_len - 1] =
|
||||
write_buf[29 + hostname_len + 2 * path_len - 1] == 'L'
|
||||
? 'S' : 's';
|
||||
}
|
||||
DEBUG_ANCHOR("Write buffer: \"%s\"\n", write_buf);
|
||||
a->tcp.write_buf = (uint8_t *)(a->http = write_buf);
|
||||
a->tcp.write_buf_len = buf_sz - 1;
|
||||
a->tcp.written = 0;
|
||||
|
||||
GETDNS_SCHEDULE_EVENT(a->loop, a->fd, 2000,
|
||||
|
@ -1301,6 +1401,7 @@ static void tas_connect(getdns_context *context, tas_connection *a)
|
|||
} else
|
||||
DEBUG_ANCHOR("Connect error: %s\n", strerror(errno));
|
||||
|
||||
error:
|
||||
tas_next(context, a);
|
||||
}
|
||||
|
||||
|
@ -1316,7 +1417,7 @@ static void tas_happy_eyeballs_cb(void *userarg)
|
|||
tas_connect(context, &context->a);
|
||||
}
|
||||
|
||||
static void data_iana_org(getdns_dns_req *dnsreq)
|
||||
static void _tas_hostname_lookup_cb(getdns_dns_req *dnsreq)
|
||||
{
|
||||
getdns_context *context = (getdns_context *)dnsreq->user_pointer;
|
||||
tas_connection *a;
|
||||
|
@ -1328,19 +1429,30 @@ static void data_iana_org(getdns_dns_req *dnsreq)
|
|||
a->rrset = _getdns_rrset_answer(
|
||||
&a->rrset_spc, a->req->response, a->req->response_len);
|
||||
|
||||
if (!a->rrset)
|
||||
DEBUG_ANCHOR("%s lookup for data.iana.org. returned no "
|
||||
"response\n", rt_str(a->req->request_type));
|
||||
|
||||
else if (a->req->response_len < dnsreq->name_len + 12 ||
|
||||
if (!a->rrset) {
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
char tas_hostname[256] = "<no hostname>";
|
||||
(void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL);
|
||||
DEBUG_ANCHOR("%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)
|
||||
DEBUG_ANCHOR("%s lookup for data.iana.org. returned wrong "
|
||||
"response\n", rt_str(a->req->request_type));
|
||||
else if (!(a->rr = _getdns_rrtype_iter_init(&a->rr_spc, a->rrset)))
|
||||
DEBUG_ANCHOR("%s lookup for data.iana.org. returned no "
|
||||
"addresses\n", rt_str(a->req->request_type));
|
||||
else {
|
||||
a->rrset->rr_type != a->req->request_type) {
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
char tas_hostname[256] = "<no hostname>";
|
||||
(void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL);
|
||||
DEBUG_ANCHOR("%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] = "<no hostname>";
|
||||
(void) _getdns_get_tas_url_hostname(context, tas_hostname, NULL);
|
||||
DEBUG_ANCHOR("%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;
|
||||
a->loop = dnsreq->loop;
|
||||
|
@ -1371,11 +1483,44 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
{
|
||||
getdns_return_t r;
|
||||
size_t scheduled;
|
||||
char tas_hostname[256];
|
||||
const char *verify_CA;
|
||||
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));
|
||||
return;
|
||||
|
||||
} else if ((r = getdns_context_get_trust_anchor_verify_CA(
|
||||
context, ".", &verify_CA))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not get verify CA"
|
||||
": \"%s\"", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
return;
|
||||
|
||||
} else if (!*verify_CA) {
|
||||
DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely "
|
||||
"disabled by empty verify CA\n");
|
||||
return;
|
||||
} else if ((r = getdns_context_get_trust_anchor_verify_email(
|
||||
context, ".", &verify_email))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not get verify email address"
|
||||
": \"%s\"", __FUNC__
|
||||
, getdns_get_errorstr_by_id(r));
|
||||
return;
|
||||
|
||||
} else if (!*verify_email) {
|
||||
DEBUG_ANCHOR("NOTICE: Trust anchor fetching explicitely "
|
||||
"disabled by empty verify email address\n");
|
||||
return;
|
||||
}
|
||||
DEBUG_ANCHOR("Hostname: %s\n", tas_hostname);
|
||||
DEBUG_ANCHOR("%s on the %ssynchronous loop\n", __FUNC__,
|
||||
loop == &context->sync_eventloop.loop ? "" : "a");
|
||||
|
||||
while (!context->sys_ctxt) {
|
||||
while (!context->sys_ctxt) { /* Used as breakable if. Never repeats. */
|
||||
if ((r = getdns_context_create_with_extended_memory_functions(
|
||||
&context->sys_ctxt, 1, context->mf.mf_arg,
|
||||
context->mf.mf.ext.malloc, context->mf.mf.ext.realloc,
|
||||
|
@ -1411,10 +1556,10 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
#if 1
|
||||
context->a.state = TAS_LOOKUP_ADDRESSES;
|
||||
if ((r = _getdns_general_loop(context->sys_ctxt, loop,
|
||||
"data.iana.org.", GETDNS_RRTYPE_A, NULL, context,
|
||||
&context->a.req, NULL, data_iana_org))) {
|
||||
DEBUG_ANCHOR("Error scheduling A lookup for data.iana.org: "
|
||||
"%s\n", getdns_get_errorstr_by_id(r));
|
||||
tas_hostname, GETDNS_RRTYPE_A, NULL, 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));
|
||||
} else
|
||||
scheduled += 1;
|
||||
#endif
|
||||
|
@ -1422,17 +1567,18 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
#if 1
|
||||
context->aaaa.state = TAS_LOOKUP_ADDRESSES;
|
||||
if ((r = _getdns_general_loop(context->sys_ctxt, loop,
|
||||
"data.iana.org.", GETDNS_RRTYPE_AAAA, NULL, context,
|
||||
&context->aaaa.req, NULL, data_iana_org))) {
|
||||
DEBUG_ANCHOR("Error scheduling AAAA lookup for data.iana.org: "
|
||||
"%s\n", getdns_get_errorstr_by_id(r));
|
||||
tas_hostname, GETDNS_RRTYPE_AAAA, NULL, 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));
|
||||
} else
|
||||
scheduled += 1;
|
||||
#endif
|
||||
|
||||
if (!scheduled) {
|
||||
DEBUG_ANCHOR("Fatal error fetching trust anchor: Unable to "
|
||||
"schedule address requests for data.iana.org\n");
|
||||
"schedule address requests for %s\n"
|
||||
, tas_hostname);
|
||||
context->trust_anchors_source = GETDNS_TASRC_FAILED;
|
||||
_getdns_ta_notify_dnsreqs(context);
|
||||
} else
|
||||
|
|
147
src/context.c
147
src/context.c
|
@ -1343,6 +1343,37 @@ static void _getdns_check_expired_pending_netreqs_cb(void *arg)
|
|||
_getdns_check_expired_pending_netreqs((getdns_context *)arg, &now_ms);
|
||||
}
|
||||
|
||||
static const char *_getdns_default_root_anchor_url =
|
||||
"http://data.iana.org/root-anchors/root-anchors.xml";
|
||||
|
||||
/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */
|
||||
static const char *_getdns_default_root_anchor_verify_CA =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
|
||||
"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
|
||||
"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
|
||||
"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
|
||||
"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
|
||||
"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
|
||||
"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
|
||||
"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
|
||||
"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
|
||||
"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
|
||||
"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
|
||||
"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
|
||||
"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
|
||||
"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
|
||||
"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
|
||||
"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
|
||||
"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
|
||||
"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
|
||||
"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char *_getdns_default_root_anchor_verify_email =
|
||||
"dnssec@iana.org";
|
||||
|
||||
|
||||
/*
|
||||
* getdns_context_create
|
||||
*
|
||||
|
@ -1443,6 +1474,11 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->suffixes_len = sizeof(no_suffixes);
|
||||
|
||||
result->trust_anchors_source = GETDNS_TASRC_NONE;
|
||||
result->can_write_appdata = PROP_UNKNOWN;
|
||||
result->root_anchor_url = _getdns_default_root_anchor_url;
|
||||
result->root_anchor_verify_email
|
||||
= _getdns_default_root_anchor_verify_email;
|
||||
result->root_anchor_verify_CA = _getdns_default_root_anchor_verify_CA;
|
||||
|
||||
(void) memset(&result->a, 0, sizeof(result->a));
|
||||
(void) memset(&result->aaaa, 0, sizeof(result->aaaa));
|
||||
|
@ -4626,5 +4662,116 @@ void _getdns_context_write_priv_file(getdns_context *context,
|
|||
}
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_url(
|
||||
getdns_context *context, const char *zone, const char *url)
|
||||
{
|
||||
const char *path;
|
||||
size_t path_len;
|
||||
|
||||
if (!context || !url)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && !(zone[0] == '.' && zone[1] == '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
if (! ((url[0] == 'h' || url[0] == 'H')
|
||||
&& (url[1] == 't' || url[1] == 'T')
|
||||
&& (url[2] == 't' || url[2] == 'T')
|
||||
&& (url[3] == 'p' || url[3] == 'P')
|
||||
&& url[4] == ':' && url[5] == '/' && url[6] == '/'
|
||||
&& (path = strchr(url + 7, '/'))))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
path_len = strlen(path);
|
||||
if (! ( path_len >= 4
|
||||
&& (path[path_len - 3] == 'x' || path[path_len - 3] == 'X')
|
||||
&& (path[path_len - 2] == 'm' || path[path_len - 2] == 'm')
|
||||
&& (path[path_len - 1] == 'l' || path[path_len - 1] == 'l')))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
context->root_anchor_url = url;
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_url(
|
||||
getdns_context *context, const char *zone, const char **url)
|
||||
{
|
||||
if (!context || !url)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
*url = context && context->root_anchor_url
|
||||
? context->root_anchor_url
|
||||
: _getdns_default_root_anchor_url;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_verify_CA(
|
||||
getdns_context *context, const char *zone, const char *verify_CA)
|
||||
{
|
||||
if (!context || !verify_CA)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
context->root_anchor_verify_CA = verify_CA;
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_verify_CA(
|
||||
getdns_context *context, const char *zone, const char **verify_CA)
|
||||
{
|
||||
if (!verify_CA)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
*verify_CA = context && context->root_anchor_verify_CA
|
||||
? context->root_anchor_verify_CA
|
||||
: _getdns_default_root_anchor_verify_CA;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_verify_email(
|
||||
getdns_context *context, const char *zone, const char *verify_email)
|
||||
{
|
||||
if (!context || !verify_email)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
context->root_anchor_verify_email = verify_email;
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_verify_email(
|
||||
getdns_context *context, const char *zone, const char **verify_email)
|
||||
{
|
||||
if (!verify_email)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
*verify_email = context && context->root_anchor_verify_email
|
||||
? context->root_anchor_verify_email
|
||||
: _getdns_default_root_anchor_verify_email;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
/* context.c */
|
||||
|
|
|
@ -113,6 +113,7 @@ typedef enum getdns_tsig_algo {
|
|||
GETDNS_HMAC_SHA512 = 7
|
||||
} getdns_tsig_algo;
|
||||
|
||||
|
||||
typedef struct getdns_tsig_info {
|
||||
getdns_tsig_algo alg;
|
||||
const char *name;
|
||||
|
@ -281,6 +282,13 @@ typedef enum tas_state {
|
|||
TAS_RETRY_DONE
|
||||
} tas_state;
|
||||
|
||||
typedef enum _getdns_property {
|
||||
PROP_INHERIT = 0,
|
||||
PROP_UNKNOWN = 1,
|
||||
PROP_UNABLE = 2,
|
||||
PROP_ABLE = 3
|
||||
} _getdns_property;
|
||||
|
||||
typedef struct tas_connection {
|
||||
getdns_eventloop *loop;
|
||||
getdns_network_req *req;
|
||||
|
@ -292,6 +300,7 @@ typedef struct tas_connection {
|
|||
getdns_eventloop_event event;
|
||||
tas_state state;
|
||||
getdns_tcp_state tcp;
|
||||
char *http;
|
||||
getdns_bindata xml;
|
||||
} tas_connection;
|
||||
|
||||
|
@ -325,6 +334,12 @@ struct getdns_context {
|
|||
tas_connection aaaa;
|
||||
uint8_t tas_hdr_spc[512];
|
||||
|
||||
_getdns_property can_write_appdata : 2;
|
||||
|
||||
const char *root_anchor_url;
|
||||
const char *root_anchor_verify_CA;
|
||||
const char *root_anchor_verify_email;
|
||||
|
||||
getdns_upstreams *upstreams;
|
||||
uint16_t limit_outstanding_queries;
|
||||
uint32_t dnssec_allowed_skew;
|
||||
|
|
|
@ -79,6 +79,13 @@ extern "C" {
|
|||
#define GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT "Change related to getdns_context_set_tls_backoff_time"
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES 624
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT "Change related to getdns_context_set_tls_connection_retries"
|
||||
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL 625
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL_TEXT "Change related to getdns_context_set_trust_anchor_url"
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA 626
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA_TEXT "Change related to getdns_context_set_trust_anchor_verify_ca"
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL 627
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL_TEXT "Change related to getdns_context_set_trust_anchor_verify_email"
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
@ -537,6 +544,28 @@ getdns_return_t
|
|||
getdns_context_set_logfunc(getdns_context *context, void *userarg,
|
||||
uint64_t system, getdns_loglevel_type level, getdns_logfunc_type func);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_url(
|
||||
getdns_context *context, const char *zone, const char *url);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_verify_CA(
|
||||
getdns_context *context, const char *zone, const char *verify_CA);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_verify_email(
|
||||
getdns_context *context, const char *zone, const char *verify_email);
|
||||
|
||||
|
||||
/**
|
||||
* Get the current resolution type setting from this context.
|
||||
* @see getdns_context_set_resolution_type
|
||||
|
@ -902,6 +931,28 @@ getdns_return_t
|
|||
getdns_context_get_update_callback(getdns_context *context, void **userarg,
|
||||
void (**value) (getdns_context *, getdns_context_code_t, void *));
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_url(
|
||||
getdns_context *context, const char *zone, const char **url);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_verify_CA(
|
||||
getdns_context *context, const char *zone, const char **verify_CA);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_verify_email(
|
||||
getdns_context *context, const char *zone, const char **verify_email);
|
||||
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue