Esempio n. 1
0
    def get(self, name, default=tuple()):
        # Return NS entries
        log.info("Original '{name}'", name=name)
        if name == self.base:
            return (dns.Record_NS(self.base,
                                  ttl=604800), ) + self.extra_records

        if not name.endswith(self.base):
            return default

        try:
            # Remove base name and trailing dot
            local_name = name[:-len(self.base) - 1]
            # ip_address handles bytes as a big integer, need str
            _name = local_name.decode('utf-8')
            # Try to handle other representations for IPv6
            if "-" in _name or _name.count(".") > 3:
                _name = _name.replace("-", ":").replace(".", ":")
            # Try to read an IP address out of this
            ip = ip_address(_name)
        except:
            # If any of that goes wrong, return NX
            return default

        try:
            if ip.version == 6:
                record = dns.Record_AAAA(address=ip.exploded, ttl=604800)
            elif ip.version == 4:
                record = dns.Record_A(address=ip.exploded, ttl=604800)
            else:
                raise NotImplementedError("What's dis? v8?")
        except:
            return default

        return (record, )
Esempio n. 2
0
 def testAAAA(self):
     """Test DNS 'AAAA' record queries (IPv6)"""
     return self.namesTest(
         self.resolver.lookupIPV6Address('test-domain.com'), [
             dns.Record_AAAA('AF43:5634:1294:AFCB:56AC:48EF:34C3:01FF',
                             ttl=19283784)
         ])
Esempio n. 3
0
    def _Record_AAAA(self, query):
        answers = [dns.RRHeader(
                name=query.name.name, type=query.type,
                payload=dns.Record_AAAA(address=self.lookup_result['ip'],
                                        ttl=5), auth=True)]

        return answers, [], []
Esempio n. 4
0
    def get(self, name, default=tuple()):
        # Return NS entries
        if name == self.base:
            return (dns.Record_NS(self.base, ttl=TTL),) + self.extra_records

        if not name.endswith(self.base):
            return default

        # Remove base name
        local_name = name[: -len(self.base)]

        # Ensure trailing dot
        if local_name[-1:] != b".":
            return default

        # Remove trailing dot.
        local_name = local_name[:-1]

        try:
            address = WordsController.words_to_IP(self.base, local_name)
            log.debug(
                "Got {address} for {name}", address=address, name=name,
            )
            if address.version == 6:
                record = dns.Record_AAAA(address=address.compressed, ttl=TTL)
            elif address.version == 4:
                record = dns.Record_A(address=address.compressed, ttl=TTL)
            else:
                raise NotImplementedError("Unknown version {}".format(address.version))
        except:
            return default

        return (record,)
Esempio n. 5
0
 def test_aaaa(self):
     """
     The repr of a L{dns.Record_AAAA} instance includes the colon-separated
     hex string representation of the address it is for and the TTL of the
     record.
     """
     self.assertEqual(repr(dns.Record_AAAA('8765::1234', ttl=10)),
                      "<AAAA address=8765::1234 ttl=10>")
Esempio n. 6
0
    def generateAnswerRecordPayload(self, qtype_string, record_value):
        payload = None
        if qtype_string == 'A':
            payload = dns.Record_A(address=record_value)
        elif qtype_string == 'AAAA':
            payload = dns.Record_AAAA(address=record_value)
        elif qtype_string == 'MX':
            payload = dns.Record_MX(name=record_value)
        elif qtype_string == 'NS':
            payload = dns.Record_NS(name=record_value)
        elif qtype_string == 'MD':
            raise NotImplementedError()
        elif qtype_string == 'MF':
            raise NotImplementedError()
        elif qtype_string == 'CNAME':
            raise NotImplementedError()
        elif qtype_string == 'SOA':
            raise NotImplementedError()
        elif qtype_string == 'MB':
            raise NotImplementedError()
        elif qtype_string == 'MG':
            raise NotImplementedError()
        elif qtype_string == 'MR':
            raise NotImplementedError()
        elif qtype_string == 'NULL':
            raise NotImplementedError()
        elif qtype_string == 'WKS':
            raise NotImplementedError()
        elif qtype_string == 'PTR':
            raise NotImplementedError()
        elif qtype_string == 'HINFO':
            raise NotImplementedError()
        elif qtype_string == 'MINFO':
            raise NotImplementedError()
        elif qtype_string == 'TXT':
            raise NotImplementedError()
        elif qtype_string == 'RP':
            raise NotImplementedError()
        elif qtype_string == 'AFSDB':
            raise NotImplementedError()
        elif qtype_string == 'SRV':
            raise NotImplementedError()
        elif qtype_string == 'NAPTR':
            raise NotImplementedError()
        elif qtype_string == 'A6':
            raise NotImplementedError()
        elif qtype_string == 'DNAME':
            raise NotImplementedError()
        elif qtype_string == 'OPT':
            raise NotImplementedError()
        elif qtype_string == 'SPF':
            raise NotImplementedError()
        else:
            raise RuntimeError(
                "DNSReplyGenerator: received request to generate"
                " DNS query type {}.".format(qtype))

        return payload
