+2014-04-04 Bob Halley <halley@dnspython.org>
+
+ * dns/message.py: Making a response didn't work correctly if the
+ query was signed with TSIG and we knew the key. Thanks to Jeffrey
+ Stiles for reporting the problem.
+
2014-01-10 Bob Halley <halley@ndnspython.org>
* dns/inet.py (is_multicast): Removed lingering ord()s.
secret = self.message.keyring.get(absolute_name)
if secret is None:
raise UnknownTSIGKey("key '%s' unknown" % name)
+ self.message.keyname = absolute_name
+ (self.message.keyalgorithm, self.message.mac) = \
+ dns.tsig.get_algorithm_and_mac(self.wire, self.current,
+ rdlen)
self.message.tsig_ctx = \
dns.tsig.validate(self.wire,
absolute_name,
m.want_dnssec(want_dnssec)
return m
-def make_response(query, recursion_available=False, our_payload=8192):
+def make_response(query, recursion_available=False, our_payload=8192,
+ fudge=300):
"""Make a message which is a response for the specified query.
The message returned is really a response skeleton; it has all
of the infrastructure required of a response, but none of the
@param our_payload: payload size to advertise in EDNS responses; default
is 8192.
@type our_payload: int
+ @param fudge: TSIG time fudge; default is 300 seconds.
+ @type fudge: int
@rtype: dns.message.Message object"""
if query.flags & dns.flags.QR:
response.question = list(query.question)
if query.edns >= 0:
response.use_edns(0, 0, our_payload, query.payload)
- if not query.keyname is None:
- response.keyname = query.keyname
- response.keyring = query.keyring
+ if query.had_tsig:
+ response.use_tsig(query.keyring, query.keyname, fudge, None, 0, '',
+ query.keyalgorithm)
response.request_mac = query.mac
return response
except KeyError:
raise NotImplementedError("TSIG algorithm " + str(algorithm) +
" is not supported")
+
+def get_algorithm_and_mac(wire, tsig_rdata, tsig_rdlen):
+ """Return the tsig algorithm for the specified tsig_rdata
+ @raises FormError: The TSIG is badly formed.
+ """
+ current = tsig_rdata
+ (aname, used) = dns.name.from_wire(wire, current)
+ current = current + used
+ (upper_time, lower_time, fudge, mac_size) = \
+ struct.unpack("!HIHH", wire[current:current + 10])
+ current += 10
+ mac = wire[current:current + mac_size]
+ current += mac_size
+ if current > tsig_rdata + tsig_rdlen:
+ raise dns.exception.FormError
+ return (aname, mac)