diff --git a/shadow-add-sm3-crypt-support.patch b/shadow-add-sm3-crypt-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..cd1a42c15efeaba3e763e0daedbb8a53f64aa0b2 --- /dev/null +++ b/shadow-add-sm3-crypt-support.patch @@ -0,0 +1,780 @@ +From d7fa75bbd22a08b4e0b8c7e3ccab588c87d23835 Mon Sep 17 00:00:00 2001 +From: root +Date: Wed, 29 Dec 2021 16:05:56 +0800 +Subject: [PATCH] shadow add sm3 crypt support + +--- + configure.ac | 9 ++++ + etc/login.defs | 17 ++++++++ + lib/encrypt.c | 3 ++ + lib/getdef.c | 4 ++ + libmisc/obscure.c | 3 ++ + libmisc/salt.c | 106 +++++++++++++++++++++++++++++++++++++++++++--- + src/chgpasswd.c | 48 +++++++++++++++------ + src/chpasswd.c | 44 +++++++++++++------ + src/newusers.c | 59 +++++++++++++++++++------- + src/passwd.c | 7 ++- + 10 files changed, 252 insertions(+), 48 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 994836b..40348c0 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -288,6 +288,9 @@ AC_ARG_WITH(libcrack, + AC_ARG_WITH(sha-crypt, + [AC_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])], + [with_sha_crypt=$withval], [with_sha_crypt=yes]) ++AC_ARG_WITH(sm3-crypt, ++ [AC_HELP_STRING([--with-sm3-crypt], [allow the SM3 password encryption algorithms @<:@default=yes@:>@])], ++ [with_sm3_crypt=$withval], [with_sm3_crypt=yes]) + AC_ARG_WITH(bcrypt, + [AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])], + [with_bcrypt=$withval], [with_bcrypt=no]) +@@ -321,6 +324,11 @@ if test "$with_sha_crypt" = "yes"; then + AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms]) + fi + ++AM_CONDITIONAL(USE_SM3_CRYPT, test "x$with_sm3_crypt" = "xyes") ++if test "$with_sm3_crypt" = "yes"; then ++ AC_DEFINE(USE_SM3_CRYPT, 1, [Define to allow the SM3 password encryption algorithms]) ++fi ++ + AM_CONDITIONAL(ENABLE_SHARED, test "x$enable_shared" = "xyes") + + AM_CONDITIONAL(USE_BCRYPT, test "x$with_bcrypt" = "xyes") +@@ -766,6 +774,7 @@ echo " tcb support (incomplete): $with_tcb" + echo " shadow group support: $enable_shadowgrp" + echo " S/Key support: $with_skey" + echo " SHA passwords encryption: $with_sha_crypt" ++echo " SM3 passwords encryption: $with_sm3_crypt" + echo " bcrypt passwords encryption: $with_bcrypt" + echo " yescrypt passwords encryption: $with_yescrypt" + echo " nscd support: $with_nscd" +diff --git a/etc/login.defs b/etc/login.defs +index 94a2b1b..6db08e1 100644 +--- a/etc/login.defs ++++ b/etc/login.defs +@@ -353,6 +353,23 @@ CHFN_RESTRICT rwh + #SHA_CRYPT_MIN_ROUNDS 5000 + #SHA_CRYPT_MAX_ROUNDS 5000 + ++# ++# Only works if ENCRYPT_METHOD is set to SM3. ++# ++# Define the number of SM3 rounds. ++# With a lot of rounds, it is more difficult to brute-force the password. ++# However, more CPU resources will be needed to authenticate users if ++# this value is increased. ++# ++# If not specified, the libc will choose the default number of rounds (5000), ++# which is orders of magnitude too low for modern hardware. ++# The values must be within the 1000-999999999 range. ++# If only one of the MIN or MAX values is set, then this value will be used. ++# If MIN > MAX, the highest value will be used. ++# ++#SM3_CRYPT_MAX_ROUNDS 5000 ++#SM3_CRYPT_MIN_ROUNDS 5000 ++ + # + # Only works if ENCRYPT_METHOD is set to BCRYPT. + # +diff --git a/lib/encrypt.c b/lib/encrypt.c +index 66c52f2..7fae31d 100644 +--- a/lib/encrypt.c ++++ b/lib/encrypt.c +@@ -74,6 +74,9 @@ + case '6': + method = "SHA512"; + break; ++ case 's': // salt = $sm3$... ++ method = "SM3"; ++ break; + case 'y': + method = "YESCRYPT"; + break; +diff --git a/lib/getdef.c b/lib/getdef.c +index 80eb18c..00459ff 100644 +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -124,6 +124,10 @@ static struct itemdef def_table[] = { + {"SHA_CRYPT_MAX_ROUNDS", NULL}, + {"SHA_CRYPT_MIN_ROUNDS", NULL}, + #endif ++#ifdef USE_SM3_CRYPT ++ {"SM3_CRYPT_MAX_ROUNDS", NULL}, ++ {"SM3_CRYPT_MIN_ROUNDS", NULL}, ++#endif + #ifdef USE_BCRYPT + {"BCRYPT_MAX_ROUNDS", NULL}, + {"BCRYPT_MIN_ROUNDS", NULL}, +diff --git a/libmisc/obscure.c b/libmisc/obscure.c +index dc69f76..3907294 100644 +--- a/libmisc/obscure.c ++++ b/libmisc/obscure.c +@@ -269,6 +269,9 @@ static /*@observer@*//*@null@*/const char *obscure_msg ( + || (strcmp (result, "SHA256") == 0) + || (strcmp (result, "SHA512") == 0) + #endif ++#ifdef USE_SM3_CRYPT ++ || (strcmp (result, "SM3") == 0) ++#endif + #ifdef USE_BCRYPT + || (strcmp (result, "BCRYPT") == 0) + #endif +diff --git a/libmisc/salt.c b/libmisc/salt.c +index 30eefb9..b108a23 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -55,6 +55,17 @@ + #define SHA_ROUNDS_MAX 999999999 + #endif + ++#ifdef USE_SM3_CRYPT ++/* Fixed salt len for sm3 crypt. */ ++#define SM3_CRYPT_SALT_SIZE 16 ++/* Default number of rounds if not explicitly specified. */ ++#define SM3_ROUNDS_DEFAULT 5000 ++/* Minimum number of rounds. */ ++#define SM3_ROUNDS_MIN 1000 ++/* Maximum number of rounds. */ ++#define SM3_ROUNDS_MAX 999999999 ++#endif ++ + #ifdef USE_YESCRYPT + /* + * Default number of base64 characters used for the salt. +@@ -87,13 +98,17 @@ static long read_random_bytes (void); + #if !USE_XCRYPT_GENSALT + static /*@observer@*/const char *gensalt (size_t salt_size); + #endif /* !USE_XCRYPT_GENSALT */ +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + static long shadow_random (long min, long max); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SM3_CRYPT*/ + #ifdef USE_SHA_CRYPT + static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *prefered_rounds); + static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds); + #endif /* USE_SHA_CRYPT */ ++#ifdef USE_SM3_CRYPT ++static /*@observer@*/const unsigned long SM3_get_salt_rounds (/*@null@*/int *prefered_rounds); ++static /*@observer@*/void SM3_salt_rounds_to_buf (char *buf, unsigned long rounds); ++#endif + #ifdef USE_BCRYPT + static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds); + static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds); +@@ -186,7 +201,7 @@ end: + return randval; + } + +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + /* + * Return a random number between min and max (both included). + * +@@ -208,7 +223,7 @@ static long shadow_random (long min, long max) + } + return ret; + } +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SM3_CRYPT*/ + + #ifdef USE_SHA_CRYPT + /* Return the the rounds number for the SHA crypt methods. */ +@@ -284,6 +299,80 @@ static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long round + } + #endif /* USE_SHA_CRYPT */ + ++#ifdef USE_SM3_CRYPT ++/* Return the the rounds number for the SM3 crypt methods. */ ++static /*@observer@*/const unsigned long SM3_get_salt_rounds (/*@null@*/int *prefered_rounds) ++{ ++ unsigned long rounds; ++ ++ if (NULL == prefered_rounds) { ++ long min_rounds = getdef_long ("SM3_CRYPT_MIN_ROUNDS", -1); ++ long max_rounds = getdef_long ("SM3_CRYPT_MAX_ROUNDS", -1); ++ ++ if ((-1 == min_rounds) && (-1 == max_rounds)) { ++ rounds = SM3_ROUNDS_DEFAULT; ++ } ++ else { ++ if (-1 == min_rounds) { ++ min_rounds = max_rounds; ++ } ++ ++ if (-1 == max_rounds) { ++ max_rounds = min_rounds; ++ } ++ ++ if (min_rounds > max_rounds) { ++ max_rounds = min_rounds; ++ } ++ ++ rounds = (unsigned long) shadow_random (min_rounds, max_rounds); ++ } ++ } else if (0 == *prefered_rounds) { ++ rounds = SM3_ROUNDS_DEFAULT; ++ } else { ++ rounds = (unsigned long) *prefered_rounds; ++ } ++ ++ /* Sanity checks. The libc should also check this, but this ++ * protects against a rounds_prefix overflow. */ ++ if (rounds < SM3_ROUNDS_MIN) { ++ rounds = SM3_ROUNDS_MIN; ++ } ++ ++ if (rounds > SM3_ROUNDS_MAX) { ++ rounds = SM3_ROUNDS_MAX; ++ } ++ ++ return rounds; ++} ++ ++/* ++ * Fill a salt prefix specifying the rounds number for the SM3 crypt methods ++ * to a buffer. ++ */ ++static /*@observer@*/void SM3_salt_rounds_to_buf (char *buf, unsigned long rounds) ++{ ++ const size_t buf_begin = strlen (buf); ++ ++ /* Nothing to do here if SM3_ROUNDS_DEFAULT is used. */ ++ if (rounds == SM3_ROUNDS_DEFAULT) { ++ return; ++ } ++ ++ /* ++ * Check if the result buffer is long enough. ++ * We are going to write a maximum of 17 bytes, ++ * plus one byte for the terminator. ++ * rounds=XXXXXXXXX$ ++ * 00000000011111111 ++ * 12345678901234567 ++ */ ++ assert (GENSALT_SETTING_SIZE > buf_begin + 17); ++ ++ (void) snprintf (buf + buf_begin, 18, "rounds=%lu$", rounds); ++} ++#endif /* USE_SM3_CRYPT */ ++ + #ifdef USE_BCRYPT + /* Return the the rounds number for the BCRYPT method. */ + static /*@observer@*/const unsigned long BCRYPT_get_salt_rounds (/*@null@*/int *prefered_rounds) +@@ -453,7 +542,7 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + * which can both be set inside the login.defs file. + * + * If meth is specified, an additional parameter can be provided. +- * * For the SHA256 and SHA512 method, this specifies the number of rounds ++ * * For the SHA256 and SHA512 and SM3 method, this specifies the number of rounds + * (if not NULL). + * * For the YESCRYPT method, this specifies the cost factor (if not NULL). + */ +@@ -505,6 +594,13 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + rounds = SHA_get_salt_rounds ((int *) arg); + SHA_salt_rounds_to_buf (result, rounds); + #endif /* USE_SHA_CRYPT */ ++#ifdef USE_SM3_CRYPT ++ } else if (0 == strcmp (method, "SM3")) { ++ strcpy(result, "$sm3$"); ++ salt_len = SM3_CRYPT_SALT_SIZE; ++ rounds = SM3_get_salt_rounds ((int *) arg); ++ SM3_salt_rounds_to_buf (result, rounds); ++#endif /* USE_SM3_CRYPT */ + } else if (0 != strcmp (method, "DES")) { + fprintf (shadow_logfd, + _("Invalid ENCRYPT_METHOD value: '%s'.\n" +diff --git a/src/chgpasswd.c b/src/chgpasswd.c +index 56f3e88..f019d99 100644 +--- a/src/chgpasswd.c ++++ b/src/chgpasswd.c +@@ -62,15 +62,18 @@ const char *Prog; + FILE *shadow_logfd = NULL; + static bool eflg = false; + static bool md5flg = false; +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + static bool sflg = false; +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + + static /*@null@*//*@observer@*/const char *crypt_method = NULL; + #define cflg (NULL != crypt_method) + #ifdef USE_SHA_CRYPT + static long sha_rounds = 5000; + #endif ++#ifdef USE_SM3_CRYPT ++static long sm3_rounds = 5000; ++#endif + #ifdef USE_BCRYPT + static long bcrypt_rounds = 13; + #endif +@@ -141,6 +144,9 @@ static /*@noreturn@*/void usage (int status) + #endif + #if defined(USE_YESCRYPT) + " YESCRYPT" ++#endif ++#if defined(USE_SM3_CRYPT) ++ " SM3" + #endif + ); + (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); +@@ -149,11 +155,11 @@ static /*@noreturn@*/void usage (int status) + " the MD5 algorithm\n"), + usageout); + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) +- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) ++ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT, SM3\n" + " or YESCRYPT crypt algorithms\n"), + usageout); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + (void) fputs ("\n", usageout); + + exit (status); +@@ -167,22 +173,22 @@ static /*@noreturn@*/void usage (int status) + static void process_flags (int argc, char **argv) + { + int c; +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + int bad_s; +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + static struct option long_options[] = { + {"crypt-method", required_argument, NULL, 'c'}, + {"encrypted", no_argument, NULL, 'e'}, + {"help", no_argument, NULL, 'h'}, + {"md5", no_argument, NULL, 'm'}, + {"root", required_argument, NULL, 'R'}, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + {"sha-rounds", required_argument, NULL, 's'}, +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + {NULL, 0, NULL, '\0'} + }; + while ((c = getopt_long (argc, argv, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + "c:ehmR:s:", + #else + "c:ehmR:", +@@ -203,7 +209,7 @@ static void process_flags (int argc, char **argv) + break; + case 'R': /* no-op, handled in process_root_flag () */ + break; +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + case 's': + sflg = true; + bad_s = 0; +@@ -225,6 +231,12 @@ static void process_flags (int argc, char **argv) + bad_s = 1; + } + #endif /* USE_YESCRYPT */ ++#if defined(USE_SM3_CRYPT) ++ if (( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds)))) { ++ bad_s = 1; ++ } ++#endif /* USE_SM3_CRYPT */ + if (bad_s != 0) { + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), +@@ -232,7 +244,7 @@ static void process_flags (int argc, char **argv) + usage (E_USAGE); + } + break; +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + + default: + usage (E_USAGE); +@@ -251,7 +263,7 @@ static void process_flags (int argc, char **argv) + */ + static void check_flags (void) + { +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + if (sflg && !cflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), +@@ -282,6 +294,9 @@ static void check_flags (void) + #ifdef USE_YESCRYPT + && (0 != strcmp (crypt_method, "YESCRYPT")) + #endif /* USE_YESCRYPT */ ++#ifdef USE_SM3_CRYPT ++ && (0 != strcmp (crypt_method, "SM3")) ++#endif /* USE_SM3_CRYPT */ + ) { + fprintf (stderr, + _("%s: unsupported crypt method: %s\n"), +@@ -505,7 +520,7 @@ int main (int argc, char **argv) + if (md5flg) { + crypt_method = "MD5"; + } +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + if (sflg) { + #if defined(USE_SHA_CRYPT) + if ( (0 == strcmp (crypt_method, "SHA256")) +@@ -523,6 +538,11 @@ int main (int argc, char **argv) + arg = &yescrypt_cost; + } + #endif /* USE_YESCRYPT */ ++#if defined(USE_SM3_CRYPT) ++ if (0 == strcmp (crypt_method, "SM3")) { ++ arg = &sm3_rounds; ++ } ++#endif /* USE_SM3_CRYPT */ + } + #endif + salt = crypt_make_salt (crypt_method, arg); +diff --git a/src/chpasswd.c b/src/chpasswd.c +index 8a01227..5dfb995 100644 +--- a/src/chpasswd.c ++++ b/src/chpasswd.c +@@ -59,7 +59,7 @@ const char *Prog; + FILE *shadow_logfd = NULL; + static bool eflg = false; + static bool md5flg = false; +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + static bool sflg = false; + #endif + +@@ -68,6 +68,9 @@ static /*@null@*//*@observer@*/const char *crypt_method = NULL; + #ifdef USE_SHA_CRYPT + static long sha_rounds = 5000; + #endif ++#ifdef USE_SM3_CRYPT ++static long sm3_rounds = 5000; ++#endif + #ifdef USE_BCRYPT + static long bcrypt_rounds = 13; + #endif +@@ -134,6 +137,9 @@ static /*@noreturn@*/void usage (int status) + #endif + #if defined(USE_YESCRYPT) + " YESCRYPT" ++#endif ++#if defined(USE_SM3_CRYPT) ++ " SM3" + #endif + ); + (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); +@@ -142,11 +148,11 @@ static /*@noreturn@*/void usage (int status) + " the MD5 algorithm\n"), + usageout); + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) +- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) ++ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT, SM3\n" + " or YESCRYPT crypt algorithms\n"), + usageout); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + (void) fputs ("\n", usageout); + + exit (status); +@@ -160,23 +166,23 @@ static /*@noreturn@*/void usage (int status) + static void process_flags (int argc, char **argv) + { + int c; +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + int bad_s; +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + static struct option long_options[] = { + {"crypt-method", required_argument, NULL, 'c'}, + {"encrypted", no_argument, NULL, 'e'}, + {"help", no_argument, NULL, 'h'}, + {"md5", no_argument, NULL, 'm'}, + {"root", required_argument, NULL, 'R'}, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + {"sha-rounds", required_argument, NULL, 's'}, +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + {NULL, 0, NULL, '\0'} + }; + + while ((c = getopt_long (argc, argv, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + "c:ehmR:s:", + #else + "c:ehmR:", +@@ -197,7 +203,7 @@ static void process_flags (int argc, char **argv) + break; + case 'R': /* no-op, handled in process_root_flag () */ + break; +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + case 's': + sflg = true; + bad_s = 0; +@@ -219,6 +225,12 @@ static void process_flags (int argc, char **argv) + bad_s = 1; + } + #endif /* USE_YESCRYPT */ ++#if defined(USE_SM3_CRYPT) ++ if (( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds)))) { ++ bad_s = 1; ++ } ++#endif /* USE_SM3_CRYPT */ + if (bad_s != 0) { + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), +@@ -226,7 +238,7 @@ static void process_flags (int argc, char **argv) + usage (E_USAGE); + } + break; +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + + default: + usage (E_USAGE); +@@ -245,7 +257,7 @@ static void process_flags (int argc, char **argv) + */ + static void check_flags (void) + { +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + if (sflg && !cflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), +@@ -270,6 +282,9 @@ static void check_flags (void) + && (0 != strcmp (crypt_method, "SHA256")) + && (0 != strcmp (crypt_method, "SHA512")) + #endif /* USE_SHA_CRYPT */ ++#ifdef USE_SM3_CRYPT ++ && (0 != strcmp (crypt_method, "SM3")) ++#endif /* USE_SM3_CRYPT */ + #ifdef USE_BCRYPT + && (0 != strcmp (crypt_method, "BCRYPT")) + #endif /* USE_BCRYPT */ +@@ -556,6 +571,11 @@ int main (int argc, char **argv) + arg = &yescrypt_cost; + } + #endif /* USE_YESCRYPT */ ++#if defined(USE_SM3_CRYPT) ++ if (0 == strcmp (crypt_method, "SM3")) { ++ arg = &sm3_rounds; ++ } ++#endif /* USE_SM3_CRYPT */ + } + #endif + salt = crypt_make_salt (crypt_method, arg); +diff --git a/src/newusers.c b/src/newusers.c +index 16bf722..dd101fb 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -81,12 +81,15 @@ static bool rflg = false; /* create a system account */ + #ifndef USE_PAM + static /*@null@*//*@observer@*/char *crypt_method = NULL; + #define cflg (NULL != crypt_method) +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + static bool sflg = false; + #endif + #ifdef USE_SHA_CRYPT + static long sha_rounds = 5000; + #endif /* USE_SHA_CRYPT */ ++#ifdef USE_SM3_CRYPT ++static long sm3_rounds = 5000; ++#endif /* USE_SM3_CRYPT */ + #ifdef USE_BCRYPT + static long bcrypt_rounds = 13; + #endif /* USE_BCRYPT */ +@@ -152,6 +155,9 @@ static void usage (int status) + #endif + #if defined(USE_YESCRYPT) + " YESCRYPT" ++#endif ++#if defined(USE_SM3_CRYPT) ++ " SM3" + #endif + ); + #endif /* !USE_PAM */ +@@ -159,11 +165,11 @@ static void usage (int status) + (void) fputs (_(" -r, --system create system accounts\n"), usageout); + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) +- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) ++ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT, SM3\n" + " or YESCRYPT crypt algorithms\n"), + usageout); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + #endif /* !USE_PAM */ + (void) fputs ("\n", usageout); + +@@ -460,6 +466,13 @@ static int update_passwd (struct passwd *pwd, const char *password) + } + } + #endif /* USE_YESCRYPT */ ++#if defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if (0 == strcmp (crypt_method, "SM3")) { ++ crypt_arg = &sm3_rounds; ++ } ++ } ++#endif /* USE_SM3_CRYPT */ + } + + if ((NULL != crypt_method) && (0 == strcmp(crypt_method, "NONE"))) { +@@ -514,6 +527,13 @@ static int add_passwd (struct passwd *pwd, const char *password) + } + } + #endif /* USE_PAM */ ++#if defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if (0 == strcmp (crypt_method, "SM3")) { ++ crypt_arg = &sm3_rounds; ++ } ++ } ++#endif /* USE_SM3_CRYPT */ + } + + /* +@@ -630,9 +650,9 @@ static int add_passwd (struct passwd *pwd, const char *password) + static void process_flags (int argc, char **argv) + { + int c; +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + int bad_s; +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + static struct option long_options[] = { + {"badnames", no_argument, NULL, 'b'}, + #ifndef USE_PAM +@@ -642,20 +662,20 @@ static void process_flags (int argc, char **argv) + {"system", no_argument, NULL, 'r'}, + {"root", required_argument, NULL, 'R'}, + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + {"sha-rounds", required_argument, NULL, 's'}, +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + #endif /* !USE_PAM */ + {NULL, 0, NULL, '\0'} + }; + + while ((c = getopt_long (argc, argv, + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + "c:bhrs:", +-#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */ ++#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT && !USE_SM3_CRYPT*/ + "c:bhr", +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + #else /* USE_PAM */ + "bhr", + #endif +@@ -678,7 +698,7 @@ static void process_flags (int argc, char **argv) + case 'R': /* no-op, handled in process_root_flag () */ + break; + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + case 's': + sflg = true; + bad_s = 0; +@@ -700,6 +720,12 @@ static void process_flags (int argc, char **argv) + bad_s = 1; + } + #endif /* USE_YESCRYPT */ ++#if defined(USE_SM3_CRYPT) ++ if (( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds)))) { ++ bad_s = 1; ++ } ++#endif /* USE_SM3_CRYPT */ + if (bad_s != 0) { + fprintf (stderr, + _("%s: invalid numeric argument '%s'\n"), +@@ -707,7 +733,7 @@ static void process_flags (int argc, char **argv) + usage (EXIT_FAILURE); + } + break; +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + #endif /* !USE_PAM */ + default: + usage (EXIT_FAILURE); +@@ -741,14 +767,14 @@ static void process_flags (int argc, char **argv) + static void check_flags (void) + { + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) || defined(USE_SM3_CRYPT) + if (sflg && !cflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), + Prog, "-s", "-c"); + usage (EXIT_FAILURE); + } +-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT*/ + + if (cflg) { + if ( (0 != strcmp (crypt_method, "DES")) +@@ -758,6 +784,9 @@ static void check_flags (void) + && (0 != strcmp (crypt_method, "SHA256")) + && (0 != strcmp (crypt_method, "SHA512")) + #endif /* USE_SHA_CRYPT */ ++#ifdef USE_SM3_CRYPT ++ && (0 != strcmp (crypt_method, "SM3")) ++#endif /* USE_SM3_CRYPT */ + #ifdef USE_BCRYPT + && (0 != strcmp (crypt_method, "BCRYPT")) + #endif /* USE_BCRYPT */ +diff --git a/src/passwd.c b/src/passwd.c +index 00cbef6..aa4eb5e 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -107,7 +107,7 @@ static bool spw_locked = false; + #ifndef USE_PAM + /* + * Size of the biggest passwd: +- * $6$ 3 ++ * $sm3$ 5 + * rounds= 7 + * 999999999 9 + * $ 1 +@@ -116,7 +116,7 @@ static bool spw_locked = false; + * SHA512 123 + * nul 1 + * +- * total 161 ++ * total 163 + */ + static char crypt_passwd[256]; + static bool do_update_pwd = false; +@@ -287,6 +287,9 @@ static int new_password (const struct passwd *pw) + #ifdef USE_YESCRYPT + || (strcmp (method, "YESCRYPT") == 0) + #endif /* USE_YESCRYPT*/ ++#ifdef USE_SM3_CRYPT ++ || (strcmp (method, "SM3") == 0) ++#endif /* USE_SM3_CRYPT*/ + + ) { + pass_max_len = -1; +-- +2.27.0 + diff --git a/shadow.spec b/shadow.spec index eb6f81b99c63f35edb91cb3de96df8e3346ea448..e2d98e2c0ff039446c803e0af2ef5d913d3064aa 100644 --- a/shadow.spec +++ b/shadow.spec @@ -1,6 +1,6 @@ Name: shadow Version: 4.9 -Release: 1 +Release: 2 Epoch: 2 License: BSD and GPLv2+ Summary: Tools for managing accounts and shadow password files @@ -37,6 +37,7 @@ Patch17: Fixes-the-linking-issues-when-libsubid-is-static-and.patch Patch18: pwck-fix-segfault-when-calling-fprintf.patch Patch19: newgrp-fix-segmentation-fault.patch Patch20: groupdel-fix-SIGSEGV-when-passwd-does-not-exist.patch +Patch21: shadow-add-sm3-crypt-support.patch BuildRequires: gcc, libselinux-devel, audit-libs-devel, libsemanage-devel BuildRequires: libacl-devel, libattr-devel @@ -203,6 +204,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_mandir}/*/* %changelog +* Thu Dec 30 2021 wangcheng - 2:4.9-2 +- add sm3 support + * Tue Dec 21 2021 panxiaohe - 2:4.9-1 - update to 4.9