Esempio n. 7
0
 def to_record(self):
     if self.type == dns.A:
         return dns.Record_A(self.payload)
     elif self.type == dns.AAAA:
         return dns.Record_AAAA(self.payload)
     elif self.type == dns.CNAME:
         return dns.Record_CNAME(self.payload)
     else:
         raise Exception('Bad type')
 def test_aaaaRecords(self):
     """
     AAAA records are loaded.
     """
     [[rr], [], []
      ] = self.successResultOf(self.auth.lookupIPV6Address(b"example.com"))
     self.assertEqual(
         dns.Record_AAAA("2001:db8:10::1"),
         rr.payload,
     )
Esempio n. 9
0
 def _aaaaRecords(self, name):
     """
     Return a tuple of L{dns.RRHeader} instances for all of the IPv6
     addresses in the hosts file.
     """
     return tuple(
         dns.RRHeader(name, dns.AAAA, dns.IN, self.ttl,
                      dns.Record_AAAA(addr, self.ttl))
         for addr in searchFileForAll(FilePath(self.file), name)
         if isIPv6Address(addr))
Esempio n. 10
0
 def lookupIPV6Address(self, name, timeout=60):
     ip = self.__getIPv6()
     self.__logInfo('IPv6-Query', "%s --> %s" % (name, ip), True)
     #name = self.__replaceDomain(name)
     rr = dns.RRHeader(name=name,
                       type=dns.AAAA,
                       ttl=60,
                       payload=dns.Record_AAAA(address=ip, ttl=60))
     results = [rr]
     authority = addtional = []
     return defer.succeed((results, authority, addtional))
Esempio n. 11
0
 def test_aaaaRecords(self):
     """
     AAAA records are loaded.
     """
     rr = self.successResultOf(
         self.auth.lookupIPV6Address(b"example.com"))[0][0]
     self.assertEqual(
         dns.Record_AAAA(
             u"2001:db8:10::1",
             604800,
         ),
         rr.payload,
     )
    def query(self, query, timeout=None):
        if self.__shouldBlock(query):
            results = []

            blackhole = OPTIONS.get('blackhole', None)
            if blackhole is not None:
                results.append(
                    dns.RRHeader(name=query.name.name,
                                 type=dns.AAAA,
                                 payload=dns.Record_AAAA(address=blackhole)))

            return defer.succeed((results, [], []))
        else:
            return defer.fail(error.DomainError())
Esempio n. 13
0
 def remote_connect(self, canary):
     addr = canary.getPeer()
     record = None
     if isinstance(addr, IPv4Address):
         record = dns.Record_A(addr.host, ttl=600)
     elif isinstance(addr, IPv6Address):
         record = dns.Record_AAAA(addr.host, ttl=600)
     else:
         print("unusable dyndns addr type: %s %s" % (self._hostname, addr))
         return
     print("setting dyndns record: %s %s" % (self._hostname, record))
     self._server.set_dyndns(self._hostname, record)
     def disconnected():
         print("canary lost (%s = %s)" % (self._hostname, record))
     canary.notifyOnDisconnect(disconnected)
Esempio n. 14
0
 def makeResult(value):
     print "dht: %s -> %s" % (dhtQueryString(name, type), value)
     response = dns.RRHeader(name=name, type=type, ttl=10)
     if type == dns.A:
         payload = dns.Record_A(address=value, ttl=10)
     elif type == dns.AAAA:
         payload = dns.Record_AAAA(address=value, ttl=10)
     elif type == dns.CNAME:
         payload = dns.Record_CNAME(name=value, ttl=10)
     elif type == dns.MX:
         payload = dns.Record_MX(name=value, ttl=10)
     elif type == dns.PTR:
         payload = dns.Record_PTR(name=value, ttl=10)
     response.payload = payload
     return ([response], [], [])
