diff options
| author | CoprDistGit <infra@openeuler.org> | 2023-10-12 11:50:23 +0000 |
|---|---|---|
| committer | CoprDistGit <infra@openeuler.org> | 2023-10-12 11:50:23 +0000 |
| commit | a39ad350cc564b3b46e6f75e2f9d1f26f646861e (patch) | |
| tree | 2c862b9103baa1192a30703077647caeac8d638c /shadow-add-sm3-crypt-support.patch | |
| parent | 9db7dc8abcf40be92578f61ae05c86ba78c65866 (diff) | |
automatic import of shadowopeneuler22.03_LTS
Diffstat (limited to 'shadow-add-sm3-crypt-support.patch')
| -rw-r--r-- | shadow-add-sm3-crypt-support.patch | 782 |
1 files changed, 782 insertions, 0 deletions
diff --git a/shadow-add-sm3-crypt-support.patch b/shadow-add-sm3-crypt-support.patch new file mode 100644 index 0000000..bfb5184 --- /dev/null +++ b/shadow-add-sm3-crypt-support.patch @@ -0,0 +1,782 @@ +From d7fa75bbd22a08b4e0b8c7e3ccab588c87d23835 Mon Sep 17 00:00:00 2001
+From: root <root@localhost.localdomain>
+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 | 46 ++++++++++++++------
+ src/newusers.c | 61 +++++++++++++++++++-------
+ src/passwd.c | 7 ++-
+ 10 files changed, 254 insertions(+), 50 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 924254a..dde1de8 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -274,6 +274,9 @@ AC_ARG_WITH(libcrack,
+ AC_ARG_WITH(sha-crypt,
+ [AS_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,
++ [AS_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,
+ [AS_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])
+@@ -752,6 +760,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 114dbcd..fd310b7 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 c84a255..11b301b 100644
+--- a/lib/encrypt.c
++++ b/lib/encrypt.c
+@@ -52,6 +52,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 dcd1fe7..9a8089a 100644
+--- a/lib/getdef.c
++++ b/lib/getdef.c
+@@ -102,6 +102,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 3daaa95..644259d 100644
+--- a/libmisc/obscure.c
++++ b/libmisc/obscure.c
+@@ -246,6 +246,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 e5f633a..df4b328 100644
+--- a/libmisc/salt.c
++++ b/libmisc/salt.c
+@@ -63,6 +63,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.
+@@ -95,13 +106,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@*/unsigned long SHA_get_salt_rounds (/*@null@*/const 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@*/unsigned long BCRYPT_get_salt_rounds (/*@null@*/const int *prefered_rounds);
+ static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds);
+@@ -195,7 +210,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).
+ *
+@@ -217,7 +232,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. */
+@@ -293,6 +308,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@*/unsigned long BCRYPT_get_salt_rounds (/*@null@*/const int *prefered_rounds)
+@@ -463,7 +552,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).
+ */
+@@ -515,6 +604,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 (log_get_logfd(),
+ _("Invalid ENCRYPT_METHOD value: '%s'.\n"
+diff --git a/src/chgpasswd.c b/src/chgpasswd.c
+index d17acb6..9b00520 100644
+--- a/src/chgpasswd.c
++++ b/src/chgpasswd.c
+@@ -39,15 +39,18 @@
+ const char *Prog;
+ 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
+@@ -119,6 +122,9 @@ static /*@noreturn@*/void usage (int status)
+ #if defined(USE_YESCRYPT)
+ " YESCRYPT"
+ #endif
++#if defined(USE_SM3_CRYPT)
++ " SM3"
++ #endif
+ );
+ (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
+ (void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
+@@ -126,11 +132,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);
+@@ -144,22 +150,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:",
+@@ -180,7 +186,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;
+@@ -202,6 +208,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"),
+@@ -209,7 +221,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);
+@@ -228,7 +240,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"),
+@@ -259,6 +271,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"),
+@@ -483,7 +498,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"))
+@@ -501,6 +516,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 48d5178..9003c18 100644
+--- a/src/chpasswd.c
++++ b/src/chpasswd.c
+@@ -38,7 +38,7 @@
+ const char *Prog;
+ 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
+
+@@ -47,6 +47,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
+@@ -113,6 +116,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);
+@@ -121,11 +127,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);
+@@ -139,23 +145,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:",
+@@ -176,7 +182,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;
+@@ -198,14 +204,20 @@ static void process_flags (int argc, char **argv)
+ bad_s = 1;
+ }
+ #endif /* USE_YESCRYPT */
+- if (bad_s != 0) {
++#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"),
+ Prog, optarg);
+ 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);
+@@ -224,7 +236,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"),
+@@ -249,6 +261,9 @@ static void check_flags (void)
+ &&(!IS_CRYPT_METHOD("SHA256"))
+ &&(!IS_CRYPT_METHOD("SHA512"))
+ #endif /* USE_SHA_CRYPT */
++#ifdef USE_SM3_CRYPT
++ &&(!IS_CRYPT_METHOD("SM3"))
++#endif /* USE_SM3_CRYPT */
+ #ifdef USE_BCRYPT
+ &&(!IS_CRYPT_METHOD("BCRYPT"))
+ #endif /* USE_BCRYPT */
+@@ -422,6 +437,11 @@ static const char *get_salt(void)
+ arg = &yescrypt_cost;
+ }
+ #endif /* USE_YESCRYPT */
++#if defined(USE_SM3_CRYPT)
++ if (IS_CRYPT_METHOD("SM3")) {
++ arg = &sm3_rounds;
++ }
++#endif /* USE_SM3_CRYPT */
+ }
+ #endif
+ return crypt_make_salt (crypt_method, arg);
+diff --git a/src/newusers.c b/src/newusers.c
+index deeb361..149670e 100644
+--- a/src/newusers.c
++++ b/src/newusers.c
+@@ -58,12 +58,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 */
+@@ -129,6 +132,9 @@ static void usage (int status)
+ #endif
+ #if defined(USE_YESCRYPT)
+ " YESCRYPT"
++#endif
++#if defined(USE_SM3_CRYPT)
++ " SM3"
+ #endif
+ );
+ #endif /* !USE_PAM */
+@@ -136,11 +142,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);
+
+@@ -436,6 +442,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"))) {
+@@ -492,6 +505,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 */
+ }
+
+ /*
+@@ -609,9 +629,9 @@ static void process_flags (int argc, char **argv)
+ {
+ int c;
+ #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)
+ int bad_s;
+-#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
++#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT || USE_SM3_CRYPT */
+ #endif /* !USE_PAM */
+ static struct option long_options[] = {
+ {"badname", no_argument, NULL, 'b'},
+@@ -622,20 +642,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
+@@ -658,7 +678,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;
+@@ -680,14 +700,20 @@ static void process_flags (int argc, char **argv)
+ bad_s = 1;
+ }
+ #endif /* USE_YESCRYPT */
+- if (bad_s != 0) {
++#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"),
+ Prog, optarg);
+ 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);
+@@ -721,14 +747,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"))
+@@ -738,6 +764,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 8c6f81a..00711da 100644
+--- a/src/passwd.c
++++ b/src/passwd.c
+@@ -84,7 +84,7 @@ static bool spw_locked = false;
+ #ifndef USE_PAM
+ /*
+ * Size of the biggest passwd:
+- * $6$ 3
++ * $sm3$ 5
+ * rounds= 7
+ * 999999999 9
+ * $ 1
+@@ -93,7 +93,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;
+@@ -263,6 +263,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
+
|
