1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
#!/usr/bin/env python3
'''cookies module functionality test'''
import dns.exception
import dns.message
import dns.query
import dns.edns
import os
import time
from dnstest.test import Test
from dnstest.module import ModCookies
from dnstest.utils import *
secret1 = bytearray(b'\xde\xad\xbe\xef\xde\xad\xbe\xef\xde\xad\xbe\xef\xde\xad\xbe\xef')
secret2 = bytearray(b'\x8b\xad\xf0\x0d\x8b\xad\xf0\x0d\x8b\xad\xf0\x0d\x8b\xad\xf0\x0d')
clientCookie = bytearray(b'\xde\xad\xbe\xef\xfe\xeb\xda\xed')
clientCookieLen = 8
cookieOpcode = 10
rcodeNoerror = 0
rcodeBadcookie = 23
def reconfigure(server, zone, badcookie_slip, secret_lifetime = None, secret = None):
"""
Reconfigure server module.
"""
server.clear_modules(None)
server.add_module(None, ModCookies(secret_lifetime=secret_lifetime,
badcookie_slip=badcookie_slip, secret=secret))
server.gen_confile()
server.reload()
server.zone_wait(zone)
def check_rcode(server, query, rcode, msg, tcp=False):
try:
if tcp:
response = dns.query.tcp(query, server.addr, port=server.port, timeout=1)
else:
response = dns.query.udp(query, server.addr, port=server.port, timeout=1)
except dns.exception.Timeout:
response = None
if response is None:
return None
compare(response.rcode(), rcode, msg)
return response
t = Test(stress=False)
ModCookies.check()
knot = t.server("knot")
zone = t.zone("example.com")
t.link(zone, knot)
t.start()
reconfigure(knot, zone, 1, secret_lifetime=5)
# Try a query without EDNS
query = dns.message.make_query("dns1.example.com", "A", use_edns=False)
check_rcode(knot, query, rcodeNoerror, "NO EDNS")
# Try a query without a cookie option
query = dns.message.make_query("dns1.example.com", "A", use_edns=True)
check_rcode(knot, query, rcodeNoerror, "NO COOKIE OPT")
# Try a query without a server cookie over TCP
cookieOpt = dns.edns.option_from_wire(cookieOpcode, clientCookie, 0, clientCookieLen)
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
response = check_rcode(knot, query, rcodeNoerror, "ONLY CLIENT COOKIE [TCP]", tcp=True)
# Try a query with the received cookie over TCP
cookieOpt = response.options[0]
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
check_rcode(knot, query, rcodeNoerror, "CORRECT COOKIE", tcp=True)
# Try a query without a server cookie
cookieOpt = dns.edns.option_from_wire(cookieOpcode, clientCookie, 0, clientCookieLen)
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
response = check_rcode(knot, query, rcodeBadcookie, "ONLY CLIENT COOKIE")
# Try a query with the received cookie
cookieOpt = response.options[0]
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
check_rcode(knot, query, rcodeNoerror, "CORRECT COOKIE")
# Try the same cookie after the secret rollover
time.sleep(6)
response = check_rcode(knot, query, rcodeBadcookie, "ROLLOVER")
# Try a query with the new received cookie
cookieOpt = response.options[0]
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
response = check_rcode(knot, query, rcodeNoerror, "CORRECT COOKIE 2")
reconfigure(knot, zone, 4, secret_lifetime=1000000)
cookieOpt = dns.edns.option_from_wire(cookieOpcode, clientCookie, 0, clientCookieLen)
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
response = check_rcode(knot, query, rcodeBadcookie, "ONLY CLIENT COOKIE 2")
# Next 3 attempts to get the server cookie should timeout
for i in range(3):
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
response = check_rcode(knot, query, rcodeNoerror, "TIMEOUT "+str(i))
compare(response, None, "BADCOOKIE TIMEOUT " + str(i))
# The 4th attempt should succeed
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
check_rcode(knot, query, rcodeBadcookie, "BADCOOKIE")
## Fixed secret(s)
reconfigure(knot, zone, 1, secret=[secret1])
# Receive a server cookie for secret1
cookieOpt = dns.edns.option_from_wire(cookieOpcode, clientCookie, 0, clientCookieLen)
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
response = check_rcode(knot, query, rcodeBadcookie, "ONLY CLIENT COOKIE - SECRET1")
# Try a query with the received cookie
cookieOpt1 = response.options[0]
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt1])
check_rcode(knot, query, rcodeNoerror, "CORRECT COOKIE - SECRET1")
reconfigure(knot, zone, 1, secret=[secret2])
# Re-try a query with the received cookie against secret2
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt1])
response = check_rcode(knot, query, rcodeBadcookie, "BADCOOKIE - SECRET2")
cookieOpt2 = response.options[0]
# Re-try a query with the received cookie against secret1 again
reconfigure(knot, zone, 1, secret=[secret1])
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt1])
check_rcode(knot, query, rcodeNoerror, "CORRECT COOKIE - SECRET1")
reconfigure(knot, zone, 1, secret=[secret2, secret1])
# Re-try cookie with secret1
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt1])
check_rcode(knot, query, rcodeNoerror, "CORRECT COOKIE - SECRET1,2")
# Re-try cookie with secret2
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt2])
check_rcode(knot, query, rcodeNoerror, "CORRECT COOKIE - SECRET2,1")
# Get new server cookie when two secret are configured
cookieOpt = dns.edns.option_from_wire(cookieOpcode, clientCookie, 0, clientCookieLen)
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt])
response = check_rcode(knot, query, rcodeBadcookie, "ONLY CLIENT COOKIE - SECRET2,1")
cookieOpt21 = response.options[0]
reconfigure(knot, zone, 1, secret=[secret2])
# Re-try cookie with first secret2
query = dns.message.make_query("dns1.example.com", "A", use_edns=True, options=[cookieOpt21])
check_rcode(knot, query, rcodeNoerror, "CORRECT COOKIE - SECRET2,1")
t.end()
|