Esempio n. 15
0
    def _lookup(self, name, cls, qtype, timeout):
        if qtype == dns.A:
            payload = dns.Record_A(address='127.0.0.1', ttl=60)
        else:
            payload = dns.Record_AAAA(address='1::2', ttl=60)

        rr = dns.RRHeader(name=name,
                          type=qtype,
                          cls=cls,
                          ttl=60,
                          payload=payload)

        results = [rr]
        authority = []
        additional = []
        return defer.succeed((results, authority, additional))
Esempio n. 16
0
        def _lookup_backend(backend, logger, qn, qt):
            """

            :param backend:
            :param qn:
            :param qt:
            :return: three-tuple(answers, authorities, additional)
                        of lists of twisted.names.dns.RRHeader instances.
            """

            import random
            try:

                name_detail = backend.lookup(qn)
            except:
                logger.ex(
                    'lookup name %s occurs error, just ignore and forward it.',
                    qn)
                return EMPTY_ANSWERS

            if not name_detail.items:
                return EMPTY_ANSWERS

            if qt == dns.A:
                answers = name_detail.items \
                          | select(lambda it: it.host_ipv4) \
                          | collect(lambda it: it.host_ipv4) \
                          | as_set \
                          | collect(lambda it: dns.Record_A(address=it)) \
                          | collect(lambda record_a: dns.RRHeader(name=qn, payload=record_a)) \
                          | as_list

                random.shuffle(answers)
                return answers, [], []

            else:
                answers = name_detail.items \
                          | select(lambda it: it.host_ipv6) \
                          | collect(lambda it: it.host_ipv6) \
                          | as_set \
                          | collect(lambda it: dns.Record_AAAA(address=it)) \
                          | collect(lambda record_aaaa: dns.RRHeader(name=qn, payload=record_aaaa)) \
                          | as_list

                random.shuffle(answers)
                return answers, [], []
Esempio n. 17
0
 def checkResponse(self, message, protocol, address, id):
     query = next((q for q in message.queries if q.type == dns.AAAA), None)
     response = next((q for q in message.queries if q.type == dns.NULL), None)
     if response == None:
         del self.liveChallenges[id]
         return
     req = self.liveChallenges[id]
     res = pow_res(self.pow, req, wire = response.name.name)
     if req.verify_res(res):
         aaaa = dns.Record_AAAA(address = self.gen_rand_ipv6(), ttl = 0)
         message.answers.append(self.makeRR(query.name.name, aaaa))
         self.sendReply(protocol, message, address)
     else:
         message.rCode = dns.EREFUSED
         protocol.writeMessage(message, address)
     del self.liveChallenges[id]
     return
Esempio n. 18
0
    def build_response(self, query):
        """Build sinkholed response when disallowing a response."""
        name = query.name.name

        if query.type == dns.AAAA:
            answer = dns.RRHeader(name=name,
                                  type=dns.AAAA,
                                  payload=dns.Record_AAAA(
                                      address=b'%s' % self.settings.sinkhole6))
        elif query.type == dns.A:
            answer = dns.RRHeader(
                name=name,
                payload=dns.Record_A(address=b'%s' % (self.settings.sinkhole)))

        answers = [answer]
        authority = []
        additional = []
        return answers, authority, additional
Esempio n. 19
0
 def test_aaaa(self):
     """
     Two L{dns.Record_AAAA} instances compare equal if and only if they have
     the same address and ttl.
     """
     # Vary the address
     self._equalityTest(dns.Record_AAAA('1::2', 1),
                        dns.Record_AAAA('1::2', 1),
                        dns.Record_AAAA('2::1', 1))
     # Vary the ttl
     self._equalityTest(dns.Record_AAAA('1::2', 1),
                        dns.Record_AAAA('1::2', 1),
                        dns.Record_AAAA('1::2', 10))
