def dns_handler(s, peer, data):
    request = DNSRecord.parse(data)
    id = request.header.id
    qname = request.q.qname
    qtype = request.q.qtype

    reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)

    if "secsquare.herokuapp.com" == qname:
        # if the query is for SecSquare server
        reply.add_answer(RR(qname,qtype, rdata=A(SECSQUARE_HOST_ADDRESS)))
    else:
        # if query is for any other host names
        label = str(qname)
        raw_data = urllib2.urlopen("https://secsquare.herokuapp.com/api.php?name="+label).read()
        data = json.loads(raw_data)
        results = data['results']
        for entry in results:
            # put all results from SecSquare server into reply
            if 'MX' in entry['type']:
                reply.add_answer(RR(qname,qtype, rdata=MX(entry['target'])))
            elif 'AAAA' in entry['type']:
                reply.add_answer(RR(qname,qtype, rdata=AAAA(entry['ipv6'])))
            elif 'A' in entry['type']:
                reply.add_answer(RR(qname,qtype, rdata=A(entry['ip'])))
    print(reply) # print the DNS response for debugging purposes
    s.sendto(reply.pack(), peer)
Example #2
0
def dns_handler(s, peer, data):
    request = DNSRecord.parse(data)
    id = request.header.id
    qname = request.q.qname
    qtype = request.q.qtype
    print "------ Request (%s): %r (%s)" % (str(peer), qname.label,
                                            QTYPE[qtype])
    print request

    reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)
    if qtype == QTYPE.A:
        reply.add_answer(RR(qname, qtype, rdata=A(IP)))
    if qtype == QTYPE.AAAA:
        reply.add_answer(RR(qname, qtype, rdata=AAAA(IPV6)))
    elif qtype == QTYPE['*']:
        reply.add_answer(RR(qname, QTYPE.A, rdata=A(IP)))
        reply.add_answer(RR(qname, QTYPE.MX, rdata=MX(IP)))
        reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(MSG)))
    else:
        reply.add_answer(RR(qname, QTYPE.CNAME, rdata=CNAME(MSG)))

    print "------ Reply"
    print reply

    s.sendto(reply.pack(), peer)
Example #3
0
    def resolve(self, request, handler):
        reply = request.reply()
        value = self._resolve_request(request)

        if value and request.q.qtype == QTYPE.MX:
            reply.add_answer(
                RR(request.q.qname, QTYPE.MX, rdata=MX(label=value)), )
        elif value and request.q.qtype == QTYPE.A:
            reply.add_answer(RR(request.q.qname, QTYPE.A, rdata=A(value)), )
        elif value and request.q.qtype == QTYPE.TXT:
            reply.add_answer(RR(
                request.q.qname,
                QTYPE.TXT,
                rdata=TXT(value),
            ))
        elif value and request.q.qtype == QTYPE.PTR:
            reply.add_answer(RR(
                request.q.qname,
                QTYPE.PTR,
                rdata=PTR(value),
            ))

        reply.add_auth(
            RR(request.q.qname,
               QTYPE.SOA,
               ttl=60,
               rdata=SOA(
                   "ns1.local.dev",
                   "ns2.local.dev",
                   (20140101, 3600, 3600, 3600, 3600),
               )))

        reply.add_ar(RR("ns1.local.dev", ttl=60, rdata=A("127.0.0.1")))

        return reply
