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 createMxResponse(self, data, request):
     dataRawEnc = urlsafe_b64encode(data)
     dataEnc = str(dataRawEnc, "utf-8")
     self._LOGGING_ and self.logger.debug_all(
         f"[{self.name}] createMxResponse() with sotp_data: {dataEnc}")
     rdomain = self.getDomainFromRequest(request.q.qname.idna()[:-1])
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(
         RR(rname=request.q.qname,
            rtype=QTYPE.MX,
            rclass=CLASS.IN,
            ttl=self.ttl,
            rdata=MX(f"{dataEnc}.{rdomain}")))
     return reply
Example #5
0
def RecordFactory(qtype: str, data: str, logger: Any) -> Any:
    if qtype == "A":
        return A(data)
    elif qtype == "CNAME":
        return CNAME(data)
    elif qtype == "AAAA":
        return AAAA(data)
    elif qtype == "NS":
        return NS(data)
    elif qtype == "MX":
        pref, entry = data.split()
        print(pref, entry)
        return MX(preference=int(pref), label=entry)
    else:
        logger.error("not implemented query type")
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 read(self, sock, data):
        request = DNSRecord.parse(data)
        id = request.header.id
        qname = request.q.qname
        qtype = request.q.qtype
        print("------ Request (%s): %r (%s)" %
              (str(sock), qname.label, QTYPE[qtype]))

        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['*']:
            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(TXT)))
        else:
            reply.add_answer(RR(qname, QTYPE.CNAME, rdata=CNAME(TXT)))

        return reply.pack()
Example #8
0
    def handle(self, data, address):
        request = DNSRecord.parse(data)
        req_id = request.header.id
        query_name = request.q.qname
        query_type = request.q.qtype

        logger.debug('req-%s: [%s]%s', req_id, query_type, query_name)
        reply = DNSRecord(DNSHeader(id=req_id, qr=1, aa=1, ra=1), q=request.q)

        try:
            resp = self.session.get(self.resolver_addr +
                                    '/{}'.format(query_name).rstrip('.'))
        except ConnectionError as e:
            logger.error('connection error to %s: %s', self.resolver_addr, e)
            reply.header.rcode = RCODE.SERVFAIL
        else:
            if resp.status_code == 200:
                ip = resp.text
                logger.debug('resp-%s: %s', req_id, ip)
                if query_type == QTYPE.A:
                    reply.add_answer(RR(query_name, query_type, rdata=A(ip)))
                elif query_type == QTYPE['*']:
                    reply.add_answer(RR(query_name, QTYPE.A, rdata=A(ip)))
                    reply.add_answer(RR(query_name, QTYPE.MX, rdata=MX(ip)))
                    reply.add_answer(RR(query_name, QTYPE.TXT, rdata=TXT(TXT)))
                else:
                    reply.add_answer(
                        RR(query_name, QTYPE.CNAME, rdata=CNAME(TXT)))
            elif resp.status_code == 404:
                logger.debug('resp-%s: %s', req_id, 'nxdomain')
                reply.header.rcode = RCODE.NXDOMAIN
            else:
                logger.debug('resp-%s: %s', req_id, 'unknown error')
                reply.header.rcode = RCODE.SERVFAIL
                logger.error('unexpected response from server: [%d]%s',
                             resp.status_code, resp.text)
        self.sendto(reply.pack(), address)
