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 less than 2008 to ensure the kerberos newer keys are not
29 from samba
.tests
.password_hash
import (
34 from samba
.ndr
import ndr_unpack
35 from samba
.dcerpc
import drsblobs
40 class PassWordHashFl2003Tests(PassWordHashTests
):
43 super(PassWordHashFl2003Tests
, self
).setUp()
45 def test_default_supplementalCredentials(self
):
46 self
.add_user(options
=[("password hash userPassword schemes", "")])
48 sc
= self
.get_supplemental_creds()
50 # Check that we got all the expected supplemental credentials
51 # And they are in the expected order.
52 size
= len(sc
.sub
.packages
)
53 self
.assertEquals(3, size
)
55 (pos
, package
) = get_package(sc
, "Primary:Kerberos")
56 self
.assertEquals(1, pos
)
57 self
.assertEquals("Primary:Kerberos", package
.name
)
59 (pos
, package
) = get_package(sc
, "Packages")
60 self
.assertEquals(2, pos
)
61 self
.assertEquals("Packages", package
.name
)
63 (pos
, package
) = get_package(sc
, "Primary:WDigest")
64 self
.assertEquals(3, pos
)
65 self
.assertEquals("Primary:WDigest", package
.name
)
67 # Check that the WDigest values are correct.
69 digests
= ndr_unpack(drsblobs
.package_PrimaryWDigestBlob
,
70 binascii
.a2b_hex(package
.data
))
71 self
.check_wdigests(digests
)
73 def test_userPassword_sha256(self
):
74 self
.add_user(options
=[("password hash userPassword schemes",
77 sc
= self
.get_supplemental_creds()
79 # Check that we got all the expected supplemental credentials
80 # And they are in the expected order.
81 size
= len(sc
.sub
.packages
)
82 self
.assertEquals(4, size
)
84 (pos
, package
) = get_package(sc
, "Primary:Kerberos")
85 self
.assertEquals(1, pos
)
86 self
.assertEquals("Primary:Kerberos", package
.name
)
88 (pos
, wd_package
) = get_package(sc
, "Primary:WDigest")
89 self
.assertEquals(2, pos
)
90 self
.assertEquals("Primary:WDigest", wd_package
.name
)
92 (pos
, package
) = get_package(sc
, "Packages")
93 self
.assertEquals(3, pos
)
94 self
.assertEquals("Packages", package
.name
)
96 (pos
, up_package
) = get_package(sc
, "Primary:userPassword")
97 self
.assertEquals(4, pos
)
98 self
.assertEquals("Primary:userPassword", up_package
.name
)
100 # Check that the WDigest values are correct.
102 digests
= ndr_unpack(drsblobs
.package_PrimaryWDigestBlob
,
103 binascii
.a2b_hex(wd_package
.data
))
104 self
.check_wdigests(digests
)
106 # Check that the userPassword hashes are computed correctly
108 up
= ndr_unpack(drsblobs
.package_PrimaryUserPasswordBlob
,
109 binascii
.a2b_hex(up_package
.data
))
111 self
.checkUserPassword(up
, [("{CRYPT}", "5", None)])
112 self
.checkNtHash(USER_PASS
, up
.current_nt_hash
.hash)
114 def test_supplementalCredentials_cleartext(self
):
115 self
.add_user(clear_text
=True,
116 options
=[("password hash userPassword schemes", "")])
118 sc
= self
.get_supplemental_creds()
120 # Check that we got all the expected supplemental credentials
121 # And they are in the expected order.
122 size
= len(sc
.sub
.packages
)
123 self
.assertEquals(4, size
)
125 (pos
, package
) = get_package(sc
, "Primary:Kerberos")
126 self
.assertEquals(1, pos
)
127 self
.assertEquals("Primary:Kerberos", package
.name
)
129 (pos
, wd_package
) = get_package(sc
, "Primary:WDigest")
130 self
.assertEquals(2, pos
)
131 self
.assertEquals("Primary:WDigest", wd_package
.name
)
133 (pos
, package
) = get_package(sc
, "Packages")
134 self
.assertEquals(3, pos
)
135 self
.assertEquals("Packages", package
.name
)
137 (pos
, ct_package
) = get_package(sc
, "Primary:CLEARTEXT")
138 self
.assertEquals(4, pos
)
139 self
.assertEquals("Primary:CLEARTEXT", ct_package
.name
)
142 # Check that the WDigest values are correct.
144 digests
= ndr_unpack(drsblobs
.package_PrimaryWDigestBlob
,
145 binascii
.a2b_hex(wd_package
.data
))
146 self
.check_wdigests(digests
)
148 # Check the clear text value is correct.
149 ct
= ndr_unpack(drsblobs
.package_PrimaryCLEARTEXTBlob
,
150 binascii
.a2b_hex(ct_package
.data
))
151 self
.assertEquals(USER_PASS
.encode('utf-16-le'), ct
.cleartext
)
153 def test_userPassword_cleartext_sha512(self
):
154 self
.add_user(clear_text
=True,
155 options
=[("password hash userPassword schemes",
156 "CryptSHA512:rounds=10000")])
158 sc
= self
.get_supplemental_creds()
160 # Check that we got all the expected supplemental credentials
161 # And they are in the expected order.
162 size
= len(sc
.sub
.packages
)
163 self
.assertEquals(5, size
)
165 (pos
, package
) = get_package(sc
, "Primary:Kerberos")
166 self
.assertEquals(1, pos
)
167 self
.assertEquals("Primary:Kerberos", package
.name
)
169 (pos
, wd_package
) = get_package(sc
, "Primary:WDigest")
170 self
.assertEquals(2, pos
)
171 self
.assertEquals("Primary:WDigest", wd_package
.name
)
173 (pos
, ct_package
) = get_package(sc
, "Primary:CLEARTEXT")
174 self
.assertEquals(3, pos
)
175 self
.assertEquals("Primary:CLEARTEXT", ct_package
.name
)
177 (pos
, package
) = get_package(sc
, "Packages")
178 self
.assertEquals(4, pos
)
179 self
.assertEquals("Packages", package
.name
)
181 (pos
, up_package
) = get_package(sc
, "Primary:userPassword")
182 self
.assertEquals(5, pos
)
183 self
.assertEquals("Primary:userPassword", up_package
.name
)
185 # Check that the WDigest values are correct.
187 digests
= ndr_unpack(drsblobs
.package_PrimaryWDigestBlob
,
188 binascii
.a2b_hex(wd_package
.data
))
189 self
.check_wdigests(digests
)
191 # Check the clear text value is correct.
192 ct
= ndr_unpack(drsblobs
.package_PrimaryCLEARTEXTBlob
,
193 binascii
.a2b_hex(ct_package
.data
))
194 self
.assertEquals(USER_PASS
.encode('utf-16-le'), ct
.cleartext
)
196 # Check that the userPassword hashes are computed correctly
198 up
= ndr_unpack(drsblobs
.package_PrimaryUserPasswordBlob
,
199 binascii
.a2b_hex(up_package
.data
))
200 self
.checkUserPassword(up
, [("{CRYPT}", "6",10000 )])
201 self
.checkNtHash(USER_PASS
, up
.current_nt_hash
.hash)