mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
tests password_hash: add tests for Primary:userPassword
Add tests to verify the generation and storage of sha256 and sha512 password hashes in suplementalCredentials Primary:userPassword Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> Reviewed-by: Garming Sam <garming@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
79f027a610
commit
de5299d155
@ -33,6 +33,7 @@ import ldb
|
||||
import samba
|
||||
import binascii
|
||||
import md5
|
||||
import crypt
|
||||
|
||||
|
||||
USER_NAME = "PasswordHashTestUser"
|
||||
@ -287,3 +288,36 @@ class PassWordHashTests(TestCase):
|
||||
"Digest",
|
||||
USER_PASS,
|
||||
digests.hashes[28].hash)
|
||||
|
||||
|
||||
def checkUserPassword(self, up, expected):
|
||||
|
||||
# Check we've received the correct number of hashes
|
||||
self.assertEquals(len(expected), up.num_hashes)
|
||||
|
||||
i = 0
|
||||
for (tag, alg, rounds) in expected:
|
||||
self.assertEquals(tag, up.hashes[i].scheme)
|
||||
|
||||
data = up.hashes[i].value.split("$")
|
||||
# Check we got the expected crypt algorithm
|
||||
self.assertEquals(alg, data[1])
|
||||
|
||||
if rounds is None:
|
||||
cmd = "$%s$%s" % (alg, data[2])
|
||||
else:
|
||||
cmd = "$%s$rounds=%d$%s" % (alg, rounds, data[3])
|
||||
|
||||
# Calculate the expected hash value
|
||||
expected = crypt.crypt(USER_PASS, cmd)
|
||||
self.assertEquals(expected, up.hashes[i].value)
|
||||
i += 1
|
||||
|
||||
# Check that the correct nt_hash was stored for userPassword
|
||||
def checkNtHash(self, password, nt_hash):
|
||||
creds = Credentials()
|
||||
creds.set_anonymous()
|
||||
creds.set_password(password)
|
||||
expected = creds.get_nt_hash()
|
||||
actual = bytearray(nt_hash)
|
||||
self.assertEquals(expected, actual)
|
||||
|
@ -36,13 +36,14 @@ from samba.dcerpc import drsblobs
|
||||
import binascii
|
||||
|
||||
|
||||
|
||||
class PassWordHashFl2003Tests(PassWordHashTests):
|
||||
|
||||
def setUp(self):
|
||||
super(PassWordHashFl2003Tests, self).setUp()
|
||||
|
||||
def test_default_supplementalCredentials(self):
|
||||
self.add_user()
|
||||
self.add_user(options=[("password hash userPassword schemes", "")])
|
||||
|
||||
sc = self.get_supplemental_creds()
|
||||
|
||||
@ -69,8 +70,50 @@ class PassWordHashFl2003Tests(PassWordHashTests):
|
||||
binascii.a2b_hex(package.data))
|
||||
self.check_wdigests(digests)
|
||||
|
||||
def test_userPassword_sha256(self):
|
||||
self.add_user(options=[("password hash userPassword schemes",
|
||||
"CryptSHA256")])
|
||||
|
||||
sc = self.get_supplemental_creds()
|
||||
|
||||
# Check that we got all the expected supplemental credentials
|
||||
# And they are in the expected order.
|
||||
size = len(sc.sub.packages)
|
||||
self.assertEquals(4, size)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos")
|
||||
self.assertEquals(1, pos)
|
||||
self.assertEquals("Primary:Kerberos", package.name)
|
||||
|
||||
(pos, wd_package) = get_package(sc, "Primary:WDigest")
|
||||
self.assertEquals(2, pos)
|
||||
self.assertEquals("Primary:WDigest", wd_package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Packages")
|
||||
self.assertEquals(3, pos)
|
||||
self.assertEquals("Packages", package.name)
|
||||
|
||||
(pos, up_package) = get_package(sc, "Primary:userPassword")
|
||||
self.assertEquals(4, pos)
|
||||
self.assertEquals("Primary:userPassword", up_package.name)
|
||||
|
||||
# Check that the WDigest values are correct.
|
||||
#
|
||||
digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
|
||||
binascii.a2b_hex(wd_package.data))
|
||||
self.check_wdigests(digests)
|
||||
|
||||
# Check that the userPassword hashes are computed correctly
|
||||
#
|
||||
up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
|
||||
binascii.a2b_hex(up_package.data))
|
||||
|
||||
self.checkUserPassword(up, [("{CRYPT}", "5", None)])
|
||||
self.checkNtHash(USER_PASS, up.current_nt_hash.hash)
|
||||
|
||||
def test_supplementalCredentials_cleartext(self):
|
||||
self.add_user(clear_text=True)
|
||||
self.add_user(clear_text=True,
|
||||
options=[("password hash userPassword schemes", "")])
|
||||
|
||||
sc = self.get_supplemental_creds()
|
||||
|
||||
@ -95,6 +138,7 @@ class PassWordHashFl2003Tests(PassWordHashTests):
|
||||
self.assertEquals(4, pos)
|
||||
self.assertEquals("Primary:CLEARTEXT", ct_package.name)
|
||||
|
||||
|
||||
# Check that the WDigest values are correct.
|
||||
#
|
||||
digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
|
||||
@ -105,3 +149,53 @@ class PassWordHashFl2003Tests(PassWordHashTests):
|
||||
ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
|
||||
binascii.a2b_hex(ct_package.data))
|
||||
self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
|
||||
|
||||
def test_userPassword_cleartext_sha512(self):
|
||||
self.add_user(clear_text=True,
|
||||
options=[("password hash userPassword schemes",
|
||||
"CryptSHA512:rounds=10000")])
|
||||
|
||||
sc = self.get_supplemental_creds()
|
||||
|
||||
# Check that we got all the expected supplemental credentials
|
||||
# And they are in the expected order.
|
||||
size = len(sc.sub.packages)
|
||||
self.assertEquals(5, size)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos")
|
||||
self.assertEquals(1, pos)
|
||||
self.assertEquals("Primary:Kerberos", package.name)
|
||||
|
||||
(pos, wd_package) = get_package(sc, "Primary:WDigest")
|
||||
self.assertEquals(2, pos)
|
||||
self.assertEquals("Primary:WDigest", wd_package.name)
|
||||
|
||||
(pos, ct_package) = get_package(sc, "Primary:CLEARTEXT")
|
||||
self.assertEquals(3, pos)
|
||||
self.assertEquals("Primary:CLEARTEXT", ct_package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Packages")
|
||||
self.assertEquals(4, pos)
|
||||
self.assertEquals("Packages", package.name)
|
||||
|
||||
(pos, up_package) = get_package(sc, "Primary:userPassword")
|
||||
self.assertEquals(5, pos)
|
||||
self.assertEquals("Primary:userPassword", up_package.name)
|
||||
|
||||
# Check that the WDigest values are correct.
|
||||
#
|
||||
digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
|
||||
binascii.a2b_hex(wd_package.data))
|
||||
self.check_wdigests(digests)
|
||||
|
||||
# Check the clear text value is correct.
|
||||
ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
|
||||
binascii.a2b_hex(ct_package.data))
|
||||
self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
|
||||
|
||||
# Check that the userPassword hashes are computed correctly
|
||||
#
|
||||
up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
|
||||
binascii.a2b_hex(up_package.data))
|
||||
self.checkUserPassword(up, [("{CRYPT}", "6",10000 )])
|
||||
self.checkNtHash(USER_PASS, up.current_nt_hash.hash)
|
||||
|
@ -71,6 +71,50 @@ class PassWordHashFl2008Tests(PassWordHashTests):
|
||||
binascii.a2b_hex(package.data))
|
||||
self.check_wdigests(digests)
|
||||
|
||||
def test_userPassword_sha512(self):
|
||||
self.add_user(options=[("password hash userPassword schemes",
|
||||
"CryptSHA512")])
|
||||
|
||||
sc = self.get_supplemental_creds()
|
||||
|
||||
# Check that we got all the expected supplemental credentials
|
||||
# And they are in the expected order.
|
||||
size = len(sc.sub.packages)
|
||||
self.assertEquals(5, size)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
|
||||
self.assertEquals(1, pos)
|
||||
self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos")
|
||||
self.assertEquals(2, pos)
|
||||
self.assertEquals("Primary:Kerberos", package.name)
|
||||
|
||||
(pos, wp_package) = get_package(sc, "Primary:WDigest")
|
||||
self.assertEquals(3, pos)
|
||||
self.assertEquals("Primary:WDigest", wp_package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Packages")
|
||||
self.assertEquals(4, pos)
|
||||
self.assertEquals("Packages", package.name)
|
||||
|
||||
(pos, up_package) = get_package(sc, "Primary:userPassword")
|
||||
self.assertEquals(5, pos)
|
||||
self.assertEquals("Primary:userPassword", up_package.name)
|
||||
|
||||
# Check that the WDigest values are correct.
|
||||
#
|
||||
digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
|
||||
binascii.a2b_hex(wp_package.data))
|
||||
self.check_wdigests(digests)
|
||||
|
||||
# Check that the userPassword hashes are computed correctly
|
||||
#
|
||||
up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
|
||||
binascii.a2b_hex(up_package.data))
|
||||
self.checkUserPassword(up, [("{CRYPT}", "6",None)])
|
||||
self.checkNtHash(USER_PASS, up.current_nt_hash.hash)
|
||||
|
||||
def test_supplementalCredentials_cleartext(self):
|
||||
self.add_user(clear_text=True)
|
||||
|
||||
@ -110,3 +154,57 @@ class PassWordHashFl2008Tests(PassWordHashTests):
|
||||
ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
|
||||
binascii.a2b_hex(ct_package.data))
|
||||
self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
|
||||
|
||||
def test_userPassword_cleartext_sha256(self):
|
||||
self.add_user(clear_text=True,
|
||||
options=[("password hash userPassword schemes",
|
||||
"CryptSHA256:rounds=100")])
|
||||
|
||||
sc = self.get_supplemental_creds()
|
||||
|
||||
# Check that we got all the expected supplemental credentials
|
||||
# And they are in the expected order.
|
||||
size = len(sc.sub.packages)
|
||||
self.assertEquals(6, size)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
|
||||
self.assertEquals(1, pos)
|
||||
self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos")
|
||||
self.assertEquals(2, pos)
|
||||
self.assertEquals("Primary:Kerberos", package.name)
|
||||
|
||||
(pos, wd_package) = get_package(sc, "Primary:WDigest")
|
||||
self.assertEquals(3, pos)
|
||||
self.assertEquals("Primary:WDigest", wd_package.name)
|
||||
|
||||
(pos, ct_package) = get_package(sc, "Primary:CLEARTEXT")
|
||||
self.assertEquals(4, pos)
|
||||
self.assertEquals("Primary:CLEARTEXT", ct_package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Packages")
|
||||
self.assertEquals(5, pos)
|
||||
self.assertEquals("Packages", package.name)
|
||||
|
||||
(pos, up_package) = get_package(sc, "Primary:userPassword")
|
||||
self.assertEquals(6, pos)
|
||||
self.assertEquals("Primary:userPassword", up_package.name)
|
||||
|
||||
# Check that the WDigest values are correct.
|
||||
#
|
||||
digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
|
||||
binascii.a2b_hex(wd_package.data))
|
||||
self.check_wdigests(digests)
|
||||
|
||||
# Check the clear text value is correct.
|
||||
ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
|
||||
binascii.a2b_hex(ct_package.data))
|
||||
self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
|
||||
|
||||
# Check that the userPassword hashes are computed correctly
|
||||
#
|
||||
up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
|
||||
binascii.a2b_hex(up_package.data))
|
||||
self.checkUserPassword(up, [("{CRYPT}", "5",100 )])
|
||||
self.checkNtHash(USER_PASS, up.current_nt_hash.hash)
|
||||
|
@ -124,3 +124,109 @@ class PassWordHashGpgmeTests(PassWordHashTests):
|
||||
ct = ndr_unpack(drsblobs.package_PrimaryCLEARTEXTBlob,
|
||||
binascii.a2b_hex(ct_package.data))
|
||||
self.assertEquals(USER_PASS.encode('utf-16-le'), ct.cleartext)
|
||||
|
||||
def test_userPassword_multiple_hashes(self):
|
||||
self.add_user(options=[(
|
||||
"password hash userPassword schemes",
|
||||
"CryptSHA512 CryptSHA256 CryptSHA512")])
|
||||
|
||||
sc = self.get_supplemental_creds()
|
||||
|
||||
# Check that we got all the expected supplemental credentials
|
||||
# And they are in the expected order.
|
||||
size = len(sc.sub.packages)
|
||||
self.assertEquals(6, size)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
|
||||
self.assertEquals(1, pos)
|
||||
self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos")
|
||||
self.assertEquals(2, pos)
|
||||
self.assertEquals("Primary:Kerberos", package.name)
|
||||
|
||||
(pos, wp_package) = get_package(sc, "Primary:WDigest")
|
||||
self.assertEquals(3, pos)
|
||||
self.assertEquals("Primary:WDigest", wp_package.name)
|
||||
|
||||
(pos, up_package) = get_package(sc, "Primary:userPassword")
|
||||
self.assertEquals(4, pos)
|
||||
self.assertEquals("Primary:userPassword", up_package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Packages")
|
||||
self.assertEquals(5, pos)
|
||||
self.assertEquals("Packages", package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:SambaGPG")
|
||||
self.assertEquals(6, pos)
|
||||
self.assertEquals("Primary:SambaGPG", package.name)
|
||||
|
||||
# Check that the WDigest values are correct.
|
||||
#
|
||||
digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
|
||||
binascii.a2b_hex(wp_package.data))
|
||||
self.check_wdigests(digests)
|
||||
|
||||
# Check that the userPassword hashes are computed correctly
|
||||
# Expect three hashes to be calculated
|
||||
up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
|
||||
binascii.a2b_hex(up_package.data))
|
||||
self.checkUserPassword(up, [
|
||||
("{CRYPT}", "6", None),
|
||||
("{CRYPT}", "5", None),
|
||||
("{CRYPT}", "6", None)
|
||||
])
|
||||
self.checkNtHash(USER_PASS, up.current_nt_hash.hash)
|
||||
|
||||
def test_userPassword_multiple_hashes_rounds_specified(self):
|
||||
self.add_user(options=[(
|
||||
"password hash userPassword schemes",
|
||||
"CryptSHA512:rounds=5120 CryptSHA256:rounds=2560 CryptSHA512:rounds=5122")])
|
||||
|
||||
sc = self.get_supplemental_creds()
|
||||
|
||||
# Check that we got all the expected supplemental credentials
|
||||
# And they are in the expected order.
|
||||
size = len(sc.sub.packages)
|
||||
self.assertEquals(6, size)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos-Newer-Keys")
|
||||
self.assertEquals(1, pos)
|
||||
self.assertEquals("Primary:Kerberos-Newer-Keys", package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:Kerberos")
|
||||
self.assertEquals(2, pos)
|
||||
self.assertEquals("Primary:Kerberos", package.name)
|
||||
|
||||
(pos, wp_package) = get_package(sc, "Primary:WDigest")
|
||||
self.assertEquals(3, pos)
|
||||
self.assertEquals("Primary:WDigest", wp_package.name)
|
||||
|
||||
(pos, up_package) = get_package(sc, "Primary:userPassword")
|
||||
self.assertEquals(4, pos)
|
||||
self.assertEquals("Primary:userPassword", up_package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Packages")
|
||||
self.assertEquals(5, pos)
|
||||
self.assertEquals("Packages", package.name)
|
||||
|
||||
(pos, package) = get_package(sc, "Primary:SambaGPG")
|
||||
self.assertEquals(6, pos)
|
||||
self.assertEquals("Primary:SambaGPG", package.name)
|
||||
|
||||
# Check that the WDigest values are correct.
|
||||
#
|
||||
digests = ndr_unpack(drsblobs.package_PrimaryWDigestBlob,
|
||||
binascii.a2b_hex(wp_package.data))
|
||||
self.check_wdigests(digests)
|
||||
|
||||
# Check that the userPassword hashes are computed correctly
|
||||
# Expect three hashes to be calculated
|
||||
up = ndr_unpack(drsblobs.package_PrimaryUserPasswordBlob,
|
||||
binascii.a2b_hex(up_package.data))
|
||||
self.checkUserPassword(up, [
|
||||
("{CRYPT}", "6", 5120),
|
||||
("{CRYPT}", "5", 2560),
|
||||
("{CRYPT}", "6", 5122)
|
||||
])
|
||||
self.checkNtHash(USER_PASS, up.current_nt_hash.hash)
|
||||
|
@ -330,3 +330,12 @@
|
||||
# We currently don't send referrals for LDAP modify of non-replicated attrs
|
||||
^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.*
|
||||
^samba4.ldap.rodc_rwdc.python.*.__main__.RodcRwdcTests.test_change_password_reveal_on_demand_kerberos
|
||||
# Tests for password hash supplemental credentials, userPassword hashes
|
||||
# Will fail as the implementation has not been written
|
||||
#
|
||||
^samba.tests.password_hash_gpgme.samba.tests.password_hash_gpgme.PassWordHashGpgmeTests.test_userPassword_multiple_hashes\(ad_dc:local\)
|
||||
^samba.tests.password_hash_gpgme.samba.tests.password_hash_gpgme.PassWordHashGpgmeTests.test_userPassword_multiple_hashes_rounds_specified\(ad_dc:local\)
|
||||
^samba.tests.password_hash_fl2008.samba.tests.password_hash_fl2008.PassWordHashFl2008Tests.test_userPassword_cleartext_sha256\(ad_dc_ntvfs:local\)
|
||||
^samba.tests.password_hash_fl2008.samba.tests.password_hash_fl2008.PassWordHashFl2008Tests.test_userPassword_sha512\(ad_dc_ntvfs:local\)
|
||||
^samba.tests.password_hash_fl2003.samba.tests.password_hash_fl2003.PassWordHashFl2003Tests.test_userPassword_cleartext_sha512\(fl2003dc:local\)
|
||||
^samba.tests.password_hash_fl2003.samba.tests.password_hash_fl2003.PassWordHashFl2003Tests.test_userPassword_sha256\(fl2003dc:local\)
|
||||
|
Loading…
Reference in New Issue
Block a user