]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
modules/policy: use origin and domain name as binary data
authorLukáš Ježek <lukas.jezek@nic.cz>
Tue, 14 Apr 2020 08:33:38 +0000 (10:33 +0200)
committerPetr Špaček <petr.spacek@nic.cz>
Tue, 14 Apr 2020 15:38:19 +0000 (17:38 +0200)
modules/policy/README.rst
modules/policy/policy.lua
modules/policy/policy.rpz.test.lua
modules/policy/policy.test.rpz
tests/integration/deckard

index 031f0afe2ea43fca3308134d541df439b783111a..7d5f86903c24cf456d4c4150ddb675aad18672a3 100644 (file)
@@ -152,7 +152,7 @@ Following actions stop the policy matching on the query, i.e. other rules are no
 
    .. code-block:: lua
 
-       -- this policy change IPv4 adress and TTL for `exmaple.com`
+       -- this policy changes IPv4 adress and TTL for `exmaple.com`
        policy.add(policy.suffix(policy.ANSWER({ [kres.type.A] = { ttl=300, rdata='\192\0\2\7' } }), { todname('example.com') }))
 
 More complex non-chain actions are described in their own chapters, namely:
index 3448ce3dc55971898594d6e200afac6edc1151e4..b9b90f5e8b58ab3cbfba2e8029a98ee8336bbb0f 100644 (file)
@@ -378,7 +378,7 @@ end
 local function rpz_parse(action, path)
        local rules = {}
        local new_actions = {}
-       local origin = '.'
+       local origin = '\0'
        local action_map = {
                -- RPZ Policy Actions
                ['\0'] = action,
@@ -416,22 +416,33 @@ local function rpz_parse(action, path)
                end
                if not ok then break end
 
-               local name = ffi.string(parser.r_owner, parser.r_owner_length)
+               local full_name = ffi.gc(ffi.C.knot_dname_copy(parser.r_owner, nil), ffi.C.free)
                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
-                       -- parser return \0 if SOA use @ as owner
-                       origin = (name == '\0') and origin or name
+                       origin = ffi.gc(ffi.C.knot_dname_copy(full_name, nil), ffi.C.free)
                        goto continue
                end
 
-               name = (name == origin) and name or name:gsub('%'..origin, '')
+               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
 
                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 in RPZ is not supported', path, tonumber(parser.line_counter))
+                               log('[poli] RPZ %s:%d: CNAME with custom target in RPZ is not supported', path, tonumber(parser.line_counter))
                        end
                else
                        -- Warn when NYI
@@ -449,8 +460,8 @@ local function rpz_parse(action, path)
                ::continue::
        end
        collectgarbage()
-       for k, v in pairs(new_actions) do
-               rules[k] = policy.ANSWER(v, true)
+       for qname, rrsets in pairs(new_actions) do
+               rules[qname] = policy.ANSWER(rrsets, true)
        end
        return rules
 end
index 4f219ca2035ca6c18b3824599532ef9808feb74e..846b642b069251c3421d784630a05b1e4156e761 100644 (file)
@@ -45,18 +45,26 @@ end
 local function test_rpz()
        check_answer('"CNAME ." return NXDOMAIN',
                'nxdomain.', kres.type.A, kres.rcode.NXDOMAIN)
-       check_answer('"CNAME *." return NXDOMAIN',
+       check_answer('"CNAME *." return NODATA',
                'nodata.', kres.type.A, kres.rcode.NOERROR)
+       check_answer('"CNAME *. on wildcard" return NODATA',
+               'nodata.nxdomain.', kres.type.A, kres.rcode.NOERROR)
        check_answer('"CNAME rpz-drop." be dropped',
                'rpzdrop.', kres.type.A, kres.rcode.SERVFAIL)
        check_answer('"CNAME rpz-passthru" return A rrset',
                'rpzpassthru.', kres.type.A, kres.rcode.NOERROR, '127.0.0.9')
-       check_answer('"A 192.168.55.5" return local A rrset',
-               'rra.', kres.type.A, kres.rcode.NOERROR, '192.168.55.5')
-       check_answer('"A 192.168.66.6" with suffixed zone name in owner return local A rrset',
-               'rra-zonename-suffix.', kres.type.A, kres.rcode.NOERROR, '192.168.66.6')
+       check_answer('"A 192.168.5.5" return local A rrset',
+               'rra.', kres.type.A, kres.rcode.NOERROR, '192.168.5.5')
+       check_answer('"A 192.168.6.6" with suffixed zone name in owner return local A rrset',
+               'rra-zonename-suffix.', kres.type.A, kres.rcode.NOERROR, '192.168.6.6')
+       check_answer('"A 192.168.7.7" with suffixed zone name in owner return local A rrset',
+               'testdomain.rra.', kres.type.A, kres.rcode.NOERROR, '192.168.7.7')
        check_answer('non existing AAAA on rra domain return NODATA',
                'rra.', kres.type.AAAA, kres.rcode.NOERROR)
+       check_answer('"A 192.168.8.8" and domain with uppercase and lowercase letters',
+               'case.sensitive.', kres.type.A, kres.rcode.NOERROR, '192.168.8.8')
+       check_answer('"A 192.168.8.8" and domain with uppercase and lowercase letters',
+               'CASe.SENSItivE.', kres.type.A, kres.rcode.NOERROR, '192.168.8.8')
 end
 
 net.ipv4 = false
index dd8fe3979b11e3210ff3772f64fc03a6327b3bc2..16c5c39a543e0a0064497851480fc787eb130795 100644 (file)
@@ -1,10 +1,13 @@
 $TTL 30
 testdomain.            SOA nonexistent.testdomain. testdomain. 1 12h 15m 3w 2h
-                       NS  nonexistant.testdomain.
+                       NS  nonexistent.testdomain.
 
 nxdomain.              CNAME   .
 nodata.                        CNAME   *.
+*.nxdomain.            CNAME   *.
 rpzdrop.               CNAME   rpz-drop.
 rpzpassthru.           CNAME   rpz-passthru.
-rra.                   A       192.168.55.5
-rra-zonename-suffix.testdomain.                A       192.168.66.6
+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
index a90e8deacafc3a66b6109e62986fb2a72ea57c49..84d16f4bf169e1365e6e2bc68efd44592a7e37a1 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a90e8deacafc3a66b6109e62986fb2a72ea57c49
+Subproject commit 84d16f4bf169e1365e6e2bc68efd44592a7e37a1