Ejemplo n.º 1
0
    def _onVerify (self, dataPacket, status):
        if not status:
            return self.onError ("Query answer not trusted")

        if self.parse_dns:
            try:
                msg = dns.message.from_wire (dataPacket.content)
            except:
                if not self.rrtype:
                    self.rrtype = self.query[-1] if self.query[-1][0] != '\xFD' else self.query[-2]

                if self.rrtype == "NDNCERT":
                    if not self.zone or not self.label:
                        matches = ndn.nre.match ("(<>*)<DNS>(<>*)<NDNCERT>", self.query)
                        if not matches:
                            return self.onError ("Incorrectly formatted query [%s]" % self.query)

                        dns_zone = dns.name.from_text (dnsify (str (matches.expand ("\\1"))))
                        dns_label = dns.name.from_text (dnsify (str (matches.expand ("\\2"))), origin = dns_zone)
                    else:
                        dns_zone = dns.name.from_text (dnsify (str (self.zone)))
                        dns_label = dns.name.from_text (dnsify (str (self.label)), origin = dns_zone)

                    ndncert = dns.rdtypes.IN.NDNCERT.NDNCERT (dns.rdataclass.IN, dns.rdatatype.NDNCERT, dataPacket.content)
                    rrset = dns.rrset.RRset (dns_label, dns.rdataclass.IN, dns.rdatatype.NDNCERT)
                    rrset.add (ttl = dataPacket.signedInfo.freshnessSeconds, rd = ndncert)

                    msg = dns.message.Message (id=0)
                    msg.answer.append (rrset)
                else:
                    msg = dns.message.from_wire (dataPacket.content)
        else:
            msg = None

        return self.onResult (dataPacket, msg)
Ejemplo n.º 2
0
def add_rdataset(msg, name, rds):
    rrset = msg.get_rrset(msg.answer,
                          name,
                          rds.rdclass,
                          rds.rdtype,
                          create=True,
                          force_unique=True)
    for rd in rds:
        rrset.add(rd, ttl=rds.ttl)
Ejemplo n.º 3
0
    def _rr_line(self, section_number):
        """Process one line from the text format answer, authority, or
        additional data sections.
        """

        section = self.message.sections[section_number]
        # Name
        token = self.tok.get(want_leading=True)
        if not token.is_whitespace():
            self.last_name = self.tok.as_name(token, self.message.origin,
                                              self.relativize,
                                              self.relativize_to)
        name = self.last_name
        token = self.tok.get()
        if not token.is_identifier():
            raise dns.exception.SyntaxError
        # TTL
        try:
            ttl = int(token.value, 0)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except Exception:
            ttl = 0
        # Class
        try:
            rdclass = dns.rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except Exception:
            rdclass = dns.rdataclass.IN
        # Type
        rdtype = dns.rdatatype.from_text(token.value)
        (rdclass, rdtype, deleting, empty) = \
            self.message._parse_rr_header(section_number, name, rdclass, rdtype)
        token = self.tok.get()
        if empty and not token.is_eol_or_eof():
            raise dns.exception.SyntaxError
        if not token.is_eol_or_eof():
            self.tok.unget(token)
            rd = dns.rdata.from_text(rdclass, rdtype, self.tok,
                                     self.message.origin, self.relativize,
                                     self.relativize_to)
            covers = rd.covers()
        else:
            rd = None
            covers = dns.rdatatype.NONE
        rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers,
                                        deleting, True, self.one_rr_per_rrset)
        if rd is not None:
            rrset.add(rd, ttl)
