resolve: parse CAA records

This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2016-01-31 16:21:00 -05:00
parent fa45182ed6
commit 95052df376
5 changed files with 100 additions and 0 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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:

View file

@ -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);

View file

@ -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;
};
};