]>
git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.recursor-dnssec/recursortests.py
15 class RecursorTest ( unittest
. TestCase
):
17 Setup all recursors and auths required for the tests
22 _recursorStartupDelay
= 2.0
27 _PREFIX
= os
. environ
[ 'PREFIX' ]
29 _config_template_default
= """
33 local-address=127.0.0.1
35 packetcache-servfail-ttl=0
41 _config_template
= """
44 _lua_config_file
= None
47 ns.root. 3600 IN A %s .8
49 _root_DS
= "63149 13 1 a59da3f5c1b97fcd5fa2b3b2b0ac91d38a60d33a"
51 # The default SOA for zones in the authoritative servers
52 _SOA
= "ns1.example.net. hostmaster.example.net. 1 3600 1800 1209600 300"
54 # The definitions of the zones on the authoritative servers, the key is the
55 # zonename and the value is the zonefile content. several strings are replaced:
56 # - {soa} => value of _SOA
57 # - {prefix} value of _PREFIX
62 ns.root. 3600 IN A {prefix} .8
64 example. 3600 IN NS ns1.example.
65 example. 3600 IN NS ns2.example.
66 example. 3600 IN DS 53174 13 1 50c9e913818767c236c06c2d8272723cb78cbf26
68 ns1.example. 3600 IN A {prefix} .10
69 ns2.example. 3600 IN A {prefix} .11
72 example. 3600 IN SOA {soa}
73 example. 3600 IN NS ns1.example.
74 example. 3600 IN NS ns2.example.
75 ns1.example. 3600 IN A {prefix} .10
76 ns2.example. 3600 IN A {prefix} .11
78 secure.example. 3600 IN NS ns.secure.example.
79 secure.example. 3600 IN DS 64723 13 1 53eb985040d3a89bacf29dbddb55a65834706f33
80 ns.secure.example. 3600 IN A {prefix} .9
82 cname-secure.example. 3600 IN NS ns.cname-secure.example.
83 cname-secure.example. 3600 IN DS 49148 13 1 a10314452d5ec4d97fcc6d7e275d217261fe790f
84 ns.cname-secure.example. 3600 IN A {prefix} .15
86 bogus.example. 3600 IN NS ns.bogus.example.
87 bogus.example. 3600 IN DS 65034 13 1 6df3bb50ea538e90eacdd7ae5419730783abb0ee
88 ns.bogus.example. 3600 IN A {prefix} .12
90 insecure.example. 3600 IN NS ns.insecure.example.
91 ns.insecure.example. 3600 IN A {prefix} .13
93 optout.example. 3600 IN NS ns1.optout.example.
94 optout.example. 3600 IN DS 59332 13 1 e664f886ae1b5df03d918bc1217d22afc29925b9
95 ns1.optout.example. 3600 IN A {prefix} .14
97 insecure-formerr.example. 3600 IN NS ns1.insecure-formerr.example.
98 ns1.insecure-formerr.example. 3600 IN A {prefix} .2
100 ecs-echo.example. 3600 IN NS ns1.ecs-echo.example.
101 ns1.ecs-echo.example. 3600 IN A {prefix} .21
103 islandofsecurity.example. 3600 IN NS ns1.islandofsecurity.example.
104 ns1.islandofsecurity.example. 3600 IN A {prefix} .9
106 sortcname.example. 3600 IN CNAME sort
107 sort.example. 3600 IN A 17.38.42.80
108 sort.example. 3600 IN A 192.168.0.1
109 sort.example. 3600 IN A 17.238.240.5
110 sort.example. 3600 IN MX 25 mx
112 'secure.example' : """
113 secure.example. 3600 IN SOA {soa}
114 secure.example. 3600 IN NS ns.secure.example.
115 ns.secure.example. 3600 IN A {prefix} .9
117 secure.example. 3600 IN A 192.0.2.17
119 host1.secure.example. 3600 IN A 192.0.2.2
120 cname.secure.example. 3600 IN CNAME host1.secure.example.
121 cname-to-insecure.secure.example. 3600 IN CNAME node1.insecure.example.
122 cname-to-bogus.secure.example. 3600 IN CNAME ted.bogus.example.
123 cname-to-islandofsecurity.secure.example. 3600 IN CNAME node1.islandofsecurity.example.
125 host1.sub.secure.example. 3600 IN A 192.0.2.11
128 sub2.secure.example. 3600 IN CNAME doesnotmatter.insecure.example.
129 insecure.sub2.secure.example. 3600 IN NS ns1.insecure.example.
131 *.wildcard.secure.example. 3600 IN A 192.0.2.10
133 *.cnamewildcard.secure.example. 3600 IN CNAME host1.secure.example.
135 *.cnamewildcardnxdomain.secure.example. 3600 IN CNAME doesntexist.secure.example.
137 cname-to-formerr.secure.example. 3600 IN CNAME host1.insecure-formerr.example.
139 'cname-secure.example' : """
140 cname-secure.example. 3600 IN SOA {soa}
141 cname-secure.example. 3600 IN NS ns.cname-secure.example.
142 ns.cname-secure.example. 3600 IN A {prefix} .15
143 cname-secure.example. 3600 IN CNAME secure.example.
146 bogus.example. 3600 IN SOA {soa}
147 bogus.example. 3600 IN NS ns1.bogus.example.
148 ns1.bogus.example. 3600 IN A {prefix} .12
149 ted.bogus.example. 3600 IN A 192.0.2.1
150 bill.bogus.example. 3600 IN AAAA 2001:db8:12::3
152 'insecure.sub2.secure.example' : """
153 insecure.sub2.secure.example. 3600 IN SOA {soa}
154 insecure.sub2.secure.example. 3600 IN NS ns1.insecure.example.
156 node1.insecure.sub2.secure.example. 3600 IN A 192.0.2.18
158 'insecure.example' : """
159 insecure.example. 3600 IN SOA {soa}
160 insecure.example. 3600 IN NS ns1.insecure.example.
161 ns1.insecure.example. 3600 IN A {prefix} .13
163 node1.insecure.example. 3600 IN A 192.0.2.6
165 cname-to-secure.insecure.example. 3600 IN CNAME host1.secure.example.
167 'optout.example' : """
168 optout.example. 3600 IN SOA {soa}
169 optout.example. 3600 IN NS ns1.optout.example.
170 ns1.optout.example. 3600 IN A {prefix} .14
172 insecure.optout.example. 3600 IN NS ns1.insecure.optout.example.
173 ns1.insecure.optout.example. 3600 IN A {prefix} .15
175 secure.optout.example. 3600 IN NS ns1.secure.optout.example.
176 secure.optout.example. 3600 IN DS 64215 13 1 b88284d7a8d8605c398e8942262f97b9a5a31787
177 ns1.secure.optout.example. 3600 IN A {prefix} .15
179 'insecure.optout.example' : """
180 insecure.optout.example. 3600 IN SOA {soa}
181 insecure.optout.example. 3600 IN NS ns1.insecure.optout.example.
182 ns1.insecure.optout.example. 3600 IN A {prefix} .15
184 node1.insecure.optout.example. 3600 IN A 192.0.2.7
186 'secure.optout.example' : """
187 secure.optout.example. 3600 IN SOA {soa}
188 secure.optout.example. 3600 IN NS ns1.secure.optout.example.
189 ns1.secure.optout.example. 3600 IN A {prefix} .15
191 node1.secure.optout.example. 3600 IN A 192.0.2.8
193 'islandofsecurity.example' : """
194 islandofsecurity.example. 3600 IN SOA {soa}
195 islandofsecurity.example. 3600 IN NS ns1.islandofsecurity.example.
196 ns1.islandofsecurity.example. 3600 IN A {prefix} .9
198 node1.islandofsecurity.example. 3600 IN A 192.0.2.20
200 'undelegated.secure.example' : """
201 undelegated.secure.example. 3600 IN SOA {soa}
202 undelegated.secure.example. 3600 IN NS ns1.undelegated.secure.example.
204 node1.undelegated.secure.example. 3600 IN A 192.0.2.21
206 'undelegated.insecure.example' : """
207 undelegated.insecure.example. 3600 IN SOA {soa}
208 undelegated.insecure.example. 3600 IN NS ns1.undelegated.insecure.example.
210 node1.undelegated.insecure.example. 3600 IN A 192.0.2.22
214 # The private keys for the zones (note that DS records should go into
215 # the zonecontent in _zones
218 Private-key-format: v1.2
219 Algorithm: 13 (ECDSAP256SHA256)
220 PrivateKey: rhWuEydDz3QaIspSVj683B8Xq5q/ozzA38XUgzD4Fbo=
224 Private-key-format: v1.2
225 Algorithm: 13 (ECDSAP256SHA256)
226 PrivateKey: Lt0v0Gol3pRUFM7fDdcy0IWN0O/MnEmVPA+VylL8Y4U=
229 'secure.example' : """
230 Private-key-format: v1.2
231 Algorithm: 13 (ECDSAP256SHA256)
232 PrivateKey: 1G4WRoOFJJXk+fotDCHVORtJmIG2OUhKi8AO2jDPGZA=
236 Private-key-format: v1.2
237 Algorithm: 13 (ECDSAP256SHA256)
238 PrivateKey: f5jV7Q8kd5hDpMWObsuQ6SQda0ftf+JrO3uZwEg6nVw=
241 'optout.example' : """
242 Private-key-format: v1.2
243 Algorithm: 13 (ECDSAP256SHA256)
244 PrivateKey: efmq9G+J4Y2iPnIBRwJiy6Z/nIHSzpsCy/7XHhlS19A=
247 'secure.optout.example' : """
248 Private-key-format: v1.2
249 Algorithm: 13 (ECDSAP256SHA256)
250 PrivateKey: xcNUxt1Knj14A00lKQFDboluiJyM2f7FxpgsQaQ3AQ4=
253 'islandofsecurity.example' : """
254 Private-key-format: v1.2
255 Algorithm: 13 (ECDSAP256SHA256)
256 PrivateKey: o9F5iix8V68tnMcuOaM2Lt8XXhIIY//SgHIHEePk6cM=
259 'cname-secure.example' : """
260 Private-key-format: v1.2
261 Algorithm: 13 (ECDSAP256SHA256)
262 PrivateKey: kvoV/g4IO/tefSro+FLJ5UC7H3BUf0IUtZQSUOfQGyA=
266 # This dict is keyed with the suffix of the IP address and its value
267 # is a list of zones hosted on that IP. Note that delegations should
268 # go into the _zones's zonecontent
271 '9' : [ 'secure.example' , 'islandofsecurity.example' ],
274 '12' : [ 'bogus.example' , 'undelegated.secure.example' , 'undelegated.insecure.example' ],
275 '13' : [ 'insecure.example' , 'insecure.sub2.secure.example' ],
276 '14' : [ 'optout.example' ],
277 '15' : [ 'insecure.optout.example' , 'secure.optout.example' , 'cname-secure.example' ]
280 _auth_cmd
= [ 'authbind' ,
286 def createConfigDir ( cls
, confdir
):
288 shutil
. rmtree ( confdir
)
290 if e
. errno
!= errno
. ENOENT
:
292 os
. mkdir ( confdir
, 0755 )
295 def generateAuthZone ( cls
, confdir
, zonename
, zonecontent
):
296 with
open ( os
. path
. join ( confdir
, ' %s .zone' % zonename
), 'w' ) as zonefile
:
297 zonefile
. write ( zonecontent
. format ( prefix
= cls
._ PREFIX
, soa
= cls
._ SOA
))
300 def generateAuthNamedConf ( cls
, confdir
, zones
):
301 with
open ( os
. path
. join ( confdir
, 'named.conf' ), 'w' ) as namedconf
:
306 for zonename
in zones
:
307 zone
= '.' if zonename
== 'ROOT' else zonename
313 };""" % ( zone
, zonename
))
316 def generateAuthConfig ( cls
, confdir
):
317 bind_dnssec_db
= os
. path
. join ( confdir
, 'bind-dnssec.sqlite3' )
319 with
open ( os
. path
. join ( confdir
, 'pdns.conf' ), 'w' ) as pdnsconf
:
321 module-dir=../regression-tests/modules
325 bind-config= {confdir} /named.conf
326 bind-dnssec-db= {bind_dnssec_db}
334 distributor-threads=1""" . format ( confdir
= confdir
,
335 bind_dnssec_db
= bind_dnssec_db
))
337 pdnsutilCmd
= [ os
. environ
[ 'PDNSUTIL' ],
338 '--config-dir= %s ' % confdir
,
342 print ' ' . join ( pdnsutilCmd
)
344 subprocess
. check_output ( pdnsutilCmd
, stderr
= subprocess
. STDOUT
)
345 except subprocess
. CalledProcessError
as e
:
350 def secureZone ( cls
, confdir
, zonename
, key
= None ):
351 zone
= '.' if zonename
== 'ROOT' else zonename
353 pdnsutilCmd
= [ os
. environ
[ 'PDNSUTIL' ],
354 '--config-dir= %s ' % confdir
,
358 keyfile
= os
. path
. join ( confdir
, 'dnssec.key' )
359 with
open ( keyfile
, 'w' ) as fdKeyfile
:
362 pdnsutilCmd
= [ os
. environ
[ 'PDNSUTIL' ],
363 '--config-dir= %s ' % confdir
,
370 print ' ' . join ( pdnsutilCmd
)
372 subprocess
. check_output ( pdnsutilCmd
, stderr
= subprocess
. STDOUT
)
373 except subprocess
. CalledProcessError
as e
:
378 def generateAllAuthConfig ( cls
, confdir
):
380 for auth_suffix
, zones
in cls
._ auth
_ zones
. items ():
381 authconfdir
= os
. path
. join ( confdir
, 'auth- %s ' % auth_suffix
)
383 os
. mkdir ( authconfdir
)
385 cls
. generateAuthConfig ( authconfdir
)
386 cls
. generateAuthNamedConf ( authconfdir
, zones
)
389 cls
. generateAuthZone ( authconfdir
,
392 if cls
._ zone
_ keys
. get ( zone
, None ):
393 cls
. secureZone ( authconfdir
, zone
, cls
._ zone
_ keys
. get ( zone
))
396 def startAllAuth ( cls
, confdir
):
398 for auth_suffix
, _
in cls
._ auth
_ zones
. items ():
399 authconfdir
= os
. path
. join ( confdir
, 'auth- %s ' % auth_suffix
)
400 ipaddress
= cls
._ PREFIX
+ '.' + auth_suffix
401 cls
. startAuth ( authconfdir
, ipaddress
)
404 def startAuth ( cls
, confdir
, ipaddress
):
405 print ( "Launching pdns_server.." )
406 authcmd
= list ( cls
._ auth
_ cmd
)
407 authcmd
. append ( '--config-dir= %s ' % confdir
)
408 authcmd
. append ( '--local-address= %s ' % ipaddress
)
409 print ( ' ' . join ( authcmd
))
411 logFile
= os
. path
. join ( confdir
, 'pdns.log' )
412 with
open ( logFile
, 'w' ) as fdLog
:
413 cls
._ auths
[ ipaddress
] = subprocess
. Popen ( authcmd
, close_fds
= True ,
414 stdout
= fdLog
, stderr
= fdLog
,
419 if cls
._ auths
[ ipaddress
]. poll () is not None :
421 cls
._ auths
[ ipaddress
]. kill ()
423 if e
. errno
!= errno
. ESRCH
:
425 with
open ( logFile
, 'r' ) as fdLog
:
427 sys
. exit ( cls
._ auths
[ ipaddress
]. returncode
)
430 def generateRecursorConfig ( cls
, confdir
):
431 params
= tuple ([ getattr ( cls
, param
) for param
in cls
._ config
_ params
])
435 recursorconf
= os
. path
. join ( confdir
, 'recursor.conf' )
437 with
open ( recursorconf
, 'w' ) as conf
:
438 conf
. write ( "# Autogenerated by recursortests.py \n " )
439 conf
. write ( cls
._ config
_ template
_ default
)
440 conf
. write ( cls
._ config
_ template
% params
)
442 conf
. write ( "socket-dir= %s \n " % confdir
)
443 if cls
._lu a
_ config
_ file
or cls
._ root
_ DS
:
444 luaconfpath
= os
. path
. join ( confdir
, 'conffile.lua' )
445 with
open ( luaconfpath
, 'w' ) as luaconf
:
447 luaconf
. write ( "addDS('.', ' %s ')" % cls
._ root
_ DS
)
448 if cls
._lu a
_ config
_ file
:
449 luaconf
. write ( cls
._lu a
_ config
_ file
)
450 conf
. write ( "lua-config-file= %s \n " % luaconfpath
)
452 roothintspath
= os
. path
. join ( confdir
, 'root.hints' )
453 with
open ( roothintspath
, 'w' ) as roothints
:
454 roothints
. write ( cls
._ roothints
)
455 conf
. write ( "hint-file= %s \n " % roothintspath
)
458 def startResponders ( cls
):
462 def startRecursor ( cls
, confdir
, port
):
463 print ( "Launching pdns_recursor.." )
464 recursorcmd
= [ os
. environ
[ 'PDNSRECURSOR' ],
465 '--config-dir= %s ' % confdir
,
466 '--local-port= %s ' % port
,
467 '--security-poll-suffix=' ]
468 print ( ' ' . join ( recursorcmd
))
470 logFile
= os
. path
. join ( confdir
, 'recursor.log' )
471 with
open ( logFile
, 'w' ) as fdLog
:
472 cls
._ recursor
= subprocess
. Popen ( recursorcmd
, close_fds
= True ,
473 stdout
= fdLog
, stderr
= fdLog
)
475 if 'PDNSRECURSOR_FAST_TESTS' in os
. environ
:
478 delay
= cls
._ recursorStartupDelay
482 if cls
._ recursor
. poll () is not None :
486 if e
. errno
!= errno
. ESRCH
:
488 with
open ( logFile
, 'r' ) as fdLog
:
490 sys
. exit ( cls
._ recursor
. returncode
)
493 def wipeRecursorCache ( cls
, confdir
):
494 rec_controlCmd
= [ os
. environ
[ 'RECCONTROL' ],
495 '--config-dir= %s ' % confdir
,
499 subprocess
. check_output ( rec_controlCmd
, stderr
= subprocess
. STDOUT
)
500 except subprocess
. CalledProcessError
as e
:
505 def setUpSockets ( cls
):
506 print ( "Setting up UDP socket.." )
507 cls
._ sock
= socket
. socket ( socket
. AF_INET
, socket
. SOCK_DGRAM
)
508 cls
._ sock
. settimeout ( 2.0 )
509 cls
._ sock
. connect (( "127.0.0.1" , cls
._ recursorPort
))
515 cls
. startResponders ()
517 confdir
= os
. path
. join ( 'configs' , cls
._ confdir
)
518 cls
. createConfigDir ( confdir
)
519 cls
. generateAllAuthConfig ( confdir
)
520 cls
. startAllAuth ( confdir
)
522 cls
. generateRecursorConfig ( confdir
)
523 cls
. startRecursor ( confdir
, cls
._ recursorPort
)
525 print ( "Launching tests.." )
528 def tearDownClass ( cls
):
529 cls
. tearDownRecursor ()
531 cls
. tearDownResponders ()
534 def tearDownResponders ( cls
):
538 def tearDownAuth ( cls
):
539 if 'PDNSRECURSOR_FAST_TESTS' in os
. environ
:
544 for _
, auth
in cls
._ auths
. items ():
547 if auth
. poll () is None :
549 if auth
. poll () is None :
553 if e
. errno
!= errno
. ESRCH
:
557 def tearDownRecursor ( cls
):
558 if 'PDNSRECURSOR_FAST_TESTS' in os
. environ
:
564 cls
._ recursor
. terminate ()
565 if cls
._ recursor
. poll () is None :
567 if cls
._ recursor
. poll () is None :
571 # There is a race-condition with the poll() and
572 # kill() statements, when the process is dead on the
573 # kill(), this is fine
574 if e
. errno
!= errno
. ESRCH
:
578 def sendUDPQuery ( cls
, query
, timeout
= 2.0 , decode
= True , fwparams
= dict ()):
580 cls
._ sock
. settimeout ( timeout
)
583 cls
._ sock
. send ( query
. to_wire ())
584 data
= cls
._ sock
. recv ( 4096 )
585 except socket
. timeout
:
589 cls
._ sock
. settimeout ( None )
595 message
= dns
. message
. from_wire ( data
, ** fwparams
)
599 def sendTCPQuery ( cls
, query
, timeout
= 2.0 ):
600 sock
= socket
. socket ( socket
. AF_INET
, socket
. SOCK_STREAM
)
602 sock
. settimeout ( timeout
)
604 sock
. connect (( "127.0.0.1" , cls
._ recursorPort
))
607 wire
= query
. to_wire ()
608 sock
. send ( struct
. pack ( "!H" , len ( wire
)))
612 ( datalen
,) = struct
. unpack ( "!H" , data
)
613 data
= sock
. recv ( datalen
)
614 except socket
. timeout
as e
:
615 print ( "Timeout: %s " % ( str ( e
)))
617 except socket
. error
as e
:
618 print ( "Network error: %s " % ( str ( e
)))
625 message
= dns
. message
. from_wire ( data
)
629 # This function is called before every tests
632 ## Functions for comparisons
633 def assertMessageHasFlags ( self
, msg
, flags
, ednsflags
=[]):
634 """Asserts that msg has all the flags from flags set
636 @param msg: the dns.message.Message to check
637 @param flags: a list of strings with flag mnemonics (like ['RD', 'RA'])
638 @param ednsflags: a list of strings with edns-flag mnemonics (like ['DO'])"""
640 if not isinstance ( msg
, dns
. message
. Message
):
641 raise TypeError ( "msg is not a dns.message.Message" )
643 if isinstance ( flags
, list ):
645 if not isinstance ( elem
, str ):
646 raise TypeError ( "flags is not a list of strings" )
648 raise TypeError ( "flags is not a list of strings" )
650 if isinstance ( ednsflags
, list ):
651 for elem
in ednsflags
:
652 if not isinstance ( elem
, str ):
653 raise TypeError ( "ednsflags is not a list of strings" )
655 raise TypeError ( "ednsflags is not a list of strings" )
657 msgFlags
= dns
. flags
. to_text ( msg
. flags
). split ()
658 missingFlags
= [ flag
for flag
in flags
if flag
not in msgFlags
]
660 msgEdnsFlags
= dns
. flags
. edns_to_text ( msg
. ednsflags
). split ()
661 missingEdnsFlags
= [ ednsflag
for ednsflag
in ednsflags
if ednsflag
not in msgEdnsFlags
]
663 if len ( missingFlags
) or len ( missingEdnsFlags
) or len ( msgFlags
) > len ( flags
):
664 raise AssertionError ( "Expected flags ' %s ' (EDNS: ' %s '), found ' %s ' (EDNS: ' %s ') in query %s " %
665 ( ' ' . join ( flags
), ' ' . join ( ednsflags
),
666 ' ' . join ( msgFlags
), ' ' . join ( msgEdnsFlags
),
669 def assertMessageIsAuthenticated ( self
, msg
):
670 """Asserts that the message has the AD bit set
672 @param msg: the dns.message.Message to check"""
674 if not isinstance ( msg
, dns
. message
. Message
):
675 raise TypeError ( "msg is not a dns.message.Message" )
677 msgFlags
= dns
. flags
. to_text ( msg
. flags
)
678 self
. assertTrue ( 'AD' in msgFlags
, "No AD flag found in the message for %s " % msg
. question
[ 0 ]. name
)
680 def assertRRsetInAnswer ( self
, msg
, rrset
):
681 """Asserts the rrset (without comparing TTL) exists in the
682 answer section of msg
684 @param msg: the dns.message.Message to check
685 @param rrset: a dns.rrset.RRset object"""
688 if not isinstance ( msg
, dns
. message
. Message
):
689 raise TypeError ( "msg is not a dns.message.Message" )
691 if not isinstance ( rrset
, dns
. rrset
. RRset
):
692 raise TypeError ( "rrset is not a dns.rrset.RRset" )
695 for ans
in msg
. answer
:
696 ret
+= " %s \n " % ans
. to_text ()
697 if ans
. match ( rrset
. name
, rrset
. rdclass
, rrset
. rdtype
, 0 , None ):
698 self
. assertEqual ( ans
, rrset
)
702 raise AssertionError ( "RRset not found in answer \n\n %s " % ret
)
704 def assertMatchingRRSIGInAnswer ( self
, msg
, coveredRRset
, keys
= None ):
705 """Looks for coveredRRset in the answer section and if there is an RRSIG RRset
706 that covers that RRset. If keys is not None, this function will also try to
707 validate the RRset against the RRSIG
709 @param msg: The dns.message.Message to check
710 @param coveredRRset: The RRSet to check for
711 @param keys: a dictionary keyed by dns.name.Name with node or rdataset values to use for validation"""
713 if not isinstance ( msg
, dns
. message
. Message
):
714 raise TypeError ( "msg is not a dns.message.Message" )
716 if not isinstance ( coveredRRset
, dns
. rrset
. RRset
):
717 raise TypeError ( "coveredRRset is not a dns.rrset.RRset" )
723 for ans
in msg
. answer
:
724 ret
+= ans
. to_text () + " \n "
726 if ans
. match ( coveredRRset
. name
, coveredRRset
. rdclass
, coveredRRset
. rdtype
, 0 , None ):
728 if ans
. match ( coveredRRset
. name
, dns
. rdataclass
. IN
, dns
. rdatatype
. RRSIG
, coveredRRset
. rdtype
, None ):
730 if msgRRSet
and msgRRsigRRSet
:
734 raise AssertionError ( "RRset for ' %s ' not found in answer" % msg
. question
[ 0 ]. to_text ())
736 if not msgRRsigRRSet
:
737 raise AssertionError ( "No RRSIGs found in answer for %s : \n Full answer: \n %s " % ( msg
. question
[ 0 ]. to_text (), ret
))
741 dns
. dnssec
. validate ( msgRRSet
, msgRRsigRRSet
. to_rdataset (), keys
)
742 except dns
. dnssec
. ValidationFailure
as e
:
743 raise AssertionError ( "Signature validation failed for %s : \n %s " % ( msg
. question
[ 0 ]. to_text (), e
))
745 def assertNoRRSIGsInAnswer ( self
, msg
):
746 """Checks if there are _no_ RRSIGs in the answer section of msg"""
748 if not isinstance ( msg
, dns
. message
. Message
):
749 raise TypeError ( "msg is not a dns.message.Message" )
752 for ans
in msg
. answer
:
753 if ans
. rdtype
== dns
. rdatatype
. RRSIG
:
754 ret
+= ans
. name
. to_text () + " \n "
757 raise AssertionError ( "RRSIG found in answers for: \n %s " % ret
)
759 def assertAnswerEmpty ( self
, msg
):
760 self
. assertTrue ( len ( msg
. answer
) == 0 , "Data found in the the answer section for %s : \n %s " % ( msg
. question
[ 0 ]. to_text (), ' \n ' . join ([ i
. to_text () for i
in msg
. answer
])))
762 def assertRcodeEqual ( self
, msg
, rcode
):
763 if not isinstance ( msg
, dns
. message
. Message
):
764 raise TypeError ( "msg is not a dns.message.Message but a %s " % type ( msg
))
766 if not isinstance ( rcode
, int ):
767 if isinstance ( rcode
, str ):
768 rcode
= dns
. rcode
. from_text ( rcode
)
770 raise TypeError ( "rcode is neither a str nor int" )
772 if msg
. rcode () != rcode
:
773 msgRcode
= dns
. rcode
._ by
_ value
[ msg
. rcode ()]
774 wantedRcode
= dns
. rcode
._ by
_ value
[ rcode
]
776 raise AssertionError ( "Rcode for %s is %s , expected %s ." % ( msg
. question
[ 0 ]. to_text (), msgRcode
, wantedRcode
))
778 def assertAuthorityHasSOA ( self
, msg
):
779 if not isinstance ( msg
, dns
. message
. Message
):
780 raise TypeError ( "msg is not a dns.message.Message but a %s " % type ( msg
))
783 for rrset
in msg
. authority
:
784 if rrset
. rdtype
== dns
. rdatatype
. SOA
:
789 raise AssertionError ( "No SOA record found in the authority section: \n %s " % msg
. to_text ())