def _lookup(self, name, cls, type, timeout):
        if cls != dns.IN:
            return defer.fail(error.DomainError())

        # Try to answer dynamically
        res = self.store.match(name, type)
        
        if res:
            # Return positive response
            # Be prepared to chase CNAMEs
            if res.payload:
            #    if query.type == res.type:
                answer = dns.RRHeader(
                    name=name,
                    type=res.type,
                    payload=res.to_record(),
                )
                answers = [answer]
                authority = []
                additional = []
                return defer.succeed((answers, authority, additional))
            # Return negative response
            else:
                return defer.fail(error.AuthoritativeDomainError())
        # Don't know
        else:
            return defer.fail(error.DomainError())
Example #2
0
    def query(self, query, timeout=None):

        if not query.type in (dns.A, dns.SOA):
            log.debug('Received incompatible query for type %s record' %
                      query.type)
            return defer.fail(error.DomainError())

        name = query.name.name.decode("utf8")

        if name in self.ns_records:
            return [self.ns_records[name]], [self.authority], []

        match = self._matcher.match(name)

        try:
            answers = []
            if match:
                answer = dns.RRHeader(
                    name=name,
                    payload=dns.Record_A(
                        address=str(netaddr.IPAddress(int(match.group(1))))))
                answers.append(answer)

            authorities = [self.authority]
            additional = []
            return answers, authorities, additional
        except:
            log.failure("Failure in serving address for query %s" % name)
            return defer.fail(error.DomainError())
Example #3
0
    def query(self, query, timeout=5):
        # example of explicit blocking of record type PTR
        if query.type == dns.PTR:
            return defer.fail(error.DomainError())

        if query.type in DNSResolver.blackListRecordType:
            return defer.fail(error.DomainError())
        
        if DNSResolver.checkBlackList(b"%s"%query.name): 
            return  defer.fail(error.DomainError())

        return client.Resolver.query(self,query,timeout)
Example #4
0
    def _lookup(self, name, cls, type, timeout):
        """
        Build a L{dns.Query} for the given parameters and dispatch it
        to each L{IResolver} in C{self.resolvers} until an answer or
        L{error.AuthoritativeDomainError} is returned.

        @type name: C{str}
        @param name: DNS name to resolve.

        @type type: C{int}
        @param type: DNS record type.

        @type cls: C{int}
        @param cls: DNS record class.

        @type timeout: Sequence of C{int}
        @param timeout: Number of seconds after which to reissue the query.
            When the last timeout expires, the query is considered failed.

        @rtype: L{Deferred}
        @return: A L{Deferred} which fires with a three-tuple of lists of
            L{twisted.names.dns.RRHeader} instances.  The first element of the
            tuple gives answers.  The second element of the tuple gives
            authorities.  The third element of the tuple gives additional
            information.  The L{Deferred} may instead fail with one of the
            exceptions defined in L{twisted.names.error} or with
            C{NotImplementedError}.
        """
        if not self.resolvers:
            return defer.fail(error.DomainError())
        q = dns.Query(name, type, cls)
        d = self.resolvers[0].query(q, timeout)
        for r in self.resolvers[1:]:
            d = d.addErrback(FailureHandler(r.query, q, timeout))
        return d
Example #5
0
 def lookupAddress(self,name,timeout=None):
     if len(name) > DNSResolver.maxReqNameLen:
         return defer.fail(error.DomainError())
     else:
         result = client.Resolver.lookupAddress(self,name,timeout)
         result.addCallback(self.specialLookUp)
         return result
Example #6
0
 def onResult(result, additional=[]):
     if not result:
         self._logger.info("Database polling failed")
         promise.errback(error.DomainError())
     else:
         self._logger.debug("Database polling successful")
         promise.callback(result)
