From: Vladimír Čunát Date: Tue, 30 Jun 2020 12:37:12 +0000 (+0200) Subject: policy.rpz: fix $ORIGIN-related handling X-Git-Tag: v5.1.2~1^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f78fea28f4df3aa0be4940db10eb8ab791c80da7;p=thirdparty%2Fknot-resolver.git policy.rpz: fix $ORIGIN-related handling - use parser-detected $ORIGIN instead of looking at SOA owner - skip records outside $ORIGIN (and warn) instead of nesting them - simplify a bit, and tweak warnings --- diff --git a/modules/policy/policy.lua b/modules/policy/policy.lua index 8a4e94079..1bb528d53 100644 --- a/modules/policy/policy.lua +++ b/modules/policy/policy.lua @@ -378,7 +378,6 @@ end local function rpz_parse(action, path) local rules = {} local new_actions = {} - local origin = '\0' local action_map = { -- RPZ Policy Actions ['\0'] = action, @@ -388,11 +387,11 @@ local function rpz_parse(action, path) ['\012rpz-tcp-only\0'] = policy.TC, -- Policy triggers @NYI@ } - -- RR types to be skipped; boolean denoting whether to throw a warning. + -- RR types to be skipped; boolean denoting whether to throw a warning even for RPZ apex. local rrtype_bad = { [kres.type.DNAME] = true, - [kres.type.NS] = false, -- it's mandatory; could be improved to warn based on owner - [kres.type.SOA] = false, -- it's mandatory; could be improved to warn based on owner + [kres.type.NS] = false, + [kres.type.SOA] = false, [kres.type.DNSKEY] = true, [kres.type.DS] = true, [kres.type.RRSIG] = true, @@ -415,42 +414,34 @@ local function rpz_parse(action, path) local rdata = ffi.string(parser.r_data, parser.r_data_length) ffi.C.knot_dname_to_lower(full_name) - if (parser.r_type == kres.type.SOA) then - origin = ffi.gc(ffi.C.knot_dname_copy(full_name, nil), ffi.C.free) + local prefix_labels = ffi.C.knot_dname_in_bailiwick(full_name, parser.zone_origin) + if prefix_labels < 0 then + log('[poli] RPZ %s:%d: RR owner "%s" outside the zone (ignored)', + path, tonumber(parser.line_counter), kres.dname2str(full_name)) goto continue end - local prefix_labels = ffi.C.knot_dname_in_bailiwick(full_name, origin) - local name - if prefix_labels > 0 then - local bytes = 0 - for _=1,prefix_labels do - bytes = bytes + 1 + full_name[bytes] - end - name = ffi.string(full_name, bytes) - name = name..'\0' - else - name = ffi.string(full_name, parser.r_owner_length) - end + local bytes = ffi.C.knot_dname_size(full_name) - ffi.C.knot_dname_size(parser.zone_origin) + local name = ffi.string(full_name, bytes) .. '\0' if parser.r_type == kres.type.CNAME then if action_map[rdata] then rules[name] = action_map[rdata] else - log('[poli] RPZ %s:%d: CNAME with custom target in RPZ is not supported', path, tonumber(parser.line_counter)) + log('[poli] RPZ %s:%d: CNAME with custom target in RPZ is not supported yet (ignored)', + path, tonumber(parser.line_counter)) end else - -- Warn when NYI if #name then local is_bad = rrtype_bad[parser.r_type] - if is_bad == true then - log('[poli] RPZ %s:%d: RR type %s is not allowed in RPZ', path, tonumber(parser.line_counter), - kres.tostring.type[parser.r_type]) + if is_bad == true or (is_bad == false and prefix_labels ~= 0) then + log('[poli] RPZ %s:%d warning: RR type %s is not allowed in RPZ (ignored)', + path, tonumber(parser.line_counter), kres.tostring.type[parser.r_type]) elseif is_bad == nil then if new_actions[name] == nil then new_actions[name] = {} end new_actions[name][parser.r_type] = { ttl=parser.r_ttl, rdata=rdata } else - assert(is_bad == false) + assert(is_bad == false and prefix_labels == 0) end end end diff --git a/modules/policy/policy.test.rpz b/modules/policy/policy.test.rpz index 16c5c39a5..8c07efc2e 100644 --- a/modules/policy/policy.test.rpz +++ b/modules/policy/policy.test.rpz @@ -1,13 +1,15 @@ +$ORIGIN testdomain. $TTL 30 testdomain. SOA nonexistent.testdomain. testdomain. 1 12h 15m 3w 2h NS nonexistent.testdomain. -nxdomain. CNAME . -nodata. CNAME *. -*.nxdomain. CNAME *. -rpzdrop. CNAME rpz-drop. -rpzpassthru. CNAME rpz-passthru. -rra. A 192.168.5.5 -rra-zonename-suffix.testdomain. A 192.168.6.6 -testdomain.rra.testdomain. A 192.168.7.7 -CaSe.SeNSiTiVe. A 192.168.8.8 +nxdomain CNAME . +nodata CNAME *. +*.nxdomain CNAME *. +rpzdrop CNAME rpz-drop. +rpzpassthru CNAME rpz-passthru. +rra A 192.168.5.5 +rra-zonename-suffix A 192.168.6.6 +testdomain.rra.testdomain. A 192.168.7.7 +CaSe.SeNSiTiVe A 192.168.8.8 +