Ejemplo n.º 4
0
 def _rr_line(self, section):
     """Process one line from the text format answer, authority, or
     additional data sections.
     """
     
     deleting = None
     # Name
     token = self.tok.get(want_leading = True)
     if token[0] != dns.tokenizer.WHITESPACE:
         self.last_name = dns.name.from_text(token[1], None)
     name = self.last_name
     token = self.tok.get()
     if token[0] != dns.tokenizer.IDENTIFIER:
         raise dns.exception.SyntaxError
     # TTL
     try:
         ttl = int(token[1], 0)
         token = self.tok.get()
         if token[0] != dns.tokenizer.IDENTIFIER:
             raise dns.exception.SyntaxError
     except dns.exception.SyntaxError:
         raise dns.exception.SyntaxError
     except:
         ttl = 0
     # Class
     try:
         rdclass = dns.rdataclass.from_text(token[1])
         token = self.tok.get()
         if token[0] != dns.tokenizer.IDENTIFIER:
             raise dns.exception.SyntaxError
         if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
             deleting = rdclass
             rdclass = self.zone_rdclass
     except dns.exception.SyntaxError:
         raise dns.exception.SyntaxError
     except:
         rdclass = dns.rdataclass.IN
     # Type
     rdtype = dns.rdatatype.from_text(token[1])
     token = self.tok.get()
     if token[0] != dns.tokenizer.EOL and token[0] != dns.tokenizer.EOF:
         self.tok.unget(token)
         rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None)
         covers = rd.covers()
     else:
         rd = None
         covers = dns.rdatatype.NONE
     rrset = self.message.find_rrset(section, name,
                                     rdclass, rdtype, covers,
                                     deleting, True, self.updating)
     if not rd is None:
         rrset.add(rd, ttl)
Ejemplo n.º 5
0
    def _rr_line(self, section):
        """Process one line from the text format answer, authority, or
        additional data sections.
        """

        deleting = None
        # Name
        token = self.tok.get(want_leading = True)
        if not token.is_whitespace():
            self.last_name = dns.name.from_text(token.value, None)
        name = self.last_name
        token = self.tok.get()
        if not token.is_identifier():
            raise dns.exception.SyntaxError
        # TTL
        try:
            ttl = int(token.value, 0)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except:
            ttl = 0
        # Class
        try:
            rdclass = dns.rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
            if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
                deleting = rdclass
                rdclass = self.zone_rdclass
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except:
            rdclass = dns.rdataclass.IN
        # Type
        rdtype = dns.rdatatype.from_text(token.value)
        token = self.tok.get()
        if not token.is_eol_or_eof():
            self.tok.unget(token)
            rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None)
            covers = rd.covers()
        else:
            rd = None
            covers = dns.rdatatype.NONE
        rrset = self.message.find_rrset(section, name,
                                        rdclass, rdtype, covers,
                                        deleting, True, self.updating)
        if not rd is None:
            rrset.add(rd, ttl)
Ejemplo n.º 6
0
    def _rr_line(self, section):
        """Process one line from the text format answer, authority, or
        additional data sections.
        """

        deleting = None
        # Name
        token = self.tok.get(want_leading=True)
        if not token.is_whitespace():
            self.last_name = dns.name.from_text(token.value, None)
        name = self.last_name
        token = self.tok.get()
        if not token.is_identifier():
            raise dns.exception.SyntaxError
        # TTL
        try:
            ttl = int(token.value, 0)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except Exception:
            ttl = 0
        # Class
        try:
            rdclass = dns.rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
            if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
                deleting = rdclass
                rdclass = self.zone_rdclass
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except Exception:
            rdclass = dns.rdataclass.IN
        # Type
        rdtype = dns.rdatatype.from_text(token.value)
        token = self.tok.get()
        if not token.is_eol_or_eof():
            self.tok.unget(token)
            rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None)
            covers = rd.covers()
        else:
            rd = None
            covers = dns.rdatatype.NONE
        rrset = self.message.find_rrset(section, name,
                                        rdclass, rdtype, covers,
                                        deleting, True, self.updating)
        if rd is not None:
            rrset.add(rd, ttl)
Ejemplo n.º 7
0
def fake_answer(name, rdtype, rvalues):
    name = dns.name.from_text(name)
    rdtype = dns.rdatatype.from_text(rdtype)
    msg = dns.message.make_query(name, rdtype, dns.rdataclass.IN)
    resp = dns.message.make_response(msg)
    rrset = resp.find_rrset(resp.answer,
                            name,
                            dns.rdataclass.IN,
                            rdtype,
                            create=True)
    for rvalue in rvalues:
        rrset.add(dns.rdata.from_text(dns.rdataclass.IN, rdtype, rvalue))
    return dns.resolver.Answer(name, rdtype, dns.rdataclass.IN, resp)
