Ejemplo n.º 1
0
    def verify_packet(self, response, response_packet, request_mac=b""):
        self.assertEqual(response.additional[0].rr_type, dns.DNS_QTYPE_TSIG)

        tsig_record = response.additional[0].rdata
        mac = binary_type(bytearray(tsig_record.mac))

        # Cut off tsig record from dns response packet for MAC verification
        # and reset additional record count.
        key_name_len = len(self.key_name) + 2
        tsig_record_len = len(ndr.ndr_pack(tsig_record)) + key_name_len + 10

        # convert str/bytes to a list (of string char or int)
        # so it can be modified
        response_packet_list = [
            x if isinstance(x, int) else ord(x) for x in response_packet
        ]
        del response_packet_list[-tsig_record_len:]
        if isinstance(response_packet_list[11], int):
            response_packet_list[11] = 0
        else:
            response_packet_list[11] = chr(0)

        # convert modified list (of string char or int) to str/bytes
        response_packet_wo_tsig = binary_type(bytearray(response_packet_list))

        fake_tsig = dns.fake_tsig_rec()
        fake_tsig.name = self.key_name
        fake_tsig.rr_class = dns.DNS_QCLASS_ANY
        fake_tsig.ttl = 0
        fake_tsig.time_prefix = tsig_record.time_prefix
        fake_tsig.time = tsig_record.time
        fake_tsig.algorithm_name = tsig_record.algorithm_name
        fake_tsig.fudge = tsig_record.fudge
        fake_tsig.error = 0
        fake_tsig.other_size = 0
        fake_tsig_packet = ndr.ndr_pack(fake_tsig)

        data = request_mac + response_packet_wo_tsig + fake_tsig_packet
        self.g.check_packet(data, data, mac)
Ejemplo n.º 2
0
    def tkey_trans(self, creds=None):
        "Do a TKEY transaction and establish a gensec context"

        if creds is None:
            creds = self.creds

        self.key_name = "%s.%s" % (uuid.uuid4(), self.get_dns_domain())

        p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
        q = self.make_name_question(self.key_name, dns.DNS_QTYPE_TKEY,
                                    dns.DNS_QCLASS_IN)
        questions = []
        questions.append(q)
        self.finish_name_packet(p, questions)

        r = dns.res_rec()
        r.name = self.key_name
        r.rr_type = dns.DNS_QTYPE_TKEY
        r.rr_class = dns.DNS_QCLASS_IN
        r.ttl = 0
        r.length = 0xffff
        rdata = dns.tkey_record()
        rdata.algorithm = "gss-tsig"
        rdata.inception = int(time.time())
        rdata.expiration = int(time.time()) + 60 * 60
        rdata.mode = dns.DNS_TKEY_MODE_GSSAPI
        rdata.error = 0
        rdata.other_size = 0

        self.g = gensec.Security.start_client(self.settings)
        self.g.set_credentials(creds)
        self.g.set_target_service("dns")
        self.g.set_target_hostname(self.server)
        self.g.want_feature(gensec.FEATURE_SIGN)
        self.g.start_mech_by_name("spnego")

        finished = False
        client_to_server = b""

        (finished, server_to_client) = self.g.update(client_to_server)
        self.assertFalse(finished)

        data = [
            x if isinstance(x, int) else ord(x) for x in list(server_to_client)
        ]
        rdata.key_data = data
        rdata.key_size = len(data)
        r.rdata = rdata

        additional = [r]
        p.arcount = 1
        p.additional = additional

        (response, response_packet) =\
            self.dns_transaction_tcp(p, self.server_ip)
        self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK)

        tkey_record = response.answers[0].rdata
        server_to_client = binary_type(bytearray(tkey_record.key_data))
        (finished, client_to_server) = self.g.update(server_to_client)
        self.assertTrue(finished)

        self.verify_packet(response, response_packet)