Example #1
0
    def test_transfer(self):
        """
        An attempt is made to transfer the zone for the domain the
        L{SecondaryAuthority} was constructed with from the server address it
        was constructed with when L{SecondaryAuthority.transfer} is called.
        """
        secondary = SecondaryAuthority.fromServerAddressAndDomain(
            ('192.168.1.2', 1234), 'example.com')
        secondary._reactor = reactor = MemoryReactorClock()

        secondary.transfer()

        # Verify a connection attempt to the server address above
        host, port, factory, timeout, bindAddress = reactor.tcpClients.pop(0)
        self.assertEqual(host, '192.168.1.2')
        self.assertEqual(port, 1234)

        # See if a zone transfer query is issued.
        proto = factory.buildProtocol((host, port))
        transport = StringTransport()
        proto.makeConnection(transport)

        msg = Message()
        # DNSProtocol.writeMessage length encodes the message by prepending a
        # 2 byte message length to the buffered value.
        msg.decode(StringIO(transport.value()[2:]))

        self.assertEqual(
            [dns.Query('example.com', dns.AXFR, dns.IN)], msg.queries)
Example #2
0
 def queryTCP(queries):
     self.assertEqual(queries, m.queries)
     response = Message()
     response.answers = ['answer']
     response.authority = ['authority']
     response.additional = ['additional']
     return succeed(response)
Example #3
0
    def test_transfer(self):
        """
        An attempt is made to transfer the zone for the domain the
        L{SecondaryAuthority} was constructed with from the server address it
        was constructed with when L{SecondaryAuthority.transfer} is called.
        """
        secondary = SecondaryAuthority.fromServerAddressAndDomain(
            ('192.168.1.2', 1234), 'example.com')
        secondary._reactor = reactor = MemoryReactorClock()

        secondary.transfer()

        # Verify a connection attempt to the server address above
        host, port, factory, timeout, bindAddress = reactor.tcpClients.pop(0)
        self.assertEqual(host, '192.168.1.2')
        self.assertEqual(port, 1234)

        # See if a zone transfer query is issued.
        proto = factory.buildProtocol((host, port))
        transport = StringTransport()
        proto.makeConnection(transport)

        msg = Message()
        # DNSProtocol.writeMessage length encodes the message by prepending a
        # 2 byte message length to the buffered value.
        msg.decode(StringIO(transport.value()[2:]))

        self.assertEqual([dns.Query('example.com', dns.AXFR, dns.IN)],
                         msg.queries)
