Example #1
0
 def resolve(self, request, handler):
     reply = request.reply()
     qname = request.q.qname
     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:
         reply.header.rcode = RCODE.NXDOMAIN
     return reply
Example #2
0
 def genDefaultError(self, request):
     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.TXT,
            rclass=CLASS.IN,
            ttl=self.server.ttl,
            rdata=TXT(
                "google-site-verification=qt5d8b2252742f0bcab14623d9714bee9ba7e82da3"
            )))
     return reply
Example #3
0
 def response_str_in_txt(request, data: str):
     '''
     将字符串包装在TXT记录里作为结果返回
     return: bytes
     '''
     request = DNSRecord.parse(request)
     qname = request.q.qname
     qtype = request.q.qtype
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(RR(qname, qtype, rdata=TXT(data)))
     return reply.pack()
Example #4
0
def parse_request(data):
    """Parsing incomming data"""
    request = DNSRecord.parse(data)
    fqdn = [x.decode() for x in request.q.qname.label]
    city = '.'.join(fqdn[-3:-2])

    if '.'.join(fqdn[-2:]) == parse_config():
        # declare
        id_ = request.header.id
        rq_ = request.q
        qn_ = request.q.qname
        qt_ = request.q.qtype

        # generate message
        msg_ = get_weather(city, record=qt_)

        # generate dns reponse
        reply = DNSRecord(DNSHeader(id=id_, qr=1, aa=1, ra=1), q=rq_)
        if qt_ == QTYPE.A:
            if ('.'.join(fqdn) == parse_config(2)[0]) or ('.'.join(fqdn) == parse_config()):
                ip_, ttl_ = parse_config(qt_)
                reply.add_answer(RR(qn_, qt_, rdata=A(ip_), ttl=ttl_))
            else:
                for ip_ in msg_:
                    reply.add_answer(RR(qn_, qt_, rdata=A('.'.join(ip_))))

        elif qt_ == QTYPE.TXT:
            if len(msg_) > 255:
                for msg in textwrap.wrap(msg_.decode(), 255):
                    reply.add_answer(RR(qn_, qt_, rdata=TXT(msg)))
            else:
                reply.add_answer(RR(qn_, qt_, rdata=TXT(msg_)))

        elif qt_ == QTYPE.NS:
            ns_, ttl_ = parse_config(qt_)
            reply.add_answer(RR(qn_, qt_, rdata=NS(ns_), ttl=ttl_))

        elif qt_ == QTYPE.SRV:
            reply.add_answer(RR(qn_, qt_, rdata=SRV(*msg_)))
        return reply.pack()
def get_chromecast_mdns_response_2017_22(query_data, chromecast_ip, chromecast_uuid, friendly_name, bs):
    from dnslib import dns, RR, QTYPE, A, PTR, TXT, SRV
    # query_a = dns.DNSRecord.parse(query_data)
    query_a = query_data
    ans = query_a.reply(ra=0)
    ans.questions = []
    collapsed_uuid=chromecast_uuid.replace("-","")
    long_mdns_name = "Chromecast-%s._googlecast._tcp.local"%collapsed_uuid
    ans.add_answer(RR("_googlecast._tcp.local", QTYPE.PTR, rdata=PTR(long_mdns_name), ttl=120))
    ans.add_ar(RR(long_mdns_name, QTYPE.TXT, rdata=TXT(["id=%s"%collapsed_uuid, "rm=", "ve=05", "md=Chromecast", "ic=/setup/icon.png", "fn=%s"%friendly_name, "ca=4101", "st=0", "bs=%s"%bs, "rs="]), ttl=4500, rclass=32769))
    ans.add_ar(RR(long_mdns_name, QTYPE.SRV, rdata=SRV(0, 0, 8009, "%s.local"%chromecast_uuid), rclass=32769,ttl=120))
    ans.add_ar(RR("%s.local"%chromecast_uuid, QTYPE.A, rdata=A(chromecast_ip),rclass=32769,ttl=120))
    return [ans]
