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
38 class PassWordHashFl2008Tests(PassWordHashTests):
41 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 # Check that the Package names are correct.
66 pb = ndr_unpack(drsblobs.package_PackagesBlob,
67 binascii.a2b_hex(package.data))
68 expected = ["Kerberos-Newer-Keys", "Kerberos", "WDigest"]
69 self.assertEquals(expected, pb.names)
71 (pos, package) = get_package(sc, "Primary:WDigest")
72 self.assertEquals(4, pos)
73 self.assertEquals("Primary:WDigest", package.name)
75 # Check that the WDigest values are correct.
77 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
78 binascii.a2b_hex(package.data))
79 self.check_wdigests(digests)
81 def test_userPassword_sha512(self):
82 self.add_user(options=[("password hash userPassword schemes",
85 sc = self.get_supplemental_creds()
87 # Check that we got all the expected supplemental credentials
88 # And they are in the expected order.
89 size = len(sc.sub.packages)
90 self.assertEquals(5, size)
92 (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
93 self.assertEquals(1, pos)
94 self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
96 (pos, package) = get_package(sc, "Primary:Kerberos")
97 self.assertEquals(2, pos)
98 self.assertEquals("Primary:Kerberos", package.name)
100 (pos, wp_package) = get_package(sc, "Primary:WDigest")
101 self.assertEquals(3, pos)
102 self.assertEquals("Primary:WDigest", wp_package.name)
104 (pos, package) = get_package(sc, "Packages")
105 self.assertEquals(4, pos)
106 self.assertEquals("Packages", package.name)
108 (pos, up_package) = get_package(sc, "Primary:userPassword")
109 self.assertEquals(5, pos)
110 self.assertEquals("Primary:userPassword", up_package.name)
112 # Check that the WDigest values are correct.
114 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
115 binascii.a2b_hex(wp_package.data))
116 self.check_wdigests(digests)
118 # Check that the userPassword hashes are computed correctly
120 up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
121 binascii.a2b_hex(up_package.data))
122 self.checkUserPassword(up, [("{CRYPT}", "6", None)])
123 self.checkNtHash(USER_PASS, up.current_nt_hash.hash)
125 def test_supplementalCredentials_cleartext(self):
126 self.add_user(clear_text=True)
128 sc = self.get_supplemental_creds()
130 # Check that we got all the expected supplemental credentials
131 # And they are in the expected order.
132 size = len(sc.sub.packages)
133 self.assertEquals(5, size)
134 (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
135 self.assertEquals(1, pos)
136 self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
138 (pos, package) = get_package(sc, "Primary:Kerberos")
139 self.assertEquals(2, pos)
140 self.assertEquals("Primary:Kerberos", package.name)
142 (pos, wd_package) = get_package(sc, "Primary:WDigest")
143 self.assertEquals(3, pos)
144 self.assertEquals("Primary:WDigest", wd_package.name)
146 (pos, package) = get_package(sc, "Packages")
147 self.assertEquals(4, pos)
148 self.assertEquals("Packages", package.name)
150 (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT")
151 self.assertEquals(5, pos)
152 self.assertEquals("Primary:CLEARTEXT", ct_package.name)
154 # Check that the WDigest values are correct.
156 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
157 binascii.a2b_hex(wd_package.data))
158 self.check_wdigests(digests)
160 # Check the clear text value is correct.
161 ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
162 binascii.a2b_hex(ct_package.data))
163 self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
165 def test_userPassword_cleartext_sha256(self):
166 self.add_user(clear_text=True,
167 options=[("password hash userPassword schemes",
168 "CryptSHA256:rounds=100")])
170 sc = self.get_supplemental_creds()
172 # Check that we got all the expected supplemental credentials
173 # And they are in the expected order.
174 size = len(sc.sub.packages)
175 self.assertEquals(6, size)
177 (pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
178 self.assertEquals(1, pos)
179 self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
181 (pos, package) = get_package(sc, "Primary:Kerberos")
182 self.assertEquals(2, pos)
183 self.assertEquals("Primary:Kerberos", package.name)
185 (pos, wd_package) = get_package(sc, "Primary:WDigest")
186 self.assertEquals(3, pos)
187 self.assertEquals("Primary:WDigest", wd_package.name)
189 (pos, ct_package) = get_package(sc, "Primary:CLEARTEXT")
190 self.assertEquals(4, pos)
191 self.assertEquals("Primary:CLEARTEXT", ct_package.name)
193 (pos, package) = get_package(sc, "Packages")
194 self.assertEquals(5, pos)
195 self.assertEquals("Packages", package.name)
197 (pos, up_package) = get_package(sc, "Primary:userPassword")
198 self.assertEquals(6, pos)
199 self.assertEquals("Primary:userPassword", up_package.name)
201 # Check that the WDigest values are correct.
203 digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
204 binascii.a2b_hex(wd_package.data))
205 self.check_wdigests(digests)
207 # Check the clear text value is correct.
208 ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
209 binascii.a2b_hex(ct_package.data))
210 self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
212 # Check that the userPassword hashes are computed correctly
214 up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
215 binascii.a2b_hex(up_package.data))
216 self.checkUserPassword(up, [("{CRYPT}", "5", 100)])
217 self.checkNtHash(USER_PASS, up.current_nt_hash.hash)