2 # Unix SMB/CIFS implementation.
3 # Copyright (C) Stefan Metzmacher 2020
4 # Copyright (C) 2020 Catalyst.Net Ltd
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 sys
.path
.insert(0, "bin/python")
24 os
.environ
["PYTHONUNBUFFERED"] = "1"
26 from samba
.tests
.krb5
.kdc_base_test
import KDCBaseTest
27 from samba
.tests
.krb5
.rfc4120_constants
import (
28 AES256_CTS_HMAC_SHA1_96
,
36 global_asn1_print
= False
37 global_hexdump
= False
40 class KdcTgsTests(KDCBaseTest
):
44 self
.do_asn1_print
= global_asn1_print
45 self
.do_hexdump
= global_hexdump
47 def test_tgs_req_cname_does_not_not_match_authenticator_cname(self
):
48 ''' Try and obtain a ticket from the TGS, but supply a cname
49 that differs from that provided to the krbtgt
51 # Create the user account
52 samdb
= self
.get_samdb()
53 user_name
= "tsttktusr"
54 (uc
, _
) = self
.create_account(samdb
, user_name
)
55 realm
= uc
.get_realm().lower()
57 # Do the initial AS-REQ, should get a pre-authentication required
59 etype
= (AES256_CTS_HMAC_SHA1_96
,)
60 cname
= self
.PrincipalName_create(
61 name_type
=NT_PRINCIPAL
, names
=[user_name
])
62 sname
= self
.PrincipalName_create(
63 name_type
=NT_SRV_INST
, names
=["krbtgt", realm
])
65 rep
= self
.as_req(cname
, sname
, realm
, etype
)
66 self
.check_pre_authentication(rep
)
69 padata
= self
.get_pa_data(uc
, rep
)
70 key
= self
.get_as_rep_key(uc
, rep
)
71 rep
= self
.as_req(cname
, sname
, realm
, etype
, padata
=padata
)
72 self
.check_as_reply(rep
)
74 # Request a service ticket, but use a cname that does not match
75 # that in the original AS-REQ
76 enc_part2
= self
.get_as_rep_enc_data(key
, rep
)
77 key
= self
.EncryptionKey_import(enc_part2
['key'])
78 ticket
= rep
['ticket']
80 cname
= self
.PrincipalName_create(
81 name_type
=NT_PRINCIPAL
,
82 names
=["Administrator"])
83 sname
= self
.PrincipalName_create(
84 name_type
=NT_PRINCIPAL
,
85 names
=["host", samdb
.host_dns_name()])
87 (rep
, enc_part
) = self
.tgs_req(cname
, sname
, realm
, ticket
, key
, etype
)
91 "rep = {%s}, enc_part = {%s}" % (rep
, enc_part
))
92 self
.assertEqual(KRB_ERROR
, rep
['msg-type'], "rep = {%s}" % rep
)
98 def test_ldap_service_ticket(self
):
99 '''Get a ticket to the ldap service
101 # Create the user account
102 samdb
= self
.get_samdb()
103 user_name
= "tsttktusr"
104 (uc
, _
) = self
.create_account(samdb
, user_name
)
105 realm
= uc
.get_realm().lower()
107 # Do the initial AS-REQ, should get a pre-authentication required
109 etype
= (AES256_CTS_HMAC_SHA1_96
,)
110 cname
= self
.PrincipalName_create(
111 name_type
=NT_PRINCIPAL
, names
=[user_name
])
112 sname
= self
.PrincipalName_create(
113 name_type
=NT_SRV_INST
, names
=["krbtgt", realm
])
115 rep
= self
.as_req(cname
, sname
, realm
, etype
)
116 self
.check_pre_authentication(rep
)
119 padata
= self
.get_pa_data(uc
, rep
)
120 key
= self
.get_as_rep_key(uc
, rep
)
121 rep
= self
.as_req(cname
, sname
, realm
, etype
, padata
=padata
)
122 self
.check_as_reply(rep
)
124 enc_part2
= self
.get_as_rep_enc_data(key
, rep
)
125 key
= self
.EncryptionKey_import(enc_part2
['key'])
126 ticket
= rep
['ticket']
128 # Request a ticket to the ldap service
129 sname
= self
.PrincipalName_create(
130 name_type
=NT_SRV_INST
,
131 names
=["ldap", samdb
.host_dns_name()])
133 (rep
, _
) = self
.tgs_req(
134 cname
, sname
, uc
.get_realm(), ticket
, key
, etype
)
136 self
.check_tgs_reply(rep
)
138 def test_get_ticket_for_host_service_of_machine_account(self
):
140 # Create a user and machine account for the test.
142 samdb
= self
.get_samdb()
143 user_name
= "tsttktusr"
144 (uc
, dn
) = self
.create_account(samdb
, user_name
)
145 (mc
, _
) = self
.create_account(samdb
, "tsttktmac", machine_account
=True)
146 realm
= uc
.get_realm().lower()
148 # Do the initial AS-REQ, should get a pre-authentication required
150 etype
= (AES256_CTS_HMAC_SHA1_96
, ARCFOUR_HMAC_MD5
)
151 cname
= self
.PrincipalName_create(
152 name_type
=NT_PRINCIPAL
, names
=[user_name
])
153 sname
= self
.PrincipalName_create(
154 name_type
=NT_SRV_INST
, names
=["krbtgt", realm
])
156 rep
= self
.as_req(cname
, sname
, realm
, etype
)
157 self
.check_pre_authentication(rep
)
160 padata
= self
.get_pa_data(uc
, rep
)
161 key
= self
.get_as_rep_key(uc
, rep
)
162 rep
= self
.as_req(cname
, sname
, realm
, etype
, padata
=padata
)
163 self
.check_as_reply(rep
)
165 # Request a ticket to the host service on the machine account
166 ticket
= rep
['ticket']
167 enc_part2
= self
.get_as_rep_enc_data(key
, rep
)
168 key
= self
.EncryptionKey_import(enc_part2
['key'])
169 cname
= self
.PrincipalName_create(
170 name_type
=NT_PRINCIPAL
,
172 sname
= self
.PrincipalName_create(
173 name_type
=NT_PRINCIPAL
,
174 names
=[mc
.get_username()])
176 (rep
, enc_part
) = self
.tgs_req(
177 cname
, sname
, uc
.get_realm(), ticket
, key
, etype
)
178 self
.check_tgs_reply(rep
)
180 # Check the contents of the service ticket
181 ticket
= rep
['ticket']
182 enc_part
= self
.decode_service_ticket(mc
, ticket
)
184 pac_data
= self
.get_pac_data(enc_part
['authorization-data'])
185 sid
= self
.get_objectSid(samdb
, dn
)
186 upn
= "%s@%s" % (uc
.get_username(), realm
)
189 str(pac_data
.account_name
),
190 "rep = {%s},%s" % (rep
, pac_data
))
194 "rep = {%s},%s" % (rep
, pac_data
))
197 pac_data
.domain_name
,
198 "rep = {%s},%s" % (rep
, pac_data
))
202 "rep = {%s},%s" % (rep
, pac_data
))
205 pac_data
.account_sid
,
206 "rep = {%s},%s" % (rep
, pac_data
))
209 if __name__
== "__main__":
210 global_asn1_print
= True
211 global_hexdump
= True