Example #4
0
	def resolve(self, request, handler):
		reply = request.reply()
		
		# DNSLabel qname
		qname = request.q.qname

		if qname.matchSuffix("time.") or qname.matchSuffix("date."):
			utc_now = pytz.utc.localize(datetime.datetime.utcnow())
			try:
				timezone = str(qname)[:-6].replace('.', '/')
				tz_now = utc_now.astimezone(pytz.timezone(timezone))
			except pytz.UnknownTimeZoneError:
				reply.header.rcode = RCODE.REFUSED
				return reply
			
			if qname.matchSuffix("time."):
				reply.add_answer(RR(qname, QTYPE.A, ttl=0, rdata=A(tz_now.strftime("%H.%M.%S.0"))))
			elif qname.matchSuffix("date."):
				reply.add_answer(RR(qname, QTYPE.A, ttl=0, rdata=A(tz_now.strftime("%y.%m.%d.0"))))
				
			reply.add_answer(RR(qname, QTYPE.TXT, ttl=0, rdata=TXT(tz_now.strftime("%Y-%m-%d %H:%M:%S"))))
			reply.add_answer(RR(qname, QTYPE.AAAA, ttl=0, rdata=AAAA(tz_now.strftime("%Y:%m:%d::%H:%M:%S"))))
		
		elif qname.matchSuffix("md5."):
			md5 = hashlib.md5(str(qname.stripSuffix("md5."))[:-1])
			hash = str(md5.hexdigest())
			ipv6 = ':'.join([hash[i:i+4] for i in range(0, len(hash), 4)])
			reply.add_answer(RR(qname, QTYPE.AAAA, ttl=0, rdata=AAAA(ipv6)))
			reply.add_answer(RR(qname, QTYPE.TXT, ttl=0, rdata=TXT(hash)))
		
		if RR() == reply.get_a():
			reply.header.rcode = RCODE.NXDOMAIN
		return reply
Example #5
0
 def lookup(self, qtype, domain):
     if qtype != 'A':
         return tuple()
     if domain == 'ftp.se.debian.org.':
         return (A('10.32.12.1'), )
     else:
         try:
             return (A(socket.gethostbyname(domain)), )
         except:
             return tuple()
Example #6
0
def dns_handler(s, peer, data):
    request = DNSRecord.parse(data)
    id = request.header.id
    qname = request.q.qname
    qtype = request.q.qtype
    print "------ Request (%s): %r (%s)" % (str(peer), qname.label,
                                            QTYPE[qtype])
    print "\n".join(["  %s" % l for l in str(request).split("\n")])
    print ', '.join(str(x) for x in request.ar)

    def get_ecs_option(req):
        for record in request.ar:
            if type(record) is RR:
                for opt in record.rdata:
                    if type(opt) is EDNSOption:
                        if opt.code == 8:
                            return opt

    def ip_from_edns_subnet(req):
        opt = get_ecs_option(req)
        if opt is not None:
            data = opt.data[4:].ljust(4, '\0')
            data = socket.inet_ntoa(data)
            subnetlen = str(ord(opt.data[2]))
            print "Got ECS:", data, subnetlen
            return [data, data + "/" + subnetlen]
        return ["99.99.99.99", "0/0"]

    [IP, MSG] = ip_from_edns_subnet(request)

    reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)
    if qtype == QTYPE.A:
        reply.add_answer(RR(qname, qtype, rdata=A(IP)))
    elif qtype == QTYPE.AAAA:
        reply.add_answer(RR(qname, qtype, rdata=AAAA(IPV6)))
    elif qtype == QTYPE['*']:
        reply.add_answer(RR(qname, QTYPE.A, rdata=A(IP)))
        reply.add_answer(RR(qname, QTYPE.MX, rdata=MX(IP)))
        reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(MSG)))
    else:
        reply.add_answer(RR(qname, QTYPE.CNAME, rdata=CNAME(MSG)))

    reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(MSG)))

    print "------ Reply"
    print "\n".join(["  %s" % l for l in str(reply).split("\n")])

    s.sendto(reply.pack(), peer)
