1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import cStringIO
17 import struct
18
19 import dns.exception
20 import dns.inet
21 import dns.name
22
24 """IPSECKEY record
25
26 @ivar precedence: the precedence for this key data
27 @type precedence: int
28 @ivar gateway_type: the gateway type
29 @type gateway_type: int
30 @ivar algorithm: the algorithm to use
31 @type algorithm: int
32 @ivar gateway: the public key
33 @type gateway: None, IPv4 address, IPV6 address, or domain name
34 @ivar key: the public key
35 @type key: string
36 @see: RFC 4025"""
37
38 __slots__ = ['precedence', 'gateway_type', 'algorithm', 'gateway', 'key']
39
40 - def __init__(self, rdclass, rdtype, precedence, gateway_type, algorithm,
41 gateway, key):
63
64 - def to_text(self, origin=None, relativize=True, **kw):
65 if self.gateway_type == 0:
66 gateway = '.'
67 elif self.gateway_type == 1:
68 gateway = self.gateway
69 elif self.gateway_type == 2:
70 gateway = self.gateway
71 elif self.gateway_type == 3:
72 gateway = str(self.gateway.choose_relativity(origin, relativize))
73 else:
74 raise ValueError, 'invalid gateway type'
75 return '%d %d %d %s %s' % (self.precedence, self.gateway_type,
76 self.algorithm, gateway,
77 dns.rdata._base64ify(self.key))
78
79 - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
80 precedence = tok.get_uint8()
81 gateway_type = tok.get_uint8()
82 algorithm = tok.get_uint8()
83 if gateway_type == 3:
84 gateway = tok.get_name().choose_relativity(origin, relativize)
85 else:
86 gateway = tok.get_string()
87 chunks = []
88 while 1:
89 t = tok.get()
90 if t[0] == dns.tokenizer.EOL or t[0] == dns.tokenizer.EOF:
91 break
92 if t[0] != dns.tokenizer.IDENTIFIER:
93 raise dns.exception.SyntaxError
94 chunks.append(t[1])
95 b64 = ''.join(chunks)
96 key = b64.decode('base64_codec')
97 return cls(rdclass, rdtype, precedence, gateway_type, algorithm,
98 gateway, key)
99
100 from_text = classmethod(from_text)
101
102 - def to_wire(self, file, compress = None, origin = None):
117
118 - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
119 if rdlen < 3:
120 raise dns.exception.FormError
121 header = struct.unpack('!BBB', wire[current : current + 3])
122 gateway_type = header[1]
123 current += 3
124 rdlen -= 3
125 if gateway_type == 0:
126 gateway = None
127 elif gateway_type == 1:
128 gateway = dns.inet.inet_ntop(dns.inet.AF_INET,
129 wire[current : current + 4])
130 current += 4
131 rdlen -= 4
132 elif gateway_type == 2:
133 gateway = dns.inet.inet_ntop(dns.inet.AF_INET6,
134 wire[current : current + 16])
135 current += 16
136 rdlen -= 16
137 elif gateway_type == 3:
138 (gateway, cused) = dns.name.from_wire(wire[: current + rdlen],
139 current)
140 current += cused
141 rdlen -= cused
142 else:
143 raise dns.exception.FormError, 'invalid IPSECKEY gateway type'
144 key = wire[current : current + rdlen]
145 return cls(rdclass, rdtype, header[0], gateway_type, header[2],
146 gateway, key)
147
148 from_wire = classmethod(from_wire)
149
150 - def _cmp(self, other):
151 f = cStringIO.StringIO()
152 self.to_wire(f)
153 wire1 = f.getvalue()
154 f.seek(0)
155 f.truncate()
156 other.to_wire(f)
157 wire2 = f.getvalue()
158 f.close()
159
160 return cmp(wire1, wire2)
161