From: Štěpán Balážik Date: Thu, 23 Jul 2026 11:02:39 +0000 (+0200) Subject: Refactor the fwdfirst ans3 response server X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0301bd6a6521f561297e970e5e42ae3f1699994b;p=thirdparty%2Fbind9.git Refactor the fwdfirst ans3 response server Serve the forged answer with a declarative QnameQtypeHandler scoped to the victim query instead of an imperative handler that poisoned every A query. ns.fwd.hack is reached only if the resolver wrongly follows the poison referral, and the victim name is the query the test inspects. Assisted-by: Claude:claude-fable-5 --- diff --git a/bin/tests/system/fwdfirst/ans3/ans.py b/bin/tests/system/fwdfirst/ans3/ans.py index 8a7ecf8a4de..390278fbbe7 100644 --- a/bin/tests/system/fwdfirst/ans3/ans.py +++ b/bin/tests/system/fwdfirst/ans3/ans.py @@ -11,38 +11,32 @@ See the COPYRIGHT file distributed with this work for additional information regarding copyright ownership. """ -from collections.abc import AsyncGenerator - import dns.rcode +import dns.rdataclass import dns.rdatatype import dns.rrset -from isctest.asyncserver import ( - AsyncDnsServer, - DnsResponseSend, - QueryContext, - ResponseAction, - ResponseHandler, -) +from isctest.asyncserver import AsyncDnsServer, QnameQtypeHandler, StaticResponseHandler + +VICTIM = "victim.sibling.hack." +POISON_ADDRESS = "6.6.6.6" + +def a(name: str) -> dns.rrset.RRset: + return dns.rrset.from_text( + name, 300, dns.rdataclass.IN, dns.rdatatype.A, POISON_ADDRESS + ) -class AttackerAuthority(ResponseHandler): - async def get_responses( - self, qctx: QueryContext - ) -> AsyncGenerator[ResponseAction, None]: - if qctx.qtype == dns.rdatatype.A: - qctx.response.answer.append( - dns.rrset.from_text( - qctx.qname, 300, qctx.qclass, dns.rdatatype.A, "6.6.6.6" - ) - ) - yield DnsResponseSend(qctx.response) +class PoisonedAHandler(QnameQtypeHandler, StaticResponseHandler): + qnames = [VICTIM] + qtypes = [dns.rdatatype.A] + answer = [a(VICTIM)] def main() -> None: server = AsyncDnsServer(default_aa=True, default_rcode=dns.rcode.NOERROR) - server.install_response_handler(AttackerAuthority()) + server.install_response_handler(PoisonedAHandler()) server.run()