Example #7
0
    def resolve(self, request, handler):
        type_name = QTYPE[request.q.qtype]
        reply = request.reply()
        for record in self.records:
            if record.match(request.q):
                reply.add_answer(record.rr)
        if reply.rr:
            logger.info('found zone for %s[%s], %d replies', request.q.qname,
                        type_name, len(reply.rr))
            return reply

        # no direct zone so look for an SOA record for a higher level zone
        for record in self.records:
            if record.sub_match(request.q):
                reply.add_answer(record.rr)

        if reply.rr:
            logger.info('found higher level SOA resource for %s[%s]',
                        request.q.qname, type_name)
            return reply

        logger.info('no local zone found, proxying %s[%s]', request.q.qname,
                    type_name)
        proxy_resp = super().resolve(request, handler)
        if type_name == 'A':
            if (self.check_block(proxy_resp.rr)):
                rr = RR(proxy_resp.rr[0].get_rname(),
                        request.q.qtype,
                        ttl=60,
                        rdata=A("127.0.0.1"))
                proxy_resp.rr = [rr]
                return proxy_resp
        return super().resolve(request, handler)
Example #8
0
 def resolve(self,request,handler):
     reply = request.reply()
     qtype = QTYPE[request.q.qtype]
     qname = request.q.qname
     # with 'exists:%{i}._ip.%{h}._domain.surfspf.net' in SPF-record of 'surf.nl'
     # mail from: '*****@*****.**' via 'outgoing2-ams.mf.surf.net' should result in a A-record query;
     # '145.0.1.5._ip.outgoing2-ams.mf.surf.net._helo.surf.nl._domain.surfspf.net.'
     if str(self.origin) in str(qname):
         if qtype == 'A':
             ip_version, ip_address = self.spfcheck(qname)
             if ip_version == -1:
                 reply.header.rcode = RCODE.SERVFAIL
             elif ip_version == 4:
                 reply.add_answer(RR(qname,QTYPE.A,ttl=self.ttl,
                                     rdata=A(ip_address)))
             elif ip_version == 6:
                 reply.add_answer(RR(qname,QTYPE.AAAA,ttl=self.ttl,
                                     rdata=AAAA(ip_address)))
             else:
                 reply.header.rcode = RCODE.NXDOMAIN
         else:
             reply.header.rcode = RCODE.NXDOMAIN
     else:
         reply.header.rcode = RCODE.REFUSED
     return reply
Example #9
0
    def resolve(self, request, handler):
        reply = request.reply()
        zone = self.zones.get(request.q.qname)
        if zone is not None:
            for zone_records in zone:
                rr = zone_records.try_rr(request.q)
                rr and reply.add_answer(rr)
        else:
            # no direct zone so look for an SOA record for a higher level zone
            found = False
            for zone_label, zone_records in self.zones.items():
                if request.q.qname.matchSuffix(zone_label):
                    try:
                        soa_record = next(r for r in zone_records if r.is_soa)
                    except StopIteration:
                        continue
                    else:
                        reply.add_answer(soa_record.as_rr(zone_label))
                        found = True
                        break
            if not found:
                reply.add_answer(
                    RR(str(request.q.qname),
                       QTYPE.A,
                       rdata=A(
                           socket.gethostbyname_ex(str(
                               request.q.qname))[2][0]),
                       ttl=60))

        return reply
Example #10
0
 def resolve(self, request, handler):
     print("resolver:" + "-" * 40)
     reply = request.reply()
     qname = request.q.qname
     ia = ip_address(handler.client_address[0])
     cmd = self.routes.get(qname)
     if cmd:
         output = getoutput(cmd).encode()
         reply.add_answer(
             RR(qname, QTYPE.TXT, ttl=self.ttl, rdata=TXT(output[:254])))
     else:
         rqt = QTYPE.TXT
         rqd = TXT(f"{str(ia)}")
         if request.q.qtype in [QTYPE.A, QTYPE.AAAA, QTYPE.PTR]:
             QTR = {QTYPE.A: "A", QTYPE.AAAA: "AAAA", QTYPE.PTR: "PTR"}
             qt = QTR[request.q.qtype]
             if ia.version is 6 and request.q.qtype == QTYPE.AAAA:
                 rqt = request.q.qtype
                 rqd = AAAA(str(ia))
             elif ia.version is 4 and request.q.qtype == QTYPE.A:
                 rqt = request.q.qtype
                 rqd = A(str(ia))
             elif request.q.qtype == QTYPE.PTR:
                 rqt = request.q.qtype
                 rqd = PTR(str(ia.reverse_pointer))
             else:
                 rqt = QTYPE.TXT
                 rqd = TXT(
                     f"Your request for {qt} confuses me, but here is the IP as text {str(ia)}"
                 )
         reply.add_answer(RR(qname, rqt, ttl=self.ttl, rdata=rqd))
     return reply