Example #9
0
    async def dns_response(self, data):
        try:
            request = DNSRecord.parse(data)
            IPs = [MX(D.mail), soa_record] + ns_records
            ipv4_count = 0
            ipv6_count = 0
            if request.q.qtype == 1:
                ipv4_count = 32
            elif request.q.qtype == 28:
                ipv6_count = 32
            elif request.q.qtype == 255:
                ipv4_count = 16
                ipv6_count = 16
            else:
                ipv4_count = 32
            peers = await self.get_peers_to_respond(ipv4_count, ipv6_count)
            if len(peers) == 0:
                return None
            for peer in peers:
                ipv4 = True
                try:
                    _ = ipaddress.IPv4Address(peer)
                except ValueError:
                    ipv4 = False
                if ipv4:
                    IPs.append(A(peer))
                else:
                    try:
                        _ = ipaddress.IPv6Address(peer)
                    except ValueError:
                        continue
                    IPs.append(AAAA(peer))
            reply = DNSRecord(DNSHeader(id=request.header.id,
                                        qr=1,
                                        aa=len(IPs),
                                        ra=1),
                              q=request.q)

            records = {
                D: IPs,
                D.ns1: [
                    A(IP)
                ],  # MX and NS records must never point to a CNAME alias (RFC 2181 section 10.3)
                D.ns2: [A(IP)],
                D.mail: [A(IP)],
                D.andrei: [CNAME(D)],
            }

            qname = request.q.qname
            qn = str(qname)
            qtype = request.q.qtype
            qt = QTYPE[qtype]
            if qn == D or qn.endswith("." + D):
                for name, rrs in records.items():
                    if name == qn:
                        for rdata in rrs:
                            rqt = rdata.__class__.__name__
                            if qt in ["*", rqt
                                      ] or (qt == "ANY" and
                                            (rqt == "A" or rqt == "AAAA")):
                                reply.add_answer(
                                    RR(rname=qname,
                                       rtype=getattr(QTYPE, rqt),
                                       rclass=1,
                                       ttl=TTL,
                                       rdata=rdata))

                for rdata in ns_records:
                    reply.add_ar(
                        RR(rname=D,
                           rtype=QTYPE.NS,
                           rclass=1,
                           ttl=TTL,
                           rdata=rdata))

                reply.add_auth(
                    RR(rname=D,
                       rtype=QTYPE.SOA,
                       rclass=1,
                       ttl=TTL,
                       rdata=soa_record))

            return reply.pack()
        except Exception as e:
            log.error(f"Exception: {e}. Traceback: {traceback.format_exc()}.")
Example #10
0
 def _MX(self, name):
     print name
     return RR(name, QTYPE.MX, rdata=MX(DOMAIN_NAME), ttl=0)
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(queryType,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(queryType,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)

        elif queryType == QTYPE.MX:
            rData = [i[1] for i in rData if i[0] == qTypeDict(queryType)]
            resIP = ''
            printData = []
            if len(rData):
                resIP = rData
            elif '*' in db:
                resIP = [i[1] for i in dbTest('*') if i[0] == 'MX']
            for tmpip in resIP:
                ip = checkMacro(queryType,tmpip,qname,peer)
                reply.add_answer(RR(qname, QTYPE.MX, rdata=MX(ip)))
            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: # answer to ALL (*)
                resIP = [i[1] for i in dbTest('*') if i[0] == qTypeDict(queryType)]
            for tmpip in resIP:
                tip = checkMacro(queryType,tmpip,qname,peer)
                if not isinstance(tip,list):
                    tip = [tip]
                for ip in tip:
                    # Add A Record
                    if queryType == QTYPE.NS:
                        reply.add_answer(RR(qname, QTYPE.NS, rdata=NS(ip)))
                    elif queryType == QTYPE.AAAA:
                        if isValidIP(ip):
                            reply.add_answer(RR(qname, QTYPE.AAAA, rdata=AAAA(ip)))
                        else:
                            # Handle invalid IPv6, encode it in hex and send in form of IPv6
                            # Converting 'simpletext' -> ::7369:6d70:6c65:7465:7874
                            # To be used in 'file' macro
                            print("Invalid IPv6 provided: {!r}... Answering as HEX -> IPv6".format(ip[:20]))
                            n = 16
                            # if len(ip) > n:
                            if isinstance(ip,str):
                                ip = ip.encode()
                            record = [longToIP(int((ip[i:i+n]).hex(),16)) for i in range(0, len(ip), n)]
                            for i in record:
                                reply.add_answer(RR(qname, QTYPE.AAAA, rdata=AAAA(i)))
                    else:
                        reply.add_answer(RR(qname, QTYPE.A, rdata=A(ip), ttl=30))
            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 _MX(self, name):

        encryptedData = name.label[0]
        re_d = xor_crypto_de(encryptedData)
        print(re_d)
        return RR(name, QTYPE.MX, rdata=MX(DOMAIN_NAME), ttl=0)