def make_ds(name, key, algorithm, origin=None): if algorithm.upper() == 'SHA1': dsalg = 1 hash = hash.get('SHA1')() elif algorithm.upper() == 'SHA256': dsalg = 2 hash = hash.get('SHA256')() else: raise UnsupportedAlgorithm, 'unsupported algorithm "%s"' % algorithm if isinstance(name, (str, unicode)): name = name.from_text(name, origin) hash.update(name.canonicalize().to_wire()) hash.update(_to_rdata(key, origin)) digest = hash.digest() dsrdata = struct.pack("!HBB", key_id(key), key.algorithm, dsalg) + digest return rdata.from_wire(rdataclass.IN, rdatatype.DS, dsrdata, 0, len(dsrdata))
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