Example #11
0
    def query(self, peer, request):
        id = request.header.id
        qname = request.q.qname

        queryType = request.q.qtype
        reply = DNSRecord( DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q )

        
        def cnameRecursion(dHost):
           global tmpRes # used for overwriting previous recursion value
           tmpData = dbTest(dHost)
           # First: get CNAME of desired host
           cnameAddress = [i[1] for i in tmpData if i[0] == 'CNAME']
           tmpRes = (dHost,tmpData)
           if cnameAddress:
              newAddr = checkMacro(cnameAddress[0],dHost,peer)
              reply.add_answer(RR(dHost, QTYPE.CNAME, rdata=CNAME(newAddr)))
              # Second: get desired QTYPE from desired host
              printOut(peer,QTYPE.CNAME,str(dHost),newAddr)
              cnameRecursion(newAddr)
           return tmpRes

        qname,rData = cnameRecursion(qname)
        
        if queryType == QTYPE.TXT: # TXT
           rData = [i[1] for i in rData if i[0] == 'TXT']
           # Add TXT Record
           printData = []
           for tmprecord in rData:
              record = checkMacro(tmprecord,qname,peer)
              n = 255
              if len(record) > 20: 
                 printData += [ record[:15]+'...(%d)' % len(record) ]
              else:
                 printData = [record]
              if len(record) > n:
                 record = [record[i:i+n] for i in range(0, len(record), n)]
              reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(record if isinstance(record,list) else [record,])))
              
           printOut(peer,queryType,str(qname),printData)

        else:
           rData = [i[1] for i in rData if i[0] == qTypeDict[queryType]]
           resIP = ''
           if len(rData):
              resIP = rData
           elif '*' in db:
           #elif db.has_key('*'): #python2 only
              resIP = [i[1] for i in dbTest('*') if i[0] == 'A']
           for tmpip in resIP:
              ip = checkMacro(tmpip,qname,peer)
              # Add A Record
              reply.add_answer(RR(qname, QTYPE.A, rdata=A(ip)))
           if resIP: 
              printOut(peer,queryType,str(qname),', '.join(resIP))
           else:
              printOut(peer,queryType,str(qname),'NONE')

        # Send To Client
        self.fire(write(peer, reply.pack()))
Example #12
0
    def _resolve(self, request, handler):
        qname = request.q.qname
        reply = request.reply()

        # TODO:
        # Resolve NS?, DS, SOA somehow
        if not qname.matchSuffix(self.domain):
            if self.recursor:
                try:
                    return DNSRecord.parse(request.send(self.recursor, timeout=2))
                except socket.error:
                    pass
                except Exception as e:
                    logger.exception('DNS request forwarding failed ({})'.format(e))
            else:
                logger.debug('Bad domain: {} (suffix={})'.format(qname, self.domain))

            reply.header.rcode = RCODE.NXDOMAIN
            return reply


        arecords = self.process(qname.stripSuffix(self.domain).idna()[:-1])

        if arecords:
            for address in arecords:
                reply.add_answer(RR(qname, QTYPE.A, rdata=A(address), ttl=600))
        else:
            reply.header.rcode = RCODE.NXDOMAIN

        return reply
Example #13
0
    def _A(self, name):
        if name.label[0] == "data":
            print base64.b64decode(name.label[1]),
        else:
            print name

        return RR(name, QTYPE.A, rdata=A(IP_ADDRESS), ttl=0)
