1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

tests/krb5: Add tests for AS-REQ with an SPN

Using a SPN should only be permitted if it is also a UPN, and is not an
enterprise principal.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Joseph Sutton 2021-11-25 16:22:58 +13:00 committed by Andrew Bartlett
parent 31900a0a58
commit 860065a3c9
4 changed files with 128 additions and 27 deletions

View File

@ -27,9 +27,11 @@ from samba.tests.krb5.kdc_base_test import KDCBaseTest
import samba.tests.krb5.kcrypto as kcrypto import samba.tests.krb5.kcrypto as kcrypto
import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1
from samba.tests.krb5.rfc4120_constants import ( from samba.tests.krb5.rfc4120_constants import (
KDC_ERR_C_PRINCIPAL_UNKNOWN,
KDC_ERR_ETYPE_NOSUPP, KDC_ERR_ETYPE_NOSUPP,
KDC_ERR_PREAUTH_REQUIRED, KDC_ERR_PREAUTH_REQUIRED,
KU_PA_ENC_TIMESTAMP, KU_PA_ENC_TIMESTAMP,
NT_ENTERPRISE_PRINCIPAL,
NT_PRINCIPAL, NT_PRINCIPAL,
NT_SRV_INST, NT_SRV_INST,
PADATA_ENC_TIMESTAMP PADATA_ENC_TIMESTAMP
@ -40,20 +42,28 @@ global_hexdump = False
class AsReqBaseTest(KDCBaseTest): class AsReqBaseTest(KDCBaseTest):
def _run_as_req_enc_timestamp(self, client_creds): def _run_as_req_enc_timestamp(self, client_creds, client_account=None,
client_account = client_creds.get_username() expected_cname=None,
name_type=NT_PRINCIPAL, etypes=None,
expected_error=None, expect_edata=None,
kdc_options=None):
user_name = client_creds.get_username()
if client_account is None:
client_account = user_name
client_as_etypes = self.get_default_enctypes() client_as_etypes = self.get_default_enctypes()
client_kvno = client_creds.get_kvno() client_kvno = client_creds.get_kvno()
krbtgt_creds = self.get_krbtgt_creds(require_strongest_key=True) krbtgt_creds = self.get_krbtgt_creds(require_strongest_key=True)
krbtgt_account = krbtgt_creds.get_username() krbtgt_account = krbtgt_creds.get_username()
krbtgt_supported_etypes = krbtgt_creds.tgs_supported_enctypes
realm = krbtgt_creds.get_realm() realm = krbtgt_creds.get_realm()
cname = self.PrincipalName_create(name_type=NT_PRINCIPAL, cname = self.PrincipalName_create(name_type=name_type,
names=[client_account]) names=client_account.split('/'))
sname = self.PrincipalName_create(name_type=NT_SRV_INST, sname = self.PrincipalName_create(name_type=NT_SRV_INST,
names=[krbtgt_account, realm]) names=[krbtgt_account, realm])
expected_crealm = realm expected_crealm = realm
if expected_cname is None:
expected_cname = cname expected_cname = cname
expected_srealm = realm expected_srealm = realm
expected_sname = sname expected_sname = sname
@ -61,11 +71,17 @@ class AsReqBaseTest(KDCBaseTest):
till = self.get_KerberosTime(offset=36000) till = self.get_KerberosTime(offset=36000)
initial_etypes = client_as_etypes if etypes is None:
initial_kdc_options = krb5_asn1.KDCOptions('forwardable') etypes = client_as_etypes
if kdc_options is None:
kdc_options = krb5_asn1.KDCOptions('forwardable')
if expected_error is not None:
initial_error_mode = expected_error
else:
initial_error_mode = KDC_ERR_PREAUTH_REQUIRED initial_error_mode = KDC_ERR_PREAUTH_REQUIRED
rep, kdc_exchange_dict = self._test_as_exchange(cname, rep, kdc_exchange_dict = self._test_as_exchange(
cname,
realm, realm,
sname, sname,
till, till,
@ -76,10 +92,17 @@ class AsReqBaseTest(KDCBaseTest):
expected_srealm, expected_srealm,
expected_sname, expected_sname,
expected_salt, expected_salt,
initial_etypes, etypes,
None, None,
initial_kdc_options, kdc_options,
pac_request=True) expected_supported_etypes=krbtgt_supported_etypes,
expected_account_name=user_name,
pac_request=True,
expect_edata=expect_edata)
if expected_error is not None:
return None
etype_info2 = kdc_exchange_dict['preauth_etype_info2'] etype_info2 = kdc_exchange_dict['preauth_etype_info2']
self.assertIsNotNone(etype_info2) self.assertIsNotNone(etype_info2)
@ -98,8 +121,6 @@ class AsReqBaseTest(KDCBaseTest):
pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts) pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts)
preauth_padata = [pa_ts] preauth_padata = [pa_ts]
preauth_etypes = client_as_etypes
preauth_kdc_options = krb5_asn1.KDCOptions('forwardable')
preauth_error_mode = 0 # AS-REP preauth_error_mode = 0 # AS-REP
krbtgt_decryption_key = ( krbtgt_decryption_key = (
@ -117,9 +138,11 @@ class AsReqBaseTest(KDCBaseTest):
expected_srealm, expected_srealm,
expected_sname, expected_sname,
expected_salt, expected_salt,
preauth_etypes, etypes,
preauth_padata, preauth_padata,
preauth_kdc_options, kdc_options,
expected_supported_etypes=krbtgt_supported_etypes,
expected_account_name=user_name,
preauth_key=preauth_key, preauth_key=preauth_key,
ticket_decryption_key=krbtgt_decryption_key, ticket_decryption_key=krbtgt_decryption_key,
pac_request=True) pac_request=True)
@ -249,6 +272,78 @@ class AsReqKerberosTests(AsReqBaseTest):
etypes={kcrypto.Enctype.AES128, etypes={kcrypto.Enctype.AES128,
kcrypto.Enctype.RC4}) kcrypto.Enctype.RC4})
def test_as_req_enc_timestamp_spn(self):
client_creds = self.get_mach_creds()
spn = client_creds.get_spn()
self._run_as_req_enc_timestamp(
client_creds, client_account=spn,
expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN,
expect_edata=False)
def test_as_req_enc_timestamp_spn_realm(self):
samdb = self.get_samdb()
realm = samdb.domain_dns_name().upper()
client_creds = self.get_cached_creds(
account_type=self.AccountType.COMPUTER,
opts={'upn': f'host/{{account}}.{realm}@{realm}'})
spn = client_creds.get_spn()
self._run_as_req_enc_timestamp(
client_creds, client_account=spn,
expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN,
expect_edata=False)
def test_as_req_enc_timestamp_spn_upn(self):
samdb = self.get_samdb()
realm = samdb.domain_dns_name().upper()
client_creds = self.get_cached_creds(
account_type=self.AccountType.COMPUTER,
opts={'upn': f'host/{{account}}.{realm}@{realm}',
'spn': f'host/{{account}}.{realm}'})
spn = client_creds.get_spn()
self._run_as_req_enc_timestamp(client_creds, client_account=spn)
def test_as_req_enc_timestamp_spn_enterprise(self):
client_creds = self.get_mach_creds()
spn = client_creds.get_spn()
self._run_as_req_enc_timestamp(
client_creds, client_account=spn,
name_type=NT_ENTERPRISE_PRINCIPAL,
expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN,
expect_edata=False)
def test_as_req_enc_timestamp_spn_enterprise_realm(self):
samdb = self.get_samdb()
realm = samdb.domain_dns_name().upper()
client_creds = self.get_cached_creds(
account_type=self.AccountType.COMPUTER,
opts={'upn': f'host/{{account}}.{realm}@{realm}'})
spn = client_creds.get_spn()
self._run_as_req_enc_timestamp(
client_creds,
name_type=NT_ENTERPRISE_PRINCIPAL,
client_account=spn,
expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN,
expect_edata=False)
def test_as_req_enc_timestamp_spn_upn_enterprise(self):
samdb = self.get_samdb()
realm = samdb.domain_dns_name().upper()
client_creds = self.get_cached_creds(
account_type=self.AccountType.COMPUTER,
opts={'upn': f'host/{{account}}.{realm}@{realm}',
'spn': f'host/{{account}}.{realm}'})
spn = client_creds.get_spn()
self._run_as_req_enc_timestamp(
client_creds,
name_type=NT_ENTERPRISE_PRINCIPAL,
client_account=spn,
expected_error=KDC_ERR_C_PRINCIPAL_UNKNOWN,
expect_edata=False)
if __name__ == "__main__": if __name__ == "__main__":
global_asn1_print = False global_asn1_print = False