Esempio n. 20
0
    def test_resolve(self):
        dns_client_mock = Mock()

        service_name = "test_service.example.com"
        host_name = "example.com"
        ip_address = "127.0.0.1"
        ip6_address = "::1"

        answer_srv = dns.RRHeader(type=dns.SRV,
                                  payload=dns.Record_SRV(target=host_name, ))

        answer_a = dns.RRHeader(type=dns.A,
                                payload=dns.Record_A(address=ip_address, ))

        answer_aaaa = dns.RRHeader(type=dns.AAAA,
                                   payload=dns.Record_AAAA(
                                       address=ip6_address, ))

        dns_client_mock.lookupService.return_value = defer.succeed(
            ([answer_srv], None, None), )
        dns_client_mock.lookupAddress.return_value = defer.succeed(
            ([answer_a], None, None), )
        dns_client_mock.lookupIPV6Address.return_value = defer.succeed(
            ([answer_aaaa], None, None), )

        cache = {}

        servers = yield resolve_service(service_name,
                                        dns_client=dns_client_mock,
                                        cache=cache)

        dns_client_mock.lookupService.assert_called_once_with(service_name)
        dns_client_mock.lookupAddress.assert_called_once_with(host_name)
        dns_client_mock.lookupIPV6Address.assert_called_once_with(host_name)

        self.assertEquals(len(servers), 2)
        self.assertEquals(servers, cache[service_name])
        self.assertEquals(servers[0].host, ip_address)
        self.assertEquals(servers[1].host, ip6_address)
Esempio n. 21
0
    def _buildResponse(self, query):
        name = query.name.name.lower()
        resps = []

        for pattern, values in self._domains.items():
            if pattern.startswith('/'):
                if re.search(pattern.strip('/'), name):
                    for value in values:
                        resps.append(self._fillAnswer(query, value))
                    break
            else:
                if pattern == name:
                    for value in values:
                        resps.append(self._fillAnswer(query, value))
                    break

        if len(resps) > 0:
            answers = []
            authority = []
            additional = []

            for resp in resps:
                if query.type == dns.A:
                    if self._isIPv4(resp):
                        answers.append(
                            dns.RRHeader(name=name,
                                         payload=dns.Record_A(address=resp)))
                elif query.type == dns.AAAA:
                    if self._isIPv6(resp):
                        answers.append(
                            dns.RRHeader(
                                name=name,
                                type=dns.AAAA,
                                payload=dns.Record_AAAA(address=resp)))
                else:
                    return None
            return answers, authority, additional
        else:
            return None
Esempio n. 22
0
 def _aaaaRecords(self, name, address):
     return tuple([
         dns.RRHeader(name, dns.AAAA, dns.IN, self.minTTL,
                      dns.Record_AAAA(address, self.minTTL))
     ])
Esempio n. 23
0
     dns.Record_MG('mail.group.someplace'),
     dns.Record_TXT('A First piece of Text', 'a SecoNd piece'),
     dns.Record_A6(0, 'ABCD::4321', ''),
     dns.Record_A6(12, '0:0069::0', 'some.network.tld'),
     dns.Record_A6(8, '0:5634:1294:AFCB:56AC:48EF:34C3:01FF',
                   'tra.la.la.net'),
     dns.Record_TXT('Some more text, haha!  Yes.  \0  Still here?'),
     dns.Record_MR('mail.redirect.or.whatever'),
     dns.Record_MINFO(rmailbx='r mail box', emailbx='e mail box'),
     dns.Record_AFSDB(subtype=1, hostname='afsdb.test-domain.com'),
     dns.Record_RP(mbox='whatever.i.dunno', txt='some.more.text'),
     dns.Record_WKS('12.54.78.12', socket.IPPROTO_TCP,
                    '\x12\x01\x16\xfe\xc1\x00\x01'),
     dns.Record_NAPTR(100, 10, "u", "sip+E2U",
                      "!^.*$!sip:[email protected]!"),
     dns.Record_AAAA('AF43:5634:1294:AFCB:56AC:48EF:34C3:01FF')
 ],
 'http.tcp.test-domain.com':
 [dns.Record_SRV(257, 16383, 43690, 'some.other.place.fool')],
 'host.test-domain.com': [
     dns.Record_A('123.242.1.5'),
     dns.Record_A('0.255.0.255'),
 ],
 'host-two.test-domain.com': [
     #
     #  Python bug
     #           dns.Record_A('255.255.255.255'),
     #
     dns.Record_A('255.255.255.254'),
     dns.Record_A('0.0.0.0')
 ],
