#!/usr/bin/env python # Impacket - Collection of Python classes for working with network protocols. # # Copyright (C) 2023 Fortra. All rights reserved. # # This software is provided under a slightly modified version # of the Apache Software License. See the accompanying LICENSE file # for more information. # # Description: # Kerberos CCACHE unit tests # import os import pytest import unittest from six import PY2 if PY2: mock = None FileNotFoundError = IOError else: from unittest import mock from impacket.krb5.ccache import CCache, Credential class CCACHETests(unittest.TestCase): service = "krbtgt" domain = "INNOVATION.ROCKS" username = "user01" server = "{}/{}@{}".format(service, domain, domain) cache_v1_file = "tests/data/ccache-v1" cache_v2_file = "tests/data/ccache-v2" cache_v3_file = "tests/data/ccache-v3" cache_v4_file = "tests/data/ccache-v4" cache_v3_kirbi_file = "tests/data/ccache-v3-kirbi" cache_v4_kirbi_file = "tests/data/ccache-v4-kirbi" def assert_ccache(self, ccache): ccache.prettyPrint() self.assertIsInstance(ccache, CCache) self.assertEqual(len(ccache.credentials), 1) for cred in ccache.credentials: self.assertIsInstance(cred, Credential) self.assertIsNone(ccache.getCredential("krbtgt/UNEXISTENT.COM@UNEXISTENT.COM", True)) self.assertIsNone(ccache.getCredential("krbtgt/UNEXISTENT.COM@UNEXISTENT.COM", False)) self.assertIsNotNone(ccache.getCredential(self.server, True)) self.assertIsNotNone(ccache.getCredential(self.server, False)) def test_ccache_loadFile(self): with self.assertRaises(FileNotFoundError): CCache.loadFile("NON_EXISTENT") for cache_file in [self.cache_v1_file, self.cache_v2_file]: with self.assertRaises(NotImplementedError): CCache.loadFile(cache_file) for cache_file in [self.cache_v3_file, self.cache_v4_file]: ccache = CCache.loadFile(cache_file) self.assert_ccache(ccache) def test_ccache_fromKirbi(self): with self.assertRaises(FileNotFoundError): CCache.loadKirbiFile("NON_EXISTENT") for kirbi_file in [self.cache_v3_kirbi_file, self.cache_v4_kirbi_file]: ccache = CCache.loadKirbiFile(kirbi_file) self.assert_ccache(ccache) @pytest.mark.skipif(PY2, reason="requires python 3.3 or higher") def test_ccache_parseFile_no_cache(self): if not PY2: with mock.patch.dict(os.environ, {}, clear=True): domain, username, TGT, TGS = CCache.parseFile(self.domain, self.username) self.assertEqual(domain, self.domain) self.assertEqual(username, self.username) self.assertIsNone(TGT) self.assertIsNone(TGS) @pytest.mark.skipif(PY2, reason="requires python 3.3 or higher") def test_ccache_parseFile_unexistent(self): if not PY2: with mock.patch.dict(os.environ, {"KRB5CCNAME": "ccache-unexistent-file"}): with self.assertRaises(FileNotFoundError): CCache.parseFile(self.domain, self.username) @pytest.mark.skipif(PY2, reason="requires python 3.3 or higher") def test_ccache_parseFile(self): if not PY2: with mock.patch.dict(os.environ, {"KRB5CCNAME": self.cache_v4_file}): domain, username, TGT, TGS = CCache.parseFile("") self.assertEqual(domain, self.domain) self.assertEqual(username, self.username) self.assertIsNone(TGS) self.assertIsNotNone(TGT) domain, username, TGT, TGS = CCache.parseFile("unexistent_domain") self.assertIsNone(TGS) self.assertIsNone(TGT) domain, username, TGT, TGS = CCache.parseFile(self.domain) self.assertEqual(domain, self.domain) self.assertEqual(username, self.username) self.assertIsNone(TGS) self.assertIsNotNone(TGT) domain, username, TGT, TGS = CCache.parseFile(self.domain, self.username) self.assertEqual(domain, self.domain) self.assertEqual(username, self.username) self.assertIsNone(TGS) self.assertIsNotNone(TGT) if __name__ == "__main__": unittest.main(verbosity=1)