View File

@ -285,6 +285,8 @@ class KDCBaseTest(RawKerberosTest):
"sAMAccountName": account_name, "sAMAccountName": account_name,
"userAccountControl": str(account_control), "userAccountControl": str(account_control),
"unicodePwd": utf16pw} "unicodePwd": utf16pw}
if upn is not None:
upn = upn.format(account=account_name)
if spn is not None: if spn is not None:
if isinstance(spn, str): if isinstance(spn, str):
spn = spn.format(account=account_name) spn = spn.format(account=account_name)

View File

@ -3758,6 +3758,7 @@ class RawKerberosTest(TestCaseInTempDir):
expect_pac_attrs=None, expect_pac_attrs=None,
expect_pac_attrs_pac_request=None, expect_pac_attrs_pac_request=None,
expect_requester_sid=None, expect_requester_sid=None,
expect_edata=None,
to_rodc=False): to_rodc=False):
def _generate_padata_copy(_kdc_exchange_dict, def _generate_padata_copy(_kdc_exchange_dict,
@ -3804,6 +3805,7 @@ class RawKerberosTest(TestCaseInTempDir):
expect_pac_attrs=expect_pac_attrs, expect_pac_attrs=expect_pac_attrs,
expect_pac_attrs_pac_request=expect_pac_attrs_pac_request, expect_pac_attrs_pac_request=expect_pac_attrs_pac_request,
expect_requester_sid=expect_requester_sid, expect_requester_sid=expect_requester_sid,
expect_edata=expect_edata,
to_rodc=to_rodc) to_rodc=to_rodc)
rep = self._generic_kdc_exchange(kdc_exchange_dict, rep = self._generic_kdc_exchange(kdc_exchange_dict,

View File

@ -285,6 +285,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_
# #
^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp_aes128_rc4.*fl2003dc ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp_aes128_rc4.*fl2003dc
^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp_mac_aes128_rc4.*fl2003dc ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp_mac_aes128_rc4.*fl2003dc
^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp_spn(?!_)
^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_enc_timestamp_spn_realm
^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth.*aes.*rc4.*fl2003dc ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth.*aes.*rc4.*fl2003dc
^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth.*rc4.*aes.*fl2003dc ^samba.tests.krb5.as_req_tests.samba.tests.krb5.as_req_tests.AsReqKerberosTests.test_as_req_no_preauth.*rc4.*aes.*fl2003dc
# Differences in our KDC compared to windows # Differences in our KDC compared to windows