From 1d616e8e9c0dceabebd1f079fc4d652d6bf2060d Mon Sep 17 00:00:00 2001 From: Joseph Sutton Date: Wed, 24 Nov 2021 12:09:18 +1300 Subject: [PATCH] tests/krb5: Add TGS-REQ tests with FAST Signed-off-by: Joseph Sutton Reviewed-by: Andrew Bartlett (cherry picked from commit ec823c2a83c639f1d7c422153a53d366750e5f2a) --- python/samba/tests/krb5/kdc_tgs_tests.py | 184 ++++++++++++++++++++++- selftest/knownfail_heimdal_kdc | 13 ++ selftest/knownfail_mit_kdc | 17 +++ 3 files changed, 212 insertions(+), 2 deletions(-) diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py b/python/samba/tests/krb5/kdc_tgs_tests.py index 52297c963e8..99a91528fa8 100755 --- a/python/samba/tests/krb5/kdc_tgs_tests.py +++ b/python/samba/tests/krb5/kdc_tgs_tests.py @@ -32,6 +32,7 @@ os.environ["PYTHONUNBUFFERED"] = "1" import samba.tests.krb5.kcrypto as kcrypto from samba.tests.krb5.kdc_base_test import KDCBaseTest +from samba.tests.krb5.raw_testcase import Krb5EncryptionKey from samba.tests.krb5.rfc4120_constants import ( AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5, @@ -513,6 +514,11 @@ class KdcTgsTests(KDCBaseTest): tgt = self._get_tgt(creds) self._user2user(tgt, creds, expected_error=0) + def test_fast_req(self): + creds = self._get_creds() + tgt = self._get_tgt(creds) + self._fast(tgt, creds, expected_error=0) + def test_tgs_req_invalid(self): creds = self._get_creds() tgt = self._get_tgt(creds, invalid=True) @@ -528,6 +534,12 @@ class KdcTgsTests(KDCBaseTest): tgt = self._get_tgt(creds, invalid=True) self._user2user(tgt, creds, expected_error=KRB_ERR_TKT_NYV) + def test_fast_req_invalid(self): + creds = self._get_creds() + tgt = self._get_tgt(creds, invalid=True) + self._fast(tgt, creds, expected_error=KRB_ERR_TKT_NYV, + expected_sname=self.get_krbtgt_sname()) + def test_tgs_req_no_requester_sid(self): creds = self._get_creds() tgt = self._get_tgt(creds, remove_requester_sid=True) @@ -583,6 +595,12 @@ class KdcTgsTests(KDCBaseTest): tgt = self._get_tgt(creds, remove_pac=True) self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) + def test_fast_no_pac(self): + creds = self._get_creds() + tgt = self._get_tgt(creds, remove_pac=True) + self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, + expected_sname=self.get_krbtgt_sname()) + # Test making a request with authdata and without a PAC. def test_tgs_authdata_no_pac(self): creds = self._get_creds() @@ -613,6 +631,12 @@ class KdcTgsTests(KDCBaseTest): tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) + def test_fast_authdata_no_pac(self): + creds = self._get_creds() + tgt = self._get_tgt(creds, remove_pac=True, allow_empty_authdata=True) + self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, + expected_sname=self.get_krbtgt_sname()) + # Test changing the SID in the PAC to that of another account. def test_tgs_sid_mismatch_existing(self): creds = self._get_creds() @@ -646,6 +670,14 @@ class KdcTgsTests(KDCBaseTest): self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) + def test_fast_sid_mismatch_existing(self): + creds = self._get_creds() + existing_rid = self._get_existing_rid() + tgt = self._get_tgt(creds, new_rid=existing_rid) + self._fast(tgt, creds, + expected_error=KDC_ERR_TGT_REVOKED, + expected_sname=self.get_krbtgt_sname()) + def test_requester_sid_mismatch_existing(self): creds = self._get_creds() existing_rid = self._get_existing_rid() @@ -702,6 +734,14 @@ class KdcTgsTests(KDCBaseTest): self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) + def test_fast_sid_mismatch_nonexisting(self): + creds = self._get_creds() + nonexistent_rid = self._get_non_existent_rid() + tgt = self._get_tgt(creds, new_rid=nonexistent_rid) + self._fast(tgt, creds, + expected_error=KDC_ERR_TGT_REVOKED, + expected_sname=self.get_krbtgt_sname()) + def test_requester_sid_mismatch_nonexisting(self): creds = self._get_creds() nonexistent_rid = self._get_non_existent_rid() @@ -799,6 +839,16 @@ class KdcTgsTests(KDCBaseTest): self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) + def test_fast_rodc_sid_mismatch_existing(self): + creds = self._get_creds(replication_allowed=True, + revealed_to_rodc=True) + existing_rid = self._get_existing_rid(replication_allowed=True, + revealed_to_rodc=True) + tgt = self._get_tgt(creds, from_rodc=True, new_rid=existing_rid) + self._fast(tgt, creds, + expected_error=KDC_ERR_TGT_REVOKED, + expected_sname=self.get_krbtgt_sname()) + def test_tgs_rodc_requester_sid_mismatch_existing(self): creds = self._get_creds(replication_allowed=True, revealed_to_rodc=True) @@ -866,6 +916,15 @@ class KdcTgsTests(KDCBaseTest): self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) + def test_fast_rodc_sid_mismatch_nonexisting(self): + creds = self._get_creds(replication_allowed=True, + revealed_to_rodc=True) + nonexistent_rid = self._get_non_existent_rid() + tgt = self._get_tgt(creds, from_rodc=True, new_rid=nonexistent_rid) + self._fast(tgt, creds, + expected_error=KDC_ERR_TGT_REVOKED, + expected_sname=self.get_krbtgt_sname()) + def test_tgs_rodc_requester_sid_mismatch_nonexisting(self): creds = self._get_creds(replication_allowed=True, revealed_to_rodc=True) @@ -955,6 +1014,14 @@ class KdcTgsTests(KDCBaseTest): self._remove_rodc_partial_secrets() self._user2user(tgt, creds, expected_error=KDC_ERR_POLICY) + def test_fast_rodc_no_partial_secrets(self): + creds = self._get_creds(replication_allowed=True, + revealed_to_rodc=True) + tgt = self._get_tgt(creds, from_rodc=True) + self._remove_rodc_partial_secrets() + self._fast(tgt, creds, expected_error=KDC_ERR_POLICY, + expected_sname=self.get_krbtgt_sname()) + # Test with an RODC-issued ticket where the RODC account does not have an # msDS-KrbTgtLink. def test_tgs_rodc_no_krbtgt_link(self): @@ -992,6 +1059,14 @@ class KdcTgsTests(KDCBaseTest): self._remove_rodc_krbtgt_link() self._user2user(tgt, creds, expected_error=KDC_ERR_POLICY) + def test_fast_rodc_no_krbtgt_link(self): + creds = self._get_creds(replication_allowed=True, + revealed_to_rodc=True) + tgt = self._get_tgt(creds, from_rodc=True) + self._remove_rodc_krbtgt_link() + self._fast(tgt, creds, expected_error=KDC_ERR_POLICY, + expected_sname=self.get_krbtgt_sname()) + # Test with an RODC-issued ticket where the client is not allowed to # replicate to the RODC. def test_tgs_rodc_not_allowed(self): @@ -1019,6 +1094,12 @@ class KdcTgsTests(KDCBaseTest): tgt = self._get_tgt(creds, from_rodc=True) self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) + def test_fast_rodc_not_allowed(self): + creds = self._get_creds(revealed_to_rodc=True) + tgt = self._get_tgt(creds, from_rodc=True) + self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, + expected_sname=self.get_krbtgt_sname()) + # Test with an RODC-issued ticket where the client is denied from # replicating to the RODC. def test_tgs_rodc_denied(self): @@ -1051,6 +1132,13 @@ class KdcTgsTests(KDCBaseTest): tgt = self._get_tgt(creds, from_rodc=True) self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) + def test_fast_rodc_denied(self): + creds = self._get_creds(replication_denied=True, + revealed_to_rodc=True) + tgt = self._get_tgt(creds, from_rodc=True) + self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, + expected_sname=self.get_krbtgt_sname()) + # Test with an RODC-issued ticket where the client is both allowed and # denied replicating to the RODC. def test_tgs_rodc_allowed_denied(self): @@ -1088,6 +1176,14 @@ class KdcTgsTests(KDCBaseTest): tgt = self._get_tgt(creds, from_rodc=True) self._user2user(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED) + def test_fast_rodc_allowed_denied(self): + creds = self._get_creds(replication_allowed=True, + replication_denied=True, + revealed_to_rodc=True) + tgt = self._get_tgt(creds, from_rodc=True) + self._fast(tgt, creds, expected_error=KDC_ERR_TGT_REVOKED, + expected_sname=self.get_krbtgt_sname()) + # Test user-to-user with incorrect service principal names. def test_user2user_matching_sname_host(self): creds = self._get_creds() @@ -1295,6 +1391,17 @@ class KdcTgsTests(KDCBaseTest): self._user2user(service_ticket, creds, expected_error=(KDC_ERR_MODIFIED, KDC_ERR_POLICY)) + # Expected to fail against Windows, which does not produce a policy error. + def test_fast_service_ticket(self): + creds = self._get_creds() + tgt = self._get_tgt(creds) + + service_creds = self.get_service_creds() + service_ticket = self.get_service_ticket(tgt, service_creds) + + self._fast(service_ticket, creds, + expected_error=KDC_ERR_POLICY) + def test_pac_attrs_none(self): creds = self._get_creds() self.get_tgt(creds, pac_request=None, @@ -1792,6 +1899,34 @@ class KdcTgsTests(KDCBaseTest): pac = self.get_ticket_pac(ticket) self.assertIsNotNone(pac) + def test_fast_pac_request_none(self): + creds = self._get_creds() + tgt = self.get_tgt(creds, pac_request=None) + + ticket = self._fast(tgt, creds, expected_error=0, expect_pac=True) + + pac = self.get_ticket_pac(ticket) + self.assertIsNotNone(pac) + + def test_fast_pac_request_false(self): + creds = self._get_creds() + tgt = self.get_tgt(creds, pac_request=False) + + ticket = self._fast(tgt, creds, expected_error=0, + expect_pac=True) + + pac = self.get_ticket_pac(ticket, expect_pac=True) + self.assertIsNotNone(pac) + + def test_fast_pac_request_true(self): + creds = self._get_creds() + tgt = self.get_tgt(creds, pac_request=True) + + ticket = self._fast(tgt, creds, expected_error=0, expect_pac=True) + + pac = self.get_ticket_pac(ticket) + self.assertIsNotNone(pac) + def test_tgs_rodc_pac_request_none(self): creds = self._get_creds(replication_allowed=True, revealed_to_rodc=True) @@ -2192,13 +2327,28 @@ class KdcTgsTests(KDCBaseTest): srealm=srealm, expect_pac=expect_pac) + def _fast(self, armor_tgt, armor_tgt_creds, expected_error, + expected_sname=None, expect_pac=True): + user_creds = self._get_mach_creds() + user_tgt = self.get_tgt(user_creds) + + target_creds = self.get_service_creds() + + return self._tgs_req(user_tgt, expected_error, target_creds, + armor_tgt=armor_tgt, + expected_sname=expected_sname, + expect_pac=expect_pac) + def _tgs_req(self, tgt, expected_error, target_creds, + armor_tgt=None, kdc_options='0', expected_cname=None, + expected_sname=None, additional_ticket=None, generate_padata_fn=None, sname=None, srealm=None, + use_fast=False, expect_claims=True, expect_pac=True, expect_pac_attrs=None, @@ -2214,7 +2364,8 @@ class KdcTgsTests(KDCBaseTest): if sname is False: sname = None - expected_sname = self.get_krbtgt_sname() + if expected_sname is None: + expected_sname = self.get_krbtgt_sname() else: if sname is None: target_name = target_creds.get_username() @@ -2229,7 +2380,8 @@ class KdcTgsTests(KDCBaseTest): name_type=NT_PRINCIPAL, names=['host', target_name]) - expected_sname = sname + if expected_sname is None: + expected_sname = sname if additional_ticket is not None: additional_tickets = [additional_ticket.ticket] @@ -2241,6 +2393,28 @@ class KdcTgsTests(KDCBaseTest): subkey = self.RandomKey(tgt.session_key.etype) + if armor_tgt is not None: + armor_subkey = self.RandomKey(subkey.etype) + explicit_armor_key = self.generate_armor_key(armor_subkey, + armor_tgt.session_key) + armor_key = kcrypto.cf2(explicit_armor_key.key, + subkey.key, + b'explicitarmor', + b'tgsarmor') + armor_key = Krb5EncryptionKey(armor_key, None) + + generate_fast_fn = self.generate_simple_fast + generate_fast_armor_fn = self.generate_ap_req + + pac_options = '1' # claims support + else: + armor_subkey = None + armor_key = None + generate_fast_fn = None + generate_fast_armor_fn = None + + pac_options = None + etypes = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5) if expected_error: @@ -2260,12 +2434,18 @@ class KdcTgsTests(KDCBaseTest): expected_sname=expected_sname, ticket_decryption_key=decryption_key, generate_padata_fn=generate_padata_fn, + generate_fast_fn=generate_fast_fn, + generate_fast_armor_fn=generate_fast_armor_fn, check_error_fn=check_error_fn, check_rep_fn=check_rep_fn, check_kdc_private_fn=self.generic_check_kdc_private, expected_error_mode=expected_error, expected_status=expected_status, tgt=tgt, + armor_key=armor_key, + armor_tgt=armor_tgt, + armor_subkey=armor_subkey, + pac_options=pac_options, authenticator_subkey=subkey, kdc_options=kdc_options, expect_edata=expect_edata, diff --git a/selftest/knownfail_heimdal_kdc b/selftest/knownfail_heimdal_kdc index 1b7e159c381..61de06659be 100644 --- a/selftest/knownfail_heimdal_kdc +++ b/selftest/knownfail_heimdal_kdc @@ -274,6 +274,19 @@ # # KDC TGS tests # +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_authdata_no_pac +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_no_pac +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_req_invalid +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_allowed_denied +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_denied +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_no_krbtgt_link +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_no_partial_secrets +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_not_allowed +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_sid_mismatch_existing +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_sid_mismatch_nonexisting +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_remove_pac diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc index 98e8a34cd5f..3e19ee6c8b9 100644 --- a/selftest/knownfail_mit_kdc +++ b/selftest/knownfail_mit_kdc @@ -390,6 +390,23 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ # # KDC TGT tests # +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_authdata_no_pac +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_no_pac +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_pac_request_false +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_pac_request_none +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_pac_request_true +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_req +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_req_invalid +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_allowed_denied +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_denied +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_no_krbtgt_link +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_no_partial_secrets +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_not_allowed +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_sid_mismatch_existing +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_rodc_sid_mismatch_nonexisting +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_service_ticket +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_existing +^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_fast_sid_mismatch_nonexisting ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_existing ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_only_sid_mismatch_nonexisting ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_renew_authdata_no_pac