Skip to content

Commit

Permalink
auth: prevent createReverse6 from generating illegal IDN record
Browse files Browse the repository at this point in the history
Closes #7524
  • Loading branch information
BozhanL committed Jan 18, 2025
1 parent f7822a3 commit 15dc865
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
10 changes: 10 additions & 0 deletions pdns/lua-record.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,16 @@ static void setupLuaRecords(LuaContext& lua) // NOLINT(readability-function-cogn
string dashed=ip6.toString();
boost::replace_all(dashed, ":", "-");

// https://github.com/PowerDNS/pdns/issues/7524
if (boost::ends_with(dashed, "-")) {
// "a--a-" -> "a--a-0"
dashed.push_back('0');
}
if (boost::starts_with(dashed, "-") || dashed.compare(2, 2, "--") == 0) {
// "-a--a" -> "0-a--a" "aa--a" -> "0aa--a"
dashed.insert(0, "0");
}

for(int i=31; i>=0; --i)
fmt % labels[i];
fmt % dashed;
Expand Down
41 changes: 41 additions & 0 deletions regression-tests.auth-py/test_LuaRecords.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ class BaseLuaTest(AuthTest):
*.createforward IN LUA A "filterForward(createForward(), newNMG{{'1.0.0.0/8', '64.0.0.0/8'}})"
*.createforward6 IN LUA AAAA "filterForward(createForward6(), newNMG{{'2000::/3'}}, 'fe80::1')"
*.no-filter.createforward6 IN LUA AAAA "createForward6()"
*.createreverse IN LUA PTR "createReverse('%5%.example.com', {{['10.10.10.10'] = 'quad10.example.com.'}})"
*.createreverse6 IN LUA PTR "createReverse6('%33%.example.com', {{['2001:db8::1'] = 'example.example.com.'}})"
Expand Down Expand Up @@ -1075,6 +1076,46 @@ def testCreateForwardAndReverse(self):
self.assertRcodeEqual(res, dns.rcode.NOERROR)
self.assertEqual(res.answer, response.answer)

def testCreateForwardAndReverseWithZero(self):
"""
Fix #7524
"""
expected = {
".no-filter.createforward6.example.org." : (dns.rdatatype.AAAA, {
"0--0" : "::",
"0--1" : "::1",
"0aa--0" : "aa::",
"0aa--1" : "aa::1",
"2001--0" : "2001::",
"a-b--c" : "a:b::c",
"a--b-c" : "a::b:c"
}),
".createreverse6.example.org." : (dns.rdatatype.PTR, {
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0" : "0--0.example.com.",
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0" : "0--1.example.com.",
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.a.0.0" : "0aa--0.example.com.",
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.a.0.0" : "0aa--1.example.com.",
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.2" : "2001--0.example.com.",
"c.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.0.0.0.a.0.0.0" : "a-b--c.example.com.",
"c.0.0.0.b.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.0.0.0" : "a--b-c.example.com."
})
}

for suffix, v in expected.items():
qtype, pairs = v
for prefix, target in pairs.items():
name = prefix + suffix

query = dns.message.make_query(name, qtype)
response = dns.message.make_response(query)
response.answer.append(dns.rrset.from_text(
name, 0, dns.rdataclass.IN, qtype, target))

res = self.sendUDPQuery(query)
print(res)
self.assertRcodeEqual(res, dns.rcode.NOERROR)
self.assertEqual(res.answer, response.answer)

def _getCounter(self, tcp=False):
"""
Helper function for shared/non-shared testing
Expand Down

0 comments on commit 15dc865

Please sign in to comment.