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
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
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()
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]
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)
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
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
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
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
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
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
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)
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)
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
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
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
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()
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()))
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