Example #7
0
 def lookupAddress(self, name, timeout=None, addr=None):
     if self.screened:
         for subnet in self.screened:
             if IPAddress(addr) in IPNetwork(
                     subnet) and name in self.screened[subnet]:
                 return defer.fail(error.DomainError())
     return self._lookup(name, dns.IN, dns.A, timeout)
Example #8
0
    def query(self, query, timeout=None):
        resp = self._buildResponse(query)

        if resp:
            return defer.succeed(resp)
        else:
            return defer.fail(error.DomainError())
Example #9
0
 def query(self, query, timeout=None):
     """
     This method decides how to handle 
     """
     if self._dynamicResponseRequired(query):
         return self._doDynamicResponse(query)
     else:
         return defer.fail(error.DomainError())
Example #10
0
 def query(self, query, timeout=None):
     """
     Check if the query should be answered dynamically, otherwise dispatch to
     the fallback resolver.
     """
     if self._dynamicResponseRequired(query.name.name):
         return defer.succeed(self._doDynamicResponse(query))
     return defer.fail(error.DomainError())
Example #11
0
 def query(self, query, timeout=None):
     print("Incoming query for:", query.name)
     if query.type == dns.A:
         dns_thread = threading.Thread(target=checkDNSQuery,
                                       args=(query.name, ))
         dns_thread.start()
         return defer.succeed(self._doDynamicResponse(query))
     else:
         return defer.fail(dnserror.DomainError())
Example #12
0
    def query(self, query, src_ip):
        """
        Check if the query should be answered dynamically, otherwise dispatch to
        the fallback resolver.
        """

        IS_NX_DOMAIN = True in [
            query.name.name.lower().endswith(d) for d in settings.NXDOMAINS
        ]

        if (not True in [
                query.name.name.lower().endswith(d)
                for d in self.canary_domains
        ] and not IS_NX_DOMAIN):
            return defer.fail(error.DNSQueryRefusedError())

        if query.type == dns.NS:
            return defer.succeed(self._do_ns_response(name=query.name.name))

        if query.type == dns.SOA:
            return defer.succeed(self._do_soa_response(name=query.name.name))

        if query.type != dns.A:
            return defer.succeed(self._do_no_response(query=query))

        try:
            token = Canarytoken(value=query.name.name)

            canarydrop = Canarydrop(**get_canarydrop(
                canarytoken=token.value()))

            src_data = self.look_for_source_data(token=token.value(),
                                                 value=query.name.name)

            if canarydrop._drop['type'] == 'my_sql':
                d = deferLater(reactor,
                               10,
                               self.dispatch,
                               canarydrop=canarydrop,
                               src_ip=src_ip,
                               src_data=src_data)
                d.addErrback(self._handleMySqlErr)
            else:
                self.dispatch(canarydrop=canarydrop,
                              src_ip=src_ip,
                              src_data=src_data)

        except (NoCanarytokenPresent, NoCanarytokenFound):
            # If we dont find a canarytoken, lets just continue. No need to log.
            pass
        except Exception as e:
            log.error(e)

        if IS_NX_DOMAIN:
            return defer.fail(error.DomainError())

        return defer.succeed(self._do_dynamic_response(name=query.name.name))
Example #13
0
 def _lookup(self, name, cls, type, timeout, hostname=None):
     if not self.resolvers:
         return defer.fail(error.DomainError())
     q = FakeQuery(name, type, cls, hostname)
     d = self.resolvers[0].query(q, timeout)
     for r in self.resolvers[1:]:
         d = d.addErrback(server.resolve.FailureHandler(
             r.query, q, timeout))
     return d
Example #14
0
 def lookupCAA(self, name, timeout=None):
     if not self.resolvers:
         return defer.fail(error.DomainError())
     d = self.resolvers[0].lookupCAA(name, timeout)
     for r in self.resolvers[1:]:
         d = d.addErrback(
             twisted.names.resolve.FailureHandler(r.lookupCAA, name,
                                                  timeout))
     return d
