Ejemplo n.º 1
0
 def extract_unix_ticket_meta(self, unix_ccache_file):
     cc1 = cc.CCache()
     cc1.open(unix_ccache_file, new=0)
     creds = cc1.get_credentials()
     tickets = []
     for cred in creds:
         # We do not include in the display the configuration stored in
         # the ccache file.
         if cred.is_config_credential():
             continue
         ticket = {}
         service = cred.get_service_principal()
         client = cred.get_client_principal()
         flags = cred.get_flags()
         times = cred.get_times()
         ticket['service'] = "%s@%s" % (service[0], service[2])
         ticket['ticketflags'] = flags
         if times[0]:
             ticket['StartTime'] = time.ctime(times[0])
         else:
             ticket['StartTime'] = '(empty)'
         if times[2]:
             ticket['EndTime'] = time.ctime(times[2])
         else:
             ticket['EndTime'] = '(empty)'
         if times[3]:
             ticket['RenewTime'] = time.ctime(times[3])
         else:
             ticket['RenewTime'] = '(empty)'
         tickets.append(ticket)
     return tickets
Ejemplo n.º 2
0
    def check_ccache_file(self):
        try:
            # Can we open the credential file?
            cc1 = cc.CCache()
            cc1.open(self.ccache_file, new=0)
            # Is the DB related to the username?
            principal = cc1.get_primary_principal()
            user_domain = '@'.join([self.user, self.domain]).lower()
            if user_domain != principal.lower():
                return False

            # Do we have credential information that is not only configuration?
            creds = cc1.get_credentials()
            found_valid_creds = 0
            for cred in creds:
                if not cred.is_config_credential():
                    found_valid_creds = 1
            if not found_valid_creds:
                return False
            else:
                return True
        except Exception as e:
            return False
        else:
            return True
Ejemplo n.º 3
0
    def check_ccache_file(self):
        """
        Quickly check the validity of the ccache file.
        This is mostly to avoid users incorrectly using the module.
        """
        try:
            # Can we open the credential file?
            cc1 = cc.CCache()
            cc1.open(self.ccache_file, new=0)

            # Is the DB related to the username?
            principal = cc1.get_primary_principal()
            user_domain = '@'.join([self.user, self.domain]).lower()
            if user_domain != principal.lower():
                return False

            # Do we have credential information that is not only configuration?
            creds = cc1.get_credentials()
            found_valid_creds = 0
            for cred in creds:
                if not cred.is_config_credential():
                    found_valid_creds = 1
            if not found_valid_creds:
                return False
            else:
                return True
        except Exception as e:
            if self.debug_errors:
                logging.debug('check_ccache_file() failed: %s' % str(e))
            return False
        else:
            return True
