Merge pull request #303 from breard-r/yescrypt

Add yescrypt support
This commit is contained in:
Serge Hallyn 2021-03-28 22:13:56 -05:00 committed by GitHub
commit 697901a328
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 322 additions and 165 deletions

View File

@ -290,6 +290,9 @@ AC_ARG_WITH(sha-crypt,
AC_ARG_WITH(bcrypt, AC_ARG_WITH(bcrypt,
[AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])], [AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
[with_bcrypt=$withval], [with_bcrypt=no]) [with_bcrypt=$withval], [with_bcrypt=no])
AC_ARG_WITH(yescrypt,
[AC_HELP_STRING([--with-yescrypt], [allow the yescrypt password encryption algorithm @<:@default=no@:>@])],
[with_yescrypt=$withval], [with_yescrypt=no])
AC_ARG_WITH(nscd, AC_ARG_WITH(nscd,
[AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])], [AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
[with_nscd=$withval], [with_nscd=yes]) [with_nscd=$withval], [with_nscd=yes])
@ -322,6 +325,11 @@ if test "$with_bcrypt" = "yes"; then
AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm]) AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm])
fi fi
AM_CONDITIONAL(USE_YESCRYPT, test "x$with_yescrypt" = "xyes")
if test "$with_yescrypt" = "yes"; then
AC_DEFINE(USE_YESCRYPT, 1, [Define to allow the yescrypt password encryption algorithm])
fi
if test "$with_nscd" = "yes"; then if test "$with_nscd" = "yes"; then
AC_CHECK_FUNC(posix_spawn, AC_CHECK_FUNC(posix_spawn,
[AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])], [AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])],
@ -402,6 +410,10 @@ AC_SUBST(LIBCRYPT)
AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt], AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt],
[AC_MSG_ERROR([crypt() not found])]) [AC_MSG_ERROR([crypt() not found])])
AC_SUBST(LIYESCRYPT)
AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt],
[AC_MSG_ERROR([crypt() not found])])
AC_SUBST(LIBACL) AC_SUBST(LIBACL)
if test "$with_acl" != "no"; then if test "$with_acl" != "no"; then
AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"]) AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"])
@ -752,6 +764,7 @@ echo " shadow group support: $enable_shadowgrp"
echo " S/Key support: $with_skey" echo " S/Key support: $with_skey"
echo " SHA passwords encryption: $with_sha_crypt" echo " SHA passwords encryption: $with_sha_crypt"
echo " bcrypt passwords encryption: $with_bcrypt" echo " bcrypt passwords encryption: $with_bcrypt"
echo " yescrypt passwords encryption: $with_yescrypt"
echo " nscd support: $with_nscd" echo " nscd support: $with_nscd"
echo " sssd support: $with_sssd" echo " sssd support: $with_sssd"
echo " subordinate IDs support: $enable_subids" echo " subordinate IDs support: $enable_subids"

View File

@ -326,6 +326,7 @@ CHFN_RESTRICT rwh
# If set to SHA256, SHA256-based algorithm will be used for encrypting password # If set to SHA256, SHA256-based algorithm will be used for encrypting password
# If set to SHA512, SHA512-based algorithm will be used for encrypting password # If set to SHA512, SHA512-based algorithm will be used for encrypting password
# If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password # If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password
# If set to YESCRYPT, YESCRYPT-based algorithm will be used for encrypting password
# If set to DES, DES-based algorithm will be used for encrypting password (default) # If set to DES, DES-based algorithm will be used for encrypting password (default)
# MD5 and DES should not be used for new hashes, see crypt(5) for recommendations. # MD5 and DES should not be used for new hashes, see crypt(5) for recommendations.
# Overrides the MD5_CRYPT_ENAB option # Overrides the MD5_CRYPT_ENAB option
@ -367,6 +368,19 @@ CHFN_RESTRICT rwh
#BCRYPT_MIN_ROUNDS 13 #BCRYPT_MIN_ROUNDS 13
#BCRYPT_MAX_ROUNDS 13 #BCRYPT_MAX_ROUNDS 13
#
# Only works if ENCRYPT_METHOD is set to YESCRYPT.
#
# Define the YESCRYPT cost factor.
# With a higher cost factor, it is more difficult to brute-force the password.
# However, more CPU time and more memory will be needed to authenticate users
# if this value is increased.
#
# If not specified, a cost factor of 5 will be used.
# The value must be within the 1-11 range.
#
#YESCRYPT_COST_FACTOR 5
# #
# List of groups to add to the user's supplementary group set # List of groups to add to the user's supplementary group set
# when logging in from the console (as determined by the CONSOLE # when logging in from the console (as determined by the CONSOLE

