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
22 These tests need to be run in an environment in which
23 io->ac->gpg_key_ids == NULL, so that the gpg supplemental credentials
24 are not generated. And also need to be in an environment with a
25 functional level of 2008 or greater to ensure the kerberos newer keys are
28 from samba.tests.password_hash import (
33 from samba.ndr import ndr_unpack
34 from samba.dcerpc import drsblobs
37 class PassWordHashFl2008Tests(PassWordHashTests):
40 super(PassWordHashFl2008Tests, self).setUp()
43 def test_default_supplementalCredentials(self):
46 sc = self.get_supplemental_creds()
48 # Check that we got all the expected supplemental credentials
49 # And they are in the expected order.
50 size = len(sc.sub.packages)
51 self.assertEquals(4, size)
52 (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
53 self.assertEquals(1, pos)
54 self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
56 (pos, package) = get_package(sc, "Primary:Kerberos")
57 self.assertEquals(2, pos)
58 self.assertEquals("Primary:Kerberos", package.name)
60 (pos, package) = get_package(sc, "Packages")
61 self.assertEquals(3, pos)
62 self.assertEquals("Packages", package.name)
64 (pos, package) = get_package(sc, "Primary:WDigest")
65 self.assertEquals(4, pos)
66 self.assertEquals("Primary:WDigest", package.name)
68 # Check that the WDigest values are correct.
70 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
71 binascii.a2b_hex(package.data))
72 self.check_wdigests(digests)
74 def test_userPassword_sha512(self):
75 self.add_user(options=[("password hash userPassword schemes",
78 sc = self.get_supplemental_creds()
80 # Check that we got all the expected supplemental credentials
81 # And they are in the expected order.
82 size = len(sc.sub.packages)
83 self.assertEquals(5, size)
85 (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
86 self.assertEquals(1, pos)
87 self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
89 (pos, package) = get_package(sc, "Primary:Kerberos")
90 self.assertEquals(2, pos)
91 self.assertEquals("Primary:Kerberos", package.name)
93 (pos, wp_package) = get_package(sc, "Primary:WDigest")
94 self.assertEquals(3, pos)
95 self.assertEquals("Primary:WDigest", wp_package.name)
97 (pos, package) = get_package(sc, "Packages")
98 self.assertEquals(4, pos)
99 self.assertEquals("Packages", package.name)
101 (pos, up_package) = get_package(sc, "Primary:userPassword")
102 self.assertEquals(5, pos)
103 self.assertEquals("Primary:userPassword", up_package.name)
105 # Check that the WDigest values are correct.
107 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
108 binascii.a2b_hex(wp_package.data))
109 self.check_wdigests(digests)
111 # Check that the userPassword hashes are computed correctly
113 up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
114 binascii.a2b_hex(up_package.data))
115 self.checkUserPassword(up, [("{CRYPT}", "6",None)])
116 self.checkNtHash(USER_PASS, up.current_nt_hash.hash)
118 def test_supplementalCredentials_cleartext(self):
119 self.add_user(clear_text=True)
121 sc = self.get_supplemental_creds()
123 # Check that we got all the expected supplemental credentials
124 # And they are in the expected order.
125 size = len(sc.sub.packages)
126 self.assertEquals(5, size)
127 (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
128 self.assertEquals(1, pos)
129 self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
131 (pos, package) = get_package(sc, "Primary:Kerberos")
132 self.assertEquals(2, pos)
133 self.assertEquals("Primary:Kerberos", package.name)
135 (pos, wd_package) = get_package(sc, "Primary:WDigest")
136 self.assertEquals(3, pos)
137 self.assertEquals("Primary:WDigest", wd_package.name)
139 (pos, package) = get_package(sc, "Packages")
140 self.assertEquals(4, pos)
141 self.assertEquals("Packages", package.name)
143 (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT")
144 self.assertEquals(5, pos)
145 self.assertEquals("Primary:CLEARTEXT", ct_package.name)
147 # Check that the WDigest values are correct.
149 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
150 binascii.a2b_hex(wd_package.data))
151 self.check_wdigests(digests)
153 # Check the clear text value is correct.
154 ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
155 binascii.a2b_hex(ct_package.data))
156 self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
158 def test_userPassword_cleartext_sha256(self):
159 self.add_user(clear_text=True,
160 options=[("password hash userPassword schemes",
161 "CryptSHA256:rounds=100")])
163 sc = self.get_supplemental_creds()
165 # Check that we got all the expected supplemental credentials
166 # And they are in the expected order.
167 size = len(sc.sub.packages)
168 self.assertEquals(6, size)
170 (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
171 self.assertEquals(1, pos)
172 self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
174 (pos, package) = get_package(sc, "Primary:Kerberos")
175 self.assertEquals(2, pos)
176 self.assertEquals("Primary:Kerberos", package.name)
178 (pos, wd_package) = get_package(sc, "Primary:WDigest")
179 self.assertEquals(3, pos)
180 self.assertEquals("Primary:WDigest", wd_package.name)
182 (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT")
183 self.assertEquals(4, pos)
184 self.assertEquals("Primary:CLEARTEXT", ct_package.name)
186 (pos, package) = get_package(sc, "Packages")
187 self.assertEquals(5, pos)
188 self.assertEquals("Packages", package.name)
190 (pos, up_package) = get_package(sc, "Primary:userPassword")
191 self.assertEquals(6, pos)
192 self.assertEquals("Primary:userPassword", up_package.name)
194 # Check that the WDigest values are correct.
196 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
197 binascii.a2b_hex(wd_package.data))
198 self.check_wdigests(digests)
200 # Check the clear text value is correct.
201 ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
202 binascii.a2b_hex(ct_package.data))
203 self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
205 # Check that the userPassword hashes are computed correctly
207 up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
208 binascii.a2b_hex(up_package.data))
209 self.checkUserPassword(up, [("{CRYPT}", "5",100)])
210 self.checkNtHash(USER_PASS, up.current_nt_hash.hash)