Example #4
0
def buildResponse(inMessage):
    outMessage = Message(id=inMessage.id, answer=1, opCode=inMessage.opCode, recDes=1, recAv=1, auth=1, authenticData=1)
    outMessage.queries = inMessage.queries
    rcode = NOERROR
    querytlds = []
    for query in inMessage.queries:
        tld = query.name.name.decode("utf-8").lower().split(".")[-1]
        if not tld in tlds:
            if rcode != SERVFAIL:
                rcode = REFUSED
        if not tld in querytlds: # SOA even if wrong type
            querytlds.append(tld)
        if not (query.type == 28 or query.type == 255): # AAAA or ALL
            continue # NOERROR without record
        try:
            error, queryRRH = doQuery(query)
            if error:
                print("error", query.name.name.decode("utf-8"), error)
            if len(inMessage.queries) < 2:
                rcode = error
            elif error == NOERROR: # Don't change for NOERROR
                pass
            elif error == SERVFAIL or rcode == SERVFAIL: # SERVFAIL replaces all
                rcode = SERVFAIL
            elif error == REFUSED or rcode == REFUSED: # Refused replaces all but SERVFAIL
                rcode = REFUSED
            elif error == NXDOMAIN or rcode == NXDOMAIN: # NXDOMAIN
                rcode = NXDOMAIN
            else:
                print("Unexpected error from doQuery:", error)
                rcode = SERVFAIL
        except Exception as e:
            rcode = SERVFAIL
            print("oops", query, traceback.format_exc())
            outMessage.answers = []
            querytlds = []
            break
        if queryRRH != None:
            outMessage.answers.append(queryRRH)
    for tld in querytlds:
        outMessage.authority.append(RRHeader(
                name=tld,
                type=6, # SOA
                cls=query.cls,
                ttl=ttl,
                payload=Record_SOA(
                        mname=tld,
                        rname="", serial=int(time()/ttl),
                        refresh=ttl, retry=ttl, expire=ttl, minimum=ttl),
                        auth=True))
    outMessage.rCode = rcode
    return(outMessage)
    def _respond(self, answers=[], authority=[], additional=[], rCode=OK):
        """
        Create a L{Message} suitable for use as a response to a query.

        @param answers: A C{list} of two-tuples giving data for the answers
            section of the message.  The first element of each tuple is a name
            for the L{RRHeader}.  The second element is the payload.
        @param authority: A C{list} like C{answers}, but for the authority
            section of the response.
        @param additional: A C{list} like C{answers}, but for the
            additional section of the response.
        @param rCode: The response code the message will be created with.

        @return: A new L{Message} initialized with the given values.
        """
        response = Message(rCode=rCode)
        for (section, data) in [
            (response.answers, answers),
            (response.authority, authority),
            (response.additional, additional),
        ]:
            section.extend([
                RRHeader(name,
                         record.TYPE,
                         getattr(record, "CLASS", IN),
                         payload=record) for (name, record) in data
            ])
        return response
Example #6
0
 def test_notifyMessageReceived(self):
     """
     L{DNSServerFactory.messageReceived} passes messages with an opcode
     of C{OP_NOTIFY} on to L{DNSServerFactory.handleNotify}.
     """
     # RFC 1996, section 4.5
     opCode = 4
     self._messageReceivedTest('handleNotify', Message(opCode=opCode))
Example #7
0
    def test_lookupAddress(self):
        """
        L{SecondaryAuthority.lookupAddress} returns a L{Deferred} that fires
        with the I{A} records the authority has cached from the primary.
        """
        secondary = SecondaryAuthority.fromServerAddressAndDomain(
            (b'192.168.1.2', 1234), b'example.com')
        secondary._reactor = reactor = MemoryReactorClock()

        secondary.transfer()

        host, port, factory, timeout, bindAddress = reactor.tcpClients.pop(0)

        proto = factory.buildProtocol((host, port))
        transport = StringTransport()
        proto.makeConnection(transport)

        query = Message(answer=1, auth=1)
        query.decode(StringIO(transport.value()[2:]))

        # Generate a response with some data we can check.
        soa = Record_SOA(
            mname=b'ns1.example.com',
            rname='admin.example.com',
            serial=123456,
            refresh=3600,
            minimum=4800,
            expire=7200,
            retry=9600,
            ttl=12000,
            )
        a = Record_A(b'192.168.1.2', ttl=0)
        answer = Message(id=query.id, answer=1, auth=1)
        answer.answers.extend([
                RRHeader(b'example.com', type=SOA, payload=soa),
                RRHeader(b'example.com', payload=a),
                RRHeader(b'example.com', type=SOA, payload=soa),
                ])

        data = answer.toStr()
        proto.dataReceived(pack('!H', len(data)) + data)

        result = self.successResultOf(secondary.lookupAddress('example.com'))
        self.assertEqual((
                [RRHeader(b'example.com', payload=a, auth=True)], [], []), result)
