From 6d99904f5a263cc119ac79718d83d7136dde349d Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sun, 31 Jan 2016 00:10:42 -0500 Subject: test-dns-packet: add framework to read and dump packets Packets are stored in a simple format: ... Packets for some example domains are dumped, to test rr code for various record types. Currently: A AAAA CAA DNSKEY LOC MX NS NSEC OPENPGPKEY SOA SPF TXT The hashing code is executed, but results are not checked. Also build other tests in src/resolve only with --enable-resolve. --- src/resolve/resolved-dns-rr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/resolve/resolved-dns-rr.c') diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 783ec7516c..2803ec017e 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -1302,7 +1302,7 @@ int dns_resource_record_is_synthetic(DnsResourceRecord *rr) { return !r; } -static void dns_resource_record_hash_func(const void *i, struct siphash *state) { +void dns_resource_record_hash_func(const void *i, struct siphash *state) { const DnsResourceRecord *rr = i; assert(rr); -- cgit v1.2.3-54-g00ecf From fa45182ed6b833017dde5a7cee27cdf25985790a Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sun, 31 Jan 2016 16:23:00 -0500 Subject: Fix hashing of TLSA packets Also add example files with TLSA and SSHFP records. --- Makefile.am | 4 +++- src/resolve/resolved-dns-rr.c | 2 +- src/resolve/test-data/_443._tcp.fedoraproject.org.pkts | Bin 0 -> 169 bytes src/resolve/test-data/kyhwana.org.pkts | Bin 0 -> 1803 bytes 4 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 src/resolve/test-data/_443._tcp.fedoraproject.org.pkts create mode 100644 src/resolve/test-data/kyhwana.org.pkts (limited to 'src/resolve/resolved-dns-rr.c') diff --git a/Makefile.am b/Makefile.am index 754772156c..8ab04e74ba 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5324,7 +5324,9 @@ EXTRA_DIST += \ src/resolve/test-data/root.pkts \ src/resolve/test-data/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts \ src/resolve/test-data/teamits.com.pkts \ - src/resolve/test-data/zbyszek@fedoraproject.org.pkts + src/resolve/test-data/zbyszek@fedoraproject.org.pkts \ + src/resolve/test-data/_443._tcp.fedoraproject.org.pkts \ + src/resolve/test-data/kyhwana.org.pkts test_dnssec_SOURCES = \ src/resolve/test-dnssec.c \ diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 2803ec017e..422bbe4bc4 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -1429,7 +1429,7 @@ void dns_resource_record_hash_func(const void *i, struct siphash *state) { siphash24_compress(&rr->tlsa.cert_usage, sizeof(rr->tlsa.cert_usage), state); siphash24_compress(&rr->tlsa.selector, sizeof(rr->tlsa.selector), state); siphash24_compress(&rr->tlsa.matching_type, sizeof(rr->tlsa.matching_type), state); - siphash24_compress(&rr->tlsa.data, rr->tlsa.data_size, state); + siphash24_compress(rr->tlsa.data, rr->tlsa.data_size, state); break; case DNS_TYPE_OPENPGPKEY: diff --git a/src/resolve/test-data/_443._tcp.fedoraproject.org.pkts b/src/resolve/test-data/_443._tcp.fedoraproject.org.pkts new file mode 100644 index 0000000000..a383c6286d Binary files /dev/null and b/src/resolve/test-data/_443._tcp.fedoraproject.org.pkts differ diff --git a/src/resolve/test-data/kyhwana.org.pkts b/src/resolve/test-data/kyhwana.org.pkts new file mode 100644 index 0000000000..e28a725c9a Binary files /dev/null and b/src/resolve/test-data/kyhwana.org.pkts differ -- cgit v1.2.3-54-g00ecf From 95052df3760523e1f3bb9705c918d85aae7fb431 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sun, 31 Jan 2016 16:21:00 -0500 Subject: resolve: parse CAA records --- src/basic/escape.c | 28 ++++++++++++++++++++++++++++ src/basic/escape.h | 1 + src/resolve/resolved-dns-packet.c | 27 +++++++++++++++++++++++++++ src/resolve/resolved-dns-rr.c | 36 ++++++++++++++++++++++++++++++++++++ src/resolve/resolved-dns-rr.h | 8 ++++++++ 5 files changed, 100 insertions(+) (limited to 'src/resolve/resolved-dns-rr.c') diff --git a/src/basic/escape.c b/src/basic/escape.c index f276c36c56..d59aa9f42f 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -415,6 +415,34 @@ char *xescape(const char *s, const char *bad) { return r; } +char *octescape(const char *s, size_t len) { + char *r, *t; + const char *f; + + /* Escapes all chars in bad, in addition to \ and " chars, + * in \nnn style escaping. */ + + r = new(char, len * 4 + 1); + if (!r) + return NULL; + + for (f = s, t = r; f < s + len; f++) { + + if (*f < ' ' || *f >= 127 || *f == '\\' || *f == '"') { + *(t++) = '\\'; + *(t++) = '0' + (*f >> 6); + *(t++) = '0' + ((*f >> 3) & 8); + *(t++) = '0' + (*f & 8); + } else + *(t++) = *f; + } + + *t = 0; + + return r; + +} + static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) { assert(bad); diff --git a/src/basic/escape.h b/src/basic/escape.h index ac8f5f3910..bc25646a3d 100644 --- a/src/basic/escape.h +++ b/src/basic/escape.h @@ -50,6 +50,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit); char *xescape(const char *s, const char *bad); +char *octescape(const char *s, size_t len); char *shell_escape(const char *s, const char *bad); char *shell_maybe_quote(const char *s); diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 6a9a1f732d..4c4d16d109 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1086,6 +1086,18 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star r = dns_packet_append_blob(p, rr->tlsa.data, rr->tlsa.data_size, NULL); break; + case DNS_TYPE_CAA: + r = dns_packet_append_uint8(p, rr->caa.flags, NULL); + if (r < 0) + goto fail; + + r = dns_packet_append_string(p, rr->caa.tag, NULL); + if (r < 0) + goto fail; + + r = dns_packet_append_blob(p, rr->caa.value, rr->caa.value_size, NULL); + break; + case DNS_TYPE_OPT: case DNS_TYPE_OPENPGPKEY: case _DNS_TYPE_INVALID: /* unparseable */ @@ -1967,6 +1979,21 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl break; + case DNS_TYPE_CAA: + r = dns_packet_read_uint8(p, &rr->caa.flags, NULL); + if (r < 0) + return r; + + r = dns_packet_read_string(p, &rr->caa.tag, NULL); + if (r < 0) + return r; + + r = dns_packet_read_memdup(p, + rdlength + offset - p->rindex, + &rr->caa.value, &rr->caa.value_size, NULL); + + break; + case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */ case DNS_TYPE_OPENPGPKEY: default: diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 422bbe4bc4..35c0de1a6d 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -24,6 +24,7 @@ #include "alloc-util.h" #include "dns-domain.h" #include "dns-type.h" +#include "escape.h" #include "hexdecoct.h" #include "resolved-dns-dnssec.h" #include "resolved-dns-packet.h" @@ -492,6 +493,11 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) { free(rr->tlsa.data); break; + case DNS_TYPE_CAA: + free(rr->caa.tag); + free(rr->caa.value); + break; + case DNS_TYPE_OPENPGPKEY: default: free(rr->generic.data); @@ -699,6 +705,12 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor a->tlsa.matching_type == b->tlsa.matching_type && FIELD_EQUAL(a->tlsa, b->tlsa, data); + case DNS_TYPE_CAA: + return a->caa.flags == b->caa.flags && + streq(a->caa.tag, b->caa.tag) && + FIELD_EQUAL(a->caa, b->caa, value); + + case DNS_TYPE_OPENPGPKEY: default: return FIELD_EQUAL(a->generic, b->generic, data); } @@ -1142,6 +1154,24 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { break; } + case DNS_TYPE_CAA: { + _cleanup_free_ char *value; + + value = octescape(rr->caa.value, rr->caa.value_size); + if (!value) + return NULL; + + r = asprintf(&s, "%s %u %s \"%s\"", + k, + rr->caa.flags, + rr->caa.tag, + value); + if (r < 0) + return NULL; + + break; + } + case DNS_TYPE_OPENPGPKEY: { int n; @@ -1432,6 +1462,12 @@ void dns_resource_record_hash_func(const void *i, struct siphash *state) { siphash24_compress(rr->tlsa.data, rr->tlsa.data_size, state); break; + case DNS_TYPE_CAA: + siphash24_compress(&rr->caa.flags, sizeof(rr->caa.flags), state); + string_hash_func(rr->caa.tag, state); + siphash24_compress(rr->caa.value, rr->caa.value_size, state); + break; + case DNS_TYPE_OPENPGPKEY: default: siphash24_compress(rr->generic.data, rr->generic.data_size, state); diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index 01c7091645..b75676912b 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -251,6 +251,14 @@ struct DnsResourceRecord { void *data; size_t data_size; } tlsa; + + /* https://tools.ietf.org/html/rfc6844 */ + struct { + uint8_t flags; + char *tag; + void *value; + size_t value_size; + } caa; }; }; -- cgit v1.2.3-54-g00ecf From 718af59e9ac1a525b0a73b99a74bc376f1b4d49d Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Mon, 1 Feb 2016 21:35:44 -0500 Subject: resolve: always align flags to 8th column and print CAA flags Left-over unknown flags are printed numerically. Otherwise, it wouldn't be known what bits are remaining without knowning what the known bits are. A test case is added to verify the flag printing code: ============== src/resolve/test-data/fake-caa.pkts ============== google.com. IN CAA 0 issue "symantec.com" google.com. IN CAA 128 issue "symantec.com" -- Flags: critical google.com. IN CAA 129 issue "symantec.com" -- Flags: critical 1 google.com. IN CAA 22 issue "symantec.com" -- Flags: 22 --- Makefile.am | 3 ++- src/resolve/dns-type.h | 3 +++ src/resolve/resolved-dns-rr.c | 31 ++++++++++++++++--------------- src/resolve/test-data/fake-caa.pkts | Bin 0 -> 196 bytes 4 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 src/resolve/test-data/fake-caa.pkts (limited to 'src/resolve/resolved-dns-rr.c') diff --git a/Makefile.am b/Makefile.am index 8ab04e74ba..5d39967f2c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5326,7 +5326,8 @@ EXTRA_DIST += \ src/resolve/test-data/teamits.com.pkts \ src/resolve/test-data/zbyszek@fedoraproject.org.pkts \ src/resolve/test-data/_443._tcp.fedoraproject.org.pkts \ - src/resolve/test-data/kyhwana.org.pkts + src/resolve/test-data/kyhwana.org.pkts \ + src/resolve/test-data/fake-caa.pkts test_dnssec_SOURCES = \ src/resolve/test-dnssec.c \ diff --git a/src/resolve/dns-type.h b/src/resolve/dns-type.h index d025544bab..ea51dfdb65 100644 --- a/src/resolve/dns-type.h +++ b/src/resolve/dns-type.h @@ -154,3 +154,6 @@ const char *tlsa_selector_to_string(uint8_t selector); /* https://tools.ietf.org/html/draft-ietf-dane-protocol-23#section-7.4 */ const char *tlsa_matching_type_to_string(uint8_t selector); + +/* https://tools.ietf.org/html/rfc6844#section-5.1 */ +#define CAA_FLAG_CRITICAL (1u << 7) diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 35c0de1a6d..d54645fc7a 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -980,7 +980,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { case DNS_TYPE_DNSKEY: { _cleanup_free_ char *alg = NULL; char *ss; - int n, n1; + int n; uint16_t key_tag; key_tag = dnssec_keytag(rr, true); @@ -989,9 +989,8 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { if (r < 0) return NULL; - r = asprintf(&s, "%s %n%u %u %s %n", + r = asprintf(&s, "%s %u %u %s %n", k, - &n1, rr->dnskey.flags, rr->dnskey.protocol, alg, @@ -1006,14 +1005,12 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { return NULL; r = asprintf(&ss, "%s\n" - "%*s-- Flags:%s%s%s\n" - "%*s-- Key tag: %u", + " -- Flags:%s%s%s\n" + " -- Key tag: %u", s, - n1, "", rr->dnskey.flags & DNSKEY_FLAG_SEP ? " SEP" : "", rr->dnskey.flags & DNSKEY_FLAG_REVOKE ? " REVOKE" : "", rr->dnskey.flags & DNSKEY_FLAG_ZONE_KEY ? " ZONE_KEY" : "", - n1, "", key_tag); if (r < 0) return NULL; @@ -1139,13 +1136,13 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { return NULL; r = asprintf(&ss, "%s\n" - "%*s-- Cert. usage: %s\n" - "%*s-- Selector: %s\n" - "%*s-- Matching type: %s", + " -- Cert. usage: %s\n" + " -- Selector: %s\n" + " -- Matching type: %s", s, - n - 6, "", cert_usage, - n - 6, "", selector, - n - 6, "", matching_type); + cert_usage, + selector, + matching_type); if (r < 0) return NULL; free(s); @@ -1161,11 +1158,15 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { if (!value) return NULL; - r = asprintf(&s, "%s %u %s \"%s\"", + r = asprintf(&s, "%s %u %s \"%s\"%s%s%s%.0u", k, rr->caa.flags, rr->caa.tag, - value); + value, + rr->caa.flags ? "\n -- Flags:" : "", + rr->caa.flags & CAA_FLAG_CRITICAL ? " critical" : "", + rr->caa.flags & ~CAA_FLAG_CRITICAL ? " " : "", + rr->caa.flags & ~CAA_FLAG_CRITICAL); if (r < 0) return NULL; diff --git a/src/resolve/test-data/fake-caa.pkts b/src/resolve/test-data/fake-caa.pkts new file mode 100644 index 0000000000..1c3ecc5491 Binary files /dev/null and b/src/resolve/test-data/fake-caa.pkts differ -- cgit v1.2.3-54-g00ecf