]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-dns-rr.c
resolved: explicitly refuse zone transfers using the bus API
[thirdparty/systemd.git] / src / resolve / resolved-dns-rr.c
index 6397005a684e3930e620b1a3fd759b14a4b64f9b..6a29a93a26786b5213c82a26f8755296d0e61476 100644 (file)
@@ -66,7 +66,7 @@ DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const D
                 DnsResourceKey *k;
                 char *destination = NULL;
 
-                r = dns_name_change_suffix(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname->key), cname->dname.name, &destination);
+                r = dns_name_change_suffix(dns_resource_key_name(key), dns_resource_key_name(cname->key), cname->dname.name, &destination);
                 if (r < 0)
                         return NULL;
                 if (r == 0)
@@ -96,7 +96,7 @@ int dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key
                 return 0;
         }
 
-        r = dns_name_concat(DNS_RESOURCE_KEY_NAME(key), name, &joined);
+        r = dns_name_concat(dns_resource_key_name(key), name, &joined);
         if (r < 0)
                 return r;
 
@@ -158,6 +158,23 @@ DnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
         return NULL;
 }
 
+const char* dns_resource_key_name(const DnsResourceKey *key) {
+        const char *name;
+
+        if (!key)
+                return NULL;
+
+        if (key->_name)
+                name = key->_name;
+        else
+                name = (char*) key + sizeof(DnsResourceKey);
+
+        if (dns_name_is_root(name))
+                return ".";
+        else
+                return name;
+}
+
 bool dns_resource_key_is_address(const DnsResourceKey *key) {
         assert(key);
 
@@ -172,7 +189,7 @@ int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
         if (a == b)
                 return 1;
 
-        r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
+        r = dns_name_equal(dns_resource_key_name(a), dns_resource_key_name(b));
         if (r <= 0)
                 return r;
 
@@ -204,18 +221,18 @@ int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr,
         if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
                 return 0;
 
-        r = dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
+        r = dns_name_equal(dns_resource_key_name(rr->key), dns_resource_key_name(key));
         if (r != 0)
                 return r;
 
         if (search_domain) {
                 _cleanup_free_ char *joined = NULL;
 
-                r = dns_name_concat(DNS_RESOURCE_KEY_NAME(key), search_domain, &joined);
+                r = dns_name_concat(dns_resource_key_name(key), search_domain, &joined);
                 if (r < 0)
                         return r;
 
-                return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), joined);
+                return dns_name_equal(dns_resource_key_name(rr->key), joined);
         }
 
         return 0;
@@ -231,9 +248,9 @@ int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsRe
                 return 0;
 
         if (cname->type == DNS_TYPE_CNAME)
-                r = dns_name_equal(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname));
+                r = dns_name_equal(dns_resource_key_name(key), dns_resource_key_name(cname));
         else if (cname->type == DNS_TYPE_DNAME)
-                r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname));
+                r = dns_name_endswith(dns_resource_key_name(key), dns_resource_key_name(cname));
         else
                 return 0;
 
@@ -243,14 +260,14 @@ int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsRe
         if (search_domain) {
                 _cleanup_free_ char *joined = NULL;
 
-                r = dns_name_concat(DNS_RESOURCE_KEY_NAME(key), search_domain, &joined);
+                r = dns_name_concat(dns_resource_key_name(key), search_domain, &joined);
                 if (r < 0)
                         return r;
 
                 if (cname->type == DNS_TYPE_CNAME)
-                        return dns_name_equal(joined, DNS_RESOURCE_KEY_NAME(cname));
+                        return dns_name_equal(joined, dns_resource_key_name(cname));
                 else if (cname->type == DNS_TYPE_DNAME)
-                        return dns_name_endswith(joined, DNS_RESOURCE_KEY_NAME(cname));
+                        return dns_name_endswith(joined, dns_resource_key_name(cname));
         }
 
         return 0;