Example #8
0
    def test_updateMessageReceived(self):
        """
        L{DNSServerFactory.messageReceived} passes messages with an opcode
        of C{OP_UPDATE} on to L{DNSServerFactory.handleOther}.

        This may change if the implementation ever covers update messages.
        """
        # RFC 2136, section 1.3
        opCode = 5
        self._messageReceivedTest('handleOther', Message(opCode=opCode))
    def _queryTest(self, filter):
        """
        Invoke L{Resolver._query} and verify that it sends the correct DNS
        query.  Deliver a canned response to the query and return whatever the
        L{Deferred} returned by L{Resolver._query} fires with.

        @param filter: The value to pass for the C{filter} parameter to
            L{Resolver._query}.
        """
        reactor = MemoryReactor()
        resolver = Resolver([], reactor=reactor)
        d = resolver._query(
            Query(b'foo.example.com', A, IN), [('1.1.2.3', 1053)], (30,),
            filter)

        # A UDP port should have been started.
        portNumber, transport = reactor.udpPorts.popitem()

        # And a DNS packet sent.
        [(packet, address)] = transport._sentPackets

        message = Message()
        message.fromStr(packet)

        # It should be a query with the parameters used above.
        self.assertEqual(message.queries, [Query(b'foo.example.com', A, IN)])
        self.assertEqual(message.answers, [])
        self.assertEqual(message.authority, [])
        self.assertEqual(message.additional, [])

        response = []
        d.addCallback(response.append)
        self.assertEqual(response, [])

        # Once a reply is received, the Deferred should fire.
        del message.queries[:]
        message.answer = 1
        message.answers.append(RRHeader(
            b'foo.example.com', payload=Record_A('5.8.13.21')))
        transport._protocol.datagramReceived(
            message.toStr(), ('1.1.2.3', 1053))
        return response[0]
Example #10
0
    def test_truncatedMessage(self):
        """
        Test that a truncated message results in an equivalent request made via
        TCP.
        """
        m = Message(trunc=True)
        m.addQuery('example.com')

        def queryTCP(queries):
            self.assertEqual(queries, m.queries)
            response = Message()
            response.answers = ['answer']
            response.authority = ['authority']
            response.additional = ['additional']
            return succeed(response)
        self.resolver.queryTCP = queryTCP
        d = self.resolver.filterAnswers(m)
        d.addCallback(
            self.assertEqual, (['answer'], ['authority'], ['additional']))
        return d
Example #11
0
 def datagramReceived(self, data, addr):
     m = Message()
     try:
         m.fromStr(data)
     except EOFError:
         log.msg("Truncated packet (%d bytes) from %s" % (len(data), addr))
         return
     except:
         log.err(failure.Failure(), "Unexpected decoding error")
         return
     if m.id in self.liveMessages:
         d, canceller = self.liveMessages[m.id]
         del self.liveMessages[m.id]
         canceller.cancel()
         try:
             d.callback(m)
         except:
             log.err()
     else:
         if m.id not in self.resends:
             self.controller.messageReceived(m, self)
Example #12
0
    def _queryTest(self, filter):
        """
        Invoke L{Resolver._query} and verify that it sends the correct DNS
        query.  Deliver a canned response to the query and return whatever the
        L{Deferred} returned by L{Resolver._query} fires with.

        @param filter: The value to pass for the C{filter} parameter to
            L{Resolver._query}.
        """
        reactor = MemoryReactor()
        resolver = Resolver([], reactor=reactor)
        d = resolver._query(Query(b'foo.example.com', A, IN),
                            [('1.1.2.3', 1053)], (30, ), filter)

        # A UDP port should have been started.
        portNumber, transport = reactor.udpPorts.popitem()

        # And a DNS packet sent.
        [(packet, address)] = transport._sentPackets

        msg = Message()
        msg.fromStr(packet)

        # It should be a query with the parameters used above.
        self.assertEqual(msg.queries, [Query(b'foo.example.com', A, IN)])
        self.assertEqual(msg.answers, [])
        self.assertEqual(msg.authority, [])
        self.assertEqual(msg.additional, [])

        response = []
        d.addCallback(response.append)
        self.assertEqual(response, [])

        # Once a reply is received, the Deferred should fire.
        del msg.queries[:]
        msg.answer = 1
        msg.answers.append(
            RRHeader(b'foo.example.com', payload=Record_A('5.8.13.21')))
        transport._protocol.datagramReceived(msg.toStr(), ('1.1.2.3', 1053))
        return response[0]