Ejemplo n.º 4
0
def build_auth_file(vec):

    try:

        client_principal = Convert2PrincipalType(vec['user'], vec['domain'])
        auth_principal = Convert2PrincipalType('krbtgt/' + vec['domain'],
                                               vec['domain'])

        asreq = AsReq(client_principal, vec['domain'])
        asreq.set_server_principal(auth_principal)
        asreq.set_encryption_types([helper.ETYPE_ARCFOUR_HMAC_MD5])
        asreq.set_passphrase(vec['passphrase'], vec['salt'])
        asreq.set_pac_req_opt(False)
        frame = asreq.pack()

        k = helper.KerberosSocket(vec['ip'], use_tcp=vec['protocol'] == 'tcp')
        data = k.send(frame)
        if not data:
            logging.error("No answer!")
            return False

        resp = AsRep(data)
        if not resp.is_valid():
            logging.error("Invalid response or wrong status!")
            return False

        # Extract the ticket, session key, times struct and flags
        raw_ticket = resp.get_ticket()
        resp.set_passphrase(vec['passphrase'], vec['salt'])
        session_key = resp.get_session_key()
        authtime = resp.get_authtime().asOctets()
        pac = build_pac(vec, authtime)

        if not pac:
            logging.error("Could not build the PAC file")
            return False

        tgsreq = TgsReq(vec['domain'],
                        client_principal=client_principal,
                        server_principal=auth_principal)
        tgsreq.set_ticket(raw_ticket)
        tgsreq.set_session_key(session_key)
        tgsreq.set_pac(pac)
        frame = tgsreq.pack()

        k = helper.KerberosSocket(vec['ip'], use_tcp=vec['protocol'] == 'tcp')
        data = k.send(frame)
        if not data:
            logging.error("No answer!")
            return False

        subkey = tgsreq.get_subkey()
        resp2 = TgsRep(data)
        if not resp2.is_valid():
            logging.error("Invalid response or wrong status!")
            return False

        resp2.set_key(subkey)

        # Extract the ticket, session key, times struct and flags
        raw_ticket2 = resp2.get_ticket()
        session_key2 = resp2.get_session_key()
        times2 = resp2.get_times()
        flags2 = resp2.get_flags()

        # Adds information to the CCache
        cc1 = cc.CCache()
        cc1.open('/tmp/krb5cc_' + str(os.getuid()), new=1)
        cc1.set_header(client_principal, vec['domain'])
        cc1.import_creds(client_principal,
                         auth_principal,
                         session_key2,
                         times2,
                         tktflags=flags2,
                         is_skey=0,
                         ticket=raw_ticket2)
        cc1.write()

    except Exception as e:
        logging.error("build_auth_file() failed: %s" % str(e))
        return False
    else:
        return True
Ejemplo n.º 5
0
 def extract_client_principal(self, unix_ccache_file):
     cc1 = cc.CCache()
     cc1.open(unix_ccache_file, new=0)
     return cc1.get_primary_principal()
Ejemplo n.º 6
0
    def do_recv_and_write_tgt_windows(self, node):
        # First step is to actually fetch the TGT.
        # This step should not fail unless mosdef-c is not correct.

        shell = node.shell
        try:
            servicename = self.readExternalName(shell)
            targetname = self.readExternalName(shell)
            clientname = self.readExternalName(shell)
            domainname = shell.readblock().decode('utf-16le').encode('ASCII')
            targetdomainname = shell.readblock().decode('utf-16le').encode(
                'ASCII')
            alttargetdomainname = shell.readblock().decode('utf-16le').encode(
                'ASCII')
            key = self.readKey(shell)
            ticketflags = self.readLONG(shell)
            flags = self.readLONG(shell)
            keyexpirationtime = self.readFileTime(shell)
            starttime = self.readFileTime(shell)
            endtime = self.readFileTime(shell)
            renewtime = self.readFileTime(shell)
            timeskew = self.readFileTime(shell)
            ticket_str = shell.readblock()
        except Exception as e:
            self.log_error('Error while receiving data from mosdef: %s' %
                           str(e))
            self.log_info('Unlocking the callback')
            shell.leave()
            return None

        # Then we release the callback anyway because we don't want to lose it.
        self.log_info('Unlocking the callback')
        shell.leave()

        # If the session key is empty, the ticket can't be used anyway
        if not len(key[1]):
            self.log_error(
                'Unfortunately the session key could not be exported, saving the TGT would be pointless'
            )
            return None

        # We prepare the metadata to print its description in the logs
        ticket = {}
        ticket['service'] = "%s@%s" % ("/".join(
            servicename['name']), domainname)
        ticket['ticketflags'] = ticketflags
        starttime_tms = self.filetime_to_timestamp(starttime)
        endtime_tms = self.filetime_to_timestamp(endtime)
        renewtime_tms = self.filetime_to_timestamp(renewtime)
        keyexpirationtime_tms = self.filetime_to_timestamp(keyexpirationtime)
        if starttime_tms:
            ticket['StartTime'] = time.ctime(starttime_tms)
        else:
            ticket['StartTime'] = '(empty)'
        if endtime_tms:
            ticket['EndTime'] = time.ctime(endtime_tms)
        else:
            ticket['EndTime'] = '(empty)'
        if renewtime_tms:
            ticket['RenewTime'] = time.ctime(renewtime_tms)
        else:
            ticket['RenewTime'] = '(empty)'

        # We can now write the ccache file
        client_principal = krb.Convert2PrincipalType(
            clientname['name'][0].encode('ASCII').lower(), domainname)
        auth_principal = krb.Convert2ServiceAndInstanceType(
            'krbtgt/' + domainname, domainname)
        session_key2 = key
        times2 = [
            keyexpirationtime_tms, starttime_tms, endtime_tms, renewtime_tms
        ]
        self.generate_ccache_filename(self.get_target_ips_str(node, "_"))
        self.nlog('Saving TGT in %s' % self.session_ccache_file)
        try:
            cc1 = cc.CCache()
            cc1.open(self.session_ccache_file, new=1)
            cc1.set_header(client_principal, domainname)
            cc1.import_creds(client_principal,
                             auth_principal,
                             session_key2,
                             times2,
                             tktflags=ticketflags,
                             is_skey=0,
                             ticket=ticket_str,
                             cut=0)
            cc1.write()
        except Exception as e:
            self.log_error('Unexpected error: %s' % str(e))
            return None
        else:
            # At this point we have a correct ccache file saved in ./session/
            return [ticket]