Ejemplo n.º 8
0
    def _rr_line(self, section):
        """Process one line from the text format answer, authority, or
        additional data sections.
        """

        deleting = None
        # Name
        token = self.tok.get(want_leading=True)
        if token[0] != dns.tokenizer.WHITESPACE:
            self.last_name = dns.name.from_text(token[1], None)
        name = self.last_name
        token = self.tok.get()
        if token[0] != dns.tokenizer.IDENTIFIER:
            raise dns.exception.SyntaxError
        # TTL
        try:
            ttl = int(token[1], 0)
            token = self.tok.get()
            if token[0] != dns.tokenizer.IDENTIFIER:
                raise dns.exception.SyntaxError
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except:
            ttl = 0
        # Class
        try:
            rdclass = dns.rdataclass.from_text(token[1])
            token = self.tok.get()
            if token[0] != dns.tokenizer.IDENTIFIER:
                raise dns.exception.SyntaxError
            if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
                deleting = rdclass
                rdclass = self.zone_rdclass
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except:
            rdclass = dns.rdataclass.IN
        # Type
        rdtype = dns.rdatatype.from_text(token[1])
        token = self.tok.get()
        if token[0] != dns.tokenizer.EOL and token[0] != dns.tokenizer.EOF:
            self.tok.unget(token)
            rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None)
            covers = rd.covers()
        else:
            rd = None
            covers = dns.rdatatype.NONE
        rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers,
                                        deleting, True, self.updating)
        if not rd is None:
            rrset.add(rd, ttl)
Ejemplo n.º 9
0
def fake_answer(name, rdtype, rvalues, sig=None):
    name = dns.name.from_text(name)
    rdtype = dns.rdatatype.from_text(rdtype)
    msg = dns.message.make_query(name, rdtype, dns.rdataclass.IN)
    resp = dns.message.make_response(msg)
    rrset = resp.find_rrset(resp.answer, name, dns.rdataclass.IN, rdtype,
                            create=True)
    for rvalue in rvalues:
        rrset.add(dns.rdata.from_text(dns.rdataclass.IN, rdtype, rvalue))

    if sig:
        rrset = resp.find_rrset(resp.answer, name, dns.rdataclass.IN,
                dns.rdatatype.RRSIG, rdtype, create=True)
        rrset.add(dns.rdata.from_text(dns.rdataclass.IN,
                dns.rdatatype.RRSIG, sig))
    return dns.resolver.Answer(name, rdtype, dns.rdataclass.IN, resp)
Ejemplo n.º 10
0
 def add(self, name, addr):
     """Add an address to a name and family"""
     try:
         rdata = dns.rdtypes.IN.A.A(dns.rdataclass.IN, dns.rdatatype.A,
                                    addr)
         family = socket.AF_INET
     except (socket.error, dns.exception.SyntaxError):
         rdata = dns.rdtypes.IN.AAAA.AAAA(dns.rdataclass.IN,
                                          dns.rdatatype.AAAA, addr)
         family = socket.AF_INET6
     family_dict = self.answers.setdefault(name, {})
     rrset = family_dict.get(family)
     if not rrset:
         family_dict[family] = rrset = dns.rrset.RRset(
             dns.name.from_text(name), rdata.rdclass, rdata.rdtype)
     rrset.add(rdata)
Ejemplo n.º 11
0
    def _get_section(self, section, count):
        """Read the next I{count} records from the wire data and add them to
        the specified section.

        section: the section of the message to which to add records
        count: the number of records to read
        """

        if self.updating or self.one_rr_per_rrset:
            force_unique = True
        else:
            force_unique = False
        seen_opt = False
        for i in range(0, count):
            rr_start = self.current
            (name, used) = dns.name.from_wire(self.wire, self.current)
            absolute_name = name
            if self.message.origin is not 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 == dns.rdatatype.OPT:
                if section is not 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 = dns.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 == dns.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) = \
                    dns.tsig.get_algorithm_and_mac(self.wire, self.current,
                                                   rdlen)
                self.message.tsig_ctx = \
                    dns.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 == dns.rdataclass.ANY or
                        rdclass == dns.rdataclass.NONE):
                    deleting = rdclass
                    rdclass = self.zone_rdclass
                else:
                    deleting = None
                if deleting == dns.rdataclass.ANY or \
                   (deleting == dns.rdataclass.NONE and
                        section is self.message.answer):
                    covers = dns.rdatatype.NONE
                    rd = None
                else:
                    rd = dns.rdata.from_wire(rdclass, rdtype, self.wire,
                                             self.current, rdlen,
                                             self.message.origin)
                    covers = rd.covers()
                if self.message.xfr and rdtype == dns.rdatatype.SOA:
                    force_unique = True
                rrset = self.message.find_rrset(section, name,
                                                rdclass, rdtype, covers,
                                                deleting, True, force_unique)
                if rd is not None:
                    rrset.add(rd, ttl)
            self.current = self.current + rdlen
