]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: store DNSKEY fields flags+protocol as-is
authorLennart Poettering <lennart@poettering.net>
Wed, 2 Dec 2015 19:53:10 +0000 (20:53 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 2 Dec 2015 21:50:11 +0000 (22:50 +0100)
When verifying signatures we need to be able to verify the original
data we got for an RR set, and that means we cannot simply drop flags
bits or consider RRs invalid too eagerly. Hence, instead of parsing the
DNSKEY flags store them as-is. Similar, accept the protocol field as it
is, and don't consider it a parsing error if it is not 3.

Of course, this means that the DNSKEY handling code later on needs to
check explicit for protocol != 3.

src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-packet.h
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-rr.h

index d6eab12f636b55c416b6e9f16d8aa8a1a04c827b..7cebad22ffc3082ee4b1fb6beaac508a9a644f56 100644 (file)
@@ -826,11 +826,11 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star
                 break;
 
         case DNS_TYPE_DNSKEY:
-                r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
+                r = dns_packet_append_uint16(p, rr->dnskey.flags, NULL);
                 if (r < 0)
                         goto fail;
 
-                r = dns_packet_append_uint8(p, 3u, NULL);
+                r = dns_packet_append_uint8(p, rr->dnskey.protocol, NULL);
                 if (r < 0)
                         goto fail;
 
@@ -1412,17 +1412,6 @@ static bool loc_size_ok(uint8_t size) {
         return m <= 9 && e <= 9 && (m > 0 || e == 0);
 }
 
-static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
-        assert(rr);
-
-        if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
-                return -EBADMSG;
-
-        rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
-        rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
-        return 0;
-}
-
 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
@@ -1691,28 +1680,15 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
 
                 break;
 
-        case DNS_TYPE_DNSKEY: {
-                uint16_t flags;
-                uint8_t proto;
-
-                r = dns_packet_read_uint16(p, &flags, NULL);
-                if (r < 0)
-                        goto fail;
-
-                r = dnskey_parse_flags(rr, flags);
+        case DNS_TYPE_DNSKEY:
+                r = dns_packet_read_uint16(p, &rr->dnskey.flags, NULL);
                 if (r < 0)
                         goto fail;
 
-                r = dns_packet_read_uint8(p, &proto, NULL);
+                r = dns_packet_read_uint8(p, &rr->dnskey.protocol, NULL);
                 if (r < 0)
                         goto fail;
 
-                /* protocol is required to be always 3 */
-                if (proto != 3) {
-                        r = -EBADMSG;
-                        goto fail;
-                }
-
                 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
                 if (r < 0)
                         goto fail;
@@ -1729,7 +1705,6 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
                 }
 
                 break;
-        }
 
         case DNS_TYPE_RRSIG:
                 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
index d26f77adbe26163b7f9c44763b20fadd09dcf18b..16a38e536194b9c3656a848040843aefe5cbf0eb 100644 (file)
@@ -223,15 +223,11 @@ DnsProtocol dns_protocol_from_string(const char *s) _pure_;
 #define LLMNR_MULTICAST_IPV4_ADDRESS ((struct in_addr) { .s_addr = htobe32(224U << 24 | 252U) })
 #define LLMNR_MULTICAST_IPV6_ADDRESS ((struct in6_addr) { .s6_addr = { 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03 } })
 
-#define DNSKEY_FLAG_ZONE_KEY (1u << 8)
-#define DNSKEY_FLAG_SEP      (1u << 0)
+#define DNSKEY_FLAG_ZONE_KEY (UINT16_C(1) << 8)
+#define DNSKEY_FLAG_SEP      (UINT16_C(1) << 0)
 
-static inline uint16_t dnskey_to_flags(const DnsResourceRecord *rr) {
-        return (rr->dnskey.zone_key_flag * DNSKEY_FLAG_ZONE_KEY |
-                rr->dnskey.sep_flag * DNSKEY_FLAG_SEP);
-}
-
-/* http://tools.ietf.org/html/rfc4034#appendix-A.1 */
+/* http://tools.ietf.org/html/rfc4034#appendix-A.1 and
+ * https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
 enum {
         DNSSEC_ALGORITHM_RSAMD5 = 1,
         DNSSEC_ALGORITHM_DH,
index 4a1abb0cdca477b8365ee8ac5868588eccb18b3d..09fe9725a22883cc27ddc2a84f7f8abfc3fe871e 100644 (file)
@@ -576,8 +576,8 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor
                        memcmp(a->sshfp.fingerprint, b->sshfp.fingerprint, a->sshfp.fingerprint_size) == 0;
 
         case DNS_TYPE_DNSKEY:
-                return a->dnskey.zone_key_flag == b->dnskey.zone_key_flag &&
-                       a->dnskey.sep_flag == b->dnskey.sep_flag &&
+                return a->dnskey.flags == b->dnskey.flags &&
+                       a->dnskey.protocol == b->dnskey.protocol &&
                        a->dnskey.algorithm == b->dnskey.algorithm &&
                        a->dnskey.key_size == b->dnskey.key_size &&
                        memcmp(a->dnskey.key, b->dnskey.key, a->dnskey.key_size) == 0;
@@ -883,9 +883,10 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) {
                 if (!t)
                         return -ENOMEM;
 
-                r = asprintf(&s, "%s %u 3 %.*s%.*u %s",
+                r = asprintf(&s, "%s %u %u %.*s%.*u %s",
                              k,
-                             dnskey_to_flags(rr),
+                             rr->dnskey.flags,
+                             rr->dnskey.protocol,
                              alg ? -1 : 0, alg,
                              alg ? 0 : 1, alg ? 0u : (unsigned) rr->dnskey.algorithm,
                              t);
index a09296182373eb62144c388ac653f8e457b798b1..ac4256b882c91abbcd1bd8606f43da82b0d03e28 100644 (file)
@@ -135,8 +135,8 @@ struct DnsResourceRecord {
 
                 /* http://tools.ietf.org/html/rfc4034#section-2.1 */
                 struct {
-                        bool zone_key_flag:1;
-                        bool sep_flag:1;
+                        uint16_t flags;
+                        uint8_t protocol;
                         uint8_t algorithm;
                         void* key;
                         size_t key_size;