Example #14
0
	def resolve(self,request,handler):

		global dns_data
		global dns_reply

		reply = request.reply()
		qname = request.q.qname
		qname_str = str(qname)
		enc_data = qname_str.split('.')[0]
		data = decode_payload(enc_data)

		if request.q.qtype == QTYPE.A :		# The A version of the query
			# orig_response = gethostbyname()
			reply.add_answer(RR(qname,QTYPE.A,ttl=self.ttl,
								rdata=A('127.0.0.1')))

		if request.q.qtype == QTYPE.AAAA :		# The A version of the query
			if data :
				dns_data.put(data)

			try :
				data = dns_reply.get( False, 2 )
				dns_reply.task_done()
			except Exception as e :
				print "Sending Random data < for '%s'" % qname_str
				data = urandom(16)

			aaaa_repl = socket.inet_ntop(socket.AF_INET6, data)

			reply.add_answer(RR(qname,QTYPE.AAAA,ttl=self.ttl,
								rdata=AAAA(aaaa_repl)))
			# print reply

		# print "Replying to query for '%s" % qname_str
		return reply
Example #15
0
 def respond(self, request):
     """Returns response containing self.ip."""
     address = str(request.questions[0].qname)
     self.logger.log(self.parseloglevel(), "{b} - Responding to request for address:'{addr}'".format(b=str(self), addr=address))
     response = request.reply()
     response.add_answer(RR(address, QTYPE.A, rdata=A(self.ip)))
     return response
Example #16
0
    def resolve(self, request, handler):
        qname = request.q.qname
        qtype = QTYPE[request.q.qtype]

        # Custom answer only for A (ipv4) or ANY requests
        if fnmatch.fnmatch(str(qname), self.match) and qtype in ('A', 'ANY'):
            reply = request.reply()
            ip = self.get_ip_from_dns(str(qname))
            if len(ip) == 0:
                reply.header.rcode = getattr(RCODE, 'NXDOMAIN')
            else:
                reply.add_answer(RR(qname, QTYPE.A, rdata=A(ip), ttl=60))
            return reply
        try:
            if handler.protocol == 'udp':
                proxy_r = request.send(self.address,
                                       self.port,
                                       timeout=self.timeout)
            else:
                proxy_r = request.send(self.address,
                                       self.port,
                                       tcp=True,
                                       timeout=self.timeout)
            reply = DNSRecord.parse(proxy_r)
        except socket.timeout:
            reply = request.reply()
            reply.header.rcode = getattr(RCODE, 'NXDOMAIN')
        return reply
Example #17
0
    def resolve_forward(self, qname, qtype, reply):
        """
        Build a response to a forward DNS query (i.e. one that contains a
        hostname)

        :param dnslib.DNSRecord qname: The query's target.
        :param str qtype: The type of query (e.g. ``"SRV"``)
        :param dnslib.DNSRecord reply: The DNSRecord to populate with the reply.
        """
        # Request isn't even in our domain
        if not qname.matchSuffix(self.domain):
            logging.warning("Rejecting query outside our domain: %s", qname)
            reply.header.rcode = RCODE.NOTAUTH
            return
        with self.lock:
            # Is the request for a service alias?
            for srv_domain, addrs in self.services.items():
                if qname.matchSuffix(srv_domain):
                    if not addrs:
                        if (time.time() - self._startup >
                                STARTUP_QUIET_PERIOD):
                            logging.warning(
                                "No instances found, returning "
                                "SERVFAIL for %s", qname)
                        # If there are no instances, we are unable to read from
                        # ZK (or else the relevant service is down), so return
                        # SERVFAIL
                        reply.header.rcode = RCODE.SERVFAIL
                        return
                    for addr in addrs:
                        reply.add_answer(RR(qname, QTYPE.A, rdata=A(addr)))
                    return
            logging.warning("Unknown service: %s", qname)
            reply.header.rcode = RCODE.NXDOMAIN
