Exemple #1
0
 def build_message(self,id, rd, aa, rcode, questions, answers, authorities, additionals):
     header = Header(id, 0, len(questions), len(answers), len(authorities), len(additionals))
     header.qr = 1
     header.opcode = 0
     header.rd = rd
     header.ra = 1
     header.aa = aa
     header.rcode = rcode
     return Message(header, questions=questions, answers=answers, authorities=authorities, additionals=additionals)
 def send_response(self, records, authoritative, error=0):
     """Send a response to some message."""
     if not error and len(records) == 0:
         error = 3  # NXDOMAIN (Domain Name not found)
     if error != 0:
         header = Header(self.message.header.ident, 0, 0, 0, 0, 0)
         header.rcode = error
     else:
         header = Header(self.message.header.ident, 0, 0, len(records), 0,
                         0)
     header.aa = authoritative  # Authoritative Answer
     header.qr = 1  # Message is Response
     header.rd = self.message.header.rd  # Recursion desired
     header.ra = 1  # Recursion Available
     response = Message(header, answers=records)
     self.sock.sendto(response.to_bytes(), self.address)
 def test_flags_aa(self):
     header = Header(0, 0, 0, 0, 0, 0)
     header.aa = 1
     self.assertEqual(header.flags, 1 << 10)
 def test_aa(self):
     header = Header(0, 0, 0, 0, 0, 0)
     header.aa = 1
     self.assertEqual(header.aa, 1)
Exemple #5
0
    def handle_request(self):
        """ Attempts to answer the received query """
        #Check this next to the given algorithm

        #print("Catalog:",self.catalog.zones)
        #for zone in self.catalog.zones:
        #    print("Records:",self.catalog.zones[zone].records)

        if self.message.header.opcode != 0:  #Send a not implemented error, we don't need to support those kinds of queries
            print("[-] - Received a nonstandard query. This is unsupported.")
            header = Header(ident, 0, 1, 0, 0, 0)
            header.qr = 1
            header.rd = self.message.header.rd
            header.ra = 1
            header.rcode = 4
            self.sendResponse(Message(header, self.message.questions, []))
            return

        #print("[*] - Handling request.")
        if len(self.message.questions) != 1:  #Send a format error response
            print("[-] - Invalid request.")
            header = Header(ident, 0, 1, 0, 0, 0)
            header.qr = 1
            header.rd = self.message.header.rd
            header.ra = 1
            header.rcode = 1
            self.sendResponse(Message(header, self.message.questions, []))
            return
        #print("MSG:",self.message)
        #print("RECEIVED QUESTION",self.message.questions[0])
        hname = str(self.message.questions[0].qname)
        #print("Solving",hname,type(hname))
        ident = self.message.header.ident
        #print("Checking zone")
        answer, authority, found = self.check_zone(hname)
        #print("Wat we in de zone hebben gevonden")
        #print("ANS:",answer,"AUTH:",authority,"FOUND:",found)
        #found = False
        if found:
            print("Found in zone")
            header = Header(ident, 0, 1, len(answer), len(authority), 0)
            header.qr = 1
            header.aa = 1
            header.rd = self.message.header.rd
            header.ra = 1

            self.sendResponse(
                Message(header, self.message.questions, answer, authority))

        elif self.message.header.rd == 1:
            h, al, ad = self.resolver.gethostbyname(hname)

            #Make and send th appropriate response
            header = Header(ident, 0, 1, len(al) + len(ad), 0, 0)
            header.qr = 1
            header.rd = self.message.header.rd
            header.ra = 1

            aliases = [
                ResourceRecord(Name(h), Type.CNAME, Class.IN, self.ttl,
                               RecordData.create(Type.CNAME, Name(alias)))
                for alias in al
            ]
            addresses = [
                ResourceRecord(Name(h), Type.A, Class.IN, self.ttl,
                               RecordData.create(Type.A, address))
                for address in ad
            ]

            self.sendResponse(
                Message(header, self.message.questions, aliases + addresses))
        else:  #Send an empty response
            header = Header(ident, 0, 1, 0, 0, 0)
            header.qr = 1
            header.rd = self.message.header.rd
            header.ra = 1
            header.rcode = 0
            self.sendResponse(Message(header, self.message.questions, []))
Exemple #6
0
    def run(self):
        """ Run the handler thread"""
        msg = Message.from_bytes(self.data)
        header = msg.header
        recursion = header.rd != 0
        questions = msg.questions

        answers = []
        authorative = []
        additional = []
        for question in questions:
            qname = question.qname
            qtype = question.qtype
            if question.qclass != Class.IN:
                pass
            domains = self.getdomains(str(qname))
            for domain in domains:
                if not self.zone.records.get(domain, False):
                    continue
                for rr in self.zone.records[domain]:
                    if (rr.type_ == Type.A or rr.type_
                            == Type.CNAME) and domain == str(qname):
                        answers.append(rr)
                    if rr.type_ == Type.NS:
                        authorative.append(rr)
                        for rec in self.zone.records[str(rr.rdata.nsdname)]:
                            if rec not in additional:
                                if rec.qtype == Type.A:
                                    additional.append(rec)
            if authorative or answers:
                header_response = Header(9001, 0, 1, len(answers),
                                         len(authorative), len(additionals))
                header_response.qr = True
                header_response.opcode(1)
                header_response.aa(False)
                header_respones.tc(False)
                header_response.rd(False)
                header_response.ra(True)
                header_response.z(False)
                header_respones.rcode(False)

                respons = Message(header_response, [question], answers,
                                  authorities, additionals)

                self.sock.sendto(respons.to_bytes(), self.addr)
                break

            if recursion and (qtype == Type.A or qtype == Type.CNAME):
                answers = []
                resolver = Resolver(100, False, 0, True)
                (hostname, aliaslist,
                 ipaddrlist) = resolver.gethostbyname(question.qname)
                header_response = Header(9001, 0, 1,
                                         len(aliaslist) + len(ipaddrlist), 0,
                                         0)
                header_response.qr = 1
                header_response.opcode = 1
                header_response.aa = 0
                header_response.tc = 0
                header_response.rd = 0
                header_response.ra = 1
                header_response.rcode = 0

                for addr in ipaddrlist:
                    answers.append(
                        ResourceRecord.from_dict({
                            "name": str(hostname),
                            "type": str(Type.A),
                            "class": str(Class.IN),
                            "ttl": 0,
                            "rdata": {
                                "address": str(addr)
                            }
                        }))
                for alias in aliaslist:
                    answers.append(
                        ResourceRecord.from_dict({
                            "name": str(hostname),
                            "type": str(Type.CNAME),
                            "class": str(Class.IN),
                            "ttl": 0,
                            "rdata": {
                                "cname": str(alias)
                            }
                        }))
                response = Message(header_response, questions, answers)
                self.sock.sendto(response.to_bytes(), self.addr)
                break