diff --git a/shadow-add-sm3-crypt-support.patch b/shadow-add-sm3-crypt-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..845f3b74f0a26c455556fb11f9ef8690ee6ce2b1 --- /dev/null +++ b/shadow-add-sm3-crypt-support.patch @@ -0,0 +1,1101 @@ +From 3f0688642317b6385329aa593af933d0bdc2974c Mon Sep 17 00:00:00 2001 +From: river <314264452@qq.com> +Date: Fri, 29 Oct 2021 12:05:57 +0800 +Subject: [PATCH] sm3 + +--- + configure.ac | 9 +++ + etc/login.defs | 17 +++++ + lib/encrypt.c | 3 + + lib/getdef.c | 4 ++ + libmisc/obscure.c | 3 + + libmisc/salt.c | 77 ++++++++++++++++++++-- + src/chgpasswd.c | 155 +++++++++++++++++++++++++++++++++++++------ + src/chpasswd.c | 147 +++++++++++++++++++++++++++++++++++------ + src/newusers.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++------- + src/passwd.c | 3 + + 10 files changed, 543 insertions(+), 68 deletions(-) + +diff --git a/configure.ac b/configure.ac +index e4c6aae..e51417e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -277,6 +277,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]) +@@ -307,6 +310,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(USE_BCRYPT, test "x$with_bcrypt" = "xyes") + if test "$with_bcrypt" = "yes"; then + AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm]) +@@ -740,6 +748,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 " nscd support: $with_nscd" + echo " sssd support: $with_sssd" +diff --git a/etc/login.defs b/etc/login.defs +index a2f8cd5..9f66ebf 100644 +--- a/etc/login.defs ++++ b/etc/login.defs +@@ -351,6 +351,23 @@ CHFN_RESTRICT rwh + #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. + # + # Define the number of BCRYPT rounds. +diff --git a/lib/encrypt.c b/lib/encrypt.c +index 4247f24..5a14c99 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; + default: + { + static char nummethod[4] = "$x$"; +diff --git a/lib/getdef.c b/lib/getdef.c +index 00f6abf..f3171f3 100644 +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -112,6 +112,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 15da760..2067602 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 e1a7ac8..da4fb11 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -22,12 +22,15 @@ + /* local function prototypes */ + static void seedRNG (void); + static /*@observer@*/const char *gensalt (size_t salt_size); +-#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 char *SHA_salt_rounds (/*@null@*/int *prefered_rounds); + #endif /* USE_SHA_CRYPT */ ++#ifdef USE_SM3_CRYPT ++static /*@observer@*/const char *SM3_salt_rounds (/*@null@*/int *prefered_rounds); ++#endif + #ifdef USE_BCRYPT + static /*@observer@*/const char *gensalt_bcrypt (void); + static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds); +@@ -94,7 +97,7 @@ static void seedRNG (void) + #define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='a',(array)[4]='\0' + #endif /* USE_BCRYPT */ + +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + /* It is not clear what is the maximum value of random(). + * We assume 2^31-1.*/ + #define RANDOM_MAX 0x7FFFFFFF +@@ -119,15 +122,18 @@ 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 ++#if defined(USE_SHA_CRYPT) || defined(USE_SM3_CRYPT) + /* Default number of rounds if not explicitly specified. */ + #define ROUNDS_DEFAULT 5000 + /* Minimum number of rounds. */ + #define ROUNDS_MIN 1000 + /* Maximum number of rounds. */ + #define ROUNDS_MAX 999999999 ++#endif ++ ++#ifdef USE_SHA_CRYPT + /* + * Return a salt prefix specifying the rounds number for the SHA crypt methods. + */ +@@ -180,6 +186,57 @@ static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds + } + #endif /* USE_SHA_CRYPT */ + ++#ifdef USE_SM3_CRYPT ++static /*@observer@*/const char *SM3_salt_rounds (/*@null@*/int *prefered_rounds) ++{ ++ static char rounds_prefix[18]; /* Max size: rounds=999999999$ */ ++ 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)) { ++ return ""; ++ } ++ ++ 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 = shadow_random (min_rounds, max_rounds); ++ } else if (0 == *prefered_rounds) { ++ return ""; ++ } else { ++ rounds = *prefered_rounds; ++ } ++ ++ /* Sanity checks. The libc should also check this, but this ++ * protects against a rounds_prefix overflow. */ ++ if (rounds < ROUNDS_MIN) { ++ rounds = ROUNDS_MIN; ++ } ++ ++ if (rounds > ROUNDS_MAX) { ++ rounds = ROUNDS_MAX; ++ } ++ ++ (void) snprintf (rounds_prefix, sizeof rounds_prefix, ++ "rounds=%ld$", rounds); ++ ++ return rounds_prefix; ++} ++#endif /* USE_SM3_CRYPT */ ++ ++ + #ifdef USE_BCRYPT + /* Default number of rounds if not explicitly specified. */ + #define B_ROUNDS_DEFAULT 13 +@@ -300,12 +357,12 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + * ENCRYPT_METHOD login.defs variables. + * + * 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). + */ + /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg) + { +- /* Max result size for the SHA methods: ++ /* Max result size for the SHA and SM3 methods: + * +3 $5$ + * +17 rounds=999999999$ + * +16 salt +@@ -343,6 +400,12 @@ static /*@observer@*/const char *gensalt (size_t salt_size) + strcat(result, SHA_salt_rounds((int *)arg)); + salt_len = (size_t) shadow_random (8, 16); + #endif /* USE_SHA_CRYPT */ ++#ifdef USE_SM3_CRYPT ++ } else if (0 == strcmp (method, "SM3")) { ++ strcpy(result, "$sm3$"); ++ strcat(result, SM3_salt_rounds((int *)arg)); ++ salt_len = (size_t) shadow_random (8, 16); ++#endif /* USE_SM3_CRYPT */ + } else if (0 != strcmp (method, "DES")) { + fprintf (stderr, + _("Invalid ENCRYPT_METHOD value: '%s'.\n" +diff --git a/src/chgpasswd.c b/src/chgpasswd.c +index 4013abb..05dd6de 100644 +--- a/src/chgpasswd.c ++++ b/src/chgpasswd.c +@@ -61,15 +61,20 @@ + const char *Prog; + static bool eflg = false; + static bool md5flg = false; +-#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 /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || 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 +@@ -128,12 +133,20 @@ static /*@noreturn@*/void usage (int status) + Prog); + (void) fprintf (usageout, + _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), +-#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) ++#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) && !defined(USE_SM3_CRYPT) + "NONE DES MD5" ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ "NONE DES MD5 SHA256 SHA512 BCRYPT SM3" + #elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) + "NONE DES MD5 SHA256 SHA512 BCRYPT" ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ "NONE DES MD5 SHA256 SHA512 SM3" ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ "NONE DES MD5 BCRYPT SM3" + #elif defined(USE_SHA_CRYPT) + "NONE DES MD5 SHA256 SHA512" ++#elif defined(USE_SM3_CRYPT) ++ "NONE DES MD5 SM3" + #else + "NONE DES MD5 BCRYPT" + #endif +@@ -144,11 +157,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) +- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) ++ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT or SM3\n" + " crypt algorithms\n"), + usageout); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SM3_CRYPT*/ + (void) fputs ("\n", usageout); + + exit (status); +@@ -168,13 +181,13 @@ static void process_flags (int argc, char **argv) + {"help", no_argument, NULL, 'h'}, + {"md5", no_argument, NULL, 'm'}, + {"root", required_argument, NULL, 'R'}, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + {"sha-rounds", required_argument, NULL, 's'}, +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SM3_CRYPT */ + {NULL, 0, NULL, '\0'} + }; + while ((c = getopt_long (argc, argv, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + "c:ehmR:s:", + #else + "c:ehmR:", +@@ -195,17 +208,70 @@ 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) ++#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) + case 's': + sflg = true; +- if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) +- && (0 == getlong(optarg, &sha_rounds))) +- || ( (0 == strcmp (crypt_method, "BCRYPT")) +- && (0 == getlong(optarg, &bcrypt_rounds)))) { +- fprintf (stderr, +- _("%s: invalid numeric argument '%s'\n"), +- Prog, optarg); +- usage (E_USAGE); ++ if (crypt_method != NULL) { ++ if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) ++ && (0 == getlong(optarg, &sha_rounds))) ++ || ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &bcrypt_rounds))) ++ || ( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds))) ++ ) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } ++ } ++ break; ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++ case 's': ++ sflg = true; ++ if (crypt_method != NULL) { ++ if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) ++ && (0 == getlong(optarg, &sha_rounds))) ++ || ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &bcrypt_rounds))) ++ ) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } ++ } ++ break; ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ case 's': ++ sflg = true; ++ if (crypt_method != NULL) { ++ if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) ++ && (0 == getlong(optarg, &sha_rounds))) ++ || ( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds))) ++ ) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } ++ } ++ break; ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ case 's': ++ sflg = true; ++ if (crypt_method != NULL) { ++ if ( ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &bcrypt_rounds))) ++ || ( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds))) ++ ) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } + } + break; + #elif defined(USE_SHA_CRYPT) +@@ -228,6 +294,16 @@ static void process_flags (int argc, char **argv) + usage (E_USAGE); + } + break; ++#elif defined(USE_SM3_CRYPT) ++ case 's': ++ sflg = true; ++ if (0 == getlong(optarg, &sm3_rounds)) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } ++ break; + #endif + + default: +@@ -247,7 +323,7 @@ static void process_flags (int argc, char **argv) + */ + static void check_flags (void) + { +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + if (sflg && !cflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), +@@ -272,6 +348,9 @@ static void check_flags (void) + && (0 != strcmp (crypt_method, "SHA256")) + && (0 != strcmp (crypt_method, "SHA512")) + #endif ++#ifdef USE_SM3_CRYPT ++ && (0 != strcmp (crypt_method, "SM3")) ++#endif + #ifdef USE_BCRYPT + && (0 != strcmp (crypt_method, "BCRYPT")) + #endif +@@ -497,7 +576,20 @@ int main (int argc, char **argv) + if (md5flg) { + crypt_method = "MD5"; + } +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if ( (0 == strcmp (crypt_method, "SHA256")) ++ || (0 == strcmp (crypt_method, "SHA512"))) { ++ arg = &sha_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "BCRYPT")) { ++ arg = &bcrypt_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "SM3")) { ++ arg = &sm3_rounds; ++ } ++ } ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) + if (sflg) { + if ( (0 == strcmp (crypt_method, "SHA256")) + || (0 == strcmp (crypt_method, "SHA512"))) { +@@ -507,6 +599,25 @@ int main (int argc, char **argv) + arg = &bcrypt_rounds; + } + } ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if ( (0 == strcmp (crypt_method, "SHA256")) ++ || (0 == strcmp (crypt_method, "SHA512"))) { ++ arg = &sha_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "SM3")) { ++ arg = &sm3_rounds; ++ } ++ } ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if (0 == strcmp (crypt_method, "BCRYPT")) { ++ arg = &bcrypt_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "SM3")) { ++ arg = &sm3_rounds; ++ } ++ } + #elif defined(USE_SHA_CRYPT) + if (sflg) { + arg = &sha_rounds; +@@ -515,6 +626,10 @@ int main (int argc, char **argv) + if (sflg) { + arg = &bcrypt_rounds; + } ++#elif defined(USE_SM3_CRYPT) ++ if (sflg) { ++ arg = &sm3_rounds; ++ } + #endif + salt = crypt_make_salt (crypt_method, arg); + cp = pw_encrypt (newpwd, salt); +diff --git a/src/chpasswd.c b/src/chpasswd.c +index be61e03..76fb562 100644 +--- a/src/chpasswd.c ++++ b/src/chpasswd.c +@@ -58,7 +58,7 @@ + const char *Prog; + static bool eflg = false; + static bool md5flg = false; +-#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 + +@@ -67,6 +67,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 +@@ -121,12 +124,20 @@ static /*@noreturn@*/void usage (int status) + Prog); + (void) fprintf (usageout, + _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), +-#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) ++#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) && !defined(USE_SM3_CRYPT) + "NONE DES MD5" ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ "NONE DES MD5 SHA256 SHA512 BCRYPT SM3" + #elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) + "NONE DES MD5 SHA256 SHA512 BCRYPT" ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ "NONE DES MD5 SHA256 SHA512 SM3" ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ "NONE DES MD5 BCRYPT SM3" + #elif defined(USE_SHA_CRYPT) + "NONE DES MD5 SHA256 SHA512" ++#elif defined(USE_SM3_CRYPT) ++ "NONE DES MD5 SM3" + #else + "NONE DES MD5 BCRYPT" + #endif +@@ -137,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) +- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) ++ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA , BCRYPT or SM3\n" + " crypt algorithms\n"), + usageout); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SM3_CRYPT*/ + (void) fputs ("\n", usageout); + + exit (status); +@@ -161,14 +172,14 @@ static void process_flags (int argc, char **argv) + {"help", no_argument, NULL, 'h'}, + {"md5", no_argument, NULL, 'm'}, + {"root", required_argument, NULL, 'R'}, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + {"sha-rounds", required_argument, NULL, 's'}, +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SM3_CRYPT*/ + {NULL, 0, NULL, '\0'} + }; + + while ((c = getopt_long (argc, argv, +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + "c:ehmR:s:", + #else + "c:ehmR:", +@@ -189,17 +200,66 @@ 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) ++#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) + case 's': + sflg = true; +- if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) +- && (0 == getlong(optarg, &sha_rounds))) +- || ( (0 == strcmp (crypt_method, "BCRYPT")) +- && (0 == getlong(optarg, &bcrypt_rounds)))) { +- fprintf (stderr, +- _("%s: invalid numeric argument '%s'\n"), +- Prog, optarg); +- usage (E_USAGE); ++ if (crypt_method != NULL) { ++ if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) ++ && (0 == getlong(optarg, &sha_rounds))) ++ || ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &bcrypt_rounds))) ++ || ( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds)))) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } ++ } ++ break; ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++ case 's': ++ sflg = true; ++ if (crypt_method != NULL) { ++ if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) ++ && (0 == getlong(optarg, &sha_rounds))) ++ || ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &bcrypt_rounds)))) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } ++ } ++ break; ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ case 's': ++ sflg = true; ++ if (crypt_method != NULL) { ++ if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) ++ && (0 == getlong(optarg, &sha_rounds))) ++ || ( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds)))) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } ++ } ++ break; ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ case 's': ++ sflg = true; ++ if (crypt_method != NULL) { ++ if ( ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &bcrypt_rounds))) ++ || ( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds)))) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } + } + break; + #elif defined(USE_SHA_CRYPT) +@@ -222,6 +282,16 @@ static void process_flags (int argc, char **argv) + usage (E_USAGE); + } + break; ++#elif defined(USE_SM3_CRYPT) ++ case 's': ++ sflg = true; ++ if ( 0 == getlong(optarg, &sm3_rounds)) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (E_USAGE); ++ } ++ break; + #endif + + default: +@@ -241,7 +311,7 @@ static void process_flags (int argc, char **argv) + */ + static void check_flags (void) + { +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + if (sflg && !cflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), +@@ -266,6 +336,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 */ +@@ -530,7 +603,7 @@ int main (int argc, char **argv) + if (md5flg) { + crypt_method = "MD5"; + } +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) + if (sflg) { + if ( (0 == strcmp (crypt_method, "SHA256")) + || (0 == strcmp (crypt_method, "SHA512"))) { +@@ -539,6 +612,38 @@ int main (int argc, char **argv) + else if (0 == strcmp (crypt_method, "BCRYPT")) { + arg = &bcrypt_rounds; + } ++ else if ( 0 == strcmp (crypt_method, "SM3")) { ++ arg = &sm3_rounds; ++ } ++ } ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++ if (sflg) { ++ if ( (0 == strcmp (crypt_method, "SHA256")) ++ || (0 == strcmp (crypt_method, "SHA512"))) { ++ arg = &sha_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "BCRYPT")) { ++ arg = &bcrypt_rounds; ++ } ++ } ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if ( (0 == strcmp (crypt_method, "SHA256")) ++ || (0 == strcmp (crypt_method, "SHA512"))) { ++ arg = &sha_rounds; ++ } ++ else if ( 0 == strcmp (crypt_method, "SM3")) { ++ arg = &sm3_rounds; ++ } ++ } ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if (0 == strcmp (crypt_method, "BCRYPT")) { ++ arg = &bcrypt_rounds; ++ } ++ else if ( 0 == strcmp (crypt_method, "SM3")) { ++ arg = &sm3_rounds; ++ } + } + #elif defined(USE_SHA_CRYPT) + if (sflg) { +@@ -548,6 +653,10 @@ int main (int argc, char **argv) + if (sflg) { + arg = &bcrypt_rounds; + } ++#elif defined(USE_SM3_CRYPT) ++ if (sflg) { ++ arg = &sm3_rounds; ++ } + #endif + salt = crypt_make_salt (crypt_method, arg); + cp = pw_encrypt (newpwd, salt); +diff --git a/src/newusers.c b/src/newusers.c +index e9fe0e2..37b739f 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -80,12 +80,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 */ +@@ -139,12 +142,20 @@ static void usage (int status) + #ifndef USE_PAM + (void) fprintf (usageout, + _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), +-#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) ++#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) && !defined(USE_SM3_CRYPT) + "NONE DES MD5" ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ "NONE DES MD5 SHA256 SHA512 BCRYPT SM3" + #elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) + "NONE DES MD5 SHA256 SHA512 BCRYPT" ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ "NONE DES MD5 SHA256 SHA512 SM3" ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ "NONE DES MD5 BCRYPT SM3" + #elif defined(USE_SHA_CRYPT) + "NONE DES MD5 SHA256 SHA512" ++#elif defined(USE_SM3_CRYPT) ++ "NONE DES MD5 SM3" + #else + "NONE DES MD5 BCRYPT" + #endif +@@ -154,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) +- (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) ++ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA , BCRYPT or SM3\n" + " crypt algorithms\n"), + usageout); +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SM3_CRYPT*/ + #endif /* !USE_PAM */ + (void) fputs ("\n", usageout); + +@@ -433,7 +444,7 @@ static int update_passwd (struct passwd *pwd, const char *password) + void *crypt_arg = NULL; + char *cp; + if (NULL != crypt_method) { +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) + if (sflg) { + if ( (0 == strcmp (crypt_method, "SHA256")) + || (0 == strcmp (crypt_method, "SHA512"))) { +@@ -442,6 +453,38 @@ static int update_passwd (struct passwd *pwd, const char *password) + else if (0 == strcmp (crypt_method, "BCRYPT")) { + crypt_arg = &bcrypt_rounds; + } ++ else if (0 == strcmp (crypt_method, "SM3")) { ++ crypt_arg = &sm3_rounds; ++ } ++ } ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++ if (sflg) { ++ if ( (0 == strcmp (crypt_method, "SHA256")) ++ || (0 == strcmp (crypt_method, "SHA512"))) { ++ crypt_arg = &sha_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "BCRYPT")) { ++ crypt_arg = &bcrypt_rounds; ++ } ++ } ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if ( (0 == strcmp (crypt_method, "SHA256")) ++ || (0 == strcmp (crypt_method, "SHA512"))) { ++ crypt_arg = &sha_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "SM3")) { ++ crypt_arg = &sm3_rounds; ++ } ++ } ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if (0 == strcmp (crypt_method, "BCRYPT")) { ++ crypt_arg = &bcrypt_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "SM3")) { ++ crypt_arg = &sm3_rounds; ++ } + } + #elif defined(USE_SHA_CRYPT) + if (sflg) { +@@ -451,6 +494,10 @@ static int update_passwd (struct passwd *pwd, const char *password) + if (sflg) { + crypt_arg = &bcrypt_rounds; + } ++#elif defined(USE_SM3_CRYPT) ++ if (sflg) { ++ crypt_arg = &sm3_rounds; ++ } + #endif + } + +@@ -484,7 +531,20 @@ static int add_passwd (struct passwd *pwd, const char *password) + #ifndef USE_PAM + void *crypt_arg = NULL; + if (NULL != crypt_method) { +-#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if ( (0 == strcmp (crypt_method, "SHA256")) ++ || (0 == strcmp (crypt_method, "SHA512"))) { ++ crypt_arg = &sha_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "BCRYPT")) { ++ crypt_arg = &bcrypt_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "SM3")) { ++ crypt_arg = &sm3_rounds; ++ } ++ } ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) + if (sflg) { + if ( (0 == strcmp (crypt_method, "SHA256")) + || (0 == strcmp (crypt_method, "SHA512"))) { +@@ -494,6 +554,25 @@ static int add_passwd (struct passwd *pwd, const char *password) + crypt_arg = &bcrypt_rounds; + } + } ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if ( (0 == strcmp (crypt_method, "SHA256")) ++ || (0 == strcmp (crypt_method, "SHA512"))) { ++ crypt_arg = &sha_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "SM3")) { ++ crypt_arg = &sm3_rounds; ++ } ++ } ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ if (sflg) { ++ if (0 == strcmp (crypt_method, "BCRYPT")) { ++ crypt_arg = &bcrypt_rounds; ++ } ++ else if (0 == strcmp (crypt_method, "SM3")) { ++ crypt_arg = &sm3_rounds; ++ } ++ } + #elif defined(USE_SHA_CRYPT) + if (sflg) { + crypt_arg = &sha_rounds; +@@ -502,6 +581,10 @@ static int add_passwd (struct passwd *pwd, const char *password) + if (sflg) { + crypt_arg = &bcrypt_rounds; + } ++#elif defined(USE_SM3_CRYPT) ++ if (sflg) { ++ crypt_arg = &sm3_rounds; ++ } + #endif + } + +@@ -628,20 +711,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) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + {"sha-rounds", required_argument, NULL, 's'}, +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || 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) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + "c:bhrs:", +-#else /* !USE_SHA_CRYPT && !USE_BCRYPT */ ++#else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_SHA_CRYPT*/ + "c:bhr", +-#endif /* USE_SHA_CRYPT || USE_BCRYPT */ ++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_SHA_CRYPT*/ + #else /* USE_PAM */ + "bhr", + #endif +@@ -664,17 +747,70 @@ 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) ++#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) + case 's': + sflg = true; +- if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) +- && (0 == getlong(optarg, &sha_rounds))) +- || ( (0 == strcmp (crypt_method, "BCRYPT")) +- && (0 == getlong(optarg, &bcrypt_rounds)))) { +- fprintf (stderr, +- _("%s: invalid numeric argument '%s'\n"), +- Prog, optarg); +- usage (EXIT_FAILURE); ++ if (crypt_method != NULL) { ++ if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) ++ && (0 == getlong(optarg, &sha_rounds))) ++ || ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &bcrypt_rounds))) ++ || ( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds))) ++ ) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (EXIT_FAILURE); ++ } ++ } ++ break; ++#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) ++ case 's': ++ sflg = true; ++ if (crypt_method != NULL) { ++ if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) ++ && (0 == getlong(optarg, &sha_rounds))) ++ || ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &bcrypt_rounds))) ++ ) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (EXIT_FAILURE); ++ } ++ } ++ break; ++#elif defined(USE_SHA_CRYPT) && defined(USE_SM3_CRYPT) ++ case 's': ++ sflg = true; ++ if (crypt_method != NULL) { ++ if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) ++ && (0 == getlong(optarg, &sha_rounds))) ++ || ( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds))) ++ ) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (EXIT_FAILURE); ++ } ++ } ++ break; ++#elif defined(USE_BCRYPT) && defined(USE_SM3_CRYPT) ++ case 's': ++ sflg = true; ++ if (crypt_method != NULL) { ++ if ( ( (0 == strcmp (crypt_method, "BCRYPT")) ++ && (0 == getlong(optarg, &bcrypt_rounds))) ++ || ( (0 == strcmp (crypt_method, "SM3")) ++ && (0 == getlong(optarg, &sm3_rounds))) ++ ) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (EXIT_FAILURE); ++ } + } + break; + #elif defined(USE_SHA_CRYPT) +@@ -697,6 +833,16 @@ static void process_flags (int argc, char **argv) + usage (EXIT_FAILURE); + } + break; ++#elif defined(USE_SM3_CRYPT) ++ case 's': ++ sflg = true; ++ if (0 == getlong(optarg, &sm3_rounds)) { ++ fprintf (stderr, ++ _("%s: invalid numeric argument '%s'\n"), ++ Prog, optarg); ++ usage (EXIT_FAILURE); ++ } ++ break; + #endif + #endif /* !USE_PAM */ + default: +@@ -731,7 +877,7 @@ static void process_flags (int argc, char **argv) + static void check_flags (void) + { + #ifndef USE_PAM +-#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) ++#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_SM3_CRYPT) + if (sflg && !cflg) { + fprintf (stderr, + _("%s: %s flag is only allowed with the %s flag\n"), +@@ -748,6 +894,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 2c83c10..bdf10cd 100644 +--- a/src/passwd.c ++++ b/src/passwd.c +@@ -280,6 +280,9 @@ static int new_password (const struct passwd *pw) + || (strcmp (method, "SHA256") == 0) + || (strcmp (method, "SHA512") == 0) + #endif /* USE_SHA_CRYPT */ ++#ifdef USE_SM3_CRYPT ++ || (strcmp (method, "SM3") == 0) ++#endif /* USE_SM3_CRYPT */ + #ifdef USE_BCRYPT + || (strcmp (method, "BCRYPT") == 0) + #endif /* USE_SHA_CRYPT */ +-- +1.8.3.1 + diff --git a/shadow.spec b/shadow.spec index 5b55aa55f2379d99ba9f15cb2395b9409e334758..0686823068b0f6b95f62b9beff1834190deb3366 100644 --- a/shadow.spec +++ b/shadow.spec @@ -1,6 +1,6 @@ Name: shadow Version: 4.8.1 -Release: 7 +Release: 8 Epoch: 2 License: BSD and GPLv2+ Summary: Tools for managing accounts and shadow password files @@ -27,6 +27,7 @@ Patch10: man-zh_CN-fix-typo.patch Patch11: useradd-free-grp-to-avoid-leak.patch Patch12: useradd.c-fix-memleaks-of-grp.patch Patch13: useradd.c-fix-memleak-in-get_groups.patch +Patch14: shadow-add-sm3-crypt-support.patch BuildRequires: gcc, libselinux-devel, audit-libs-devel, libsemanage-devel BuildRequires: libacl-devel, libattr-devel @@ -173,6 +174,9 @@ done %{_mandir}/*/* %changelog +* Wed Dec 22 2021 wangcheng - 2:4.8.1-8 +- add sm3 crypt support + * Thu Sep 30 2021 steven Y.Gui - 2:4.8.1-7 - backport some patches to fix memory leak