Native stub validation

This commit is contained in:
Willem Toorop 2015-06-11 15:40:44 +02:00
parent c28f6ee595
commit ae1db39a33
7 changed files with 123 additions and 180 deletions

4
aclocal.m4 vendored
View File

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.15 -*- Autoconf -*- # generated automatically by aclocal 1.14.1 -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Copyright (C) 1996-2013 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,

17
configure vendored
View File

@ -760,7 +760,7 @@ with_sysroot
enable_libtool_lock enable_libtool_lock
enable_rpath enable_rpath
enable_tcp_fastopen enable_tcp_fastopen
enable_broken_native_stub_dnssec enable_native_stub_dnssec
with_ssl with_ssl
enable_draft_edns_cookies enable_draft_edns_cookies
with_libidn with_libidn
@ -1406,9 +1406,8 @@ Optional Features:
--disable-libtool-lock avoid locking (might break parallel builds) --disable-libtool-lock avoid locking (might break parallel builds)
--disable-rpath disable hardcoded rpath (default=enabled) --disable-rpath disable hardcoded rpath (default=enabled)
--enable-tcp-fastopen Enable TCP Fast Open --enable-tcp-fastopen Enable TCP Fast Open
--enable-broken-native-stub-dnssec --disable-native-stub-dnssec
Enable very experimental and broken native stub Disable native stub DNSSEC support
DNSSEC support
--enable-draft-edns-cookies --enable-draft-edns-cookies
Enable experimental edns cookies Enable experimental edns cookies
@ -11738,20 +11737,20 @@ _ACEOF
;; ;;
esac esac
# Check whether --enable-broken-native-stub-dnssec was given. # Check whether --enable-native-stub-dnssec was given.
if test "${enable_broken_native_stub_dnssec+set}" = set; then : if test "${enable_native_stub_dnssec+set}" = set; then :
enableval=$enable_broken_native_stub_dnssec; enableval=$enable_native_stub_dnssec;
fi fi
case "$enable_broken_native_stub_dnssec" in case "$enable_broken_native_stub_dnssec" in
yes) yes|*)
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
#define STUB_NATIVE_DNSSEC 1 #define STUB_NATIVE_DNSSEC 1
_ACEOF _ACEOF
;; ;;
no|*) no)
;; ;;
esac esac

View File

@ -132,12 +132,12 @@ case "$enable_tcp_fastopen" in
;; ;;
esac esac
AC_ARG_ENABLE(broken-native-stub-dnssec, AC_HELP_STRING([--enable-broken-native-stub-dnssec], [Enable very experimental and broken native stub DNSSEC support])) AC_ARG_ENABLE(native-stub-dnssec, AC_HELP_STRING([--disable-native-stub-dnssec], [Disable native stub DNSSEC support]))
case "$enable_broken_native_stub_dnssec" in case "$enable_broken_native_stub_dnssec" in
yes) yes|*)
AC_DEFINE_UNQUOTED([STUB_NATIVE_DNSSEC], [1], [Define this to enable the very experimental and broken native stub DNSSEC support.]) AC_DEFINE_UNQUOTED([STUB_NATIVE_DNSSEC], [1], [Define this to enable native stub DNSSEC support.])
;; ;;
no|*) no)
;; ;;
esac esac

View File

@ -192,8 +192,7 @@
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS #undef STDC_HEADERS
/* Define this to enable the very experimental and broken native stub DNSSEC /* Define this to enable native stub DNSSEC support. */
support. */
#undef STUB_NATIVE_DNSSEC #undef STUB_NATIVE_DNSSEC
/* System configuration dir */ /* System configuration dir */

View File

