From 665f12a744dea29a4e5437ecca918ed5d57b5744 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Thu, 12 Apr 2018 00:09:40 +0000 Subject: Add CAA record support --- src/include/s6-dns/s6dns-analyze.h | 1 + src/include/s6-dns/s6dns-constants.h | 1 + src/include/s6-dns/s6dns-fmt.h | 3 +++ src/include/s6-dns/s6dns-message.h | 11 +++++++++++ src/include/s6-dns/s6dns-resolve.h | 13 +++++++++---- src/libs6dns/deps-lib/s6dns | 4 ++++ src/libs6dns/s6dns_analyze_qtype_parse.c | 1 + src/libs6dns/s6dns_analyze_record_caa.c | 22 ++++++++++++++++++++++ src/libs6dns/s6dns_analyze_rtypetable.c | 1 + src/libs6dns/s6dns_fmt_caa.c | 22 ++++++++++++++++++++++ src/libs6dns/s6dns_message_get_caa.c | 24 ++++++++++++++++++++++++ src/libs6dns/s6dns_message_parse_answer_caa.c | 17 +++++++++++++++++ 12 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 src/libs6dns/s6dns_analyze_record_caa.c create mode 100644 src/libs6dns/s6dns_fmt_caa.c create mode 100644 src/libs6dns/s6dns_message_get_caa.c create mode 100644 src/libs6dns/s6dns_message_parse_answer_caa.c (limited to 'src') diff --git a/src/include/s6-dns/s6dns-analyze.h b/src/include/s6-dns/s6dns-analyze.h index 35f34cf..ed4fb17 100644 --- a/src/include/s6-dns/s6dns-analyze.h +++ b/src/include/s6-dns/s6dns-analyze.h @@ -28,6 +28,7 @@ extern s6dns_analyze_record_func_t s6dns_analyze_record_hinfo ; extern s6dns_analyze_record_func_t s6dns_analyze_record_soa ; extern s6dns_analyze_record_func_t s6dns_analyze_record_mx ; extern s6dns_analyze_record_func_t s6dns_analyze_record_srv ; +extern s6dns_analyze_record_func_t s6dns_analyze_record_caa ; extern s6dns_analyze_record_func_t s6dns_analyze_record_domain ; extern s6dns_analyze_record_func_t s6dns_analyze_record_strings ; extern s6dns_analyze_record_func_t s6dns_analyze_record_unknown ; diff --git a/src/include/s6-dns/s6dns-constants.h b/src/include/s6-dns/s6dns-constants.h index ad47dc1..38900d1 100644 --- a/src/include/s6-dns/s6dns-constants.h +++ b/src/include/s6-dns/s6dns-constants.h @@ -25,6 +25,7 @@ #define S6DNS_T_SRV 33U #define S6DNS_T_AXFR 252U #define S6DNS_T_ANY 255U +#define S6DNS_T_CAA 257U #define S6DNS_O_RECURSIVE 0x0001U #define S6DNS_O_STRICT 0x0002U diff --git a/src/include/s6-dns/s6dns-fmt.h b/src/include/s6-dns/s6dns-fmt.h index 4be81ec..d7f00bd 100644 --- a/src/include/s6-dns/s6dns-fmt.h +++ b/src/include/s6-dns/s6dns-fmt.h @@ -26,4 +26,7 @@ extern size_t s6dns_fmt_soa (char *, size_t, s6dns_message_rr_soa_t const *) ; #define S6DNS_FMT_SRV (S6DNS_FMT_DOMAIN + 3 * UINT16_FMT) extern size_t s6dns_fmt_srv (char *, size_t, s6dns_message_rr_srv_t const *) ; +#define S6DNS_FMT_CAA 517 +extern size_t s6dns_fmt_caa (char *, size_t, s6dns_message_rr_caa_t const *) ; + #endif diff --git a/src/include/s6-dns/s6dns-message.h b/src/include/s6-dns/s6dns-message.h index cc3e68e..e57a992 100644 --- a/src/include/s6-dns/s6dns-message.h +++ b/src/include/s6-dns/s6dns-message.h @@ -109,6 +109,16 @@ struct s6dns_message_rr_srv_s extern int s6dns_message_get_srv (s6dns_message_rr_srv_t *, char const *, unsigned int, unsigned int *) ; +typedef struct s6dns_message_rr_caa_s s6dns_message_rr_caa_t, *s6dns_message_rr_caa_t_ref ; +struct s6dns_message_rr_caa_s +{ + uint8_t flags ; + char tag[256] ; + char value[256] ; +} ; + +extern int s6dns_message_get_caa (s6dns_message_rr_caa_t *, char const *, unsigned int, unsigned int *, uint16_t) ; + /* The callback function type: how to parse RRs */ @@ -157,6 +167,7 @@ extern s6dns_message_rr_func_t s6dns_message_parse_answer_mx ; extern s6dns_message_rr_func_t s6dns_message_parse_answer_hinfo ; extern s6dns_message_rr_func_t s6dns_message_parse_answer_soa ; extern s6dns_message_rr_func_t s6dns_message_parse_answer_srv ; +extern s6dns_message_rr_func_t s6dns_message_parse_answer_caa ; /* The actual parsing function */ diff --git a/src/include/s6-dns/s6dns-resolve.h b/src/include/s6-dns/s6dns-resolve.h index fe1425a..a571103 100644 --- a/src/include/s6-dns/s6dns-resolve.h +++ b/src/include/s6-dns/s6dns-resolve.h @@ -183,15 +183,20 @@ extern int s6dns_resolve_name6_r (genalloc *, char const *, s6dns_engine_t *, s6 #define s6dns_resolve_hinfo_r(hinfos, name, len, qualif, dt, rci, dbh, deadline, stamp) s6dns_resolve_r(name, len, S6DNS_T_HINFO, &s6dns_message_parse_answer_hinfo, (hinfos), qualif, dt, rci, dbh, deadline, stamp) #define s6dns_resolve_hinfo_r_g(hinfos, name, len, qualif, dt, rci, dbh, deadline) s6dns_resolve_hinfo_r(hinfos, name, len, qualif, dt, rci, dbh, (deadline), &STAMP) +#define s6dns_resolve_soa(soas, name, len, qualif, deadline, stamp) s6dns_resolve_soa_r(soas, name, len, qualif, &s6dns_engine_here, &s6dns_rci_here, &s6dns_debughook_zero, deadline, stamp) +#define s6dns_resolve_soa_g(soas, name, len, qualif, deadline) s6dns_resolve_soa(soas, name, len, qualif, (deadline), &STAMP) +#define s6dns_resolve_soa_r(soas, name, len, qualif, dt, rci, dbh, deadline, stamp) s6dns_resolve_r(name, len, S6DNS_T_SOA, &s6dns_message_parse_answer_soa, (soas), qualif, dt, rci, dbh, deadline, stamp) +#define s6dns_resolve_soa_r_g(soas, name, len, qualif, dt, rci, dbh, deadline) s6dns_resolve_soa_r(soas, name, len, qualif, dt, rci, dbh, (deadline), &STAMP) + #define s6dns_resolve_srv(srvs, name, len, qualif, deadline, stamp) s6dns_resolve_srv_r(srvs, name, len, qualif, &s6dns_engine_here, &s6dns_rci_here, &s6dns_debughook_zero, deadline, stamp) #define s6dns_resolve_srv_g(srvs, name, len, qualif, deadline) s6dns_resolve_srv(srvs, name, len, qualif, (deadline), &STAMP) #define s6dns_resolve_srv_r(srvs, name, len, qualif, dt, rci, dbh, deadline, stamp) s6dns_resolve_r(name, len, S6DNS_T_SRV, &s6dns_message_parse_answer_srv, (srvs), qualif, dt, rci, dbh, deadline, stamp) #define s6dns_resolve_srv_r_g(srvs, name, len, qualif, dt, rci, dbh, deadline) s6dns_resolve_srv_r(srvs, name, len, qualif, dt, rci, dbh, (deadline), &STAMP) -#define s6dns_resolve_soa(soas, name, len, qualif, deadline, stamp) s6dns_resolve_soa_r(soas, name, len, qualif, &s6dns_engine_here, &s6dns_rci_here, &s6dns_debughook_zero, deadline, stamp) -#define s6dns_resolve_soa_g(soas, name, len, qualif, deadline) s6dns_resolve_soa(soas, name, len, qualif, (deadline), &STAMP) -#define s6dns_resolve_soa_r(soas, name, len, qualif, dt, rci, dbh, deadline, stamp) s6dns_resolve_r(name, len, S6DNS_T_SOA, &s6dns_message_parse_answer_soa, (soas), qualif, dt, rci, dbh, deadline, stamp) -#define s6dns_resolve_soa_r_g(soas, name, len, qualif, dt, rci, dbh, deadline) s6dns_resolve_soa_r(soas, name, len, qualif, dt, rci, dbh, (deadline), &STAMP) +#define s6dns_resolve_caa(caas, name, len, qualif, deadline, stamp) s6dns_resolve_caa_r(caas, name, len, qualif, &s6dns_engine_here, &s6dns_rci_here, &s6dns_debughook_zero, deadline, stamp) +#define s6dns_resolve_caa_g(caas, name, len, qualif, deadline) s6dns_resolve_caa(caas, name, len, qualif, (deadline), &STAMP) +#define s6dns_resolve_caa_r(caas, name, len, qualif, dt, rci, dbh, deadline, stamp) s6dns_resolve_r(name, len, S6DNS_T_CAA, &s6dns_message_parse_answer_caa, (caas), qualif, dt, rci, dbh, deadline, stamp) +#define s6dns_resolve_caa_r_g(caas, name, len, qualif, dt, rci, dbh, deadline) s6dns_resolve_caa_r(caas, name, len, qualif, dt, rci, dbh, (deadline), &STAMP) /* Internals for the high-level functions. */ diff --git a/src/libs6dns/deps-lib/s6dns b/src/libs6dns/deps-lib/s6dns index b0ae95d..95c2bf5 100644 --- a/src/libs6dns/deps-lib/s6dns +++ b/src/libs6dns/deps-lib/s6dns @@ -23,6 +23,7 @@ s6dns_fmt_hinfo.o s6dns_fmt_mx.o s6dns_fmt_soa.o s6dns_fmt_srv.o +s6dns_fmt_caa.o s6dns_message_counts_next.o s6dns_message_counts_pack.o s6dns_message_counts_unpack.o @@ -36,6 +37,7 @@ s6dns_message_get_strings.o s6dns_message_get_mx.o s6dns_message_get_soa.o s6dns_message_get_srv.o +s6dns_message_get_caa.o s6dns_message_header_pack.o s6dns_message_header_unpack.o s6dns_message_header_zero.o @@ -46,6 +48,7 @@ s6dns_message_parse_answer_hinfo.o s6dns_message_parse_answer_mx.o s6dns_message_parse_answer_soa.o s6dns_message_parse_answer_srv.o +s6dns_message_parse_answer_caa.o s6dns_message_parse_answer_strings.o s6dns_message_parse.o s6dns_message_parse_getrr.o @@ -77,6 +80,7 @@ s6dns_analyze_record_hinfo.o s6dns_analyze_record_mx.o s6dns_analyze_record_soa.o s6dns_analyze_record_srv.o +s6dns_analyze_record_caa.o s6dns_analyze_record_domain.o s6dns_analyze_record_strings.o s6dns_analyze_record_unknown.o diff --git a/src/libs6dns/s6dns_analyze_qtype_parse.c b/src/libs6dns/s6dns_analyze_qtype_parse.c index 4898bfd..0764d47 100644 --- a/src/libs6dns/s6dns_analyze_qtype_parse.c +++ b/src/libs6dns/s6dns_analyze_qtype_parse.c @@ -29,6 +29,7 @@ static lookuptable_t const table[] = { "SIG", S6DNS_T_SIG }, { "KEY", S6DNS_T_KEY }, { "AXFR", S6DNS_T_AXFR }, + { "CAA", S6DNS_T_CAA }, { 0, 0 } } ; diff --git a/src/libs6dns/s6dns_analyze_record_caa.c b/src/libs6dns/s6dns_analyze_record_caa.c new file mode 100644 index 0000000..fa8ab91 --- /dev/null +++ b/src/libs6dns/s6dns_analyze_record_caa.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include +#include + +int s6dns_analyze_record_caa (genwrite_t *gp, s6dns_message_rr_t const *rr, char const *packet, unsigned int packetlen, unsigned int start) +{ + s6dns_message_rr_caa_t caa ; + size_t len ; + unsigned int pos = start ; + char buf[S6DNS_FMT_CAA] ; + if (!s6dns_message_get_caa(&caa, packet, packetlen, &pos, rr->rdlength)) return 0 ; + if (rr->rdlength != pos - start) return (errno = EPROTO, 0) ; + len = s6dns_fmt_caa(buf, S6DNS_FMT_CAA, &caa) ; + if (!len) return 0 ; + if ((*gp->put)(gp->target, buf, len) < 0) return 0 ; + return 1 ; +} diff --git a/src/libs6dns/s6dns_analyze_rtypetable.c b/src/libs6dns/s6dns_analyze_rtypetable.c index 523fc72..d6b52f0 100644 --- a/src/libs6dns/s6dns_analyze_rtypetable.c +++ b/src/libs6dns/s6dns_analyze_rtypetable.c @@ -14,6 +14,7 @@ static s6dns_analyze_rtypetable_t const s6dns_analyze_rtypetable_array[] = { 16, "TXT", &s6dns_analyze_record_strings }, { 28, "AAAA", &s6dns_analyze_record_aaaa }, { 33, "SRV", &s6dns_analyze_record_srv }, + { 257, "CAA", &s6dns_analyze_record_caa }, { 0, "unknown", &s6dns_analyze_record_unknown } } ; diff --git a/src/libs6dns/s6dns_fmt_caa.c b/src/libs6dns/s6dns_fmt_caa.c new file mode 100644 index 0000000..7fbf36b --- /dev/null +++ b/src/libs6dns/s6dns_fmt_caa.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include + +size_t s6dns_fmt_caa (char *s, size_t max, s6dns_message_rr_caa_t const *caa) +{ + size_t len = 0, taglen = strlen(caa->tag), valuelen = strlen(caa->value) ; + char fmt[UINT16_FMT] ; + size_t r = uint16_fmt(fmt, (uint16_t)caa->flags) ; + if (r + taglen + valuelen + 2 > max) return (errno = ENAMETOOLONG, 0) ; + memcpy(s + len, fmt, r) ; + len += r ; s[len++] = ' ' ; + memcpy(s + len, caa->tag, taglen) ; + len += taglen ; s[len++] = ' ' ; + memcpy(s + len, caa->value, valuelen) ; + len += valuelen ; + return len ; +} diff --git a/src/libs6dns/s6dns_message_get_caa.c b/src/libs6dns/s6dns_message_get_caa.c new file mode 100644 index 0000000..a97b8c0 --- /dev/null +++ b/src/libs6dns/s6dns_message_get_caa.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include + +int s6dns_message_get_caa (s6dns_message_rr_caa_t *caa, char const *packet, unsigned int packetlen, unsigned int *pos, uint16_t rdlength) +{ + unsigned char taglen ; + if (rdlength < 4) return (errno = EPROTO, 0) ; + if (*pos + rdlength > packetlen) return (errno = EPROTO, 0) ; + caa->flags = packet[(*pos)++] ; + taglen = packet[(*pos)++] ; + if (rdlength < taglen + 3 || rdlength > taglen + 257) return (errno = EPROTO, 0) ; + memcpy(caa->tag, packet + *pos, taglen) ; + caa->tag[taglen] = 0 ; + *pos += taglen ; + memcpy(caa->value, packet + *pos, rdlength - taglen - 2) ; + caa->value[rdlength - taglen - 1] = 0 ; + *pos += rdlength - taglen - 2 ; + return 1 ; +} diff --git a/src/libs6dns/s6dns_message_parse_answer_caa.c b/src/libs6dns/s6dns_message_parse_answer_caa.c new file mode 100644 index 0000000..3b78b43 --- /dev/null +++ b/src/libs6dns/s6dns_message_parse_answer_caa.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include +#include +#include + +int s6dns_message_parse_answer_caa (s6dns_message_rr_t const *rr, char const *packet, unsigned int packetlen, unsigned int pos, unsigned int section, void *stuff) +{ + if ((section == 2) && (rr->rtype == S6DNS_T_CAA)) + { + genalloc *data = stuff ; + s6dns_message_rr_caa_t caa ; + if (!s6dns_message_get_caa(&caa, packet, packetlen, &pos, rr->rdlength)) return 0 ; + if (!genalloc_append(s6dns_message_rr_caa_t, data, &caa)) return -1 ; + } + return 1 ; +} -- cgit v1.2.3