Example #6
0
    def handle(self):
        data = self.request[0]
        socket = self.request[1]

        d = DNSRecord.parse(data)
        q = d.questions[0]
        name = 'dns.' + '.'.join(
            map(lambda x: x.decode('utf-8'), q.qname.label[1:]))
        name = name.lower()

        ans = read_answer(name)

        a = d.reply()
        a.add_answer(RR(name, QTYPE.A, rdata=A(self.ip)))
        a.add_answer(RR(name, QTYPE.TXT, rdata=TXT(ans)))
        wildcard_answer = read_answer(WILDCARD_PREFIX + name)
        if wildcard_answer != None:
            a.add_answer(RR(name, QTYPE.TXT, rdata=TXT(wildcard_answer)))

        if DEBUG:
            print('Asked about', q.qname.label, 'and anwered with', a.pack())
        socket.sendto(a.pack(), self.client_address)
Example #7
0
    def resolve(self, request, handler):
        if self.address is None:
            raise Exception("address not set")

        reply = request.reply()
        q_name = request.q.qname
        q_rtype = request.q.qtype

        if q_rtype == QTYPE.A:
            reply.add_answer(
                RR(rname=q_name,
                   rtype=q_rtype,
                   rdata=A(str(self.address)),
                   ttl=10))

        elif q_rtype == QTYPE.TXT:
            path = join(dirname(realpath(__file__)),
                        "challenge_tokens/" + str(q_name))[:-1]

            wild_path = join(dirname(realpath(__file__)),
                             "challenge_tokens/wildcard" + str(q_name))[:-1]

            with open(path, "r") as file:
                token = file.read()
            reply.add_answer(
                RR(rname=q_name, rtype=q_rtype, rdata=TXT(token), ttl=10))

            if isfile(wild_path):
                print("it is a wildcard")
                with open(wild_path, "r") as file:
                    token = file.read()
                reply.add_answer(
                    RR(rname=q_name, rtype=q_rtype, rdata=TXT(token), ttl=10))
            else:
                print("it is not a wildcard")

        return reply
Example #8
0
 def createTxtResponse(self, data, request):
     # I embebed sopt data in one RR in TXT Response (but you can split sotp data in multiple RR)
     dataRawEnc = urlsafe_b64encode(data)
     dataEnc = str(dataRawEnc, "utf-8")
     self._LOGGING_ and self.logger.debug_all(
         f"[{self.name}] createTxtResponse() with sotp_data: {dataEnc}")
     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.TXT,
            rclass=CLASS.IN,
            ttl=self.ttl,
            rdata=TXT(dataEnc)))
     return reply
Example #9
0
    def _TXT(self, name):
        print "_TXT."+name.label[0]+"."+name.label[1]

        try:
            if name.label[0] == "ini":
                with open("ini.txt") as f:
                        cmd = "@" + base64.standard_b64encode(f.readlines()[int(name.label[1])-1]) + "@"

            elif name.label[0] == "cmd":
                with open("cmd.txt") as f:
                        cmd = "@" + base64.standard_b64encode(f.readlines()[int(name.label[1])-1]) + "@"
        except:
            cmd = ''

        return RR(name, QTYPE.TXT, rdata=TXT(cmd), ttl=0)