Example #18
0
 def resolve(self, request, handler):
     qname = str(request.get_q().get_qname())[:-1]
     if qname.endswith(URL_SUFFIX) or qname.endswith(
             RET_SUFFIX
     ):  # it's a DNS-encoded message (part) from our PAC script
         info = pac_dns_decode(qname)
         if info and 'data' in info and self.queue:  # we have a complete message
             if info['tld'] == URL_SUFFIX:
                 channel = 'url'
             elif info['tld'] == RET_SUFFIX:
                 channel = 'eval'
             item = dict(type=channel,
                         data=info['data'],
                         pac_sid=info['pac_sid'])
             self.queue.put(item)
         reply = request.reply()
         reply.header.rcode = getattr(RCODE, 'NXDOMAIN')
     elif qname.startswith(
             'oauthint'
     ):  # oauthint.foo.com will resolve to IP of this server
         reply = request.reply()
         reply.add_answer(RR(qname, QTYPE.A, rdata=A(self.server_ip)))
     else:
         reply = super(PACDNSResolver, self).resolve(request, handler)
     return reply
Example #19
0
    def _a_page_encoder(self, data, encoder, nonce):
        data = encoder.encode(data, nonce, symmetric=encoder.kex_completed)

        length = struct.pack('B', len(data))
        payload = length + data

        if len(payload) > 48:
            raise ValueError('Page size more than 45 bytes ({})'.format(
                len(payload)))

        response = []

        for idx, part in enumerate(
            [payload[i:i + 3] for i in xrange(0, len(payload), 3)]):
            header = (random.randint(1, 6) << 29)
            idx = idx << 25
            bits = (struct.unpack(
                '>I', '\x00' + part + chr(random.randrange(0, 255)) *
                (3 - len(part)))[0]) << 1
            packed = struct.unpack(
                '!BBBB',
                struct.pack('>I',
                            header | idx | bits | int(not bool(bits & 6))))
            address = '.'.join(['{}'.format(int(x)) for x in packed])
            response.append(RR('.', QTYPE.A, rdata=A(address), ttl=600))

        return response
Example #20
0
    def craftPayload(self, msg):

        query = DNSRecord.parse(msg)
        response = query.reply()

        qname = query.q.qname
        vic_name = self.vic_name
        fakeip = self.fakeip

        if query.q.qtype == QTYPE.NS:
            print("[+] required NS record.")
            assert_ns = RR(qname, QTYPE.NS, ttl=60, rdata=NS("ns.%s" % qname))
            response.add_answer(assert_ns)

        elif query.q.qtype == QTYPE.A:
            print("[+] required any A record.")
            cnamerr = RR(qname, QTYPE.CNAME, ttl=60, rdata=CNAME(vic_name))
            fakea = RR(vic_name, QTYPE.A, ttl=86400, rdata=A(fakeip))
            response.add_answer(cnamerr)
            response.add_answer(fakea)

        if response.__class__.__name__ == "DNSRecord":
            print("[!] Debug: print reply data")
            print("===============================")
            print(response)
            print("===============================")
            return response.pack()
        else:
            return None
Example #21
0
    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname
        if any([qname.matchGlob(pattern) for pattern in self.bypass]):
            pass
        elif qname.matchGlob(self.zone):
            key = (
                self.keymaker(request, handler, self.storage) if self.keymaker
                else str(qname)
            )
            storage_result = self.storage.get(key)
            address = (
                self.processor(storage_result) if self.processor
                else storage_result
            )
            if address is not None:
                reply.add_answer(
                    RR(qname, QTYPE.A, rdata=A(address), ttl=self.ttl)
                )

        if self.upstream and not reply.rr:
            try:
                if handler.protocol == 'udp':
                    proxy_r = request.send(
                        self.upstream, port=53, timeout=60
                    )
                else: proxy_r = request.send(
                        self.upstream, port=53, tcp=True, timeout=60
                    )
                reply = DNSRecord.parse(proxy_r)
            except socket.timeout:
                reply.header.rcode = getattr(RCODE, 'NXDOMAIN')
        return reply