@@ -268,7 +285,7 @@ int dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey *
         if (soa->type != DNS_TYPE_SOA)
                 return 0;
 
-        return dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(soa));
+        return dns_name_endswith(dns_resource_key_name(key), dns_resource_key_name(soa));
 }
 
 static void dns_resource_key_hash_func(const void *i, struct siphash *state) {
@@ -276,7 +293,7 @@ static void dns_resource_key_hash_func(const void *i, struct siphash *state) {
 
         assert(k);
 
-        dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), state);
+        dns_name_hash_func(dns_resource_key_name(k), state);
         siphash24_compress(&k->class, sizeof(k->class), state);
         siphash24_compress(&k->type, sizeof(k->type), state);
 }
@@ -285,7 +302,7 @@ static int dns_resource_key_compare_func(const void *a, const void *b) {
         const DnsResourceKey *x = a, *y = b;
         int ret;
 
-        ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
+        ret = dns_name_compare_func(dns_resource_key_name(x), dns_resource_key_name(y));
         if (ret != 0)
                 return ret;
 
@@ -307,32 +324,22 @@ const struct hash_ops dns_resource_key_hash_ops = {
         .compare = dns_resource_key_compare_func
 };
 
-int dns_resource_key_to_string(const DnsResourceKey *key, char **ret) {
-        char cbuf[strlen("CLASS") + DECIMAL_STR_MAX(uint16_t)], tbuf[strlen("TYPE") + DECIMAL_STR_MAX(uint16_t)];
-        const char *c, *t, *n;
-        char *s;
+char* dns_resource_key_to_string(const DnsResourceKey *key, char *buf, size_t buf_size) {
+        const char *c, *t;
+        char *ans = buf;
 
         /* If we cannot convert the CLASS/TYPE into a known string,
            use the format recommended by RFC 3597, Section 5. */
 
         c = dns_class_to_string(key->class);
-        if (!c) {
-                sprintf(cbuf, "CLASS%u", key->class);
-                c = cbuf;
-        }
-
         t = dns_type_to_string(key->type);
-        if (!t){
-                sprintf(tbuf, "TYPE%u", key->type);
-                t = tbuf;
-        }
 
-        n = DNS_RESOURCE_KEY_NAME(key);
-        if (asprintf(&s, "%s%s %s %-5s", n, endswith(n, ".") ? "" : ".", c, t) < 0)
-                return -ENOMEM;
+        snprintf(buf, buf_size, "%s %s%s%.0u %s%s%.0u",
+                 dns_resource_key_name(key),
+                 c ?: "", c ? "" : "CLASS", c ? 0 : key->class,
+                 t ?: "", t ? "" : "TYPE", t ? 0 : key->class);
 
-        *ret = s;
-        return 0;
+        return ans;
 }
 
 bool dns_resource_key_reduce(DnsResourceKey **a, DnsResourceKey **b) {
@@ -830,8 +837,8 @@ static char *format_txt(DnsTxtItem *first) {
 }
 
 const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
-        _cleanup_free_ char *k = NULL, *t = NULL;
-        char *s;
+        _cleanup_free_ char *t = NULL;
+        char *s, k[DNS_RESOURCE_KEY_STRING_MAX];
         int r;
 
         assert(rr);
@@ -839,9 +846,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
         if (rr->to_string)
                 return rr->to_string;
 
-        r = dns_resource_key_to_string(rr->key, &k);
-        if (r < 0)
-                return NULL;
+        dns_resource_key_to_string(rr->key, k, sizeof(k));
 
         switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
 
@@ -1111,40 +1116,30 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
 
         case DNS_TYPE_TLSA: {
                 const char *cert_usage, *selector, *matching_type;
-                char *ss;
-                int n;
 
                 cert_usage = tlsa_cert_usage_to_string(rr->tlsa.cert_usage);
                 selector = tlsa_selector_to_string(rr->tlsa.selector);
                 matching_type = tlsa_matching_type_to_string(rr->tlsa.matching_type);
 
-                r = asprintf(&s, "%s %u %u %u %n",
-                             k,
-                             rr->tlsa.cert_usage,
-                             rr->tlsa.selector,
-                             rr->tlsa.matching_type,
-                             &n);
-                if (r < 0)
-                        return NULL;
-
-                r = base64_append(&s, n,
-                                  rr->tlsa.data, rr->tlsa.data_size,
-                                  8, columns());
-                if (r < 0)
+                t = hexmem(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size);
+                if (!t)
                         return NULL;
 
-                r = asprintf(&ss, "%s\n"
+                r = asprintf(&s,
+                             "%s %u %u %u %s\n"
                              "        -- Cert. usage: %s\n"
                              "        -- Selector: %s\n"
                              "        -- Matching type: %s",
-                             s,
+                             k,
+                             rr->tlsa.cert_usage,
+                             rr->tlsa.selector,
+                             rr->tlsa.matching_type,
+                             t,
                              cert_usage,
                              selector,
                              matching_type);
                 if (r < 0)
                         return NULL;
-                free(s);
-                s = ss;
 
                 break;
         }
@@ -1204,6 +1199,47 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
         return s;
 }
 
+ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) {
+        assert(rr);
+        assert(out);
+
+        switch(rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
+        case DNS_TYPE_SRV:
+        case DNS_TYPE_PTR:
+        case DNS_TYPE_NS:
+        case DNS_TYPE_CNAME:
+        case DNS_TYPE_DNAME:
+        case DNS_TYPE_HINFO:
+        case DNS_TYPE_SPF:
+        case DNS_TYPE_TXT:
+        case DNS_TYPE_A:
+        case DNS_TYPE_AAAA:
+        case DNS_TYPE_SOA:
+        case DNS_TYPE_MX:
+        case DNS_TYPE_LOC:
+        case DNS_TYPE_DS:
+        case DNS_TYPE_DNSKEY:
+        case DNS_TYPE_RRSIG:
+        case DNS_TYPE_NSEC:
+        case DNS_TYPE_NSEC3:
+                return -EINVAL;
+
+        case DNS_TYPE_SSHFP:
+                *out = rr->sshfp.fingerprint;
+                return rr->sshfp.fingerprint_size;
+
+        case DNS_TYPE_TLSA:
+                *out = rr->tlsa.data;
+                return rr->tlsa.data_size;
+
+
+        case DNS_TYPE_OPENPGPKEY:
+        default:
+                *out = rr->generic.data;
+                return rr->generic.data_size;
+        }
+}
+
 int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical) {
 
         DnsPacket packet = {
@@ -1261,7 +1297,7 @@ int dns_resource_record_signer(DnsResourceRecord *rr, const char **ret) {
         if (rr->n_skip_labels_signer == (unsigned) -1)
                 return -ENODATA;
 
-        n = DNS_RESOURCE_KEY_NAME(rr->key);
+        n = dns_resource_key_name(rr->key);
         r = dns_name_skip(n, rr->n_skip_labels_signer, &n);
         if (r < 0)
                 return r;
@@ -1284,7 +1320,7 @@ int dns_resource_record_source(DnsResourceRecord *rr, const char **ret) {
         if (rr->n_skip_labels_source == (unsigned) -1)
                 return -ENODATA;
 
-        n = DNS_RESOURCE_KEY_NAME(rr->key);
+        n = dns_resource_key_name(rr->key);
         r = dns_name_skip(n, rr->n_skip_labels_source, &n);
         if (r < 0)
                 return r;
@@ -1324,7 +1360,7 @@ int dns_resource_record_is_synthetic(DnsResourceRecord *rr) {
         if (rr->n_skip_labels_source > 1)
                 return 1;
 
-        r = dns_name_startswith(DNS_RESOURCE_KEY_NAME(rr->key), "*");
+        r = dns_name_startswith(dns_resource_key_name(rr->key), "*");
         if (r < 0)
                 return r;