Example #15
0
        def processAnswer(readBack):
            count,i=readBack[0],readBack[1]
            if i >= len(result[0]):
                if len(answers) < 1 : # in case couldn't build any answer use the org one
                    logger.warn("can not build reply use the orginal answer ")
                    return result[0],result[1],[]
                return answers, authority, additional


            answer = result[0][i]
            slowDown = False
            if count and count > DNSResolver.maxSiteCharsRate:
                logger.debug("execeed the max site characters rate")
                return defer.fail(error.DomainError())
            else:
                if count and count > DNSResolver.slowSiteAtByteRate:
                    slowDown = True
                    
                if answer.type == dns.CNAME  and cRecords[0] < DNSResolver.totalCnameRecords:
                    siteName = b"%s"%answer.name
                    siteCName = getattr(answer.payload, "name", "")
                    siteCName = b"%s"%siteCName
                    if len(siteCName) > DNSResolver.maxRespNameLen: return defer.fail(error.DomainError())

                    siteRe = DNSResolver.siteRegx.match(siteName)
                    if siteRe:
                        DNSResolver.updateSite(siteRe.groups()[0] + siteRe.groups()[1],len(siteCName))

                    if answer.ttl < DNSResolver.minTTL:
                        answer.ttl = DNSResolver.minTTL
                    siteCName = siteCName if not DNSResolver.upperName else siteCName.upper()

                    answers.append(dns.RRHeader(siteName,
                        answer.type,
                        dns.IN,
                        answer.ttl,
                        dns.Record_CNAME(b"%s"%siteCName),
                        auth=False))
                    cRecords[0] +=  1

                elif answer.type == dns.A and aRecords[0] < DNSResolver.totalARecords:
                    siteName = b"%s"%answer.name
                    
                    siteName = siteName if not DNSResolver.upperName else siteName.upper()
                    addrDot = answer.payload.dottedQuad()
                    if answer.ttl < DNSResolver.minTTL:
                        answer.ttl = DNSResolver.minTTL
                    answers.append(
                        dns.RRHeader(name=siteName,
                        payload=dns.Record_A(address=addrDot),
                        ttl=answer.ttl))
                    aRecords[0] +=  1

                if slowDown == True:
                    return task.deferLater(reactor, DNSResolver.respDelayBy , slowDownResponse, None)
                else:    
                    return processAnswer([count,i+1])
Example #16
0
 def test_gotResolverErrorLogging(self):
     """
     L{server.DNSServerFactory.gotResolver} logs a message if C{verbose > 0}.
     """
     f = NoResponseDNSServerFactory(verbose=1)
     assertLogMessage(
         self,
         ["Lookup failed"],
         f.gotResolverError,
         failure.Failure(error.DomainError()),
         protocol=NoopProtocol(), message=dns.Message(), address=None)
Example #17
0
 def lookupAllRecords(self, name, timeout=None):
     # XXX: Why is this necessary? dns.ALL_RECORDS queries should
     # be handled just the same as any other type by _lookup
     # above. If I remove this method all names tests still
     # pass. See #6604 -rwall
     if not self.resolvers:
         return defer.fail(error.DomainError())
     d = self.resolvers[0].lookupAllRecords(name, timeout)
     for r in self.resolvers[1:]:
         d = d.addErrback(FailureHandler(r.lookupAllRecords, name, timeout))
     return d
Example #18
0
    def query(self, query, timeout=None):
        """
        Run the query through this object's filter
        """
        filtered_query = self.filter.do_filter(query)

        if filtered_query:
            return self.sub_resolver.query(query, timeout)
        else:
            _LOG.warning("Query for %s from %s rejected by filter %s", query,
                         query.device_addr, self.filter)
            return defer.fail(error.DomainError())
 def _query(self, query, timeout, filter):
     """
     query our child resolvers in a chain with a specific query
     """
     if not self.resolvers:
         return defer.fail(error.DomainError())
     q = query
     d = self.resolvers[0].query(q, timeout)
     for r in self.resolvers[1:]:
         d = d.addErrback(
             FailureHandler(r.query, q, timeout)
         )
     return d