@ -475,36 +475,6 @@ priv_getdns_rr_list_from_list(struct getdns_list *list, ldns_rr_list **rr_list)
return r; return r;
} }
static int
priv_getdns_rr_dict_with_compressed_names(getdns_dict *rr_dict)
{
uint32_t rr_type;
getdns_dict *rdata;
if (getdns_dict_get_int(rr_dict, "type", &rr_type))
return 0;
if (rr_type == GETDNS_RRTYPE_RRSIG) {
if (getdns_dict_get_dict(rr_dict, "rdata", &rdata))
return 0;
if (getdns_dict_get_int(rdata, "type_covered", &rr_type))
return 0;
}
switch (rr_type) {
case GETDNS_RRTYPE_NS:
case GETDNS_RRTYPE_MD:
case GETDNS_RRTYPE_CNAME:
case GETDNS_RRTYPE_SOA:
case GETDNS_RRTYPE_MG:
case GETDNS_RRTYPE_MR:
case GETDNS_RRTYPE_PTR:
case GETDNS_RRTYPE_MINFO:
case GETDNS_RRTYPE_MX:
return 1;
default:
return 0;
}
}
static int static int
ldns_dname_compare_v(const void *a, const void *b) { ldns_dname_compare_v(const void *a, const void *b) {
return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b); return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
@ -573,9 +543,6 @@ priv_getdns_dnssec_zone_from_list(struct getdns_list *list,
if ((r = getdns_list_get_dict(list, i, &rr_dict))) if ((r = getdns_list_get_dict(list, i, &rr_dict)))
break; break;
if (priv_getdns_rr_dict_with_compressed_names(rr_dict))
continue;
if ((r = priv_getdns_create_rr_from_dict(rr_dict, &rr))) if ((r = priv_getdns_create_rr_from_dict(rr_dict, &rr)))
break; break;
@ -693,6 +660,17 @@ verify_rrset(ldns_dnssec_rrsets *rrset_and_sigs,
ldns_rr_list *rrset = rrs2rr_list(rrset_and_sigs->rrs); ldns_rr_list *rrset = rrs2rr_list(rrset_and_sigs->rrs);
ldns_rr_list *sigs = rrs2rr_list(rrset_and_sigs->signatures); ldns_rr_list *sigs = rrs2rr_list(rrset_and_sigs->signatures);
s = ldns_verify(rrset, sigs, keys, good_keys); s = ldns_verify(rrset, sigs, keys, good_keys);
#if 0
if (s != 0) {
fprintf(stderr, "verify status %d\nrrset: ", s);
ldns_rr_list_print(stderr, rrset);
fprintf(stderr, "\nsigs: ");
ldns_rr_list_print(stderr, sigs);
fprintf(stderr, "\nkeys: ");
ldns_rr_list_print(stderr, keys);
fprintf(stderr, "\n\n");
}
#endif
ldns_rr_list_free(sigs); ldns_rr_list_free(sigs);
ldns_rr_list_free(rrset); ldns_rr_list_free(rrset);
return s; return s;

View File

@ -255,9 +255,9 @@ static priv_getdns_rdata_def soa_rdata[] = {
{ "rname" , GETDNS_RDF_N_C }, { "rname" , GETDNS_RDF_N_C },
{ "serial" , GETDNS_RDF_I4 }, { "serial" , GETDNS_RDF_I4 },
{ "refresh" , GETDNS_RDF_I4 }, { "refresh" , GETDNS_RDF_I4 },
{ "refresh" , GETDNS_RDF_I4 },
{ "retry" , GETDNS_RDF_I4 }, { "retry" , GETDNS_RDF_I4 },
{ "expire" , GETDNS_RDF_I4 }}; { "expire" , GETDNS_RDF_I4 },
{ "minimum" , GETDNS_RDF_I4 }};
static priv_getdns_rdata_def mg_rdata[] = { static priv_getdns_rdata_def mg_rdata[] = {
{ "mgmname" , GETDNS_RDF_N_C }}; { "mgmname" , GETDNS_RDF_N_C }};
static priv_getdns_rdata_def mr_rdata[] = { static priv_getdns_rdata_def mr_rdata[] = {
@ -742,9 +742,8 @@ static getdns_return_t priv_getdns_construct_wire_rdata_from_rdata(
uint8_t **wire, size_t *wire_size) uint8_t **wire, size_t *wire_size)
{ {
getdns_return_t r = GETDNS_RETURN_GOOD; getdns_return_t r = GETDNS_RETURN_GOOD;
const ldns_rr_descriptor *rr_descript;
const priv_getdns_rr_def *def; const priv_getdns_rr_def *def;
size_t i, size; size_t i, j, size;
struct getdns_bindata *bindata; struct getdns_bindata *bindata;
uint32_t value; uint32_t value;
uint8_t *ptr; uint8_t *ptr;
@ -754,7 +753,6 @@ static getdns_return_t priv_getdns_construct_wire_rdata_from_rdata(
assert(wire_size); assert(wire_size);
def = priv_getdns_rr_def_lookup(rr_type); def = priv_getdns_rr_def_lookup(rr_type);
rr_descript = ldns_rr_descript(rr_type);
/* First calculate needed size */ /* First calculate needed size */
size = 0; size = 0;
@ -771,23 +769,7 @@ static getdns_return_t priv_getdns_construct_wire_rdata_from_rdata(
r = GETDNS_RETURN_GENERIC_ERROR; r = GETDNS_RETURN_GENERIC_ERROR;
break; break;
} }
switch (ldns_rr_descriptor_field_type(rr_descript, i)) { size += def->rdata[i].type & GETDNS_RDF_FIXEDSZ;
case LDNS_RDF_TYPE_CLASS:
case LDNS_RDF_TYPE_ALG :
case LDNS_RDF_TYPE_INT8 : size += 1;
break;
case LDNS_RDF_TYPE_TYPE :
case LDNS_RDF_TYPE_CERT_ALG:
case LDNS_RDF_TYPE_INT16: size += 2;
break;
case LDNS_RDF_TYPE_TIME :
case LDNS_RDF_TYPE_PERIOD:
case LDNS_RDF_TYPE_INT32: size += 4;
break;
default: r = GETDNS_RETURN_GENERIC_ERROR;
break;
}
} }
*wire_size = size + 2; *wire_size = size + 2;
*wire = ptr = GETDNS_XMALLOC(rdata->mf, uint8_t, size + 2); *wire = ptr = GETDNS_XMALLOC(rdata->mf, uint8_t, size + 2);
@ -816,63 +798,20 @@ static getdns_return_t priv_getdns_construct_wire_rdata_from_rdata(
rdata, def->rdata[i].name, &value))) rdata, def->rdata[i].name, &value)))
break; break;
switch (ldns_rr_descriptor_field_type(rr_descript, i)) { for (j = def->rdata[i].type & GETDNS_RDF_FIXEDSZ; j; j--)
*ptr++ = (uint8_t)(value >> (8 * (j - 1))) & 0xff;
case LDNS_RDF_TYPE_CLASS:
case LDNS_RDF_TYPE_ALG :
case LDNS_RDF_TYPE_INT8 : ptr[0] = (uint8_t) value & 0xff;
ptr += 1;
break;
case LDNS_RDF_TYPE_TYPE :
case LDNS_RDF_TYPE_CERT_ALG:
case LDNS_RDF_TYPE_INT16: ptr[0] = (uint8_t)(value>> 8) & 0xff;
ptr[1] = (uint8_t) value & 0xff;
ptr += 2;
break;
case LDNS_RDF_TYPE_TIME :
case LDNS_RDF_TYPE_PERIOD:
case LDNS_RDF_TYPE_INT32: ptr[0] = (uint8_t)(value>>24) & 0xff;
ptr[1] = (uint8_t)(value>>16) & 0xff;
ptr[2] = (uint8_t)(value>>8 ) & 0xff;
ptr[3] = (uint8_t) value & 0xff;
ptr += 4;
break;
default: r = GETDNS_RETURN_GENERIC_ERROR;
break;
}
} }
if (r) if (r)
GETDNS_FREE(rdata->mf, ptr); GETDNS_FREE(rdata->mf, ptr);
return r; return r;
} }
static getdns_return_t
priv_getdns_dict_get_raw_rdata(struct getdns_dict *rdata,
uint8_t **wire, size_t *wire_size)
{
getdns_return_t r;
struct getdns_bindata *bindata;
if ((r = getdns_dict_get_bindata(rdata, "rdata_raw", &bindata)))
return r;
*wire_size = bindata->size + 2;
*wire = GETDNS_XMALLOC(rdata->mf, uint8_t, *wire_size);
if (! *wire)
return GETDNS_RETURN_MEMORY_ERROR;
(*wire)[0] = (uint8_t) (bindata->size >> 8) & 0xff;
(*wire)[1] = (uint8_t) bindata->size & 0xff;
(void) memcpy(*wire + 2, bindata->data, bindata->size);
return GETDNS_RETURN_GOOD;
}
getdns_return_t getdns_return_t
priv_getdns_create_rr_from_dict(struct getdns_dict *rr_dict, ldns_rr **rr) priv_getdns_create_rr_from_dict(struct getdns_dict *rr_dict, ldns_rr **rr)
{ {
getdns_return_t r = GETDNS_RETURN_GOOD; getdns_return_t r = GETDNS_RETURN_GOOD;
struct getdns_bindata *name; struct getdns_bindata *name;
struct getdns_bindata *rdata_raw;
struct getdns_dict *rdata; struct getdns_dict *rdata;
uint32_t rr_type; uint32_t rr_type;
ldns_rdf *owner; ldns_rdf *owner;
@ -887,41 +826,68 @@ priv_getdns_create_rr_from_dict(struct getdns_dict *rr_dict, ldns_rr **rr)
*rr = ldns_rr_new(); *rr = ldns_rr_new();
if (! *rr) if (! *rr)
return GETDNS_RETURN_MEMORY_ERROR; return GETDNS_RETURN_MEMORY_ERROR;
do {
r = getdns_dict_get_bindata(rr_dict, "name", &name); if ((r = getdns_dict_get_bindata(rr_dict, "name", &name)))
if (r != GETDNS_RETURN_GOOD) goto error;
owner = ldns_rdf_new_frm_data(
LDNS_RDF_TYPE_DNAME, name->size, name->data);
if (! owner) {
r = GETDNS_RETURN_MEMORY_ERROR;
goto error;
}
ldns_rr_set_owner(*rr, owner);
if ((r = getdns_dict_get_int(rr_dict, "type", &rr_type)))
goto error;
ldns_rr_set_type(*rr, rr_type);
if ((r = getdns_dict_get_dict(rr_dict, "rdata", &rdata)))
goto error;
const priv_getdns_rr_def *rr_def = priv_getdns_rr_def_lookup(rr_type);
const priv_getdns_rdata_def *rd_def;
int n_rdata_fields;
for ( rd_def = rr_def->rdata
, n_rdata_fields = rr_def->n_rdata_fields
; n_rdata_fields
; n_rdata_fields--
, rd_def++ ) {
if (rd_def->type & GETDNS_RDF_COMPRESSED)
break; break;
owner = ldns_rdf_new_frm_data( }
LDNS_RDF_TYPE_DNAME, name->size, name->data);
if (! owner) { if (n_rdata_fields == 0 && GETDNS_RETURN_GOOD ==
(r = getdns_dict_get_bindata(rdata, "rdata_raw", &rdata_raw))) {
wire_size = rdata_raw->size + 2;
wire = GETDNS_XMALLOC(rdata->mf, uint8_t, wire_size);
if (! wire) {
r = GETDNS_RETURN_MEMORY_ERROR; r = GETDNS_RETURN_MEMORY_ERROR;
break; goto error;
} }
ldns_rr_set_owner(*rr, owner);
r = getdns_dict_get_int(rr_dict, "type", &rr_type); wire[0] = (uint8_t) (rdata_raw->size >> 8) & 0xff;
if (r != GETDNS_RETURN_GOOD) wire[1] = (uint8_t) rdata_raw->size & 0xff;
break;
ldns_rr_set_type(*rr, rr_type);
r = getdns_dict_get_dict(rr_dict, "rdata", &rdata); (void) memcpy(wire + 2, rdata_raw->data, rdata_raw->size);
if (r != GETDNS_RETURN_GOOD)
break;
r = priv_getdns_dict_get_raw_rdata(rdata, &wire, &wire_size); } else if (n_rdata_fields || r == GETDNS_RETURN_NO_SUCH_DICT_NAME) {
if (r == GETDNS_RETURN_NO_SUCH_DICT_NAME) {
r = priv_getdns_construct_wire_rdata_from_rdata( r = priv_getdns_construct_wire_rdata_from_rdata(rdata, rr_type,
rdata, rr_type, &wire, &wire_size); &wire, &wire_size);
} }
if (r != GETDNS_RETURN_GOOD)
break; pos = 0;
pos = 0; s = ldns_wire2rdf(*rr, wire, wire_size, &pos);
s = ldns_wire2rdf(*rr, wire, wire_size, &pos); GETDNS_FREE(rr_dict->mf, wire);
GETDNS_FREE(rr_dict->mf, wire); if (s == LDNS_STATUS_OK)
if (s == LDNS_STATUS_OK) return r;
return r;
r = GETDNS_RETURN_GENERIC_ERROR; r = GETDNS_RETURN_GENERIC_ERROR;
} while (0); error:
ldns_rr_free(*rr); ldns_rr_free(*rr);
return r; return r;
} }