Ejemplo n.º 12
0
    def _get_section(self, section_number, count):
        """Read the next I{count} records from the wire data and add them to
        the specified section.

        section: the section of the message to which to add records
        count: the number of records to read
        """

        section = self.message.sections[section_number]
        force_unique = self.one_rr_per_rrset
        for i in range(count):
            rr_start = self.parser.current
            absolute_name = self.parser.get_name()
            if self.message.origin is not None:
                name = absolute_name.relativize(self.message.origin)
            else:
                name = absolute_name
            (rdtype, rdclass, ttl, rdlen) = self.parser.get_struct('!HHIH')
            if rdtype in (dns.rdatatype.OPT, dns.rdatatype.TSIG):
                (rdclass, rdtype, deleting, empty) = \
                    self.message._parse_special_rr_header(section_number,
                                                          count, i, name,
                                                          rdclass, rdtype)
            else:
                (rdclass, rdtype, deleting, empty) = \
                    self.message._parse_rr_header(section_number,
                                                  name, rdclass, rdtype)
            if empty:
                if rdlen > 0:
                    raise dns.exception.FormError
                rd = None
                covers = dns.rdatatype.NONE
            else:
                with self.parser.restrict_to(rdlen):
                    rd = dns.rdata.from_wire_parser(rdclass, rdtype,
                                                    self.parser,
                                                    self.message.origin)
                covers = rd.covers()
            if self.message.xfr and rdtype == dns.rdatatype.SOA:
                force_unique = True
            if rdtype == dns.rdatatype.OPT:
                self.message.opt = dns.rrset.from_rdata(name, ttl, rd)
            elif rdtype == dns.rdatatype.TSIG:
                if self.keyring is None:
                    raise UnknownTSIGKey('got signed message without keyring')
                if isinstance(self.keyring, dict):
                    key = self.keyring.get(absolute_name)
                    if isinstance(key, bytes):
                        key = dns.tsig.Key(absolute_name, key, rd.algorithm)
                else:
                    key = self.keyring
                if key is None:
                    raise UnknownTSIGKey("key '%s' unknown" % name)
                self.message.keyring = key
                self.message.tsig_ctx = \
                    dns.tsig.validate(self.parser.wire,
                                      key,
                                      absolute_name,
                                      rd,
                                      int(time.time()),
                                      self.message.request_mac,
                                      rr_start,
                                      self.message.tsig_ctx,
                                      self.multi)
                self.message.tsig = dns.rrset.from_rdata(absolute_name, 0, rd)
            else:
                rrset = self.message.find_rrset(section, name, rdclass, rdtype,
                                                covers, deleting, True,
                                                force_unique)
                if rd is not None:
                    if ttl > 0x7fffffff:
                        ttl = 0
                    rrset.add(rd, ttl)
Ejemplo n.º 13
0
    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 dns.rrset.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) = dns.name.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 == dns.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 = dns.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 == dns.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.tsig_ctx = \
                                      dns.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 == dns.rdataclass.ANY or
                    rdclass == dns.rdataclass.NONE):
                    deleting = rdclass
                    rdclass = self.zone_rdclass
                else:
                    deleting = None
                if deleting == dns.rdataclass.ANY or \
                   (deleting == dns.rdataclass.NONE and \
                    section is self.message.answer):
                    covers = dns.rdatatype.NONE
                    rd = None
                else:
                    rd = dns.rdata.from_wire(rdclass, rdtype, self.wire,
                                             self.current, rdlen,
                                             self.message.origin)
                    covers = rd.covers()
                if self.message.xfr and rdtype == dns.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
Ejemplo n.º 14
0
def cname_from_dname(name, dname_rrset):
    synthesized_cname = dns.name.Name(name.labels[:-len(dname_rrset.name)] + dname_rrset[0].target.labels)
    rrset = dns.rrset.RRset(name, dns.rdataclass.IN, dns.rdatatype.CNAME)
    rrset.update_ttl(dname_rrset.ttl)
    rrset.add(dns.rdtypes.ANY.CNAME.CNAME(dns.rdataclass.IN, dns.rdatatype.CNAME, synthesized_cname))
    return rrset
