summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2015-07-13 01:51:03 +0200
committerTom Gundersen <teg@jklm.no>2015-07-14 22:17:24 +0200
commit5d45a8808431987c370706d365fb0cc95cf03d52 (patch)
treebcdb4ea862f3c0ea815e60a49883ed1e6921aaa5 /src
parent919a7f5f1c4f1a4c3e20b0dc55143b8ad70e6a70 (diff)
resolved: rr - add NSEC3 support
Needed for DNSSEC.
Diffstat (limited to 'src')
-rw-r--r--src/resolve/resolved-dns-packet.c106
-rw-r--r--src/resolve/resolved-dns-packet.h2
-rw-r--r--src/resolve/resolved-dns-rr.c46
-rw-r--r--src/resolve/resolved-dns-rr.h11
4 files changed, 157 insertions, 8 deletions
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index d2b3cb0eb1..e44d3926d9 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -825,6 +825,40 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star
goto fail;
break;
+ case DNS_TYPE_NSEC3:
+ r = dns_packet_append_uint8(p, rr->nsec3.algorithm, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_append_uint8(p, rr->nsec3.flags, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_append_uint16(p, rr->nsec3.iterations, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_append_uint8(p, rr->nsec3.salt_size, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_append_blob(p, rr->nsec3.salt, rr->nsec3.salt_size, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_append_uint8(p, rr->nsec3.next_hashed_name_size, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_append_blob(p, rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_append_types(p, rr->nsec3.types, NULL);
+ if (r < 0)
+ goto fail;
+
+ break;
case _DNS_TYPE_INVALID: /* unparseable */
default:
@@ -1560,6 +1594,60 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
}
break;
+
+ case DNS_TYPE_NSEC3: {
+ uint8_t size;
+
+ r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
+ if (r < 0)
+ goto fail;
+
+ r = dns_packet_read_uint8(p, &size, NULL);
+ if (r < 0)
+ goto fail;
+
+ rr->nsec3.salt_size = size;
+
+ r = dns_packet_read_blob(p, &d, rr->nsec3.salt_size, NULL);
+ if (r < 0)
+ goto fail;
+
+ rr->nsec3.salt = memdup(d, rr->nsec3.salt_size);
+ if (!rr->nsec3.salt) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ r = dns_packet_read_uint8(p, &size, NULL);
+ if (r < 0)
+ goto fail;
+
+ rr->nsec3.next_hashed_name_size = size;
+
+ r = dns_packet_read(p, rr->nsec3.next_hashed_name_size, &d, NULL);
+ if (r < 0)
+ goto fail;
+
+ rr->nsec3.next_hashed_name = memdup(d, rr->nsec3.next_hashed_name_size);
+ if (!rr->nsec3.next_hashed_name) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ r = dns_packet_append_types(p, rr->nsec3.types, NULL);
+ if (r < 0)
+ goto fail;
+
+ break;
+ }
default:
unparseable:
r = dns_packet_read(p, rdlength, &d, NULL);
@@ -1694,13 +1782,15 @@ static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
- [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
- [DNSSEC_ALGORITHM_DH] = "DH",
- [DNSSEC_ALGORITHM_DSA] = "DSA",
- [DNSSEC_ALGORITHM_ECC] = "ECC",
- [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
- [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
- [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
- [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
+ [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
+ [DNSSEC_ALGORITHM_DH] = "DH",
+ [DNSSEC_ALGORITHM_DSA] = "DSA",
+ [DNSSEC_ALGORITHM_ECC] = "ECC",
+ [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
+ [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1] = "DSA-NSEC3-SHA1",
+ [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1] = "RSASHA1-NSEC3-SHA1",
+ [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
+ [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
+ [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
};
DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index 6588ed9df5..58559c85df 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -223,6 +223,8 @@ enum {
DNSSEC_ALGORITHM_DSA,
DNSSEC_ALGORITHM_ECC,
DNSSEC_ALGORITHM_RSASHA1,
+ DNSSEC_ALGORITHM_DSA_NSEC3_SHA1,
+ DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
DNSSEC_ALGORITHM_INDIRECT = 252,
DNSSEC_ALGORITHM_PRIVATEDNS,
DNSSEC_ALGORITHM_PRIVATEOID,
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
index 48fb3538ae..e9907eabc0 100644
--- a/src/resolve/resolved-dns-rr.c
+++ b/src/resolve/resolved-dns-rr.c
@@ -293,6 +293,12 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
bitmap_free(rr->nsec.types);
break;
+ case DNS_TYPE_NSEC3:
+ free(rr->nsec3.next_hashed_name);
+ free(rr->nsec3.salt);
+ bitmap_free(rr->nsec3.types);
+ break;
+
case DNS_TYPE_LOC:
case DNS_TYPE_A:
case DNS_TYPE_AAAA:
@@ -457,6 +463,15 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor
return dns_name_equal(a->nsec.next_domain_name, b->nsec.next_domain_name) &&
bitmap_equal(a->nsec.types, b->nsec.types);
+ case DNS_TYPE_NSEC3:
+ return a->nsec3.algorithm == b->nsec3.algorithm &&
+ a->nsec3.flags == b->nsec3.flags &&
+ a->nsec3.iterations == b->nsec3.iterations &&
+ a->nsec3.salt_size == b->nsec3.salt_size &&
+ memcmp(a->nsec3.salt, b->nsec3.salt, a->nsec3.salt_size) == 0 &&
+ memcmp(a->nsec3.next_hashed_name, b->nsec3.next_hashed_name, a->nsec3.next_hashed_name_size) == 0 &&
+ bitmap_equal(a->nsec3.types, b->nsec3.types);
+
default:
return a->generic.size == b->generic.size &&
memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
@@ -757,6 +772,37 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) {
return -ENOMEM;
break;
+ case DNS_TYPE_NSEC3: {
+ _cleanup_free_ char *salt = NULL, *hash = NULL;
+
+ if (rr->nsec3.salt_size) {
+ salt = hexmem(rr->nsec3.salt, rr->nsec3.salt_size);
+ if (!salt)
+ return -ENOMEM;
+ }
+
+ hash = base32hexmem(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, false);
+ if (!hash)
+ return -ENOMEM;
+
+ t = format_types(rr->nsec3.types);
+ if (!t)
+ return -ENOMEM;
+
+ r = asprintf(&s, "%s %"PRIu8" %"PRIu8" %"PRIu16" %s %s %s",
+ k,
+ rr->nsec3.algorithm,
+ rr->nsec3.flags,
+ rr->nsec3.iterations,
+ rr->nsec3.salt_size ? salt : "-",
+ hash,
+ t);
+ if (r < 0)
+ return -ENOMEM;
+
+ break;
+ }
+
default:
t = hexmem(rr->generic.data, rr->generic.size);
if (!t)
diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h
index eaaafb1f25..bdd5a5c824 100644
--- a/src/resolve/resolved-dns-rr.h
+++ b/src/resolve/resolved-dns-rr.h
@@ -151,6 +151,17 @@ struct DnsResourceRecord {
char *next_domain_name;
Bitmap *types;
} nsec;
+
+ struct {
+ uint8_t algorithm;
+ uint8_t flags;
+ uint16_t iterations;
+ void *salt;
+ size_t salt_size;
+ void *next_hashed_name;
+ size_t next_hashed_name_size;
+ Bitmap *types;
+ } nsec3;
};
};