def get_chromecast_mdns_response_2018_03(query_data, chromecast_ip, chromecast_uuid, friendly_name, bs, cd="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", rs="", ca=4101, st=0, nf=1):
    from dnslib import dns, RR, QTYPE, A, PTR, TXT, SRV
    query_a = query_data
    results = []

    collapsed_uuid=chromecast_uuid.replace("-","")
    long_mdns_name = "Chromecast-%s-1._googlecast._tcp.local"%collapsed_uuid
    for question in query_a.questions:
        ans = query_a.reply(ra=0)
        ans.questions = []
        ans.add_answer(RR(question.qname, QTYPE.PTR, rdata=PTR(long_mdns_name), ttl=120))
        ans.add_ar(RR(long_mdns_name, QTYPE.TXT, rdata=TXT(["id=%s"%collapsed_uuid, "cd=%s"%cd,"rm=", "ve=05", "md=Chromecast", "ic=/setup/icon.png", "fn=%s"%friendly_name, "ca=%s"%ca, "st=%s"%st, "bs=%s"%bs, "nf=%s"%nf,"rs=%s"%rs]), ttl=4500, rclass=32769))
        ans.add_ar(RR(long_mdns_name, QTYPE.SRV, rdata=SRV(0, 0, 8009, "%s.local"%chromecast_uuid), rclass=32769,ttl=120))
        ans.add_ar(RR("%s.local"%chromecast_uuid, QTYPE.A, rdata=A(chromecast_ip),rclass=32769,ttl=120))
        results.append(ans)
    return results
Example #11
0
 def resolve(self, request, handler):
     reply = request.reply()
     if request.q.qtype == QTYPE.ANY or request.q.qtype == QTYPE.A:
         reply.add_answer(
             server.RR(rname=request.q.qname,
                       rtype=QTYPE.A,
                       rdata=A("127.0.0.1"),
                       ttl=10))
     if request.q.qtype == QTYPE.ANY or request.q.qtype == QTYPE.TXT:
         records = self.txt_records.get(str(request.q.qname), [])
         for record in records:
             reply.add_answer(
                 server.RR(rname=request.q.qname,
                           rtype=QTYPE.TXT,
                           rdata=TXT(record),
                           ttl=10))
     return reply
Example #12
0
 def response_bytes_in_txt(request, data: bytes):
     '''
     将字节流包装在TXT记录里作为结果返回
     return: bytes
     '''
     assert len(data) < 256
     request = DNSRecord.parse(request)
     qname = request.q.qname
     qtype = request.q.qtype
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(RR(qname, qtype, rdata=TXT('')))
     reply = reply.pack()
     reply[-3:-1] = struct.pack('>H', len(data) + 1)
     reply[-1] = len(data)
     reply += data
     return reply
Example #13
0
 def resolve(self, request, handler):
     """
         Respond to DNS request - parameters are request packet & handler.
         Method is expected to return DNS response
     """
     reply = request.reply()
     qname = request.q.qname
     qtype = QTYPE[request.q.qtype]
     if qtype == 'TXT':
         txtpath = os.path.join(tempfile.gettempdir(), str(qname).lower())
         if os.path.isfile(txtpath):
             reply.add_answer(
                 RR(qname,
                    QTYPE.TXT,
                    rdata=TXT(open(txtpath).read().strip())))
     for name, rtype, rr in self.zone:
         # Check if label & type match
         if getattr(qname,
                    self.eq)(name) and (qtype == rtype or qtype == 'ANY'
                                        or rtype == 'CNAME'):
             # If we have a glob match fix reply label
             print("Request Record: %s %s" % (qtype, qname))
             if self.glob:
                 a = copy.copy(rr)
                 a.rname = qname
                 reply.add_answer(a)
             else:
                 reply.add_answer(rr)
             # Check for A/AAAA records associated with reply and
             # add in additional section
             if rtype in ['CNAME', 'NS', 'MX', 'PTR']:
                 for a_name, a_rtype, a_rr in self.zone:
                     if a_name == rr.rdata.label and a_rtype in [
                             'A', 'AAAA'
                     ]:
                         reply.add_ar(a_rr)
     if not reply.rr:
         reply.header.rcode = RCODE.NXDOMAIN
     return reply
