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