1 # Tests for Tests for source4/dsdb/samdb/ldb_modules/password_hash.c
3 # Copyright (C) Catalyst IT Ltd. 2017
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 Tests for source4/dsdb/samdb/ldb_modules/password_hash.c
21 These tests need to be run in an environment in which
22 io->ac->gpg_key_ids != NULL, so that the gpg supplemental credentials
23 are generated. The functional level needs to be >= 2008 so that the
24 kerberos newer keys are generated.
28 from samba
.tests
.password_hash
import (
33 from samba
.ndr
import ndr_unpack
34 from samba
.dcerpc
import drsblobs
38 class PassWordHashGpgmeTests(PassWordHashTests
):
41 super(PassWordHashGpgmeTests
, self
).setUp()
43 def test_default_supplementalCredentials(self
):
45 if not self
.lp
.get("password hash gpg key ids"):
46 self
.skipTest("No password hash gpg key ids, " +
47 "Primary:SambaGPG will not be generated");
49 sc
= self
.get_supplemental_creds()
51 # Check that we got all the expected supplemental credentials
52 # And they are in the expected order.
53 size
= len(sc
.sub
.packages
)
54 self
.assertEquals(5, size
)
55 (pos
, package
) = get_package(sc
, "Primary:Kerberos-Newer-Keys")
56 self
.assertEquals(1, pos
)
57 self
.assertEquals("Primary:Kerberos-Newer-Keys", package
.name
)
59 (pos
, package
) = get_package(sc
, "Primary:Kerberos")
60 self
.assertEquals(2, pos
)
61 self
.assertEquals("Primary:Kerberos", package
.name
)
63 (pos
, wd_package
) = get_package(sc
, "Primary:WDigest")
64 self
.assertEquals(3, pos
)
65 self
.assertEquals("Primary:WDigest", wd_package
.name
)
67 (pos
, package
) = get_package(sc
, "Packages")
68 self
.assertEquals(4, pos
)
69 self
.assertEquals("Packages", package
.name
)
71 (pos
, package
) = get_package(sc
, "Primary:SambaGPG")
72 self
.assertEquals(5, pos
)
73 self
.assertEquals("Primary:SambaGPG", package
.name
)
75 # Check that the WDigest values are correct.
77 digests
= ndr_unpack(drsblobs
.package_PrimaryWDigestBlob
,
78 binascii
.a2b_hex(wd_package
.data
))
79 self
.check_wdigests(digests
)
81 def test_supplementalCredentials_cleartext(self
):
82 self
.add_user(clear_text
=True)
83 if not self
.lp
.get("password hash gpg key ids"):
84 self
.skipTest("No password hash gpg key ids, " +
85 "Primary:SambaGPG will not be generated");
87 sc
= self
.get_supplemental_creds()
89 # Check that we got all the expected supplemental credentials
90 # And they are in the expected order.
91 size
= len(sc
.sub
.packages
)
92 self
.assertEquals(6, size
)
93 (pos
, package
) = get_package(sc
, "Primary:Kerberos-Newer-Keys")
94 self
.assertEquals(1, pos
)
95 self
.assertEquals("Primary:Kerberos-Newer-Keys", package
.name
)
97 (pos
, package
) = get_package(sc
, "Primary:Kerberos")
98 self
.assertEquals(2, pos
)
99 self
.assertEquals("Primary:Kerberos", package
.name
)
101 (pos
, wd_package
) = get_package(sc
, "Primary:WDigest")
102 self
.assertEquals(3, pos
)
103 self
.assertEquals("Primary:WDigest", wd_package
.name
)
105 (pos
, ct_package
) = get_package(sc
, "Primary:CLEARTEXT")
106 self
.assertEquals(4, pos
)
107 self
.assertEquals("Primary:CLEARTEXT", ct_package
.name
)
109 (pos
, package
) = get_package(sc
, "Packages")
110 self
.assertEquals(5, pos
)
111 self
.assertEquals("Packages", package
.name
)
113 (pos
, package
) = get_package(sc
, "Primary:SambaGPG")
114 self
.assertEquals(6, pos
)
115 self
.assertEquals("Primary:SambaGPG", package
.name
)
117 # Check that the WDigest values are correct.
119 digests
= ndr_unpack(drsblobs
.package_PrimaryWDigestBlob
,
120 binascii
.a2b_hex(wd_package
.data
))
121 self
.check_wdigests(digests
)
123 # Check the clear text value is correct.
124 ct
= ndr_unpack(drsblobs
.package_PrimaryCLEARTEXTBlob
,
125 binascii
.a2b_hex(ct_package
.data
))
126 self
.assertEquals(USER_PASS
.encode('utf-16-le'), ct
.cleartext
)
128 def test_userPassword_multiple_hashes(self
):
129 self
.add_user(options
=[(
130 "password hash userPassword schemes",
131 "CryptSHA512 CryptSHA256 CryptSHA512")])
133 sc
= self
.get_supplemental_creds()
135 # Check that we got all the expected supplemental credentials
136 # And they are in the expected order.
137 size
= len(sc
.sub
.packages
)
138 self
.assertEquals(6, size
)
140 (pos
, package
) = get_package(sc
, "Primary:Kerberos-Newer-Keys")
141 self
.assertEquals(1, pos
)
142 self
.assertEquals("Primary:Kerberos-Newer-Keys", package
.name
)
144 (pos
, package
) = get_package(sc
, "Primary:Kerberos")
145 self
.assertEquals(2, pos
)
146 self
.assertEquals("Primary:Kerberos", package
.name
)
148 (pos
, wp_package
) = get_package(sc
, "Primary:WDigest")
149 self
.assertEquals(3, pos
)
150 self
.assertEquals("Primary:WDigest", wp_package
.name
)
152 (pos
, up_package
) = get_package(sc
, "Primary:userPassword")
153 self
.assertEquals(4, pos
)
154 self
.assertEquals("Primary:userPassword", up_package
.name
)
156 (pos
, package
) = get_package(sc
, "Packages")
157 self
.assertEquals(5, pos
)
158 self
.assertEquals("Packages", package
.name
)
160 (pos
, package
) = get_package(sc
, "Primary:SambaGPG")
161 self
.assertEquals(6, pos
)
162 self
.assertEquals("Primary:SambaGPG", package
.name
)
164 # Check that the WDigest values are correct.
166 digests
= ndr_unpack(drsblobs
.package_PrimaryWDigestBlob
,
167 binascii
.a2b_hex(wp_package
.data
))
168 self
.check_wdigests(digests
)
170 # Check that the userPassword hashes are computed correctly
171 # Expect three hashes to be calculated
172 up
= ndr_unpack(drsblobs
.package_PrimaryUserPasswordBlob
,
173 binascii
.a2b_hex(up_package
.data
))
174 self
.checkUserPassword(up
, [
175 ("{CRYPT}", "6", None),
176 ("{CRYPT}", "5", None),
177 ("{CRYPT}", "6", None)
179 self
.checkNtHash(USER_PASS
, up
.current_nt_hash
.hash)
181 def test_userPassword_multiple_hashes_rounds_specified(self
):
182 self
.add_user(options
=[(
183 "password hash userPassword schemes",
184 "CryptSHA512:rounds=5120 CryptSHA256:rounds=2560 CryptSHA512:rounds=5122")])
186 sc
= self
.get_supplemental_creds()
188 # Check that we got all the expected supplemental credentials
189 # And they are in the expected order.
190 size
= len(sc
.sub
.packages
)
191 self
.assertEquals(6, size
)
193 (pos
, package
) = get_package(sc
, "Primary:Kerberos-Newer-Keys")
194 self
.assertEquals(1, pos
)
195 self
.assertEquals("Primary:Kerberos-Newer-Keys", package
.name
)
197 (pos
, package
) = get_package(sc
, "Primary:Kerberos")
198 self
.assertEquals(2, pos
)
199 self
.assertEquals("Primary:Kerberos", package
.name
)
201 (pos
, wp_package
) = get_package(sc
, "Primary:WDigest")
202 self
.assertEquals(3, pos
)
203 self
.assertEquals("Primary:WDigest", wp_package
.name
)
205 (pos
, up_package
) = get_package(sc
, "Primary:userPassword")
206 self
.assertEquals(4, pos
)
207 self
.assertEquals("Primary:userPassword", up_package
.name
)
209 (pos
, package
) = get_package(sc
, "Packages")
210 self
.assertEquals(5, pos
)
211 self
.assertEquals("Packages", package
.name
)
213 (pos
, package
) = get_package(sc
, "Primary:SambaGPG")
214 self
.assertEquals(6, pos
)
215 self
.assertEquals("Primary:SambaGPG", package
.name
)
217 # Check that the WDigest values are correct.
219 digests
= ndr_unpack(drsblobs
.package_PrimaryWDigestBlob
,
220 binascii
.a2b_hex(wp_package
.data
))
221 self
.check_wdigests(digests
)
223 # Check that the userPassword hashes are computed correctly
224 # Expect three hashes to be calculated
225 up
= ndr_unpack(drsblobs
.package_PrimaryUserPasswordBlob
,
226 binascii
.a2b_hex(up_package
.data
))
227 self
.checkUserPassword(up
, [
228 ("{CRYPT}", "6", 5120),
229 ("{CRYPT}", "5", 2560),
230 ("{CRYPT}", "6", 5122)
232 self
.checkNtHash(USER_PASS
, up
.current_nt_hash
.hash)