def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (mbox, cused) = name.from_wire(wire[:current + rdlen], current) current += cused rdlen -= cused if rdlen <= 0: raise exception.FormError (txt, cused) = name.from_wire(wire[:current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: mbox = mbox.relativize(origin) txt = txt.relativize(origin) return cls(rdclass, rdtype, mbox, txt)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): (mbox, cused) = name.from_wire(wire[: current + rdlen], current) current += cused rdlen -= cused if rdlen <= 0: raise exception.FormError (txt, cused) = name.from_wire(wire[: current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: mbox = mbox.relativize(origin) txt = txt.relativize(origin) return cls(rdclass, rdtype, mbox, txt)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (mname, cused) = name.from_wire(wire[:current + rdlen], current) current += cused rdlen -= cused (rname, cused) = name.from_wire(wire[:current + rdlen], current) current += cused rdlen -= cused if rdlen != 20: raise exception.FormError five_ints = struct.unpack('!IIIII', wire[current:current + rdlen]) if not origin is None: mname = mname.relativize(origin) rname = rname.relativize(origin) return cls(rdclass, rdtype, mname, rname, five_ints[0], five_ints[1], five_ints[2], five_ints[3], five_ints[4])
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): if rdlen < 3: raise exception.FormError header = struct.unpack("!BBB", wire[current : current + 3]) gateway_type = header[1] current += 3 rdlen -= 3 if gateway_type == 0: gateway = None elif gateway_type == 1: gateway = inet.inet_ntop(inet.AF_INET, wire[current : current + 4]) current += 4 rdlen -= 4 elif gateway_type == 2: gateway = inet.inet_ntop(inet.AF_INET6, wire[current : current + 16]) current += 16 rdlen -= 16 elif gateway_type == 3: (gateway, cused) = name.from_wire(wire[: current + rdlen], current) current += cused rdlen -= cused else: raise exception.FormError("invalid IPSECKEY gateway type") key = wire[current : current + rdlen].unwrap() return cls(rdclass, rdtype, header[0], gateway_type, header[2], gateway, key)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (target, cused) = name.from_wire(wire[:current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: target = target.relativize(origin) return cls(rdclass, rdtype, target)
def _get_question(self, qcount): """Read the next I{qcount} records from the wire data and add them to the question section. @param qcount: the number of questions in the message @type qcount: int""" if self.updating and qcount > 1: raise exception.FormError for i in xrange(0, qcount): (qname, used) = mname.from_wire(self.wire, self.current) if not self.message.origin is None: qname = qname.relativize(self.message.origin) self.current = self.current + used (rdtype, rdclass) = \ struct.unpack('!HH', self.wire[self.current:self.current + 4]) self.current = self.current + 4 self.message.find_rrset(self.message.question, qname, rdclass, rdtype, create=True, force_unique=True) if self.updating: self.zone_rdclass = rdclass
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): if rdlen < 3: raise exception.FormError header = struct.unpack('!BBB', wire[current:current + 3]) gateway_type = header[1] current += 3 rdlen -= 3 if gateway_type == 0: gateway = None elif gateway_type == 1: gateway = inet.inet_ntop(inet.AF_INET, wire[current:current + 4]) current += 4 rdlen -= 4 elif gateway_type == 2: gateway = inet.inet_ntop(inet.AF_INET6, wire[current:current + 16]) current += 16 rdlen -= 16 elif gateway_type == 3: (gateway, cused) = name.from_wire(wire[:current + rdlen], current) current += cused rdlen -= cused else: raise exception.FormError('invalid IPSECKEY gateway type') key = wire[current:current + rdlen].unwrap() return cls(rdclass, rdtype, header[0], gateway_type, header[2], gateway, key)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): (target, cused) = name.from_wire(wire[: current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: target = target.relativize(origin) return cls(rdclass, rdtype, target)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (preference, ) = struct.unpack('!H', wire[current:current + 2]) current += 2 rdlen -= 2 (map822, cused) = name.from_wire(wire[:current + rdlen], current) if cused > rdlen: raise exception.FormError current += cused rdlen -= cused if not origin is None: map822 = map822.relativize(origin) (mapx400, cused) = name.from_wire(wire[:current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: mapx400 = mapx400.relativize(origin) return cls(rdclass, rdtype, preference, map822, mapx400)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): (mname, cused) = name.from_wire(wire[: current + rdlen], current) current += cused rdlen -= cused (rname, cused) = name.from_wire(wire[: current + rdlen], current) current += cused rdlen -= cused if rdlen != 20: raise exception.FormError five_ints = struct.unpack('!IIIII', wire[current : current + rdlen]) if not origin is None: mname = mname.relativize(origin) rname = rname.relativize(origin) return cls(rdclass, rdtype, mname, rname, five_ints[0], five_ints[1], five_ints[2], five_ints[3], five_ints[4])
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): (preference, ) = struct.unpack('!H', wire[current : current + 2]) current += 2 rdlen -= 2 (map822, cused) = name.from_wire(wire[: current + rdlen], current) if cused > rdlen: raise exception.FormError current += cused rdlen -= cused if not origin is None: map822 = map822.relativize(origin) (mapx400, cused) = name.from_wire(wire[: current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: mapx400 = mapx400.relativize(origin) return cls(rdclass, rdtype, preference, map822, mapx400)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (preference,) = struct.unpack("!H", wire[current : current + 2]) current += 2 rdlen -= 2 (exchange, cused) = name.from_wire(wire[: current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: exchange = exchange.relativize(origin) return cls(rdclass, rdtype, preference, exchange)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (preference, ) = struct.unpack('!H', wire[current:current + 2]) current += 2 rdlen -= 2 (exchange, cused) = name.from_wire(wire[:current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: exchange = exchange.relativize(origin) return cls(rdclass, rdtype, preference, exchange)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (priority, weight, port) = struct.unpack('!HHH', wire[current:current + 6]) current += 6 rdlen -= 6 (target, cused) = name.from_wire(wire[:current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: target = target.relativize(origin) return cls(rdclass, rdtype, priority, weight, port, target)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): (priority, weight, port) = struct.unpack('!HHH', wire[current : current + 6]) current += 6 rdlen -= 6 (target, cused) = name.from_wire(wire[: current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: target = target.relativize(origin) return cls(rdclass, rdtype, priority, weight, port, target)
def validate(wire, keyname, secret, now, request_mac, tsig_start, tsig_rdata, tsig_rdlen, ctx=None, multi=False, first=True): """Validate the specified TSIG rdata against the other input parameters. @raises FormError: The TSIG is badly formed. @raises BadTime: There is too much time skew between the client and the server. @raises BadSignature: The TSIG signature did not validate @rtype: hmac.HMAC object""" (adcount,) = struct.unpack("!H", wire[10:12]) if adcount == 0: raise exception.FormError adcount -= 1 new_wire = wire[0:10] + struct.pack("!H", adcount) + wire[12:tsig_start] current = tsig_rdata (aname, used) = name.from_wire(wire, current) current = current + used (upper_time, lower_time, fudge, mac_size) = \ struct.unpack("!HIHH", wire[current:current + 10]) time = ((upper_time + 0L) << 32) + (lower_time + 0L) current += 10 mac = wire[current:current + mac_size] current += mac_size (original_id, error, other_size) = \ struct.unpack("!HHH", wire[current:current + 6]) current += 6 other_data = wire[current:current + other_size] current += other_size if current != tsig_rdata + tsig_rdlen: raise exception.FormError if error != 0: if error == BADSIG: raise PeerBadSignature elif error == BADKEY: raise PeerBadKey elif error == BADTIME: raise PeerBadTime elif error == BADTRUNC: raise PeerBadTruncation else: raise PeerError('unknown TSIG error code %d' % error) time_low = time - fudge time_high = time + fudge if now < time_low or now > time_high: raise BadTime (junk, our_mac, ctx) = sign(new_wire, keyname, secret, time, fudge, original_id, error, other_data, request_mac, ctx, multi, first, aname) if (our_mac != mac): raise BadSignature return ctx
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) = 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 exception.FormError return (aname, mac)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (order, preference) = struct.unpack('!HH', wire[current:current + 4]) current += 4 rdlen -= 4 strings = [] for i in xrange(3): l = ord(wire[current]) current += 1 rdlen -= 1 if l > rdlen or rdlen < 0: raise exception.FormError s = wire[current:current + l].unwrap() current += l rdlen -= l strings.append(s) (replacement, cused) = name.from_wire(wire[:current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: replacement = replacement.relativize(origin) return cls(rdclass, rdtype, order, preference, strings[0], strings[1], strings[2], replacement)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (next, cused) = name.from_wire(wire[:current + rdlen], current) current += cused rdlen -= cused windows = [] while rdlen > 0: if rdlen < 3: raise exception.FormError("NSEC too short") window = ord(wire[current]) octets = ord(wire[current + 1]) if octets == 0 or octets > 32: raise exception.FormError("bad NSEC octets") current += 2 rdlen -= 2 if rdlen < octets: raise exception.FormError("bad NSEC bitmap length") bitmap = wire[current:current + octets].unwrap() current += octets rdlen -= octets windows.append((window, bitmap)) if not origin is None: next = next.relativize(origin) return cls(rdclass, rdtype, next, windows)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): (order, preference) = struct.unpack('!HH', wire[current : current + 4]) current += 4 rdlen -= 4 strings = [] for i in xrange(3): l = ord(wire[current]) current += 1 rdlen -= 1 if l > rdlen or rdlen < 0: raise exception.FormError s = wire[current : current + l].unwrap() current += l rdlen -= l strings.append(s) (replacement, cused) = name.from_wire(wire[: current + rdlen], current) if cused != rdlen: raise exception.FormError if not origin is None: replacement = replacement.relativize(origin) return cls(rdclass, rdtype, order, preference, strings[0], strings[1], strings[2], replacement)
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (next, cused) = name.from_wire(wire[: current + rdlen], current) current += cused rdlen -= cused windows = [] while rdlen > 0: if rdlen < 3: raise exception.FormError("NSEC too short") window = ord(wire[current]) octets = ord(wire[current + 1]) if octets == 0 or octets > 32: raise exception.FormError("bad NSEC octets") current += 2 rdlen -= 2 if rdlen < octets: raise exception.FormError("bad NSEC bitmap length") bitmap = wire[current : current + octets].unwrap() current += octets rdlen -= octets windows.append((window, bitmap)) if not origin is None: next = next.relativize(origin) return cls(rdclass, rdtype, next, windows)
def validate(wire, keyname, secret, now, request_mac, tsig_start, tsig_rdata, tsig_rdlen, ctx=None, multi=False, first=True): """Validate the specified TSIG rdata against the other input parameters. @raises FormError: The TSIG is badly formed. @raises BadTime: There is too much time skew between the client and the server. @raises BadSignature: The TSIG signature did not validate @rtype: hmac.HMAC object""" (adcount, ) = struct.unpack("!H", wire[10:12]) if adcount == 0: raise exception.FormError adcount -= 1 new_wire = wire[0:10] + struct.pack("!H", adcount) + wire[12:tsig_start] current = tsig_rdata (aname, used) = name.from_wire(wire, current) current = current + used (upper_time, lower_time, fudge, mac_size) = \ struct.unpack("!HIHH", wire[current:current + 10]) time = ((upper_time + 0L) << 32) + (lower_time + 0L) current += 10 mac = wire[current:current + mac_size] current += mac_size (original_id, error, other_size) = \ struct.unpack("!HHH", wire[current:current + 6]) current += 6 other_data = wire[current:current + other_size] current += other_size if current != tsig_rdata + tsig_rdlen: raise exception.FormError if error != 0: if error == BADSIG: raise PeerBadSignature elif error == BADKEY: raise PeerBadKey elif error == BADTIME: raise PeerBadTime elif error == BADTRUNC: raise PeerBadTruncation else: raise PeerError('unknown TSIG error code %d' % error) time_low = time - fudge time_high = time + fudge if now < time_low or now > time_high: raise BadTime (junk, our_mac, ctx) = sign(new_wire, keyname, secret, time, fudge, original_id, error, other_data, request_mac, ctx, multi, first, aname) if (our_mac != mac): raise BadSignature return ctx
def _get_section(self, section, count): """Read the next I{count} records from the wire data and add them to the specified section. @param section: the section of the message to which to add records @type section: list of mrrset.RRset objects @param count: the number of records to read @type count: int""" if self.updating or self.one_rr_per_rrset: force_unique = True else: force_unique = False seen_opt = False for i in xrange(0, count): rr_start = self.current (name, used) = mname.from_wire(self.wire, self.current) absolute_name = name if not self.message.origin is None: name = name.relativize(self.message.origin) self.current = self.current + used (rdtype, rdclass, ttl, rdlen) = \ struct.unpack('!HHIH', self.wire[self.current:self.current + 10]) self.current = self.current + 10 if rdtype == rdatatype.OPT: if not section is self.message.additional or seen_opt: raise BadEDNS self.message.payload = rdclass self.message.ednsflags = ttl self.message.edns = (ttl & 0xff0000) >> 16 self.message.options = [] current = self.current optslen = rdlen while optslen > 0: (otype, olen) = \ struct.unpack('!HH', self.wire[current:current + 4]) current = current + 4 opt = edns.option_from_wire(otype, self.wire, current, olen) self.message.options.append(opt) current = current + olen optslen = optslen - 4 - olen seen_opt = True elif rdtype == rdatatype.TSIG: if not (section is self.message.additional and i == (count - 1)): raise BadTSIG if self.message.keyring is None: raise UnknownTSIGKey('got signed message without keyring') 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) = \ tsig.get_algorithm_and_mac(self.wire, self.current, rdlen) self.message.tsig_ctx = \ tsig.validate(self.wire, absolute_name, secret, int(time.time()), self.message.request_mac, rr_start, self.current, rdlen, self.message.tsig_ctx, self.message.multi, self.message.first) self.message.had_tsig = True else: if ttl < 0: ttl = 0 if self.updating and \ (rdclass == rdataclass.ANY or rdclass == rdataclass.NONE): deleting = rdclass rdclass = self.zone_rdclass else: deleting = None if deleting == rdataclass.ANY or \ (deleting == rdataclass.NONE and \ section is self.message.answer): covers = rdatatype.NONE rd = None else: #import pdb #pdb.set_trace() rd = rdata.from_wire(rdclass, rdtype, self.wire, self.current, rdlen, self.message.origin) covers = rd.covers() if self.message.xfr and rdtype == rdatatype.SOA: force_unique = True rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, force_unique) if not rd is None: rrset.add(rd, ttl) self.current = self.current + rdlen