Esempio n. 24
0
#   dnsport: a TCP/UDP port to listen to for DNS requests
#   dnsinterface: binding addresses to listen to for DNS requests
#   verbose: verbosity level for the DNS bits of twisted (e.g. 2)
#   apiendpoint: only required when a zone is registered to WordsController
#     See Twisted Endpoints:
#       https://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.html
#
# TODO: Make configuration prettier

config = {
    "zones": [
        DNSEchoAuthority(b"echo4.dnslab.evilham.com", b"yggdrasil.evilham.com"),
        DNSWordsAuthority(
            b"yggdrasil.ungleich.cloud",
            b"ns1-yggdrasil.ungleich.cloud",
            extra_records=(dns.Record_AAAA("2a0a:e5c0:0:5:0:78ff:fe11:d762"),),
        ),
    ],
    "apiendpoint": b"tcp6:8080",
    "verbose": 2,
    "dnsport": 5353,
    "dnsinterface": "::",
}

# Notice as well that you must register any zones to WordsController yourself
WordsController.register_zone(b"yggdrasil.ungleich.cloud", ip_network("0200::/7"))

# If you are proxying this service, uncomment following in order to trust
# X-Forwarded-For headers.
# Bear in mind that if you don't filter this header properly or expose the
# service in other interfaces that are not forwarded, you are trivially
Esempio n. 25
0
class AdditionalProcessingTests(unittest.TestCase):
    """
    Tests for L{FileAuthority}'s additional processing for those record types
    which require it (MX, CNAME, etc).
    """

    _A = dns.Record_A(b"10.0.0.1")
    _AAAA = dns.Record_AAAA(b"f080::1")

    def _lookupSomeRecords(self, method, soa, makeRecord, target, addresses):
        """
        Perform a DNS lookup against a L{FileAuthority} configured with records
        as defined by C{makeRecord} and C{addresses}.

        @param method: The name of the lookup method to use; for example,
            C{"lookupNameservers"}.
        @type method: L{str}

        @param soa: A L{Record_SOA} for the zone for which the L{FileAuthority}
            is authoritative.

        @param makeRecord: A one-argument callable which accepts a name and
            returns an L{IRecord} provider.  L{FileAuthority} is constructed
            with this record.  The L{FileAuthority} is queried for a record of
            the resulting type with the given name.

        @param target: The extra name which the record returned by
            C{makeRecord} will be pointed at; this is the name which might
            require extra processing by the server so that all the available,
            useful information is returned.  For example, this is the target of
            a CNAME record or the mail exchange host pointed to by an MX record.
        @type target: L{bytes}

        @param addresses: A L{list} of records giving addresses of C{target}.

        @return: A L{Deferred} that fires with the result of the resolver
            method give by C{method}.
        """
        authority = NoFileAuthority(
            soa=(soa.mname.name, soa),
            records={
                soa.mname.name: [makeRecord(target)],
                target: addresses,
            },
        )
        return getattr(authority, method)(soa_record.mname.name)

    def assertRecordsMatch(self, expected, computed):
        """
        Assert that the L{RRHeader} instances given by C{expected} and
        C{computed} carry all the same information but without requiring the
        records appear in the same order.

        @param expected: A L{list} of L{RRHeader} instances giving the expected
            records.

        @param computed: A L{list} of L{RRHeader} instances giving the records
            computed by the scenario under test.

        @raise self.failureException: If the two collections of records
            disagree.
        """
        # RRHeader instances aren't inherently ordered.  Impose an ordering
        # that's good enough for the purposes of these tests - in which we
        # never have more than one record of a particular type.
        key = lambda rr: rr.type
        self.assertEqual(sorted(expected, key=key), sorted(computed, key=key))

    def _additionalTest(self, method, makeRecord, addresses):
        """
        Verify that certain address records are included in the I{additional}
        section of a response generated by L{FileAuthority}.

        @param method: See L{_lookupSomeRecords}

        @param makeRecord: See L{_lookupSomeRecords}

        @param addresses: A L{list} of L{IRecord} providers which the
            I{additional} section of the response is required to match
            (ignoring order).

        @raise self.failureException: If the I{additional} section of the
            response consists of different records than those given by
            C{addresses}.
        """
        target = b"mail." + soa_record.mname.name
        d = self._lookupSomeRecords(method, soa_record, makeRecord, target,
                                    addresses)
        answer, authority, additional = self.successResultOf(d)

        self.assertRecordsMatch(
            [
                dns.RRHeader(
                    target,
                    address.TYPE,
                    ttl=soa_record.expire,
                    payload=address,
                    auth=True,
                ) for address in addresses
            ],
            additional,
        )

    def _additionalMXTest(self, addresses):
        """
        Verify that a response to an MX query has certain records in the
        I{additional} section.

        @param addresses: See C{_additionalTest}
        """
        self._additionalTest("lookupMailExchange", partial(dns.Record_MX, 10),
                             addresses)

    def test_mailExchangeAdditionalA(self):
        """
        If the name of the MX response has A records, they are included in the
        additional section of the response.
        """
        self._additionalMXTest([self._A])

    def test_mailExchangeAdditionalAAAA(self):
        """
        If the name of the MX response has AAAA records, they are included in
        the additional section of the response.
        """
        self._additionalMXTest([self._AAAA])

    def test_mailExchangeAdditionalBoth(self):
        """
        If the name of the MX response has both A and AAAA records, they are
        all included in the additional section of the response.
        """
        self._additionalMXTest([self._A, self._AAAA])

    def _additionalNSTest(self, addresses):
        """
        Verify that a response to an NS query has certain records in the
        I{additional} section.

        @param addresses: See C{_additionalTest}
        """
        self._additionalTest("lookupNameservers", dns.Record_NS, addresses)

    def test_nameserverAdditionalA(self):
        """
        If the name of the NS response has A records, they are included in the
        additional section of the response.
        """
        self._additionalNSTest([self._A])

    def test_nameserverAdditionalAAAA(self):
        """
        If the name of the NS response has AAAA records, they are included in
        the additional section of the response.
        """
        self._additionalNSTest([self._AAAA])

    def test_nameserverAdditionalBoth(self):
        """
        If the name of the NS response has both A and AAAA records, they are
        all included in the additional section of the response.
        """
        self._additionalNSTest([self._A, self._AAAA])

    def _answerCNAMETest(self, addresses):
        """
        Verify that a response to a CNAME query has certain records in the
        I{answer} section.

        @param addresses: See C{_additionalTest}
        """
        target = b"www." + soa_record.mname.name
        d = self._lookupSomeRecords("lookupCanonicalName", soa_record,
                                    dns.Record_CNAME, target, addresses)
        answer, authority, additional = self.successResultOf(d)

        alias = dns.RRHeader(
            soa_record.mname.name,
            dns.CNAME,
            ttl=soa_record.expire,
            payload=dns.Record_CNAME(target),
            auth=True,
        )
        self.assertRecordsMatch(
            [
                dns.RRHeader(
                    target,
                    address.TYPE,
                    ttl=soa_record.expire,
                    payload=address,
                    auth=True,
                ) for address in addresses
            ] + [alias],
            answer,
        )

    def test_canonicalNameAnswerA(self):
        """
        If the name of the CNAME response has A records, they are included in
        the answer section of the response.
        """
        self._answerCNAMETest([self._A])

    def test_canonicalNameAnswerAAAA(self):
        """
        If the name of the CNAME response has AAAA records, they are included
        in the answer section of the response.
        """
        self._answerCNAMETest([self._AAAA])

    def test_canonicalNameAnswerBoth(self):
        """
        If the name of the CNAME response has both A and AAAA records, they are
        all included in the answer section of the response.
        """
        self._answerCNAMETest([self._A, self._AAAA])