View File

@ -74,6 +74,9 @@
case '6': case '6':
method = "SHA512"; method = "SHA512";
break; break;
case 'y':
method = "YESCRYPT";
break;
default: default:
{ {
static char nummethod[4] = "$x$"; static char nummethod[4] = "$x$";

View File

@ -126,6 +126,9 @@ static struct itemdef def_table[] = {
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
{"BCRYPT_MAX_ROUNDS", NULL}, {"BCRYPT_MAX_ROUNDS", NULL},
{"BCRYPT_MIN_ROUNDS", NULL}, {"BCRYPT_MIN_ROUNDS", NULL},
#endif
#ifdef USE_YESCRYPT
{"YESCRYPT_COST_FACTOR", NULL},
#endif #endif
{"SUB_GID_COUNT", NULL}, {"SUB_GID_COUNT", NULL},
{"SUB_GID_MAX", NULL}, {"SUB_GID_MAX", NULL},

View File

@ -271,6 +271,9 @@ static /*@observer@*//*@null@*/const char *obscure_msg (
#endif #endif
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
|| (strcmp (result, "BCRYPT") == 0) || (strcmp (result, "BCRYPT") == 0)
#endif
#ifdef USE_YESCRYPT
|| (strcmp (result, "YESCRYPT") == 0)
#endif #endif
) { ) {
return NULL; return NULL;

View File

@ -32,6 +32,10 @@ static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds
static /*@observer@*/const char *gensalt_bcrypt (void); static /*@observer@*/const char *gensalt_bcrypt (void);
static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds); static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds);
#endif /* USE_BCRYPT */ #endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
static /*@observer@*/const char *gensalt_yescrypt (void);
static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_rounds);
#endif /* USE_YESCRYPT */
#ifndef HAVE_L64A #ifndef HAVE_L64A
static /*@observer@*/char *l64a(long value) static /*@observer@*/char *l64a(long value)
@ -263,6 +267,78 @@ static /*@observer@*/const char *gensalt_bcrypt (void)
} }
#endif /* USE_BCRYPT */ #endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
/* Default cost if not explicitly specified. */
#define Y_COST_DEFAULT 5
/* Minimum cost. */
#define Y_COST_MIN 1
/* Maximum cost. */
#define Y_COST_MAX 11
/*
* Return a salt prefix specifying the cost for the YESCRYPT method.
*/
static /*@observer@*/const char *YESCRYPT_salt_cost (/*@null@*/long *prefered_cost)
{
static char cost_prefix[5];
long cost;
if (NULL == prefered_cost) {
cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT);
} else {
cost = *prefered_cost;
}
if (cost < Y_COST_MIN) {
cost = Y_COST_MIN;
}
if (cost > Y_COST_MAX) {
cost = Y_COST_MAX;
}
cost_prefix[0] = 'j';
if (cost < 3) {
cost_prefix[1] = 0x36 + cost;
} else if (cost < 6) {
cost_prefix[1] = 0x34 + cost;
} else {
cost_prefix[1] = 0x3b + cost;
}
cost_prefix[2] = cost >= 3 ? 'T' : '5';
cost_prefix[3] = '$';
cost_prefix[4] = 0;
return cost_prefix;
}
/*
* Default number of base64 characters used for the salt.
* 24 characters gives a 144 bits (18 bytes) salt. Unlike the more
* traditional 128 bits (16 bytes) salt, this 144 bits salt is always
* represented by the same number of base64 characters without padding
* issue, even with a non-standard base64 encoding scheme.
*/
#define YESCRYPT_SALT_SIZE 24
/*
* Generate a 22 character salt string for yescrypt.
*/
static /*@observer@*/const char *gensalt_yescrypt (void)
{
static char salt[32];
salt[0] = '\0';
seedRNG ();
strcat (salt, l64a (random()));
do {
strcat (salt, l64a (random()));
} while (strlen (salt) < YESCRYPT_SALT_SIZE);
salt[YESCRYPT_SALT_SIZE] = '\0';
return salt;
}
#endif /* USE_YESCRYPT */
/* /*
* Generate salt of size salt_size. * Generate salt of size salt_size.
*/ */
@ -302,6 +378,7 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
* If meth is specified, an additional parameter can be provided. * 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 method, this specifies the number of rounds
* (if not NULL). * (if not NULL).
* * For the YESCRYPT method, this specifies the cost factor (if not NULL).
*/ */
/*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg) /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg)
{ {
@ -333,6 +410,11 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
BCRYPTMAGNUM(result); BCRYPTMAGNUM(result);
strcat(result, BCRYPT_salt_rounds((int *)arg)); strcat(result, BCRYPT_salt_rounds((int *)arg));
#endif /* USE_BCRYPT */ #endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
} else if (0 == strcmp (method, "YESCRYPT")) {
MAGNUM(result, 'y');
strcat(result, YESCRYPT_salt_cost((int *)arg));
#endif /* USE_YESCRYPT */
#ifdef USE_SHA_CRYPT #ifdef USE_SHA_CRYPT
} else if (0 == strcmp (method, "SHA256")) { } else if (0 == strcmp (method, "SHA256")) {
MAGNUM(result, '5'); MAGNUM(result, '5');
@ -362,11 +444,21 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
return result; return result;
} else { } else {
#endif /* USE_BCRYPT */ #endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
if (0 == strcmp (method, "YESCRYPT")) {
strncat (result, gensalt_yescrypt (),
sizeof (result) - strlen (result) - 1);
return result;
} else {
#endif /* USE_YESCRYPT */
strncat (result, gensalt (salt_len), strncat (result, gensalt (salt_len),
sizeof (result) - strlen (result) - 1); sizeof (result) - strlen (result) - 1);
#ifdef USE_YESCRYPT
}
#endif /* USE_YESCRYPT */
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
} }
#endif /* USE_BCRYPT */ #endif /* USE_BCRYPT */
return result; return result;
} }

