From: Andrew Bartlett Date: Tue, 19 Mar 2024 01:37:24 +0000 (+1300) Subject: python/tests/krb5: Prepare for PKINIT tests with UF_SMARTCARD_REQUIRED X-Git-Tag: samba-4.19.8~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2102b619cf68ddcd3d9b3c4e4d6a3381966d4894;p=thirdparty%2Fsamba.git python/tests/krb5: Prepare for PKINIT tests with UF_SMARTCARD_REQUIRED Signed-off-by: Andrew Bartlett Reviewed-by: Jo Sutton (backported from commit b2fe1ea1c6aba116b31a1c803b4e0d36ac1a32ee) BUG: https://bugzilla.samba.org/show_bug.cgi?id=15655 [jsutton@samba.org Fixed conflicting import statements in python/samba/tests/krb5/pkinit_tests.py] [jsutton@samba.org Fixed conflicting import statements in python/samba/tests/krb5/kdc_base_test.py] --- diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py index 76cea241d30..7d6cad9a785 100644 --- a/python/samba/tests/krb5/kdc_base_test.py +++ b/python/samba/tests/krb5/kdc_base_test.py @@ -80,7 +80,8 @@ from samba.dsdb import ( UF_NOT_DELEGATED, UF_PARTIAL_SECRETS_ACCOUNT, UF_SERVER_TRUST_ACCOUNT, - UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION + UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, + UF_SMARTCARD_REQUIRED ) from samba.dcerpc.misc import ( SEC_CHAN_NULL, @@ -907,6 +908,7 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest): creds.set_upn(upn) creds.set_spn(spn) creds.set_type(account_type) + creds.set_user_account_control(account_control) self.creds_set_enctypes(creds) @@ -1712,6 +1714,7 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest): 'assigned_policy': None, 'assigned_silo': None, 'logon_hours': None, + 'smartcard_required': False } account_opts = { @@ -1764,7 +1767,8 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest): force_nt4_hash, assigned_policy, assigned_silo, - logon_hours): + logon_hours, + smartcard_required): if account_type is self.AccountType.USER: self.assertIsNone(delegation_to_spn) self.assertIsNone(delegation_from_dn) @@ -1787,6 +1791,8 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest): user_account_control |= UF_NOT_DELEGATED if no_auth_data_required: user_account_control |= UF_NO_AUTH_DATA_REQUIRED + if smartcard_required: + user_account_control |= UF_SMARTCARD_REQUIRED if additional_details: details = {k: v for k, v in additional_details} @@ -1844,7 +1850,16 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest): preserve=use_cache) expected_etypes = None - if force_nt4_hash: + + # We don't force fetching the keys other than the NT hash as + # how the server stores the unused KDC keys for the + # smartcard_required case is not important and makes unrelated + # tests break because of differences between Samba and + # Windows. + # + # The NT hash is different, as it is returned to the client in + # the PAC so is visible in the network behaviour. + if force_nt4_hash or smartcard_required: expected_etypes = {kcrypto.Enctype.RC4} keys = self.get_keys(creds, expected_etypes=expected_etypes) self.creds_set_keys(creds, keys) diff --git a/python/samba/tests/krb5/pkinit_tests.py b/python/samba/tests/krb5/pkinit_tests.py index 3d47c799f86..afbbb45bf73 100755 --- a/python/samba/tests/krb5/pkinit_tests.py +++ b/python/samba/tests/krb5/pkinit_tests.py @@ -35,6 +35,8 @@ from cryptography.hazmat.primitives.asymmetric import dh, padding from cryptography.x509.oid import NameOID import samba.tests +from samba import credentials, generate_random_password, ntstatus +from samba.dcerpc import security, netlogon from samba.tests.krb5 import kcrypto from samba.tests.krb5.kdc_base_test import KDCBaseTest from samba.tests.krb5.raw_testcase import PkInit @@ -43,6 +45,7 @@ from samba.tests.krb5.rfc4120_constants import ( KDC_ERR_CLIENT_NOT_TRUSTED, KDC_ERR_ETYPE_NOSUPP, KDC_ERR_MODIFIED, + KDC_ERR_POLICY, KDC_ERR_PREAUTH_EXPIRED, KDC_ERR_PREAUTH_FAILED, KDC_ERR_PREAUTH_REQUIRED, @@ -69,7 +72,7 @@ class PkInitTests(KDCBaseTest): self.do_asn1_print = global_asn1_print self.do_hexdump = global_hexdump - def _get_creds(self, account_type=KDCBaseTest.AccountType.USER): + def _get_creds(self, account_type=KDCBaseTest.AccountType.USER, use_cache=False, smartcard_required=False): """Return credentials with an account having a UPN for performing PK-INIT.""" samdb = self.get_samdb() @@ -77,7 +80,9 @@ class PkInitTests(KDCBaseTest): return self.get_cached_creds( account_type=account_type, - opts={'upn': f'{{account}}.{realm}@{realm}'}) + opts={'upn': f'{{account}}.{realm}@{realm}', + 'smartcard_required': smartcard_required}, + use_cache=use_cache) def test_pkinit_no_des3(self): """Test public-key PK-INIT without specifying the DES3 encryption @@ -568,6 +573,8 @@ class PkInitTests(KDCBaseTest): target_creds, *, expect_error=0, + expect_status=False, + expected_status=None, expect_edata=False, etypes=None, freshness=None, @@ -656,7 +663,9 @@ class PkInitTests(KDCBaseTest): expected_salt=creds.get_salt(), preauth_key=preauth_key, kdc_options=str(kdc_options), - expect_edata=expect_edata) + expect_edata=expect_edata, + expect_status=expect_status, + expected_status=expected_status) till = self.get_KerberosTime(offset=36000) diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py index f3f7778c841..a80e62a29b4 100644 --- a/python/samba/tests/krb5/raw_testcase.py +++ b/python/samba/tests/krb5/raw_testcase.py @@ -54,7 +54,9 @@ from samba.dcerpc.misc import ( SEC_CHAN_WKSTA, SEC_CHAN_BDC, ) - +from samba.dsdb import ( + UF_SMARTCARD_REQUIRED +) import samba.tests from samba.tests import TestCase @@ -407,6 +409,7 @@ class KerberosCredentials(Credentials): 'spn', 'tgs_supported_enctypes', 'upn', + 'user_account_control' ] non_etype_bits = ( @@ -438,6 +441,8 @@ class KerberosCredentials(Credentials): self.sid = None self.account_type = None + self.user_account_control = None + self._private_key = None def set_as_supported_enctypes(self, value): @@ -449,6 +454,9 @@ class KerberosCredentials(Credentials): def set_ap_supported_enctypes(self, value): self.ap_supported_enctypes = int(value) + def set_user_account_control(self, value): + self.user_account_control = int(value) + etype_map = collections.OrderedDict([ (kcrypto.Enctype.AES256, security.KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96), @@ -4745,7 +4753,10 @@ class RawKerberosTest(TestCase): creds = kdc_exchange_dict['creds'] nt_password = bytes(ntlm_package.nt_password.hash) - self.assertEqual(creds.get_nt_hash(), nt_password) + if creds.user_account_control & UF_SMARTCARD_REQUIRED: + self.assertNotEqual(creds.get_nt_hash(), nt_password) + else: + self.assertEqual(creds.get_nt_hash(), nt_password) lm_password = bytes(ntlm_package.lm_password.hash) self.assertEqual(bytes(16), lm_password)