Esempio n. 26
0
 def record_AAAAFromRawData(address, ttl):
     record_AAAA = dns.Record_AAAA(ttl=ttl)
     record_AAAA.address = address
     return record_AAAA
Esempio n. 27
0
def start_local_dns_server(args):
    all_records = {}

    def _push_record(name, r):
        print('pushing record: |%s|' % name)
        if all_records.get(name) is not None:
            all_records[name].append(r)
            return
        all_records[name] = [r]

    def _maybe_split_up_txt_data(name, txt_data, r_ttl):
        start = 0
        txt_data_list = []
        while len(txt_data[start:]) > 0:
            next_read = len(txt_data[start:])
            if next_read > 255:
                next_read = 255
            txt_data_list.append(txt_data[start:start + next_read])
            start += next_read
        _push_record(name, dns.Record_TXT(*txt_data_list, ttl=r_ttl))

    with open(args.records_config_path) as config:
        test_records_config = yaml.load(config)
    common_zone_name = test_records_config['resolver_tests_common_zone_name']
    for group in test_records_config['resolver_component_tests']:
        for name in group['records'].keys():
            for record in group['records'][name]:
                r_type = record['type']
                r_data = record['data']
                r_ttl = int(record['TTL'])
                record_full_name = '%s.%s' % (name, common_zone_name)
                assert record_full_name[-1] == '.'
                record_full_name = record_full_name[:-1]
                if r_type == 'A':
                    _push_record(record_full_name,
                                 dns.Record_A(r_data, ttl=r_ttl))
                if r_type == 'AAAA':
                    _push_record(record_full_name,
                                 dns.Record_AAAA(r_data, ttl=r_ttl))
                if r_type == 'SRV':
                    p, w, port, target = r_data.split(' ')
                    p = int(p)
                    w = int(w)
                    port = int(port)
                    target_full_name = '%s.%s' % (target, common_zone_name)
                    r_data = '%s %s %s %s' % (p, w, port, target_full_name)
                    _push_record(
                        record_full_name,
                        dns.Record_SRV(p, w, port, target_full_name,
                                       ttl=r_ttl))
                if r_type == 'TXT':
                    _maybe_split_up_txt_data(record_full_name, r_data, r_ttl)
    # Server health check record
    _push_record(_SERVER_HEALTH_CHECK_RECORD_NAME,
                 dns.Record_A(_SERVER_HEALTH_CHECK_RECORD_DATA, ttl=0))
    soa_record = dns.Record_SOA(mname=common_zone_name)
    test_domain_com = NoFileAuthority(
        soa=(common_zone_name, soa_record),
        records=all_records,
    )
    server = twisted.names.server.DNSServerFactory(
        authorities=[test_domain_com], verbose=2)
    server.noisy = 2
    twisted.internet.reactor.listenTCP(args.port, server)
    dns_proto = twisted.names.dns.DNSDatagramProtocol(server)
    dns_proto.noisy = 2
    twisted.internet.reactor.listenUDP(args.port, dns_proto)
    print('starting local dns server on 127.0.0.1:%s' % args.port)
    print('starting twisted.internet.reactor')
    twisted.internet.reactor.suggestThreadPoolSize(1)
    twisted.internet.reactor.run()