Example #20
0
    def query(self, query, timeout=None):
        """
        Check if the query should be answered dynamically, otherwise dispatch to
        the fallback resolver.
        """
        logger.info("\n\n----------------------------")
        logger.info("DynamicResolver.query(): {} ask {}, type {}".format(
            self.peer_address, query.name.name, query.type))

        if self._dynamicResponseRequired(query):
            return defer.succeed(self._doDynamicResponse(query))
        else:
            return defer.fail(error.DomainError())
    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())
Example #22
0
    def query(self, query, timeout=None):
        self.ping_mysql()
        try:
            logging.info(query)
            if len(self._dynamicResponseRequired(query)) > 0:
                return defer.succeed(self._doDynamicResponse(query))
            else:
                if query.type == dns.MX:
                    return defer.succeed(self._Record_NXDOMAIN(query))

                return defer.succeed(([], [], []))
        except Exception, e:
            logging.error(e)
            return defer.fail(error.DomainError())
Example #23
0
    def query(self, query, timeout=None):
        """
        Check if the query should be answered dynamically, otherwise dispatch to
        the fallback resolver.
        """
        if query.type in (dns.A, dns.AAAA, dns.A6):
            
            # Check if domain name matches config
            labels = query.name.name.split('.')
            if ".".join(labels[1:]) in self._config.dns_domains:

                return self._doDynamicResponse(query)

        self._logger.info("Unsupported query: {data}", data=query)
        return defer.fail(error.DomainError())
Example #24
0
 def onResult(result, additional=[]):
     if not result:
         self._logger.info("{data}: No such domain", data=name)
         promise.errback(error.DomainError())
         return
     # First, try to translate the value to an IP address
     representation = result[0][0]
     self._logger.debug("SQL query result: {data}" ,
         data=representation)
     try:
         record = self._doCreateRecord(query, name, representation)
         promise.callback(([record,], [record,], additional))
         self._logger.debug("Replied with value {data}", data=record)
     # If not an IP address, resolve it recursively
     except ValueError:
         query.name.name = representation
         self._logger.warn("Recursively resolve domain: {data}",
             data=representation)
         entry = self._resolver.query(query, timeout=(3,3,3))
         entry.chainDeferred(promise)
     # If mistmatched query and address, return error
     except TypeError as err:
         self._logger.warn("Mismatched address and query")
         promise.errback(error.DomainError())
Example #25
0
    def query(self, query, timeout=None):
        """Calculate the response to the given DNS query."""

        requested_hostname = query.name.name
        logging.debug("Received query for %s" % requested_hostname)

        if known_hosts.has_key(requested_hostname) and len(
                known_hosts[requested_hostname]) >= 1:
            resultingIP = random.sample(known_hosts[requested_hostname], 1)[0]
            answer = dns.RRHeader(name=requested_hostname,
                                  payload=dns.Record_A(address=resultingIP))
            answers = [answer]
            authority = []
            additional = []
            return defer.succeed((answers, authority, additional))
        else:
            return defer.fail(error.DomainError())
Example #26
0
    def test_gotResolverErrorCallsResponseFromMessage(self):
        """
        L{server.DNSServerFactory.gotResolverError} calls
        L{server.DNSServerFactory._responseFromMessage} to generate a response.
        """
        factory = NoResponseDNSServerFactory()
        factory._responseFromMessage = raiser

        request = dns.Message()
        request.timeReceived = 1

        e = self.assertRaises(RaisedArguments,
                              factory.gotResolverError,
                              failure.Failure(error.DomainError()),
                              protocol=None,
                              message=request,
                              address=None)
        self.assertEqual(((), dict(message=request, rCode=dns.ENAME)),
                         (e.args, e.kwargs))