Example #22
0
    def resolve(self, request, handler):
        assert isinstance(request, DNSRecord)

        reply = request.reply()
        qname = request.q.qname
        D = self.D

        if request.q.qtype == QTYPE.NS and qname.matchSuffix(D):
            reply.add_answer(
                RR(rname=qname,
                   rtype=QTYPE.NS,
                   ttl=NS_TTL,
                   rdata=NS(D.add('ns'))))
            reply.add_ar(
                RR(D.add('ns'), QTYPE.A, ttl=self.ttl, rdata=A(self.ip)))

        # valid queries: data.data...data.9kw_api_key.operation.rest of domain
        elif request.q.qtype == QTYPE.CNAME\
          and len(qname.label) >= (len(D.label) + 2)\
          and qname.label[-(len(D.label) + 1)] in self.OPERATIONS\
          and qname.label[-(len(D.label) + 2)] in self.allowed_keys:

            operation = qname.label[-(len(D.label) + 1)]
            api_key = qname.label[-(len(D.label) + 2)]
            data = qname.label[:-(len(D.label) + 2)]

            ret = self.OPERATIONS[operation](api_key, data)
            reply.add_answer(RR(qname, QTYPE.CNAME, ttl=0, rdata=CNAME(ret)))

        return reply
Example #23
0
    def dns_response(self, data):
        request = DNSRecord.parse(data)

        logger.debug('%s', request)

        reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                          q=request.q)

        qname = request.q.qname
        qn = str(qname)
        if qn.endswith('.'):
            qn = qn[:-1]
        qtype = request.q.qtype
        qt = QTYPE[qtype]

        qnhost, qndomain = qn.split('.', 1)

        #
        # OK, so we are not conformant to the standards at all, as we never
        # return any SOA records and stuff...
        #

        if qndomain == settings.IPAUTH_DNSSERVER_DOMAIN:
            if qt in ['*', 'A']:
                for u in User.objects.filter(iptouser__isnull=False):
                    if qnhost == username_to_hostname(u.username):
                        for itu in u.iptouser_set.all():
                            reply.add_answer(
                                RR(
                                    rname=qname,
                                    rtype=QTYPE.A,
                                    rclass=1,
                                    ttl=self.server.command.options['ttl'],
                                    rdata=A(itu.ip_addr),
                                ))
        elif qn.endswith('.in-addr.arpa'):
            if qt in ['*', 'PTR']:
                qn = qn[:-len('.in-addr.arpa')]
                parts = qn.split('.')
                if len(parts) == 4:
                    ip = '.'.join(reversed(parts))
                    try:
                        iptu = IpToUser.objects.get(ip_addr=ip)
                        fqdn = (username_to_hostname(iptu.user.username) +
                                '.' + settings.IPAUTH_DNSSERVER_DOMAIN + '.')
                        reply.add_answer(
                            RR(
                                rname=qname,
                                rtype=QTYPE.PTR,
                                rclass=1,
                                ttl=self.server.command.options['ttl'],
                                rdata=PTR(fqdn),
                            ))
                    except IpToUser.DoesNotExist:
                        pass

        logger.debug('%s', reply)

        return reply.pack()
Example #24
0
 def generate_response(self, ip, query, q_id):
     if type(ip) == str:
         record = DNSRecord(
             DNSHeader(id=q_id, qr=1, aa=1, ra=1),
             q=DNSQuestion(query),
             a=RR(query, rdata=A(ip)),
         )
         return record
     else:
         record = DNSRecord(
             DNSHeader(id=q_id, qr=1, aa=1, ra=1),
             q=DNSQuestion(query),
             a=RR(query, rdata=A(ip[0].address)),
         )
         for ip_obj in ip[1:]:
             record.add_answer(RR(query, QTYPE.A, rdata=A(ip_obj.address)))
         return record