Example #14
0
def dns_handler(s, peer, data):
    global data_received
    command = pick_command()
    msg = "C" + base64.b32encode(command).replace("=", '')
    beacon = False
    request = DNSRecord.parse(data)
    id = request.header.id
    qname = request.q.qname
    qtype = request.q.qtype
    if qname.label[2] == TARGETED_DOMAIN:
        data = qname.label[0]
        if len(data) > 10:
            data = data[10:]
            if len(data) % 8 != 0:
                data = data + ("=" * (8 - len(data) % 8))
            decoded_data = base64.b32decode(data)
            if len(decoded_data) == 4:
                if decoded_data == decoded_data.upper():
                    decoded_data = decoded_data + " [BEACON]"
                    beacon = True
                    if data_received != "":
                        print "[+] Decoded Data Received: %s" % (data_received)
                        data_received = ""
            else:
                data_received += decoded_data
            print "[+] Raw Data Received: %s" % qname.label[0]
            if beacon:
                print "[+] Sending Command: %s | Encoded: %s" % (command, msg)

    if not beacon: msg = "C"

    reply = DNSRecord(DNSHeader(id=id, qr=1, rd=1, ra=1), q=request.q)
    if qtype == QTYPE.TXT:
        reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(msg)))
    else:
        reply.add_answer(RR(qname, QTYPE.CNAME, rdata=CNAME(msg)))
    s.sendto(reply.pack(), peer)