View File

@ -61,9 +61,9 @@
const char *Prog; const char *Prog;
static bool eflg = false; static bool eflg = false;
static bool md5flg = false; static bool md5flg = false;
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
static bool sflg = false; static bool sflg = false;
#endif /* USE_SHA_CRYPT || USE_BCRYPT */ #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
static /*@null@*//*@observer@*/const char *crypt_method = NULL; static /*@null@*//*@observer@*/const char *crypt_method = NULL;
#define cflg (NULL != crypt_method) #define cflg (NULL != crypt_method)
@ -73,6 +73,9 @@ static long sha_rounds = 5000;
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
static long bcrypt_rounds = 13; static long bcrypt_rounds = 13;
#endif #endif
#ifdef USE_YESCRYPT
static long yescrypt_cost = 5;
#endif
#ifdef SHADOWGRP #ifdef SHADOWGRP
static bool is_shadow_grp; static bool is_shadow_grp;
@ -128,14 +131,15 @@ static /*@noreturn@*/void usage (int status)
Prog); Prog);
(void) fprintf (usageout, (void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
"NONE DES MD5" "NONE DES MD5"
#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT)
"NONE DES MD5 SHA256 SHA512 BCRYPT" " SHA256 SHA512"
#elif defined(USE_SHA_CRYPT) #endif
"NONE DES MD5 SHA256 SHA512" #if defined(USE_BCRYPT)
#else " BCRYPT"
"NONE DES MD5 BCRYPT" #endif
#if defined(USE_YESCRYPT)
" YESCRYPT"
#endif #endif
); );
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
@ -144,11 +148,11 @@ static /*@noreturn@*/void usage (int status)
" the MD5 algorithm\n"), " the MD5 algorithm\n"),
usageout); usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
(void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
" crypt algorithms\n"), " or YESCRYPT crypt algorithms\n"),
usageout); usageout);
#endif /* USE_SHA_CRYPT || USE_BCRYPT */ #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
(void) fputs ("\n", usageout); (void) fputs ("\n", usageout);
exit (status); exit (status);
@ -162,19 +166,22 @@ static /*@noreturn@*/void usage (int status)
static void process_flags (int argc, char **argv) static void process_flags (int argc, char **argv)
{ {
int c; int c;
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
int bad_s;
#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
static struct option long_options[] = { static struct option long_options[] = {
{"crypt-method", required_argument, NULL, 'c'}, {"crypt-method", required_argument, NULL, 'c'},
{"encrypted", no_argument, NULL, 'e'}, {"encrypted", no_argument, NULL, 'e'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"md5", no_argument, NULL, 'm'}, {"md5", no_argument, NULL, 'm'},
{"root", required_argument, NULL, 'R'}, {"root", required_argument, NULL, 'R'},
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
{"sha-rounds", required_argument, NULL, 's'}, {"sha-rounds", required_argument, NULL, 's'},
#endif /* USE_SHA_CRYPT || USE_BCRYPT */ #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
{NULL, 0, NULL, '\0'} {NULL, 0, NULL, '\0'}
}; };
while ((c = getopt_long (argc, argv, while ((c = getopt_long (argc, argv,
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
"c:ehmR:s:", "c:ehmR:s:",
#else #else
"c:ehmR:", "c:ehmR:",
@ -195,40 +202,36 @@ static void process_flags (int argc, char **argv)
break; break;
case 'R': /* no-op, handled in process_root_flag () */ case 'R': /* no-op, handled in process_root_flag () */
break; break;
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
case 's': case 's':
sflg = true; sflg = true;
bad_s = 0;
#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
&& (0 == getlong(optarg, &sha_rounds))) && (0 == getlong(optarg, &sha_rounds)))) {
|| ( (0 == strcmp (crypt_method, "BCRYPT")) bad_s = 1;
}
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (0 == getlong(optarg, &bcrypt_rounds)))) { && (0 == getlong(optarg, &bcrypt_rounds)))) {
bad_s = 1;
}
#endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (( (0 == strcmp (crypt_method, "YESCRYPT"))
&& (0 == getlong(optarg, &yescrypt_cost)))) {
bad_s = 1;
}
#endif /* USE_YESCRYPT */
if (bad_s != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"), _("%s: invalid numeric argument '%s'\n"),
Prog, optarg); Prog, optarg);
usage (E_USAGE); usage (E_USAGE);
} }
break; break;
#elif defined(USE_SHA_CRYPT) #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
case 's':
sflg = true;
if (0 == getlong(optarg, &sha_rounds)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (E_USAGE);
}
break;
#elif defined(USE_BCRYPT)
case 's':
sflg = true;
if (0 == getlong(optarg, &bcrypt_rounds)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (E_USAGE);
}
break;
#endif
default: default:
usage (E_USAGE); usage (E_USAGE);
@ -247,7 +250,7 @@ static void process_flags (int argc, char **argv)
*/ */
static void check_flags (void) static void check_flags (void)
{ {
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg && !cflg) { if (sflg && !cflg) {
fprintf (stderr, fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"), _("%s: %s flag is only allowed with the %s flag\n"),
@ -271,10 +274,13 @@ static void check_flags (void)
#ifdef USE_SHA_CRYPT #ifdef USE_SHA_CRYPT
&& (0 != strcmp (crypt_method, "SHA256")) && (0 != strcmp (crypt_method, "SHA256"))
&& (0 != strcmp (crypt_method, "SHA512")) && (0 != strcmp (crypt_method, "SHA512"))
#endif #endif /* USE_SHA_CRYPT */
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
&& (0 != strcmp (crypt_method, "BCRYPT")) && (0 != strcmp (crypt_method, "BCRYPT"))
#endif #endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
&& (0 != strcmp (crypt_method, "YESCRYPT"))
#endif /* USE_YESCRYPT */
) { ) {
fprintf (stderr, fprintf (stderr,
_("%s: unsupported crypt method: %s\n"), _("%s: unsupported crypt method: %s\n"),
@ -497,23 +503,24 @@ int main (int argc, char **argv)
if (md5flg) { if (md5flg) {
crypt_method = "MD5"; crypt_method = "MD5";
} }
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg) { if (sflg) {
#if defined(USE_SHA_CRYPT)
if ( (0 == strcmp (crypt_method, "SHA256")) if ( (0 == strcmp (crypt_method, "SHA256"))
|| (0 == strcmp (crypt_method, "SHA512"))) { || (0 == strcmp (crypt_method, "SHA512"))) {
arg = &sha_rounds; arg = &sha_rounds;
} }
else if (0 == strcmp (crypt_method, "BCRYPT")) { #endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (0 == strcmp (crypt_method, "BCRYPT")) {
arg = &bcrypt_rounds; arg = &bcrypt_rounds;
} }
} #endif /* USE_BCRYPT */
#elif defined(USE_SHA_CRYPT) #if defined(USE_YESCRYPT)
if (sflg) { if (0 == strcmp (crypt_method, "YESCRYPT")) {
arg = &sha_rounds; arg = &yescrypt_cost;
} }
#elif defined(USE_BCRYPT) #endif /* USE_YESCRYPT */
if (sflg) {
arg = &bcrypt_rounds;
} }
#endif #endif
salt = crypt_make_salt (crypt_method, arg); salt = crypt_make_salt (crypt_method, arg);

View File

@ -58,7 +58,7 @@
const char *Prog; const char *Prog;
static bool eflg = false; static bool eflg = false;
static bool md5flg = false; static bool md5flg = false;
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
static bool sflg = false; static bool sflg = false;
#endif #endif
@ -70,6 +70,9 @@ static long sha_rounds = 5000;
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
static long bcrypt_rounds = 13; static long bcrypt_rounds = 13;
#endif #endif
#ifdef USE_YESCRYPT
static long yescrypt_cost = 5;
#endif
static bool is_shadow_pwd; static bool is_shadow_pwd;
static bool pw_locked = false; static bool pw_locked = false;
@ -121,14 +124,15 @@ static /*@noreturn@*/void usage (int status)
Prog); Prog);
(void) fprintf (usageout, (void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
"NONE DES MD5" "NONE DES MD5"
#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT)
"NONE DES MD5 SHA256 SHA512 BCRYPT" " SHA256 SHA512"
#elif defined(USE_SHA_CRYPT) #endif
"NONE DES MD5 SHA256 SHA512" #if defined(USE_BCRYPT)
#else " BCRYPT"
"NONE DES MD5 BCRYPT" #endif
#if defined(USE_YESCRYPT)
" YESCRYPT"
#endif #endif
); );
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout); (void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
@ -137,11 +141,11 @@ static /*@noreturn@*/void usage (int status)
" the MD5 algorithm\n"), " the MD5 algorithm\n"),
usageout); usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
(void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
" crypt algorithms\n"), " or YESCRYPT crypt algorithms\n"),
usageout); usageout);
#endif /* USE_SHA_CRYPT || USE_BCRYPT */ #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
(void) fputs ("\n", usageout); (void) fputs ("\n", usageout);
exit (status); exit (status);
@ -155,20 +159,23 @@ static /*@noreturn@*/void usage (int status)
static void process_flags (int argc, char **argv) static void process_flags (int argc, char **argv)
{ {
int c; int c;
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
int bad_s;
#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
static struct option long_options[] = { static struct option long_options[] = {
{"crypt-method", required_argument, NULL, 'c'}, {"crypt-method", required_argument, NULL, 'c'},
{"encrypted", no_argument, NULL, 'e'}, {"encrypted", no_argument, NULL, 'e'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"md5", no_argument, NULL, 'm'}, {"md5", no_argument, NULL, 'm'},
{"root", required_argument, NULL, 'R'}, {"root", required_argument, NULL, 'R'},
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
{"sha-rounds", required_argument, NULL, 's'}, {"sha-rounds", required_argument, NULL, 's'},
#endif /* USE_SHA_CRYPT || USE_BCRYPT */ #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
{NULL, 0, NULL, '\0'} {NULL, 0, NULL, '\0'}
}; };
while ((c = getopt_long (argc, argv, while ((c = getopt_long (argc, argv,
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
"c:ehmR:s:", "c:ehmR:s:",
#else #else
"c:ehmR:", "c:ehmR:",
@ -189,40 +196,36 @@ static void process_flags (int argc, char **argv)
break; break;
case 'R': /* no-op, handled in process_root_flag () */ case 'R': /* no-op, handled in process_root_flag () */
break; break;
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
case 's': case 's':
sflg = true; sflg = true;
bad_s = 0;
#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
&& (0 == getlong(optarg, &sha_rounds))) && (0 == getlong(optarg, &sha_rounds)))) {
|| ( (0 == strcmp (crypt_method, "BCRYPT")) bad_s = 1;
}
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (0 == getlong(optarg, &bcrypt_rounds)))) { && (0 == getlong(optarg, &bcrypt_rounds)))) {
bad_s = 1;
}
#endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (( (0 == strcmp (crypt_method, "YESCRYPT"))
&& (0 == getlong(optarg, &yescrypt_cost)))) {
bad_s = 1;
}
#endif /* USE_YESCRYPT */
if (bad_s != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"), _("%s: invalid numeric argument '%s'\n"),
Prog, optarg); Prog, optarg);
usage (E_USAGE); usage (E_USAGE);
} }
break; break;
#elif defined(USE_SHA_CRYPT) #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
case 's':
sflg = true;
if (0 == getlong(optarg, &sha_rounds)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (E_USAGE);
}
break;
#elif defined(USE_BCRYPT)
case 's':
sflg = true;
if (0 == getlong(optarg, &bcrypt_rounds)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (E_USAGE);
}
break;
#endif
default: default:
usage (E_USAGE); usage (E_USAGE);
@ -241,7 +244,7 @@ static void process_flags (int argc, char **argv)
*/ */
static void check_flags (void) static void check_flags (void)
{ {
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg && !cflg) { if (sflg && !cflg) {
fprintf (stderr, fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"), _("%s: %s flag is only allowed with the %s flag\n"),
@ -269,6 +272,9 @@ static void check_flags (void)
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
&& (0 != strcmp (crypt_method, "BCRYPT")) && (0 != strcmp (crypt_method, "BCRYPT"))
#endif /* USE_BCRYPT */ #endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
&& (0 != strcmp (crypt_method, "YESCRYPT"))
#endif /* USE_YESCRYPT */
) { ) {
fprintf (stderr, fprintf (stderr,
_("%s: unsupported crypt method: %s\n"), _("%s: unsupported crypt method: %s\n"),
@ -530,23 +536,24 @@ int main (int argc, char **argv)
if (md5flg) { if (md5flg) {
crypt_method = "MD5"; crypt_method = "MD5";
} }
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg) { if (sflg) {
#if defined(USE_SHA_CRYPT)
if ( (0 == strcmp (crypt_method, "SHA256")) if ( (0 == strcmp (crypt_method, "SHA256"))
|| (0 == strcmp (crypt_method, "SHA512"))) { || (0 == strcmp (crypt_method, "SHA512"))) {
arg = &sha_rounds; arg = &sha_rounds;
} }
else if (0 == strcmp (crypt_method, "BCRYPT")) { #endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (0 == strcmp (crypt_method, "BCRYPT")) {
arg = &bcrypt_rounds; arg = &bcrypt_rounds;
} }
} #endif /* USE_BCRYPT */
#elif defined(USE_SHA_CRYPT) #if defined(USE_YESCRYPT)
if (sflg) { if (0 == strcmp (crypt_method, "YESCRYPT")) {
arg = &sha_rounds; arg = &yescrypt_cost;
} }
#elif defined(USE_BCRYPT) #endif /* USE_YESCRYPT */
if (sflg) {
arg = &bcrypt_rounds;
} }
#endif #endif
salt = crypt_make_salt (crypt_method, arg); salt = crypt_make_salt (crypt_method, arg);

View File

@ -89,6 +89,9 @@ static long sha_rounds = 5000;
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
static long bcrypt_rounds = 13; static long bcrypt_rounds = 13;
#endif /* USE_BCRYPT */ #endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
static long yescrypt_cost = 5;
#endif /* USE_YESCRYPT */
#endif /* !USE_PAM */ #endif /* !USE_PAM */
static bool is_shadow; static bool is_shadow;
@ -139,14 +142,15 @@ static void usage (int status)
#ifndef USE_PAM #ifndef USE_PAM
(void) fprintf (usageout, (void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT) "NONE DES MD5"
"NONE DES MD5" #if defined(USE_SHA_CRYPT)
#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) " SHA256 SHA512"
"NONE DES MD5 SHA256 SHA512 BCRYPT" #endif
#elif defined(USE_SHA_CRYPT) #if defined(USE_BCRYPT)
"NONE DES MD5 SHA256 SHA512" " BCRYPT"
#else #endif
"NONE DES MD5 BCRYPT" #if defined(USE_YESCRYPT)
" YESCRYPT"
#endif #endif
); );
#endif /* !USE_PAM */ #endif /* !USE_PAM */
@ -154,11 +158,11 @@ static void usage (int status)
(void) fputs (_(" -r, --system create system accounts\n"), usageout); (void) fputs (_(" -r, --system create system accounts\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
#ifndef USE_PAM #ifndef USE_PAM
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
(void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n" (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
" crypt algorithms\n"), " or YESCRYPT crypt algorithms\n"),
usageout); usageout);
#endif /* USE_SHA_CRYPT || USE_BCRYPT */ #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#endif /* !USE_PAM */ #endif /* !USE_PAM */
(void) fputs ("\n", usageout); (void) fputs ("\n", usageout);
@ -433,25 +437,28 @@ static int update_passwd (struct passwd *pwd, const char *password)
void *crypt_arg = NULL; void *crypt_arg = NULL;
char *cp; char *cp;
if (NULL != crypt_method) { if (NULL != crypt_method) {
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT)
if (sflg) { if (sflg) {
if ( (0 == strcmp (crypt_method, "SHA256")) if ( (0 == strcmp (crypt_method, "SHA256"))
|| (0 == strcmp (crypt_method, "SHA512"))) { || (0 == strcmp (crypt_method, "SHA512"))) {
crypt_arg = &sha_rounds; crypt_arg = &sha_rounds;
} }
else if (0 == strcmp (crypt_method, "BCRYPT")) { }
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (sflg) {
if (0 == strcmp (crypt_method, "BCRYPT")) {
crypt_arg = &bcrypt_rounds; crypt_arg = &bcrypt_rounds;
} }
} }
#elif defined(USE_SHA_CRYPT) #endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (sflg) { if (sflg) {
crypt_arg = &sha_rounds; if (0 == strcmp (crypt_method, "YESCRYPT")) {
crypt_arg = &yescrypt_cost;
}
} }
#elif defined(USE_BCRYPT) #endif /* USE_YESCRYPT */
if (sflg) {
crypt_arg = &bcrypt_rounds;
}
#endif
} }
if ((NULL != crypt_method) && (0 == strcmp(crypt_method, "NONE"))) { if ((NULL != crypt_method) && (0 == strcmp(crypt_method, "NONE"))) {
@ -484,25 +491,28 @@ static int add_passwd (struct passwd *pwd, const char *password)
#ifndef USE_PAM #ifndef USE_PAM
void *crypt_arg = NULL; void *crypt_arg = NULL;
if (NULL != crypt_method) { if (NULL != crypt_method) {
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT)
if (sflg) { if (sflg) {
if ( (0 == strcmp (crypt_method, "SHA256")) if ( (0 == strcmp (crypt_method, "SHA256"))
|| (0 == strcmp (crypt_method, "SHA512"))) { || (0 == strcmp (crypt_method, "SHA512"))) {
crypt_arg = &sha_rounds; crypt_arg = &sha_rounds;
} }
else if (0 == strcmp (crypt_method, "BCRYPT")) { }
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (sflg) {
if (0 == strcmp (crypt_method, "BCRYPT")) {
crypt_arg = &bcrypt_rounds; crypt_arg = &bcrypt_rounds;
} }
} }
#elif defined(USE_SHA_CRYPT) #endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (sflg) { if (sflg) {
crypt_arg = &sha_rounds; if (0 == strcmp (crypt_method, "YESCRYPT")) {
crypt_arg = &yescrypt_cost;
}
} }
#elif defined(USE_BCRYPT) #endif /* USE_PAM */
if (sflg) {
crypt_arg = &bcrypt_rounds;
}
#endif
} }
/* /*
@ -619,6 +629,9 @@ static int add_passwd (struct passwd *pwd, const char *password)
static void process_flags (int argc, char **argv) static void process_flags (int argc, char **argv)
{ {
int c; int c;
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
int bad_s;
#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
static struct option long_options[] = { static struct option long_options[] = {
{"badnames", no_argument, NULL, 'b'}, {"badnames", no_argument, NULL, 'b'},
#ifndef USE_PAM #ifndef USE_PAM
@ -628,20 +641,20 @@ static void process_flags (int argc, char **argv)
{"system", no_argument, NULL, 'r'}, {"system", no_argument, NULL, 'r'},
{"root", required_argument, NULL, 'R'}, {"root", required_argument, NULL, 'R'},
#ifndef USE_PAM #ifndef USE_PAM
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
{"sha-rounds", required_argument, NULL, 's'}, {"sha-rounds", required_argument, NULL, 's'},
#endif /* USE_SHA_CRYPT || USE_BCRYPT */ #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#endif /* !USE_PAM */ #endif /* !USE_PAM */
{NULL, 0, NULL, '\0'} {NULL, 0, NULL, '\0'}
}; };
while ((c = getopt_long (argc, argv, while ((c = getopt_long (argc, argv,
#ifndef USE_PAM #ifndef USE_PAM
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
"c:bhrs:", "c:bhrs:",
#else /* !USE_SHA_CRYPT && !USE_BCRYPT */ #else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */
"c:bhr", "c:bhr",
#endif /* USE_SHA_CRYPT || USE_BCRYPT */ #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
#else /* USE_PAM */ #else /* USE_PAM */
"bhr", "bhr",
#endif #endif
@ -664,40 +677,36 @@ static void process_flags (int argc, char **argv)
case 'R': /* no-op, handled in process_root_flag () */ case 'R': /* no-op, handled in process_root_flag () */
break; break;
#ifndef USE_PAM #ifndef USE_PAM
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
case 's': case 's':
sflg = true; sflg = true;
bad_s = 0;
#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
&& (0 == getlong(optarg, &sha_rounds))) && (0 == getlong(optarg, &sha_rounds)))) {
|| ( (0 == strcmp (crypt_method, "BCRYPT")) bad_s = 1;
}
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (0 == getlong(optarg, &bcrypt_rounds)))) { && (0 == getlong(optarg, &bcrypt_rounds)))) {
bad_s = 1;
}
#endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (( (0 == strcmp (crypt_method, "YESCRYPT"))
&& (0 == getlong(optarg, &yescrypt_cost)))) {
bad_s = 1;
}
#endif /* USE_YESCRYPT */
if (bad_s != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"), _("%s: invalid numeric argument '%s'\n"),
Prog, optarg); Prog, optarg);
usage (EXIT_FAILURE); usage (EXIT_FAILURE);
} }
break; break;
#elif defined(USE_SHA_CRYPT) #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
case 's':
sflg = true;
if (0 == getlong(optarg, &sha_rounds)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (EXIT_FAILURE);
}
break;
#elif defined(USE_BCRYPT)
case 's':
sflg = true;
if (0 == getlong(optarg, &bcrypt_rounds)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
usage (EXIT_FAILURE);
}
break;
#endif
#endif /* !USE_PAM */ #endif /* !USE_PAM */
default: default:
usage (EXIT_FAILURE); usage (EXIT_FAILURE);
@ -731,14 +740,14 @@ static void process_flags (int argc, char **argv)
static void check_flags (void) static void check_flags (void)
{ {
#ifndef USE_PAM #ifndef USE_PAM
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
if (sflg && !cflg) { if (sflg && !cflg) {
fprintf (stderr, fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"), _("%s: %s flag is only allowed with the %s flag\n"),
Prog, "-s", "-c"); Prog, "-s", "-c");
usage (EXIT_FAILURE); usage (EXIT_FAILURE);
} }
#endif #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
if (cflg) { if (cflg) {
if ( (0 != strcmp (crypt_method, "DES")) if ( (0 != strcmp (crypt_method, "DES"))
@ -751,6 +760,9 @@ static void check_flags (void)
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
&& (0 != strcmp (crypt_method, "BCRYPT")) && (0 != strcmp (crypt_method, "BCRYPT"))
#endif /* USE_BCRYPT */ #endif /* USE_BCRYPT */
#ifdef USE_YESCRYPT
&& (0 != strcmp (crypt_method, "YESCRYPT"))
#endif /* USE_YESCRYPT */
) { ) {
fprintf (stderr, fprintf (stderr,
_("%s: unsupported crypt method: %s\n"), _("%s: unsupported crypt method: %s\n"),

View File

@ -283,6 +283,9 @@ static int new_password (const struct passwd *pw)
#ifdef USE_BCRYPT #ifdef USE_BCRYPT
|| (strcmp (method, "BCRYPT") == 0) || (strcmp (method, "BCRYPT") == 0)
#endif /* USE_BCRYPT*/ #endif /* USE_BCRYPT*/
#ifdef USE_YESCRYPT
|| (strcmp (method, "YESCRYPT") == 0)
#endif /* USE_YESCRYPT*/
) { ) {
pass_max_len = -1; pass_max_len = -1;