Example #13
0
    def test_extractAuthorityDeprecated(self):
        """
        Calling L{root.extractAuthority} produces a deprecation warning.
        """
        extractAuthority(Message(), {})

        warnings = self.flushWarnings([self.test_extractAuthorityDeprecated])
        self.assertEqual(warnings[0]['category'], DeprecationWarning)
        self.assertEqual(
            warnings[0]['message'],
            'twisted.names.root.extractAuthority is deprecated since Twisted '
            '10.0.  Please inspect the Message object directly.')
        self.assertEqual(len(warnings), 1)
Example #14
0
    def dataReceived(self, data):
        self.buffer += data

        while self.buffer:
            if self.length is None and len(self.buffer) >= 2:
                self.length = struct.unpack('!H', self.buffer[:2])[0]
                self.buffer = self.buffer[2:]

            if len(self.buffer) >= self.length:
                myChunk = self.buffer[:self.length]
                m = Message()
                m.fromStr(myChunk)
                try:
                    d, canceller = self.liveMessages[m.id]
                except KeyError:
                    self.controller.messageReceived(m, self)
                else:
                    del self.liveMessages[m.id]
                    canceller.cancel()
                    try:
                        if self.factory.controller is not None:
                            d, self.factory.controller = self.factory.controller, None
                            message = Message()
                            strio = StringIO.StringIO(myChunk)
                            message.encode(strio)
                            back = strio.getvalue()
                            b = m.toStr()
                            d.callback(b)
                            # d.callback(back)
                            # print 'dir(self.factory):',dir(self.factory.ip)
                            # d.callback(m.toStr())
                    except:
                        log.err()

                self.buffer = self.buffer[self.length:]
                self.length = None
            else:
                break
    def test_lookupAddress(self):
        """
        L{SecondaryAuthority.lookupAddress} returns a L{Deferred} that fires
        with the I{A} records the authority has cached from the primary.
        """
        secondary = SecondaryAuthority.fromServerAddressAndDomain(
            ("192.168.1.2", 1234), b"example.com")
        secondary._reactor = reactor = MemoryReactorClock()

        secondary.transfer()

        host, port, factory, timeout, bindAddress = reactor.tcpClients.pop(0)

        proto = factory.buildProtocol((host, port))
        transport = StringTransport()
        proto.makeConnection(transport)

        query = Message(answer=1, auth=1)
        query.decode(BytesIO(transport.value()[2:]))

        # Generate a response with some data we can check.
        soa = Record_SOA(
            mname=b"ns1.example.com",
            rname="admin.example.com",
            serial=123456,
            refresh=3600,
            minimum=4800,
            expire=7200,
            retry=9600,
            ttl=12000,
        )
        a = Record_A(b"192.168.1.2", ttl=0)
        answer = Message(id=query.id, answer=1, auth=1)
        answer.answers.extend([
            RRHeader(b"example.com", type=SOA, payload=soa),
            RRHeader(b"example.com", payload=a),
            RRHeader(b"example.com", type=SOA, payload=soa),
        ])

        data = answer.toStr()
        proto.dataReceived(pack("!H", len(data)) + data)

        result = self.successResultOf(secondary.lookupAddress("example.com"))
        self.assertEqual(
            ([RRHeader(b"example.com", payload=a, auth=True)], [], []), result)
Example #16
0
def buildResponseBytes(data):
    inMessage = Message()
    inMessage.fromStr(data)
    return(buildResponse(inMessage).toStr())
Example #17
0
 def _rcodeTest(self, rcode, exc):
     m = Message(rCode=rcode)
     err = self.resolver.filterAnswers(m)
     err.trap(exc)