Example #15
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 #16
0
    def resolve(self, request, handler):
        reply = request.reply()

        # IP of inbound DNS request
        yourip = ipaddress.ip_address(unicode(handler.client_address[0]))

        # Wildcards if the --host supplied is 'any', otherwise limits to predefined --host
        if str(self.host).lower() == "any":
            hostname = str(request.q.qname)
        else:
            hostname = self.host

        # Build standard record contents for reply
        # e.g. local.test.	60	IN	SOA	ns1.local.test. hostmaster.local.test. 1 3600 600 604800 60
        soar = SOA("ns1." + hostname,
                   "hostmaster." + hostname,
                   (1, 3600, 600, 604800, 60))
        # e.g. local.test.	60	IN	NS	ns1.local.test.
        #      local.test.	60	IN	NS	ns2.local.test.
        ns1r = NS("ns1." + hostname)
        ns2r = NS("ns2." + hostname)

        """
        Request construction
          Verify that the request is valid, which records were requested, and construct the response
          Uses add_answer for Answer and add_auth for Authority response sections
        """

        # Matching hostname or --host 'any' was used
        if request.q.qname == hostname:

            # A record
            if QTYPE[request.q.qtype] == "A":
                # If A was requested but inbound is v6, return SOA with NOERROR ("no problem but nothing found")
                if type(yourip) == ipaddress.IPv6Address:
                    reply.add_auth(RR(
                        hostname,
                        QTYPE.SOA,
                        rdata=soar,
                        ttl=60))
                    reply.header.rcode = RCODE.NOERROR
                # Otherwise return NS1, NS2, and A
                else:
                    reply.add_auth(RR(
                        hostname,
                        QTYPE.NS,
                        rdata=ns1r,
                        ttl=60))
                    reply.add_auth(RR(
                        hostname,
                        QTYPE.NS,
                        rdata=ns2r,
                        ttl=60))
                    reply.add_answer(RR(
                        hostname,
                        QTYPE.A,
                        rdata=A(str(yourip)),
                        ttl=60))

            # AAAA record
            elif QTYPE[request.q.qtype] == "AAAA":
                # If AAAA was requested but inbound is v4, return SOA with NOERROR ("no problem but nothing found")
                if type(yourip) == ipaddress.IPv4Address:
                    reply.add_auth(RR(
                        hostname,
                        QTYPE.SOA,
                        rdata=soar,
                        ttl=60))
                    reply.header.rcode = RCODE.NOERROR
                # Otherwise return NS1, NS2, and AAAA
                else:
                    reply.add_auth(RR(
                        hostname,
                        QTYPE.NS,
                        rdata=ns1r,
                        ttl=60))
                    reply.add_auth(RR(
                        hostname,
                        QTYPE.NS,
                        rdata=ns2r,
                        ttl=60))
                    reply.add_answer(RR(
                        hostname,
                        QTYPE.A,
                        rdata=AAAA(str(yourip)),
                        ttl=60))

            # TXT record
            #   Return NS1, NS2, and human-formatted TXT with IP address
            elif QTYPE[request.q.qtype] == "TXT":
                reply.add_auth(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns1r,
                    ttl=60))   
                reply.add_auth(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns2r,
                    ttl=60))
                reply.add_answer(RR(
                    hostname,
                    QTYPE.TXT,
                    rdata=TXT("Your IP is " + str(yourip)),
                    ttl=60))
            
            # NS record
            #   Return just NS1 and NS2
            elif QTYPE[request.q.qtype] == "NS":
                reply.add_answer(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns1r,
                    ttl=43200))
                reply.add_answer(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns2r,
                    ttl=43200))

            # SOA record
            #   Return just SOA
            elif QTYPE[request.q.qtype] == "SOA":
                reply.add_answer(RR(
                    hostname,
                    QTYPE.SOA,
                    rdata=soar,
                    ttl=60))

            # ANY record
            #   Returns A/AAAA, TXT, NS1, NS2, and SOA
            elif QTYPE[request.q.qtype] == "ANY":
                # AAAA for IPv6
                if type(yourip) == ipaddress.IPv6Address:
                    reply.add_answer(RR(
                        hostname,
                        QTYPE.A,
                        rdata=AAAA(str(yourip)),
                        ttl=60))
                # A for IPv4
                else:
                    reply.add_answer(RR(
                        hostname,
                        QTYPE.A,
                        rdata=A(str(yourip)),
                        ttl=60))
                # TXT
                reply.add_answer(RR(
                    hostname,
                    QTYPE.TXT,
                    rdata=TXT("Your IP is " + str(yourip)),
                    ttl=60))
                # NS1
                reply.add_answer(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns1r,
                    ttl=60))
                # NS2
                reply.add_answer(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns2r,
                    ttl=60))
                # SOA
                reply.add_answer(RR(
                    hostname,
                    QTYPE.SOA,
                    rdata=soar,
                    ttl=60))

            # All other types are invalid, e.g. MX or CNAME;
            #   Return only SOA and NOERROR ("no problem but nothing found")
            else:
                reply.add_auth(RR(
                    hostname,
                    QTYPE.SOA,
                    rdata=soar,
                    ttl=60))
                reply.header.rcode = RCODE.NOERROR

	# Respond with appropriate rset for NS1.hostname.tld (A/IPv4 only)
	#   Skipped for --host any, since we'd just use the same IP for NS1/NS2 anyway
        elif request.q.qname == "ns1." + hostname:
            # Only respond for A records, all others receive SOA and NOERROR ("no problem but nothing found")
            if QTYPE[request.q.qtype] == "A":
                reply.add_auth(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns1r,
                    ttl=60))   
                reply.add_auth(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns2r,
                    ttl=60))   
                reply.add_answer(RR(
                    "ns1." + hostname,
                    QTYPE.A,
                    rdata=A(myip),
                    ttl=60))
            else:
                reply.add_auth(RR(
                    hostname,
                    QTYPE.SOA,
                    rdata=soar,
                    ttl=60))   
                reply.header.rcode = RCODE.NOERROR

        # NS2.hostname.tld (A only)
        elif request.q.qname == "ns2." + hostname:
            # Only respond for A records, all others receive SOA and NOERROR ("no problem but nothing found")
            if QTYPE[request.q.qtype] == "A":
                reply.add_auth(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns1r,
                    ttl=60))   
                reply.add_auth(RR(
                    hostname,
                    QTYPE.NS,
                    rdata=ns2r,
                    ttl=60))   
                reply.add_answer(RR(
                    "ns2." + hostname,
                    QTYPE.A,
                    rdata=A(myip),
                    ttl=60))
            else:
                reply.add_auth(RR(
                    hostname,
                    QTYPE.SOA,
                    rdata=soar,
                    ttl=60))
                reply.header.rcode = RCODE.NOERROR

        # Invalid host, correct domain? NXDOMAIN
        elif hostname in str(request.q.qname):
            reply.header.rcode = RCODE.NXDOMAIN
            reply.add_auth(RR(
                hostname,
                QTYPE.SOA,
                rdata=soar,   
                ttl=60))  
        
        # Invalid domain without --host any? REFUSED
        else:
            reply.header.rcode = RCODE.REFUSED

        # Return constructed rrset
        return reply
