diff --git a/lib/dns/rdata/in_1/a_1.c b/lib/dns/rdata/in_1/a_1.c index e8d3d5a795..24e303f257 100644 --- a/lib/dns/rdata/in_1/a_1.c +++ b/lib/dns/rdata/in_1/a_1.c @@ -207,6 +207,7 @@ digest_in_a(ARGS_DIGEST) { static inline bool checkowner_in_a(ARGS_CHECKOWNER) { dns_name_t prefix, suffix; + unsigned int labels, i; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_in); @@ -214,18 +215,41 @@ checkowner_in_a(ARGS_CHECKOWNER) { UNUSED(type); UNUSED(rdclass); - /* - * Handle Active Directory gc._msdcs. name. - */ - if (dns_name_countlabels(name) > 2U) { + labels = dns_name_countlabels(name); + if (labels > 2U) { + /* + * Handle Active Directory gc._msdcs. name. + */ dns_name_init(&prefix, NULL); dns_name_init(&suffix, NULL); - dns_name_split(name, dns_name_countlabels(name) - 2, &prefix, - &suffix); + dns_name_split(name, labels - 2, &prefix, &suffix); if (dns_name_equal(&gc_msdcs, &prefix) && dns_name_ishostname(&suffix, false)) { return (true); } + + /* + * Handle SPF exists targets when the seperating label is: + * - "_spf" RFC7208, section 5.7 + * - "_spf_verify" RFC7208, Appendix D1 + * - "_spf_rate" RFC7208, Appendix D1 + */ + for (i = 0; i < labels - 2; i++) { + dns_label_t label; + dns_name_getlabel(name, i, &label); + if ((label.length == 5 && + strncasecmp((char *)label.base, "\x04_spf", 5) == + 0) || + (label.length == 12 && + strncasecmp((char *)label.base, "\x0b_spf_verify", + 12) == 0) || + (label.length == 10 && + strncasecmp((char *)label.base, "\x09_spf_rate", + 10) == 0)) + { + return (true); + } + } } return (dns_name_ishostname(name, wildcard));