diff --git a/add-sm3-crypt-support.patch b/add-sm3-crypt-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..0cb3508fb86e7c624209c000c54403617b6faed4 --- /dev/null +++ b/add-sm3-crypt-support.patch @@ -0,0 +1,626 @@ +From 4c77b98870ee4b2c3bd49e00205cca22689c0e53 Mon Sep 17 00:00:00 2001 +From: lujie42 +Date: Fri, 29 Oct 2021 15:56:12 +0800 +Subject: [PATCH] add sm3 crypt support + +Signed-off-by: lujie42 +Signed-off-by: luhuaxin <1539327763@qq.com> +--- + Makefile.am | 3 +- + docs/libuser.conf.5.in | 4 +- + lib/util.c | 4 +- + tests/files_sm3.conf.in | 25 +++ + tests/sm3_test | 43 +++++ + tests/sm3_test.py | 446 ++++++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 521 insertions(+), 4 deletions(-) + create mode 100644 tests/files_sm3.conf.in + create mode 100755 tests/sm3_test + create mode 100755 tests/sm3_test.py + +diff --git a/Makefile.am b/Makefile.am +index 9f099bd..8977c45 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -26,7 +26,7 @@ VG_ENVIRONMENT = G_SLICE=always-malloc \ + ## Targets + SUBDIRS = po docs + TESTS = tests/config_test.sh tests/fs_test tests/files_test tests/pwhash_test \ +- tests/utils_test ++ tests/utils_test tests/sm3_test + if LDAP + TESTS += tests/default_pw_test tests/ldap_test + endif +@@ -40,6 +40,7 @@ EXTRA_DIST = \ + tests/config_login.defs tests/config_login2.defs \ + tests/config_override.conf.in tests/config_test.py \ + tests/config_test.sh \ ++ tests/files_sm3.conf.in tests/sm3_test tests/sm3_test.py \ + tests/default_pw.conf.in tests/default_pw_test tests/default_pw_test.py \ + tests/files.conf.in tests/files_test tests/files_test.py \ + tests/fs.conf.in tests/fs_test tests/fs_test.py \ +diff --git a/docs/libuser.conf.5.in b/docs/libuser.conf.5.in +index bd1daa7..bdd1384 100644 +--- a/docs/libuser.conf.5.in ++++ b/docs/libuser.conf.5.in +@@ -68,7 +68,7 @@ The algorithm to use for password encryption when creating new passwords. + The current algorithm may be retained + when changing a password of an existing user, depending on the application. + +-Possible values are \fBdes\fR, \fBmd5\fR, \fBblowfish\fR, ++Possible values are \fBdes\fR, \fBmd5\fR, \fBblowfish\fR, \fBsm3\fR + .B sha256, + \fBsha512\fR, and \fByescrypt\fR, all case-insensitive. + Unrecognized values are treated as \fBdes\fR. +@@ -80,7 +80,7 @@ These variables specify an inclusive range of hash rounds used when + .B crypt_style + is + .B sha256 +-or \fBsha512\fR. ++or \fBsha512\fR or \fBsm3\fR. + A number of hash rounds is chosen from this interval randomly. + A larger number of rounds makes password checking, and brute-force attempts + to guess the password by reversing the hash, more CPU-intensive. +diff --git a/lib/util.c b/lib/util.c +index bba9420..354a991 100644 +--- a/lib/util.c ++++ b/lib/util.c +@@ -134,7 +134,7 @@ fill_urandom(char *output, size_t length) + #endif + + static const struct { +- const char initial[5]; ++ const char initial[6]; + char separator[2]; + size_t salt_length; + gboolean sha_rounds; +@@ -144,6 +144,7 @@ static const struct { + {"$2b$", "$", 8, FALSE }, + {"$5$", "$", 16, TRUE }, + {"$6$", "$", 16, TRUE }, ++ {"$sm3$", "$", 16, TRUE }, + #if HAVE_YESCRYPT + {"$y$", "$", 24, FALSE }, + #endif +@@ -275,6 +276,7 @@ lu_util_default_salt_specifier(struct lu_context *context) + { "blowfish", "$2b$", FALSE }, + { "sha256", "$5$", TRUE }, + { "sha512", "$6$", TRUE }, ++ { "sm3", "$sm3$", TRUE }, + #if HAVE_YESCRYPT + { "yescrypt", "$y$", FALSE }, + #endif +diff --git a/tests/files_sm3.conf.in b/tests/files_sm3.conf.in +new file mode 100644 +index 0000000..3831d0f +--- /dev/null ++++ b/tests/files_sm3.conf.in +@@ -0,0 +1,25 @@ ++[defaults] ++# non-portable ++moduledir = @TOP_BUILDDIR@/modules/.libs ++skeleton = /etc/skel ++mailspooldir = /var/mail ++modules = files shadow ++create_modules = files shadow ++crypt_style = sm3 ++ ++[userdefaults] ++LU_USERNAME = %n ++LU_UIDNUMBER = 500 ++LU_GIDNUMBER = %u ++ ++[groupdefaults] ++LU_GROUPNAME = %n ++LU_GIDNUMBER = 500 ++ ++[files] ++directory = @WORKDIR@/sm3 ++nonroot = yes ++ ++[shadow] ++directory = @WORKDIR@/sm3 ++nonroot = yes +diff --git a/tests/sm3_test b/tests/sm3_test +new file mode 100755 +index 0000000..bdb2034 +--- /dev/null ++++ b/tests/sm3_test +@@ -0,0 +1,43 @@ ++#!/bin/bash ++# Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. ++# Description: Automated files/shadow regression tester for sm3 crypt ++# Create: 2021-07-26 ++ ++srcdir=$srcdir/tests ++ ++workdir=$(pwd)/test_sm3 ++ ++trap 'status=$?; rm -rf "$workdir"; exit $status' 0 ++trap '(exit 1); exit 1' 1 2 13 15 ++ ++rm -rf "$workdir" ++mkdir "$workdir" ++ ++# Set up an the environment ++mkdir "$workdir"/sm3 ++ ++cat > "$workdir"/sm3/passwd <<\EOF ++empty_user::42:43::: ++EOF ++cat > "$workdir"/sm3/shadow <<\EOF ++empty_user:::::::: ++EOF ++cat > "$workdir"/sm3/group <<\EOF ++empty_group::44: ++EOF ++cat > "$workdir"/sm3/gshadow <<\EOF ++empty_group::: ++EOF ++ ++# Set up the client ++LIBUSER_CONF=$workdir/libuser.conf ++export LIBUSER_CONF ++sed "s|@WORKDIR@|$workdir|g; s|@TOP_BUILDDIR@|$(pwd)|g" \ ++ < "$srcdir"/files_sm3.conf.in > "$LIBUSER_CONF" ++# Ugly non-portable hacks ++LD_LIBRARY_PATH=$(pwd)/lib/.libs ++export LD_LIBRARY_PATH ++PYTHONPATH=$(pwd)/python/.libs ++export PYTHONPATH ++ ++workdir="$workdir" $VALGRIND $PYTHON "$srcdir"/sm3_test.py +diff --git a/tests/sm3_test.py b/tests/sm3_test.py +new file mode 100755 +index 0000000..e680dd7 +--- /dev/null ++++ b/tests/sm3_test.py +@@ -0,0 +1,446 @@ ++#!/usr/bin/python ++# Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. ++# Description: sm3 crypt testcase ++# Create: 2021-07-26 ++ ++import crypt ++import libuser ++import os ++import os.path ++import sys ++import unittest ++ ++#sm3 ++crypt_flag="$sm3$" ++crypt_flag_len=5 ++crypt_t="sm3" ++ ++ ++class Tests(unittest.TestCase): ++ def setUp(self): ++ self.a = libuser.admin() ++ ++ def testSm3UserLock1(self): ++ e = self.a.initUser('user100_1') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user100_1') ++ self.a.setpassUser(e, '00as1wm0AZG56', True) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['00as1wm0AZG56']) ++ self.a.lockUser(e) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!00as1wm0AZG56']) ++ ++ def testSm3UserLock2(self): ++ e = self.a.initUser('user100_2') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user100_2') ++ self.a.setpassUser(e, 'HABAG_12=%', False) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ self.a.lockUser(e) ++ del e ++ e = self.a.lookupUserByName('user100_2') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:2 + crypt_flag_len], '!!' + crypt_flag) ++ ++ def testSm3UserUnlock1(self): ++ e = self.a.initUser('user101_1') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user101_1') ++ self.a.setpassUser(e, '!!00as1wm0AZG56', True) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!00as1wm0AZG56']) ++ self.a.unlockUser(e) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['00as1wm0AZG56']) ++ ++ def testSm3UserUnlock2(self): ++ e = self.a.initUser('user101_2') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user101_2') ++ self.a.setpassUser(e, '00as1wm0AZG56', True) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['00as1wm0AZG56']) ++ self.a.unlockUser(e) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['00as1wm0AZG56']) ++ ++ def testSm3UserUnlock3(self): ++ e = self.a.initUser('user101_3') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user101_3') ++ self.a.setpassUser(e, 'HABAG_12=%', False) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ self.a.lockUser(e) ++ del e ++ e = self.a.lookupUserByName('user101_3') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:2 + crypt_flag_len], '!!' + crypt_flag) ++ self.a.unlockUser(e) ++ del e ++ e = self.a.lookupUserByName('user101_3') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ ++ def testSm3UserUnlockNonempty1(self): ++ e = self.a.initUser('user102_1') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user102_1') ++ self.a.setpassUser(e, '!!00as1wm0AZG56', True) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!00as1wm0AZG56']) ++ self.a.unlockUser(e, True) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['00as1wm0AZG56']) ++ ++ def testSm3UserUnlockNonempty2(self): ++ e = self.a.initUser('user102_2') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user102_2') ++ self.a.setpassUser(e, 'GJMK12#@', False) ++ ++ del e ++ e = self.a.lookupUserByName('user102_2') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ self.a.lockUser(e) ++ del e ++ e = self.a.lookupUserByName('user102_2') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:2 + crypt_flag_len], '!!' + crypt_flag) ++ self.a.unlockUser(e, True) ++ del e ++ e = self.a.lookupUserByName('user102_2') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ ++ def testSm3UserUnlockNonempty3(self): ++ e = self.a.initUser('user102_3') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user102_3') ++ self.a.setpassUser(e, '!!', True) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!']) ++ self.assertRaises(RuntimeError, self.a.unlockUser, e, True) ++ del e ++ e = self.a.lookupUserByName('user102_3') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!']) ++ ++ ++ def testSm3UserSetpass1(self): ++ e = self.a.initUser('user103_1') ++ e[libuser.SHADOWPASSWORD] = '02oawyZdjhhpg' ++ e[libuser.SHADOWLASTCHANGE] = 100 ++ self.a.addUser(e, False, False) ++ ++ del e ++ e = self.a.lookupUserByName('user103_1') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['02oawyZdjhhpg']) ++ self.assertEqual(e[libuser.SHADOWLASTCHANGE], [100]) ++ self.a.setpassUser(e, 'password', False) ++ del e ++ e = self.a.lookupUserByName('user103_1') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ crypted = crypt.crypt('password', e[libuser.SHADOWPASSWORD][0]) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], [crypted]) ++ self.assertGreater(e[libuser.SHADOWLASTCHANGE][0], 10000) ++ ++ ++ def testSm3UserSetpass2(self): ++ # Forcing the non-shadow password to 'x' ++ e = self.a.initUser('user103_2') ++ e[libuser.USERPASSWORD] = '*' ++ e[libuser.SHADOWPASSWORD] = '08lnuxCM.c36E' ++ self.a.addUser(e, False, False) ++ ++ del e ++ # shadow module's addUser forces USERPASSWORD to 'x' ++ e = self.a.lookupUserByName('user103_2') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['08lnuxCM.c36E']) ++ e[libuser.USERPASSWORD] = '*' ++ self.a.modifyUser(e, False) ++ ++ del e ++ e = self.a.lookupUserByName('user103_2') ++ self.assertEqual(e[libuser.USERPASSWORD], ['*']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['08lnuxCM.c36E']) ++ self.a.setpassUser(e, 'password', False) ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ crypted = crypt.crypt('password', e[libuser.SHADOWPASSWORD][0]) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], [crypted]) ++ ++ ++ def testSm3UserSetpass3(self): ++ # ':' in field value ++ e = self.a.initUser('user103_3') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user103_3') ++ self.assertNotIn(':', e[libuser.SHADOWPASSWORD][0]) ++ self.assertRaises(SystemError, self.a.setpassUser, e, 'a:b', True) ++ self.a.setpassUser(e, 'a:b', False) ++ del e ++ e = self.a.lookupUserByName('user103_3') ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ self.assertNotIn(':', e[libuser.SHADOWPASSWORD][0]) ++ crypted = crypt.crypt('a:b', e[libuser.SHADOWPASSWORD][0]) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], [crypted]) ++ ++ ++ def testSm3UserRemovepass1(self): ++ e = self.a.initUser('user104_1') ++ e[libuser.SHADOWPASSWORD] = '03dgZm5nZvqOc' ++ e[libuser.SHADOWLASTCHANGE] = 100 ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user104_1') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['03dgZm5nZvqOc']) ++ self.assertEqual(e[libuser.SHADOWLASTCHANGE], [100]) ++ self.a.removepassUser(e) ++ del e ++ e = self.a.lookupUserByName('user104_1') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['']) ++ self.assertGreater(e[libuser.SHADOWLASTCHANGE][0], 10000) ++ ++ def testSm3UserRemovepass2(self): ++ e = self.a.initUser('user104_2') ++ self.a.addUser(e, False, False) ++ del e ++ e = self.a.lookupUserByName('user104_2') ++ self.a.setpassUser(e, 'ABc123', False) ++ del e ++ e = self.a.lookupUserByName('user104_2') ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ self.a.removepassUser(e) ++ del e ++ e = self.a.lookupUserByName('user104_2') ++ self.assertEqual(e[libuser.USERPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['']) ++ ++ ++ def testSm3GroupLock1(self): ++ e = self.a.initGroup('group100_1') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group100_1') ++ self.a.setpassGroup(e, '04cmES7HM6wtg', True) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['04cmES7HM6wtg']) ++ self.a.lockGroup(e) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!04cmES7HM6wtg']) ++ ++ def testSm3GroupLock2(self): ++ e = self.a.initGroup('group100_2') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group100_2') ++ self.a.setpassGroup(e, '!!04cmES7HM6wtg', True) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!04cmES7HM6wtg']) ++ self.a.lockGroup(e) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!04cmES7HM6wtg']) ++ ++ def testSm3GroupLock3(self): ++ e = self.a.initGroup('group100_3') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group100_3') ++ self.a.setpassGroup(e, 'ABc123MTK', False) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ self.a.lockGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group100_3') ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:2 + crypt_flag_len], '!!' + crypt_flag) ++ ++ def testSm3GroupUnlock1(self): ++ e = self.a.initGroup('group101_1') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group101_1') ++ self.a.setpassGroup(e, '!!04cmES7HM6wtg', True) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!04cmES7HM6wtg']) ++ self.a.unlockGroup(e) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['04cmES7HM6wtg']) ++ ++ def testSm3GroupUnlock2(self): ++ e = self.a.initGroup('group101_2') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group101_2') ++ self.a.setpassGroup(e, '04cmES7HM6wtg', True) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['04cmES7HM6wtg']) ++ self.a.unlockGroup(e) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['04cmES7HM6wtg']) ++ ++ def testSm3GroupUnlock3(self): ++ e = self.a.initGroup('group101_3') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group101_3') ++ self.a.setpassGroup(e, 'axbc12#=', False) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ self.a.lockGroup(e) ++ self.a.unlockGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group101_3') ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ ++ def testSm3GroupUnlockNonempty1(self): ++ e = self.a.initGroup('group102_1') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group102_1') ++ self.a.setpassGroup(e, '!!04cmES7HM6wtg', True) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!04cmES7HM6wtg']) ++ self.a.unlockGroup(e, True) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['04cmES7HM6wtg']) ++ ++ def testSm3GroupUnlockNonempty2(self): ++ e = self.a.initGroup('group102_2') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group102_2') ++ self.a.setpassGroup(e, '04cmES7HM6wtg', True) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['04cmES7HM6wtg']) ++ self.a.unlockGroup(e) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['04cmES7HM6wtg']) ++ ++ def testSm3GroupUnlockNonempty3(self): ++ e = self.a.initGroup('group102_3') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group102_3') ++ self.a.setpassGroup(e, 'a9ld3dabd', False) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ del e ++ e = self.a.lookupGroupByName('group102_3') ++ self.a.lockGroup(e) ++ self.a.unlockGroup(e) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ ++ def testSm3GroupUnlockNonempty4(self): ++ e = self.a.initGroup('group102_4') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group102_4') ++ self.a.setpassGroup(e, '!!', True) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!']) ++ self.assertRaises(RuntimeError, self.a.unlockGroup, e, True) ++ del e ++ e = self.a.lookupGroupByName('group102_4') ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['!!']) ++ ++ def testSm3GroupSetpass1(self): ++ e = self.a.initGroup('group103_1') ++ e[libuser.SHADOWPASSWORD] = '06aZrb3pzuu/6' ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group103_1') ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['06aZrb3pzuu/6']) ++ self.a.setpassGroup(e, 'password', False) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ crypted = crypt.crypt('password', e[libuser.SHADOWPASSWORD][0]) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], [crypted]) ++ ++ def testSm3GroupSetpass2(self): ++ # Forcing the non-shadow password to 'x' ++ e = self.a.initGroup('group103_2') ++ e[libuser.GROUPPASSWORD] = '*' ++ e[libuser.SHADOWPASSWORD] = '07ZZy2Pihe/gg' ++ self.a.addGroup(e) ++ del e ++ # shadow module's addGroup forces GROUPPASSWORD to 'x' ++ e = self.a.lookupGroupByName('group103_2') ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['07ZZy2Pihe/gg']) ++ e[libuser.GROUPPASSWORD] = '*' ++ self.a.modifyGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group103_2') ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['*']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['07ZZy2Pihe/gg']) ++ self.a.setpassGroup(e, 'password', False) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ crypted = crypt.crypt('password', e[libuser.SHADOWPASSWORD][0]) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], [crypted]) ++ ++ def testSm3GroupSetpass3(self): ++ # Forcing the non-shadow password to 'x' ++ e = self.a.initGroup('group103_3') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group103_3') ++ self.a.setpassGroup(e, 'ad#la03/8da', True) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['ad#la03/8da']) ++ ++ def testSm3GroupRemovepass1(self): ++ e = self.a.initGroup('group104_1') ++ e[libuser.SHADOWPASSWORD] = '07Js7N.eEhbgs' ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group104_1') ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['07Js7N.eEhbgs']) ++ self.a.removepassGroup(e) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['']) ++ ++ def testSm3GroupRemovepass2(self): ++ e = self.a.initGroup('group104_2') ++ self.a.addGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group104_2') ++ self.a.setpassGroup(e, 'ad#la03/8da', False) ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD][0][:crypt_flag_len], crypt_flag) ++ self.a.removepassGroup(e) ++ del e ++ e = self.a.lookupGroupByName('group104_2') ++ self.assertEqual(e[libuser.GROUPPASSWORD], ['x']) ++ self.assertEqual(e[libuser.SHADOWPASSWORD], ['']) ++ ++ def tearDown(self): ++ del self.a ++ ++ ++if __name__ == '__main__': ++ unittest.main() +-- +1.8.3.1 + diff --git a/libuser.spec b/libuser.spec index 36a1fae11494faffbcc51f50a389bc33ade91b05..561b110878eca4b088299197a50054dbcf498fc4 100644 --- a/libuser.spec +++ b/libuser.spec @@ -1,6 +1,6 @@ Name: libuser Version: 0.63 -Release: 2 +Release: 3 Summary: A user and group account administration library License: LGPLv2+ URL: https://pagure.io/libuser @@ -10,6 +10,8 @@ Patch0: libuser-0.63-PR49_add_yescrypt.patch Patch1: libuser-0.63-downstream_test_xcrypt.patch Patch2: fix-ldap-test-because-openldap-was-upgraded.patch +Patch9000: add-sm3-crypt-support.patch + BuildRequires: cyrus-sasl-devel, nscd, linuxdoc-tools, pam-devel, popt-devel, gcc BuildRequires: libselinux-devel, openldap-devel, python3-devel, glib2-devel BuildRequires: openldap-clients, openldap-servers, openssl @@ -102,6 +104,9 @@ python3 -c "import libuser" %{_mandir}/man5/* %changelog +* Tue Jan 11 2022 luhuaxin - 0.63-3 +- add sm3 crypt support + * Mon Jan 10 2022 panxiaohe - 0.63-2 - fix ldap test because openldap was upgraded to 2.6.0