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())
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())
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)
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
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
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)
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)
def query(self, query, timeout=None): resp = self._buildResponse(query) if resp: return defer.succeed(resp) else: return defer.fail(error.DomainError())
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())
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())
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())
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))
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
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
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])
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)
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
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
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())
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())
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())
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())
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())
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))
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)
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())
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))
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))