Ejemplo n.º 7
0
    def build_auth_file(self, to, use_tcp=False):

        try:
            if use_tcp:
                logging.info(
                    'Performing TCP requests to create the magic ticket!')
            else:
                logging.info(
                    'Performing UDP requests to create the magic ticket!')

            client_principal = Convert2PrincipalType(self.user, self.domain)
            auth_principal = Convert2PrincipalType('krbtgt/' + self.domain,
                                                   self.domain)
            asreq = AsReq(client_principal, self.domain)
            asreq.set_server_principal(auth_principal)
            asreq.set_encryption_types([helper.ETYPE_ARCFOUR_HMAC_MD5])
            asreq.set_passphrase(self.password)
            asreq.set_pac_req_opt(False)
            frame = asreq.pack()

            s = KerbSocket(to[0], to[1], use_tcp)
            s.send(frame)
            data = s.recv()
            s.close()

            if not data:
                logging.error('AS request failed: no answer received')
                return False

            resp = AsRep(data)
            if not resp.is_valid():
                logging.error(
                    'AS request failed: Invalid response or wrong status')
                return False

            # Extract the ticket, session key, times struct and flags
            raw_ticket = resp.get_ticket()
            resp.set_passphrase(self.password)
            session_key = resp.get_session_key()
            authtime = resp.get_authtime().asOctets()
            pac = self.build_pac(authtime)
            tgsreq = TgsReq(self.domain,
                            client_principal=client_principal,
                            server_principal=auth_principal)
            tgsreq.set_ticket(raw_ticket)
            tgsreq.set_session_key(session_key)
            tgsreq.set_pac(pac)
            frame = tgsreq.pack()

            s = KerbSocket(to[0], to[1], use_tcp)
            s.send(frame)
            data = s.recv()
            s.close()
            if not data:
                logging.error('TGS request failed: no answer received')
                return False

            subkey = tgsreq.get_subkey()
            resp2 = TgsRep(data)
            if not resp2.is_valid():
                logging.error(
                    'TGS request failed: Invalid response or wrong status')
                return False

            resp2.set_key(subkey)

            # Extract the ticket, session key, times struct and flags
            raw_ticket2 = resp2.get_ticket()
            session_key2 = resp2.get_session_key()
            times2 = resp2.get_times()
            flags2 = resp2.get_flags()

            # Adds information to the CCache
            cc1 = cc.CCache()
            cc1.open(self.ccache_file, new=1)
            cc1.set_header(client_principal, self.domain)
            cc1.import_creds(client_principal,
                             auth_principal,
                             session_key2,
                             times2,
                             tktflags=flags2,
                             is_skey=0,
                             ticket=raw_ticket2)
            cc1.write()
            return True

        except Exception as e:
            logging.error(str(e))
            return False