Ejemplo n.º 15
0
            _LOG.debug ("Invalid request: label [%s] cannot be dnsified (%s)" % (request_name[len(basename):-1], e))
            return None

        rrset = self._ndns.query (ndns.RRSet).with_parent (zone).filter_by (label = label.to_text (), rtype = rrtype).first ()

        if rrset is None:
            # check if there is more a specific record:
            more_specific_rrset = self._ndns.query (ndns.RRSet).\
                with_parent (zone).\
                filter (ndns.RRSet.label.like ("%%.%s" % label.to_text ()), ndns.RRSet.rtype == rrtype).first ()
            if more_specific_rrset:

                msg = dns.message.Message (id=0)
                rrset = dns.rrset.RRset (zone.dns_name, dns.rdataclass.IN, dns.rdatatype.NDNAUTH)
                # zone.soa[0].rrs[0].ttl
                rrset.add (ttl = 1, rd = dns.rdtypes.IN.NDNAUTH.NDNAUTH (dns.rdataclass.IN, dns.rdatatype.NDNAUTH, zone.name))
                msg.authority.append (rrset)

                dataPacket = ndns.createSignedData (self._ndns,
                                                    interestName.appendVersion (),
                                                    msg.to_wire (origin = zone.dns_name),
                                                    zone.soa[0].rrs[0].ttl,
                                                    # 1,
                                                    zone.default_key)

                _LOG.debug ("<< Requested record doesn't exist, but there is a more specific record. Returning NDNAUTH as [%s]" % dataPacket.name)
                return dataPacket
            else:
                # _LOG.debug ("(!!! no action defined yet!!!) The requested record (%s %s) not found in zone [%s]" %
                #             (label.to_text (), dns.rdatatype.to_text (rrtype), zone.name))
Ejemplo n.º 16
0
        rrset = self._ndns.query(ndns.RRSet).with_parent(zone).filter_by(
            label=label.to_text(), rtype=rrtype).first()

        if rrset is None:
            # check if there is more a specific record:
            more_specific_rrset = self._ndns.query (ndns.RRSet).\
                with_parent (zone).\
                filter (ndns.RRSet.label.like ("%%.%s" % label.to_text ()), ndns.RRSet.rtype == rrtype).first ()
            if more_specific_rrset:

                msg = dns.message.Message(id=0)
                rrset = dns.rrset.RRset(zone.dns_name, dns.rdataclass.IN,
                                        dns.rdatatype.NDNAUTH)
                # zone.soa[0].rrs[0].ttl
                rrset.add(ttl=1,
                          rd=dns.rdtypes.IN.NDNAUTH.NDNAUTH(
                              dns.rdataclass.IN, dns.rdatatype.NDNAUTH,
                              zone.name))
                msg.authority.append(rrset)

                dataPacket = ndns.createSignedData(
                    self._ndns,
                    interestName.appendVersion(),
                    msg.to_wire(origin=zone.dns_name),
                    zone.soa[0].rrs[0].ttl,
                    # 1,
                    zone.default_key)

                _LOG.debug(
                    "<< Requested record doesn't exist, but there is a more specific record. Returning NDNAUTH as [%s]"
                    % dataPacket.name)
                return dataPacket
Ejemplo n.º 17
0
    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 dns.rrset.RRset objects
        @param count: the number of records to read
        @type count: int"""

        if self.updating:
            force_unique = True
        else:
            force_unique = False
        seen_opt = False
        for i in xrange(0, count):
            rr_start = self.current
            (name, used) = dns.name.from_wire(self.wire, self.current)
            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 == dns.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
                seen_opt = True
            elif rdtype == dns.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(name)
                if secret is None:
                    raise UnknownTSIGKey, "key '%s' unknown" % name
                self.message.tsig_ctx = \
                 dns.tsig.validate(self.wire,
                                          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 == dns.rdataclass.ANY or
                    rdclass == dns.rdataclass.NONE):
                    deleting = rdclass
                    rdclass = self.zone_rdclass
                else:
                    deleting = None
                if deleting == dns.rdataclass.ANY:
                    covers = dns.rdatatype.NONE
                    rd = None
                else:
                    rd = dns.rdata.from_wire(rdclass, rdtype, self.wire,
                                             self.current, rdlen,
                                             self.message.origin)
                    covers = rd.covers()
                if self.message.xfr and rdtype == dns.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