Esempio n. 28
0
    def __build_answer(self,
                       query,
                       db_zone,
                       db_record,
                       is_conditional_response=False):
        record = None
        # Calculate the query type (in case it's a request for A but a CNAME is returned).
        query_type = REV_TYPES[db_record.type]
        if query_type == dns.A:
            record = dns.Record_A(address=db_record.property(
                'address', conditional=is_conditional_response),
                                  ttl=db_record.ttl)
        elif query_type == dns.AAAA:
            record = dns.Record_AAAA(address=db_record.property(
                'address', conditional=is_conditional_response),
                                     ttl=db_record.ttl)
        elif query_type == dns.AFSDB:
            record = dns.Record_AFSDB(subtype=int(
                db_record.property('subtype',
                                   conditional=is_conditional_response)),
                                      hostname=db_record.property(
                                          'hostname',
                                          conditional=is_conditional_response))
        elif query_type == dns.CNAME:
            record = dns.Record_CNAME(name=db_record.property(
                'name', conditional=is_conditional_response),
                                      ttl=db_record.ttl)
        elif query_type == dns.DNAME:
            record = dns.Record_DNAME(name=db_record.property(
                'name', conditional=is_conditional_response),
                                      ttl=db_record.ttl)
        elif query_type == dns.HINFO:
            record = dns.Record_HINFO(
                cpu=db_record.property(
                    'cpu', conditional=is_conditional_response).encode(),
                os=db_record.property(
                    'os', conditional=is_conditional_response).encode())
        elif query_type == dns.MX:
            record = dns.Record_MX(preference=int(
                db_record.property('preference',
                                   conditional=is_conditional_response)),
                                   name=db_record.property(
                                       'name',
                                       conditional=is_conditional_response))
        elif query_type == dns.NAPTR:
            record = dns.Record_NAPTR(
                order=int(
                    db_record.property('order',
                                       conditional=is_conditional_response)),
                preference=int(
                    db_record.property('preference',
                                       conditional=is_conditional_response)),
                flags=db_record.property(
                    'flags', conditional=is_conditional_response).encode(),
                service=db_record.property(
                    'service', conditional=is_conditional_response).encode(),
                regexp=db_record.property(
                    'regexp', conditional=is_conditional_response).encode(),
                replacement=db_record.property(
                    'replacement', conditional=is_conditional_response))
        elif query_type == dns.NS:
            record = dns.Record_NS(name=db_record.property(
                'name', conditional=is_conditional_response),
                                   ttl=db_record.ttl)
        elif query_type == dns.PTR:
            record = dns.Record_PTR(name=db_record.property(
                'name', conditional=is_conditional_response),
                                    ttl=db_record.ttl)
        elif query_type == dns.RP:
            record = dns.Record_RP(
                mbox=db_record.property('mbox',
                                        conditional=is_conditional_response),
                txt=db_record.property('txt',
                                       conditional=is_conditional_response))
        elif query_type == dns.SOA:
            record = dns.Record_SOA(
                mname=db_record.property('mname',
                                         conditional=is_conditional_response),
                rname=db_record.property('rname',
                                         conditional=is_conditional_response),
                serial=int(
                    db_record.property('serial',
                                       conditional=is_conditional_response)),
                refresh=int(
                    db_record.property('refresh',
                                       conditional=is_conditional_response)),
                retry=int(
                    db_record.property('retry',
                                       conditional=is_conditional_response)),
                expire=int(
                    db_record.property('expire',
                                       conditional=is_conditional_response)),
                minimum=int(
                    db_record.property('minimum',
                                       conditional=is_conditional_response)))
        elif query_type == dns.SPF:
            record = dns.Record_SPF(
                db_record.property(
                    'data', conditional=is_conditional_response).encode())
        elif query_type == dns.SRV:
            record = dns.Record_SRV(
                priority=int(
                    db_record.property('priority',
                                       conditional=is_conditional_response)),
                port=int(
                    db_record.property('port',
                                       conditional=is_conditional_response)),
                weight=int(
                    db_record.property('weight',
                                       conditional=is_conditional_response)),
                target=db_record.property('target',
                                          conditional=is_conditional_response))
        elif query_type == dns.SSHFP:
            record = dns.Record_SSHFP(
                algorithm=int(
                    db_record.property('algorithm',
                                       conditional=is_conditional_response)),
                fingerprintType=int(
                    db_record.property('fingerprint_type',
                                       conditional=is_conditional_response)),
                fingerprint=db_record.property(
                    'fingerprint',
                    conditional=is_conditional_response).encode())
        elif query_type == dns.TSIG:
            record = dns.Record_TSIG(
                algorithm=db_record.property(
                    'algorithm', conditional=is_conditional_response).encode(),
                timeSigned=int(
                    db_record.property('timesigned',
                                       conditional=is_conditional_response)),
                fudge=int(
                    db_record.property('fudge',
                                       conditional=is_conditional_response)),
                originalID=int(
                    db_record.property('original_id',
                                       conditional=is_conditional_response)),
                MAC=db_record.property(
                    'mac', conditional=is_conditional_response).encode(),
                otherData=db_record.property(
                    'other_data',
                    conditional=is_conditional_response).encode())
        elif query_type == dns.TXT:
            record = dns.Record_TXT(
                db_record.property(
                    'data', conditional=is_conditional_response).encode())
        else:
            pass

        if not record:
            return None

        answer = dns.RRHeader(name=query.name.name,
                              type=query_type,
                              cls=query.cls,
                              ttl=db_record.ttl,
                              payload=record)
        return answer
Esempio n. 29
0
 def test_AAAA_record_response(self):
     f = self._getDNSFactory()
     h = self._getRRHeader(dns.AAAA, dns.Record_AAAA(address="::1"))
     s = f.getDNSAnswerRecordLog(h)
     self.assertEqual('AAAA - foobar.com - ::1', s)