Example #17
0
    def fileupload(self, request, qname):
        reply = request.reply()
        if len(qname.split(".")) != 4:
            error = "Error: Incorrect amount of subdomains"
            # reply.add_answer(RR(request.q.qname,QTYPE.TXT,ttl=self.ttl, rdata=TXT(error)))
            reply.header.rcode = RCODE.NXDOMAIN
            return reply

        data = qname.split(".")[0].upper()
        index = qname.split(".")[1]
        filename = qname.split(".")[2]

        if '-' in data:
            if filename not in self.files and filename not in self.keys:
                print("New file incoming, lines:", data.split("-")[1])
                self.files.update({filename: [None] * int(data.split("-")[1])})
                reply.add_answer(
                    RR(request.q.qname,
                       QTYPE.TXT,
                       ttl=self.ttl,
                       rdata=TXT("Ready")))
                return reply
            else:
                reply.add_answer(
                    RR(request.q.qname,
                       QTYPE.TXT,
                       ttl=self.ttl,
                       rdata=TXT("Exists")))
                return reply

        # print("DATA RECV:", filename, index, data)
        try:
            if self.files[filename][int(index)] is None:
                self.files[filename][int(index)] = data
            else:
                reply.add_answer(
                    RR(request.q.qname,
                       QTYPE.TXT,
                       ttl=self.ttl,
                       rdata=TXT("data already received")))
                return reply
        except KeyError:
            reply.add_answer(
                RR(request.q.qname,
                   QTYPE.TXT,
                   ttl=self.ttl,
                   rdata=TXT("File not found")))
            return reply
        except ValueError:
            reply.add_answer(
                RR(request.q.qname,
                   QTYPE.TXT,
                   ttl=self.ttl,
                   rdata=TXT("Index not an int")))
            return reply
        self.checkfile(filename)
        # reply.header.rcode = RCODE.NXDOMAIN
        reply.add_answer(
            RR(request.q.qname,
               QTYPE.TXT,
               ttl=self.ttl,
               rdata=TXT("Data received")))
        return reply
Example #18
0
def encode_data_to_response(record: DNSRecord, data: bytes) -> DNSRecord:
    resp = record.reply()
    query_name = record.questions[0].qname
    txt_data = str(base64.b64encode(data))
    resp.add_answer(RR(query_name, QTYPE.TXT, rdata=TXT(txt_data), ttl=60))
    return resp
Example #19
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()))
def server_encrypt(dns_packet: DNSRecord, data, question):
    data = base64.b64encode(data)
    dns_packet = dns_packet.reply()
    dns_packet.add_answer(RR(question, rtype=QTYPE.TXT, rdata=TXT(data)))
    return dns_packet.pack()
Example #21
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 #22
-1
 def resolve(self, request, handler):
     reply = request.reply()
     domain = request.q.qname
     if request.q.qtype == QTYPE.TXT:  #acme server validates dns challenge
         reply.add_answer(
             RR(self.TXTrecord_domain,
                QTYPE.TXT,
                rdata=TXT(self.TXTrecord_data),
                ttl=100))
     else:
         reply.add_answer(
             RR(domain, QTYPE.A, rdata=A(self.address), ttl=100))
     #print("DNS SERVER REPLY: ",reply)
     return reply