mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
CVE-2020-25719 CVE-2020-25717 tests/krb5: Refactor create_ccache_with_user() to take credentials of target service
This allows us to use get_tgt() and get_service_ticket() to obtain tickets, which simplifies the logic. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14799 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561 Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
23dc0cbd53
commit
873ac6d814
@ -1283,11 +1283,13 @@ class KDCBaseTest(RawKerberosTest):
|
|||||||
return rep, enc_part
|
return rep, enc_part
|
||||||
|
|
||||||
def get_service_ticket(self, tgt, target_creds, service='host',
|
def get_service_ticket(self, tgt, target_creds, service='host',
|
||||||
|
target_name=None,
|
||||||
to_rodc=False, kdc_options=None,
|
to_rodc=False, kdc_options=None,
|
||||||
expected_flags=None, unexpected_flags=None,
|
expected_flags=None, unexpected_flags=None,
|
||||||
pac_request=True, expect_pac=True, fresh=False):
|
pac_request=True, expect_pac=True, fresh=False):
|
||||||
user_name = tgt.cname['name-string'][0]
|
user_name = tgt.cname['name-string'][0]
|
||||||
target_name = target_creds.get_username()[:-1]
|
if target_name is None:
|
||||||
|
target_name = target_creds.get_username()[:-1]
|
||||||
cache_key = (user_name, target_name, service, to_rodc, kdc_options,
|
cache_key = (user_name, target_name, service, to_rodc, kdc_options,
|
||||||
pac_request)
|
pac_request)
|
||||||
|
|
||||||
@ -1669,51 +1671,28 @@ class KDCBaseTest(RawKerberosTest):
|
|||||||
|
|
||||||
return cachefile
|
return cachefile
|
||||||
|
|
||||||
def create_ccache_with_user(self, user_credentials, mach_name,
|
def create_ccache_with_user(self, user_credentials, mach_credentials,
|
||||||
service="host"):
|
service="host", target_name=None):
|
||||||
# Obtain a service ticket authorising the user and place it into a
|
# Obtain a service ticket authorising the user and place it into a
|
||||||
# newly created credentials cache file.
|
# newly created credentials cache file.
|
||||||
|
|
||||||
user_name = user_credentials.get_username()
|
user_name = user_credentials.get_username()
|
||||||
realm = user_credentials.get_realm()
|
realm = user_credentials.get_realm()
|
||||||
|
|
||||||
# Do the initial AS-REQ, should get a pre-authentication required
|
|
||||||
# response
|
|
||||||
etype = (AES256_CTS_HMAC_SHA1_96, ARCFOUR_HMAC_MD5)
|
|
||||||
cname = self.PrincipalName_create(name_type=NT_PRINCIPAL,
|
cname = self.PrincipalName_create(name_type=NT_PRINCIPAL,
|
||||||
names=[user_name])
|
names=[user_name])
|
||||||
sname = self.PrincipalName_create(name_type=NT_SRV_HST,
|
|
||||||
names=["krbtgt", realm])
|
|
||||||
|
|
||||||
rep = self.as_req(cname, sname, realm, etype)
|
tgt = self.get_tgt(user_credentials)
|
||||||
self.check_pre_authentication(rep)
|
|
||||||
|
|
||||||
# Do the next AS-REQ
|
|
||||||
padata = self.get_enc_timestamp_pa_data(user_credentials, rep)
|
|
||||||
key = self.get_as_rep_key(user_credentials, rep)
|
|
||||||
rep = self.as_req(cname, sname, realm, etype, padata=[padata])
|
|
||||||
self.check_as_reply(rep)
|
|
||||||
|
|
||||||
# Request a ticket to the host service on the machine account
|
# Request a ticket to the host service on the machine account
|
||||||
ticket = rep['ticket']
|
ticket = self.get_service_ticket(tgt, mach_credentials,
|
||||||
enc_part = self.get_as_rep_enc_data(key, rep)
|
service=service,
|
||||||
key = self.EncryptionKey_import(enc_part['key'])
|
target_name=target_name)
|
||||||
cname = self.PrincipalName_create(name_type=NT_PRINCIPAL,
|
|
||||||
names=[user_name])
|
|
||||||
sname = self.PrincipalName_create(name_type=NT_SRV_HST,
|
|
||||||
names=[service, mach_name])
|
|
||||||
|
|
||||||
(rep, enc_part) = self.tgs_req(
|
|
||||||
cname, sname, realm, ticket, key, etype)
|
|
||||||
self.check_tgs_reply(rep)
|
|
||||||
key = self.EncryptionKey_import(enc_part['key'])
|
|
||||||
|
|
||||||
# Check the contents of the pac, and the ticket
|
|
||||||
ticket = rep['ticket']
|
|
||||||
|
|
||||||
# Write the ticket into a credentials cache file that can be ingested
|
# Write the ticket into a credentials cache file that can be ingested
|
||||||
# by the main credentials code.
|
# by the main credentials code.
|
||||||
cachefile = self.create_ccache(cname, ticket, enc_part)
|
cachefile = self.create_ccache(cname, ticket.ticket,
|
||||||
|
ticket.encpart_private)
|
||||||
|
|
||||||
# Create a credentials object to reference the credentials cache.
|
# Create a credentials object to reference the credentials cache.
|
||||||
creds = Credentials()
|
creds = Credentials()
|
||||||
|
@ -67,7 +67,7 @@ class CcacheTests(KDCBaseTest):
|
|||||||
# ticket, to ensure that the krbtgt ticket doesn't also need to be
|
# ticket, to ensure that the krbtgt ticket doesn't also need to be
|
||||||
# stored.
|
# stored.
|
||||||
(creds, cachefile) = self.create_ccache_with_user(user_credentials,
|
(creds, cachefile) = self.create_ccache_with_user(user_credentials,
|
||||||
mach_name)
|
mach_credentials)
|
||||||
|
|
||||||
# Authenticate in-process to the machine account using the user's
|
# Authenticate in-process to the machine account using the user's
|
||||||
# cached credentials.
|
# cached credentials.
|
||||||
|
@ -53,13 +53,16 @@ class LdapTests(KDCBaseTest):
|
|||||||
# Create the user account.
|
# Create the user account.
|
||||||
(user_credentials, _) = self.create_account(samdb, user_name)
|
(user_credentials, _) = self.create_account(samdb, user_name)
|
||||||
|
|
||||||
|
mach_credentials = self.get_dc_creds()
|
||||||
|
|
||||||
# Talk to the KDC to obtain the service ticket, which gets placed into
|
# Talk to the KDC to obtain the service ticket, which gets placed into
|
||||||
# the cache. The machine account name has to match the name in the
|
# the cache. The machine account name has to match the name in the
|
||||||
# ticket, to ensure that the krbtgt ticket doesn't also need to be
|
# ticket, to ensure that the krbtgt ticket doesn't also need to be
|
||||||
# stored.
|
# stored.
|
||||||
(creds, cachefile) = self.create_ccache_with_user(user_credentials,
|
(creds, cachefile) = self.create_ccache_with_user(user_credentials,
|
||||||
mach_name,
|
mach_credentials,
|
||||||
service)
|
service,
|
||||||
|
mach_name)
|
||||||
|
|
||||||
# Authenticate in-process to the machine account using the user's
|
# Authenticate in-process to the machine account using the user's
|
||||||
# cached credentials.
|
# cached credentials.
|
||||||
|
@ -50,13 +50,16 @@ class RpcTests(KDCBaseTest):
|
|||||||
# Create the user account.
|
# Create the user account.
|
||||||
(user_credentials, _) = self.create_account(samdb, user_name)
|
(user_credentials, _) = self.create_account(samdb, user_name)
|
||||||
|
|
||||||
|
mach_credentials = self.get_dc_creds()
|
||||||
|
|
||||||
# Talk to the KDC to obtain the service ticket, which gets placed into
|
# Talk to the KDC to obtain the service ticket, which gets placed into
|
||||||
# the cache. The machine account name has to match the name in the
|
# the cache. The machine account name has to match the name in the
|
||||||
# ticket, to ensure that the krbtgt ticket doesn't also need to be
|
# ticket, to ensure that the krbtgt ticket doesn't also need to be
|
||||||
# stored.
|
# stored.
|
||||||
(creds, cachefile) = self.create_ccache_with_user(user_credentials,
|
(creds, cachefile) = self.create_ccache_with_user(user_credentials,
|
||||||
mach_name,
|
mach_credentials,
|
||||||
service)
|
service,
|
||||||
|
mach_name)
|
||||||
|
|
||||||
# Authenticate in-process to the machine account using the user's
|
# Authenticate in-process to the machine account using the user's
|
||||||
# cached credentials.
|
# cached credentials.
|
||||||
|
@ -55,13 +55,16 @@ class SmbTests(KDCBaseTest):
|
|||||||
# Create the user account.
|
# Create the user account.
|
||||||
(user_credentials, _) = self.create_account(samdb, user_name)
|
(user_credentials, _) = self.create_account(samdb, user_name)
|
||||||
|
|
||||||
|
mach_credentials = self.get_dc_creds()
|
||||||
|
|
||||||
# Talk to the KDC to obtain the service ticket, which gets placed into
|
# Talk to the KDC to obtain the service ticket, which gets placed into
|
||||||
# the cache. The machine account name has to match the name in the
|
# the cache. The machine account name has to match the name in the
|
||||||
# ticket, to ensure that the krbtgt ticket doesn't also need to be
|
# ticket, to ensure that the krbtgt ticket doesn't also need to be
|
||||||
# stored.
|
# stored.
|
||||||
(creds, cachefile) = self.create_ccache_with_user(user_credentials,
|
(creds, cachefile) = self.create_ccache_with_user(user_credentials,
|
||||||
mach_name,
|
mach_credentials,
|
||||||
service)
|
service,
|
||||||
|
mach_name)
|
||||||
|
|
||||||
# Set the Kerberos 5 credentials cache environment variable. This is
|
# Set the Kerberos 5 credentials cache environment variable. This is
|
||||||
# required because the codepath that gets run (gse_krb5) looks for it
|
# required because the codepath that gets run (gse_krb5) looks for it
|
||||||
|
Loading…
Reference in New Issue
Block a user