Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/dns/rdtypes/ANY/TSIG.py: 27%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
3# Copyright (C) 2001-2017 Nominum, Inc.
4#
5# Permission to use, copy, modify, and distribute this software and its
6# documentation for any purpose with or without fee is hereby granted,
7# provided that the above copyright notice and this permission notice
8# appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18import base64
19import struct
21import dns.exception
22import dns.immutable
23import dns.rcode
24import dns.rdata
27@dns.immutable.immutable
28class TSIG(dns.rdata.Rdata):
29 """TSIG record"""
31 __slots__ = [
32 "algorithm",
33 "time_signed",
34 "fudge",
35 "mac",
36 "original_id",
37 "error",
38 "other",
39 ]
41 def __init__(
42 self,
43 rdclass,
44 rdtype,
45 algorithm,
46 time_signed,
47 fudge,
48 mac,
49 original_id,
50 error,
51 other,
52 ):
53 """Initialize a TSIG rdata.
55 :param rdclass: The rdataclass of the Rdata.
56 :type rdclass: int
57 :param rdtype: The rdatatype of the Rdata.
58 :type rdtype: int
59 :param algorithm: The TSIG algorithm name.
60 :type algorithm: :py:class:`dns.name.Name`
61 :param time_signed: The time signed (seconds since epoch).
62 :type time_signed: int
63 :param fudge: The fudge (seconds of error permitted in time_signed).
64 :type fudge: int
65 :param mac: The message authentication code.
66 :type mac: bytes
67 :param original_id: The original message ID.
68 :type original_id: int
69 :param error: The TSIG error code.
70 :type error: int
71 :param other: Other data (typically empty).
72 :type other: bytes
73 """
75 super().__init__(rdclass, rdtype)
76 self.algorithm = self._as_name(algorithm)
77 self.time_signed = self._as_uint48(time_signed)
78 self.fudge = self._as_uint16(fudge)
79 self.mac = self._as_bytes(mac)
80 self.original_id = self._as_uint16(original_id)
81 self.error = dns.rcode.Rcode.make(error)
82 self.other = self._as_bytes(other)
84 def to_styled_text(self, style: dns.rdata.RdataStyle) -> str:
85 algorithm = self.algorithm.to_styled_text(style)
86 error = dns.rcode.to_text(self.error, True)
87 text = (
88 f"{algorithm} {self.time_signed} {self.fudge} "
89 + f"{len(self.mac)} {dns.rdata._base64ify(self.mac, 0)} "
90 + f"{self.original_id} {error} {len(self.other)}"
91 )
92 if self.other:
93 text += f" {dns.rdata._base64ify(self.other, 0)}"
94 return text
96 @classmethod
97 def from_text(
98 cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
99 ):
100 algorithm = tok.get_name(relativize=False)
101 time_signed = tok.get_uint48()
102 fudge = tok.get_uint16()
103 mac_len = tok.get_uint16()
104 mac = base64.b64decode(tok.get_string())
105 if len(mac) != mac_len:
106 raise SyntaxError("invalid MAC")
107 original_id = tok.get_uint16()
108 error = dns.rcode.from_text(tok.get_string())
109 other_len = tok.get_uint16()
110 if other_len > 0:
111 other = base64.b64decode(tok.get_string())
112 if len(other) != other_len:
113 raise SyntaxError("invalid other data")
114 else:
115 other = b""
116 return cls(
117 rdclass,
118 rdtype,
119 algorithm,
120 time_signed,
121 fudge,
122 mac,
123 original_id,
124 error,
125 other,
126 )
128 def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
129 self.algorithm.to_wire(file, None, origin, False)
130 file.write(
131 struct.pack(
132 "!HIHH",
133 (self.time_signed >> 32) & 0xFFFF,
134 self.time_signed & 0xFFFFFFFF,
135 self.fudge,
136 len(self.mac),
137 )
138 )
139 file.write(self.mac)
140 file.write(struct.pack("!HHH", self.original_id, self.error, len(self.other)))
141 file.write(self.other)
143 @classmethod
144 def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
145 algorithm = parser.get_name()
146 time_signed = parser.get_uint48()
147 fudge = parser.get_uint16()
148 mac = parser.get_counted_bytes(2)
149 original_id, error = parser.get_struct("!HH")
150 other = parser.get_counted_bytes(2)
151 return cls(
152 rdclass,
153 rdtype,
154 algorithm,
155 time_signed,
156 fudge,
157 mac,
158 original_id,
159 error,
160 other,
161 )