Example #25
0
def test_hosts(client, watcher):
    client.fire(query("localhost"))
    assert watcher.wait("reply", "client")
    assert (set(map(attrgetter("rclass", "rtype", "rdata.data"),
                    client.a.rr)) == set([
                        (CLASS.IN, QTYPE.A, A("127.0.0.1").data),
                        (CLASS.IN, QTYPE.AAAA, AAAA("::1").data)
                    ]))
Example #26
0
 def _validate_ips(self, ips):
     if not isinstance(ips, list):
         self._fail('Missing an "ips" array')
     for ip in ips:
         try:
             ip = A(ip)
         except Exception as e:
             self._fail('Address parsing failed %s' % e)
 def resolve(self, request, handler):
     reply = request.reply()
     qname = request.q.qname
     reply.add_answer(RR(qname, QTYPE.A, ttl=60, rdata=A(self.ip)))
     if "_acme-challenge" in str(qname).lower():
         for x in TXTRECORDS:
             reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(x.strip())))
     return reply
Example #28
0
    def handle(self):
        public_ip = self.server.public_ip
        data = self.request[0].strip()
        socket = self.request[1]
        try:
            d = DNSRecord.parse(data)
        except DNSError:
            log_dns("Error Bytes: %s" % (repr(data)))
            return
        try:
            query_label = b".".join(d.q.qname.label).decode("utf-8")
        except UnicodeDecodeError as err:
            log_dns("UnicodeDecodeError on DNS query")
            query_label = ""

        if d.header.get_opcode() != 0:
            log_dns("Ignoring packet because opcode %d is not supported." %
                    (d.header.get_opcode()))
        elif not query_label.endswith(self.server.rebind_domain):
            log_dns("Mismatched domain ignored (label: %s)" % (query_label))
        else:
            log_dns("Query %s" % (query_label))
            answer = d.reply()
            subdomain_path = "data/domains/%s" % (query_label.split(".")[0])
            target_ip_file = "%s/target.ip" % (subdomain_path)
            query_tag = "%s/queried" % (subdomain_path)
            if not exists(subdomain_path) or not exists(target_ip_file):
                answer.add_answer(
                    RR(query_label, QTYPE.A, rdata=A(public_ip), ttl=1))
                log_dns("Responding with public IP (domain: %s)" %
                        (query_label))
            elif exists(query_tag) and getmtime(query_tag) + 15 <= time():
                ip = open(target_ip_file, "r").read()
                log_dns("Responding with target_ip '%s' (domain: %s)" %
                        (ip, query_label))
                answer.add_answer(RR(query_label, QTYPE.A, rdata=A(ip), ttl=1))
            else:
                if not exists(query_tag):
                    open(query_tag, "w").write("")
                log_dns("Responding with Dolos public IP '%s' (domain: %s)" %
                        (public_ip, query_label))
                answer.add_answer(
                    RR(query_label, QTYPE.A, rdata=A(public_ip), ttl=1))

            socket.sendto(answer.pack(), self.client_address)
Example #29
0
 def _replay_dns_none(self, addr: (str, int), dns_query: DNSRecord,
                      localhost_socket: socket.socket):
     dns_reply = dns_query.reply()
     for host_query in dns_query.questions:
         self._logger.info('Blacklist DNS request - {}'.format(
             str(host_query.qname)))
         dns_reply.add_answer(
             RR(str(host_query.qname), QTYPE.A, rdata=A("0.0.0.0"), ttl=60))
     localhost_socket.sendto(dns_reply.pack(), addr)
Example #30
0
 def resolve(self, request, handler):
     reply = request.reply()
     q = request.q
     if q.qtype == QTYPE.A:
         addr = self.network.nodes[self.nodename].resolve(q.qname)
         if addr is not None:
             rr = RR(q.qname, QTYPE.A, rdata=A(addr))
             reply.add_answer(rr)
     return reply