View File

@ -51,56 +51,57 @@ typedef struct priv_getdns_rdf_special {
/* draft-levine-dnsextlang'ish type rr and rdata definitions */ /* draft-levine-dnsextlang'ish type rr and rdata definitions */
#define GETDNS_RDF_INTEGER 0x010000 #define GETDNS_RDF_INTEGER 0x010000
#define GETDNS_RDF_BINDATA 0x020000 #define GETDNS_RDF_BINDATA 0x020000
#define GETDNS_RDF_DNAME 0x060000 #define GETDNS_RDF_DNAME 0x060000
#define GETDNS_RDF_REPEAT 0x100000 #define GETDNS_RDF_COMPRESSED 0x080000
#define GETDNS_RDF_REPEAT 0x100000
#define GETDNS_RDF_FIXEDSZ 0x0000FF #define GETDNS_RDF_FIXEDSZ 0x0000FF
#define GETDNS_RDF_LEN_VAL 0x00FF00 #define GETDNS_RDF_LEN_VAL 0x00FF00
typedef enum priv_getdns_rdf_wf_type { typedef enum priv_getdns_rdf_wf_type {
GETDNS_RDF_N = 0x060000, /* N */ GETDNS_RDF_N = 0x060000, /* N */
GETDNS_RDF_N_A = GETDNS_RDF_N, /* N[A] */ GETDNS_RDF_N_A = 0x060000, /* N[A] */
GETDNS_RDF_N_A_C = GETDNS_RDF_N, /* N[A,C] */ GETDNS_RDF_N_C = 0x0E0000, /* N[C] */
GETDNS_RDF_N_C = GETDNS_RDF_N, /* N[C] */ GETDNS_RDF_N_A_C = 0x0E0000, /* N[A,C] */
GETDNS_RDF_N_M = 0x160000, /* N[M] */ GETDNS_RDF_N_M = 0x160000, /* N[M] */
GETDNS_RDF_I1 = 0x010001, /* I1 */ GETDNS_RDF_I1 = 0x010001, /* I1 */
GETDNS_RDF_I2 = 0x010002, /* I2 */ GETDNS_RDF_I2 = 0x010002, /* I2 */
GETDNS_RDF_I4 = 0x010004, /* I4 */ GETDNS_RDF_I4 = 0x010004, /* I4 */
GETDNS_RDF_T = 0x010004, /* T */ GETDNS_RDF_T = 0x010004, /* T */
/* Time values using ring arithmetics /* Time values using ring arithmetics
* (rfc1982) for TKEY['inception'], * (rfc1982) for TKEY['inception'],
* TKEY['expiration'], * TKEY['expiration'],
* RRSIG['inception'] and * RRSIG['inception'] and
* RRSIG['expiration'] * RRSIG['expiration']
*/ */
GETDNS_RDF_T6 = 0x020006, /* T6 */ GETDNS_RDF_T6 = 0x020006, /* T6 */
/* Absolute time values (since epoch) /* Absolute time values (since epoch)
* for TSIG['time_signed'] * for TSIG['time_signed']
*/ */
GETDNS_RDF_A = 0x020004, /* A */ GETDNS_RDF_A = 0x020004, /* A */
GETDNS_RDF_AA = 0x020008, /* AA */ GETDNS_RDF_AA = 0x020008, /* AA */
GETDNS_RDF_AAAA = 0x020010, /* AAAA */ GETDNS_RDF_AAAA = 0x020010, /* AAAA */
GETDNS_RDF_S = 0x020100, /* S */ GETDNS_RDF_S = 0x020100, /* S */
GETDNS_RDF_S_L = 0x020000, /* S[L] */ GETDNS_RDF_S_L = 0x020000, /* S[L] */
GETDNS_RDF_S_M = 0x120100, /* S[M] */ GETDNS_RDF_S_M = 0x120100, /* S[M] */
GETDNS_RDF_B = 0x020000, /* B */ GETDNS_RDF_B = 0x020000, /* B */
GETDNS_RDF_B_C = 0x020100, /* B[C] */ GETDNS_RDF_B_C = 0x020100, /* B[C] */
GETDNS_RDF_B32_C = 0x020100, /* B32[C] */ GETDNS_RDF_B32_C = 0x020100, /* B32[C] */
GETDNS_RDF_X = 0x020000, /* X */ GETDNS_RDF_X = 0x020000, /* X */
GETDNS_RDF_X_C = 0x020100, /* X[C] */ GETDNS_RDF_X_C = 0x020100, /* X[C] */
/* for NSEC3['salt'] and /* for NSEC3['salt'] and
* NSEC3PARAM['salt']. * NSEC3PARAM['salt'].
*/ */
GETDNS_RDF_X_S = 0x020200, /* X[S] */ GETDNS_RDF_X_S = 0x020200, /* X[S] */
/* for OPT['option_data'], /* for OPT['option_data'],
* TKEY['key_data'], * TKEY['key_data'],
* TKEY['other_data'], * TKEY['other_data'],
@ -109,12 +110,12 @@ typedef enum priv_getdns_rdf_wf_type {
* Although those do not have an * Although those do not have an
* official presentation format. * official presentation format.
*/ */
GETDNS_RDF_X6 = 0x020006, GETDNS_RDF_X6 = 0x020006,
GETDNS_RDF_X8 = 0x020008, GETDNS_RDF_X8 = 0x020008,
GETDNS_RDF_R = 0x100000, /* Repeat */ GETDNS_RDF_R = 0x100000, /* Repeat */
GETDNS_RDF_SPECIAL = 0x800000, GETDNS_RDF_SPECIAL = 0x800000,
} priv_getdns_rdf_type; } priv_getdns_rdf_type;
typedef struct priv_getdns_rdata_def { typedef struct priv_getdns_rdata_def {