Example #27
0
    def test_gotResolverErrorResetsResponseAttributes(self):
        """
        L{server.DNSServerFactory.gotResolverError} does not allow request
        attributes to leak into the response ie it sends a response with AD, CD
        set to 0 and empty response record sections.
        """
        factory = server.DNSServerFactory()
        responses = []
        factory.sendReply = (
            lambda protocol, response, address: responses.append(response))
        request = dns.Message(authenticData=True, checkingDisabled=True)
        request.answers = [object(), object()]
        request.authority = [object(), object()]
        request.additional = [object(), object()]
        factory.gotResolverError(failure.Failure(error.DomainError()),
                                 protocol=None,
                                 message=request,
                                 address=None)

        self.assertEqual([dns.Message(rCode=3, answer=True)], responses)
Example #28
0
    def query(self, query, timeout=None):
        """
        Lookup the hostname in our database. If we manage it, make sure it's running,
        then return its public IP address, otherwise fail.
        """

        logger.debug("recieved query: {0}".format(str(query)))

        if query.type == dns.A:
            name = query.name.name
            ip = self.resolve_hostname(name)
            logger.debug("hostname resolved")
            if ip:
                answer = dns.RRHeader(
                    name=name,
                    payload=dns.Record_A(address=ip),
                    ttl=RECORD_TTL)
                answers = [answer]
                return defer.succeed((answers,[],[]))
        return defer.fail(error.DomainError())
Example #29
0
    def query(self, query, src_ip):
        """
        Check if the query should be answered dynamically, otherwise dispatch to
        the fallback resolver.
        """
        self.logfile.write('%r\n' % query)
        self.logfile.flush()

        if query.type == dns.NS:
            return defer.succeed(self._do_ns_response(name=query.name.name))

        if query.type != dns.A:
            return defer.succeed(self._do_no_response(query=query))
            #return defer.fail(error.DomainError())

        try:
            token = Canarytoken(value=query.name.name)

            canarydrop = Canarydrop(**get_canarydrop(
                canarytoken=token.value()))

            src_data = self.look_for_source_data(token=token.value(),
                                                 value=query.name.name)

            self.dispatch(canarydrop=canarydrop,
                          src_ip=src_ip,
                          src_data=src_data)

#            return defer.succeed(
#                            self._do_dynamic_response(name=query.name.name,
#                                                      response=response))
        except NoCanarytokenPresent:
            log.err('No token seen in query: {query}'.format(
                query=query.name.name))
        except Exception as e:
            log.err(e)

        if query.name.name in settings.NXDOMAINS:
            return defer.fail(error.DomainError())

        return defer.succeed(self._do_dynamic_response(name=query.name.name))
Example #30
0
    def query(self, query, src_ip):
        """
        Check if the query should be answered dynamically, otherwise dispatch to
        the fallback resolver.
        """
        self.logfile.write('%r\n' % query)
        self.logfile.flush()

        if not True in [query.name.name.lower().endswith(d) for d in self.canary_domains]:
            return defer.fail(error.DNSQueryRefusedError())

        if query.type == dns.NS:
            return defer.succeed(self._do_ns_response(name=query.name.name))

        if query.type == dns.SOA:
            return  defer.succeed(self._do_soa_response(name=query.name.name))

        if query.type != dns.A:
            return defer.succeed(self._do_no_response(query=query))

        try:
            token = Canarytoken(value=query.name.name)

            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token.value()))

            src_data = self.look_for_source_data(token=token.value(), value=query.name.name)

            self.dispatch(canarydrop=canarydrop, src_ip=src_ip, src_data=src_data)

        except (NoCanarytokenPresent, NoCanarytokenFound):
            # If we dont find a canarytoken, lets just continue. No need to log.
            pass
        except Exception as e:
            log.err(e)

        if query.name.name in settings.NXDOMAINS:
            return defer.fail(error.DomainError())

        return defer.succeed(self._do_dynamic_response(name=query.name.name))