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(bcrypt,
+ [AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
+ [with_bcrypt=$withval], [with_bcrypt=no])
AC_ARG_WITH(nscd,
[AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
[with_nscd=$withval], [with_nscd=yes])
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 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])
+fi
+
if test "$with_nscd" = "yes"; then
AC_CHECK_FUNC(posix_spawn,
[AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])],
echo " shadow group support: $enable_shadowgrp"
echo " S/Key support: $with_skey"
echo " SHA passwords encryption: $with_sha_crypt"
+echo " bcrypt passwords encryption: $with_bcrypt"
echo " nscd support: $with_nscd"
echo " sssd support: $with_sssd"
echo " subordinate IDs support: $enable_subids"
# If set to MD5, MD5-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 BCRYPT, BCRYPT-based algorithm will be used for encrypting password
# If set to DES, DES-based algorithm will be used for encrypting password (default)
# Overrides the MD5_CRYPT_ENAB option
#
#SHA_CRYPT_MIN_ROUNDS 5000
#SHA_CRYPT_MAX_ROUNDS 5000
+#
+# Only works if ENCRYPT_METHOD is set to BCRYPT.
+#
+# Define the number of BCRYPT 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, 13 rounds will be attempted.
+# 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.
+#
+#BCRYPT_MIN_ROUNDS 13
+#BCRYPT_MAX_ROUNDS 13
+
#
# List of groups to add to the user's supplementary group set
# when logging in from the console (as determined by the CONSOLE
case '1':
method = "MD5";
break;
+ case '2':
+ method = "BCRYPT";
+ break;
case '5':
method = "SHA256";
break;
#ifdef USE_SHA_CRYPT
{"SHA_CRYPT_MAX_ROUNDS", NULL},
{"SHA_CRYPT_MIN_ROUNDS", NULL},
+#endif
+#ifdef USE_BCRYPT
+ {"BCRYPT_MAX_ROUNDS", NULL},
+ {"BCRYPT_MIN_ROUNDS", NULL},
#endif
{"SUB_GID_COUNT", NULL},
{"SUB_GID_MAX", NULL},
#ifdef USE_SHA_CRYPT
|| (strcmp (result, "SHA256") == 0)
|| (strcmp (result, "SHA512") == 0)
+#endif
+#ifdef USE_BCRYPT
+ || (strcmp (result, "BCRYPT") == 0)
#endif
) {
return NULL;
/* local function prototypes */
static void seedRNG (void);
static /*@observer@*/const char *gensalt (size_t salt_size);
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
static long shadow_random (long min, long max);
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#ifdef USE_SHA_CRYPT
static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds);
#endif /* USE_SHA_CRYPT */
+#ifdef USE_BCRYPT
+static /*@observer@*/const char *gensalt_bcrypt (void);
+static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds);
+#endif /* USE_BCRYPT */
#ifndef HAVE_L64A
static /*@observer@*/char *l64a(long value)
* Add the salt prefix.
*/
#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0'
+#ifdef USE_BCRYPT
+/*
+ * Using the Prefix $2a$ to enable an anti-collision safety measure in musl libc.
+ * Negatively affects a subset of passwords containing the '\xff' character,
+ * which is not valid UTF-8 (so "unlikely to cause much annoyance").
+ */
+#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='a',(array)[4]='\0'
+#endif /* USE_BCRYPT */
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
/* It is not clear what is the maximum value of random().
* We assume 2^31-1.*/
#define RANDOM_MAX 0x7FFFFFFF
}
return ret;
}
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
+#ifdef USE_SHA_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
-
/*
* Return a salt prefix specifying the rounds number for the SHA crypt methods.
*/
}
#endif /* USE_SHA_CRYPT */
+#ifdef USE_BCRYPT
+/* Default number of rounds if not explicitly specified. */
+#define B_ROUNDS_DEFAULT 13
+/* Minimum number of rounds. */
+#define B_ROUNDS_MIN 4
+/* Maximum number of rounds. */
+#define B_ROUNDS_MAX 31
+/*
+ * Return a salt prefix specifying the rounds number for the BCRYPT method.
+ */
+static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds)
+{
+ static char rounds_prefix[4]; /* Max size: 31$ */
+ long rounds;
+
+ if (NULL == prefered_rounds) {
+ long min_rounds = getdef_long ("BCRYPT_MIN_ROUNDS", -1);
+ long max_rounds = getdef_long ("BCRYPT_MAX_ROUNDS", -1);
+
+ if (((-1 == min_rounds) && (-1 == max_rounds)) || (0 == *prefered_rounds)) {
+ rounds = B_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 = shadow_random (min_rounds, max_rounds);
+ }
+ } else {
+ rounds = *prefered_rounds;
+ }
+
+ /*
+ * Sanity checks.
+ * Use 19 as an upper bound for now,
+ * because musl doesn't allow rounds >= 20.
+ */
+ if (rounds < B_ROUNDS_MIN) {
+ rounds = B_ROUNDS_MIN;
+ }
+
+ if (rounds > 19) {
+ /* rounds = B_ROUNDS_MAX; */
+ rounds = 19;
+ }
+
+ (void) snprintf (rounds_prefix, sizeof rounds_prefix,
+ "%2.2ld$", rounds);
+
+ return rounds_prefix;
+}
+
+#define BCRYPT_SALT_SIZE 22
+/*
+ * Generate a 22 character salt string for bcrypt.
+ */
+static /*@observer@*/const char *gensalt_bcrypt (void)
+{
+ static char salt[32];
+
+ salt[0] = '\0';
+
+ seedRNG ();
+ strcat (salt, l64a (random()));
+ do {
+ strcat (salt, l64a (random()));
+ } while (strlen (salt) < BCRYPT_SALT_SIZE);
+
+ salt[BCRYPT_SALT_SIZE] = '\0';
+
+ return salt;
+}
+#endif /* USE_BCRYPT */
+
/*
* Generate salt of size salt_size.
*/
if (0 == strcmp (method, "MD5")) {
MAGNUM(result, '1');
+#ifdef USE_BCRYPT
+ } else if (0 == strcmp (method, "BCRYPT")) {
+ BCRYPTMAGNUM(result);
+ strcat(result, BCRYPT_salt_rounds((int *)arg));
+#endif /* USE_BCRYPT */
#ifdef USE_SHA_CRYPT
} else if (0 == strcmp (method, "SHA256")) {
MAGNUM(result, '5');
* Concatenate a pseudo random salt.
*/
assert (sizeof (result) > strlen (result) + salt_len);
- strncat (result, gensalt (salt_len),
- sizeof (result) - strlen (result) - 1);
+#ifdef USE_BCRYPT
+ if (0 == strcmp (method, "BCRYPT")) {
+ strncat (result, gensalt_bcrypt (),
+ sizeof (result) - strlen (result) - 1);
+ return result;
+ } else {
+#endif /* USE_BCRYPT */
+ strncat (result, gensalt (salt_len),
+ sizeof (result) - strlen (result) - 1);
+#ifdef USE_BCRYPT
+ }
+#endif /* USE_BCRYPT */
return result;
}
const char *Prog;
static bool eflg = false;
static bool md5flg = false;
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
static bool sflg = false;
-#endif
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
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_BCRYPT
+static long bcrypt_rounds = 13;
+#endif
#ifdef SHADOWGRP
static bool is_shadow_grp;
Prog);
(void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
-#ifndef USE_SHA_CRYPT
+#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
"NONE DES MD5"
-#else /* USE_SHA_CRYPT */
+#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+ "NONE DES MD5 SHA256 SHA512 BCRYPT"
+#elif defined(USE_SHA_CRYPT)
"NONE DES MD5 SHA256 SHA512"
-#endif /* USE_SHA_CRYPT */
+#else
+ "NONE DES MD5 BCRYPT"
+#endif
);
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
" the MD5 algorithm\n"),
usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
-#ifdef USE_SHA_CRYPT
- (void) fputs (_(" -s, --sha-rounds number of SHA rounds for the SHA*\n"
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n"
" crypt algorithms\n"),
usageout);
-#endif /* USE_SHA_CRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
(void) fputs ("\n", usageout);
exit (status);
{"help", no_argument, NULL, 'h'},
{"md5", no_argument, NULL, 'm'},
{"root", required_argument, NULL, 'R'},
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
{"sha-rounds", required_argument, NULL, 's'},
-#endif
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
{NULL, 0, NULL, '\0'}
};
-
while ((c = getopt_long (argc, argv,
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
"c:ehmR:s:",
#else
"c:ehmR:",
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
case 's':
sflg = true;
- if (getlong(optarg, &sha_rounds) == 0) {
+ 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)
+ 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);
}
break;
#endif
+
default:
usage (E_USAGE);
/*@notreached@*/break;
*/
static void check_flags (void)
{
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
if (sflg && !cflg) {
fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"),
#ifdef USE_SHA_CRYPT
&& (0 != strcmp (crypt_method, "SHA256"))
&& (0 != strcmp (crypt_method, "SHA512"))
+#endif
+#ifdef USE_BCRYPT
+ && (0 != strcmp (crypt_method, "BCRYPT"))
#endif
) {
fprintf (stderr,
if (md5flg) {
crypt_method = "MD5";
}
-#ifdef USE_SHA_CRYPT
+#if 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)
if (sflg) {
arg = &sha_rounds;
}
+#elif defined(USE_BCRYPT)
+ if (sflg) {
+ arg = &bcrypt_rounds;
+ }
#endif
salt = crypt_make_salt (crypt_method, arg);
cp = pw_encrypt (newpwd, salt);
const char *Prog;
static bool eflg = false;
static bool md5flg = false;
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
static bool sflg = false;
-#endif /* USE_SHA_CRYPT */
+#endif
static /*@null@*//*@observer@*/const char *crypt_method = NULL;
#define cflg (NULL != crypt_method)
#ifdef USE_SHA_CRYPT
static long sha_rounds = 5000;
-#endif /* USE_SHA_CRYPT */
+#endif
+#ifdef USE_BCRYPT
+static long bcrypt_rounds = 13;
+#endif
static bool is_shadow_pwd;
static bool pw_locked = false;
Prog);
(void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
-#ifndef USE_SHA_CRYPT
+#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
"NONE DES MD5"
-#else /* USE_SHA_CRYPT */
+#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+ "NONE DES MD5 SHA256 SHA512 BCRYPT"
+#elif defined(USE_SHA_CRYPT)
"NONE DES MD5 SHA256 SHA512"
-#endif /* USE_SHA_CRYPT */
+#else
+ "NONE DES MD5 BCRYPT"
+#endif
);
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
" the MD5 algorithm\n"),
usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
-#ifdef USE_SHA_CRYPT
- (void) fputs (_(" -s, --sha-rounds number of SHA rounds for the SHA*\n"
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n"
" crypt algorithms\n"),
usageout);
-#endif /* USE_SHA_CRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
(void) fputs ("\n", usageout);
exit (status);
{"help", no_argument, NULL, 'h'},
{"md5", no_argument, NULL, 'm'},
{"root", required_argument, NULL, 'R'},
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
{"sha-rounds", required_argument, NULL, 's'},
-#endif /* USE_SHA_CRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv,
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
"c:ehmR:s:",
-#else /* !USE_SHA_CRYPT */
+#else
"c:ehmR:",
-#endif /* !USE_SHA_CRYPT */
+#endif
long_options, NULL)) != -1) {
switch (c) {
case 'c':
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
case 's':
sflg = true;
- if (getlong(optarg, &sha_rounds) == 0) {
+ 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;
-#endif /* USE_SHA_CRYPT */
+#elif defined(USE_SHA_CRYPT)
+ 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:
usage (E_USAGE);
/*@notreached@*/break;
*/
static void check_flags (void)
{
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
if (sflg && !cflg) {
fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"),
&& (0 != strcmp (crypt_method, "SHA256"))
&& (0 != strcmp (crypt_method, "SHA512"))
#endif /* USE_SHA_CRYPT */
+#ifdef USE_BCRYPT
+ && (0 != strcmp (crypt_method, "BCRYPT"))
+#endif /* USE_BCRYPT */
) {
fprintf (stderr,
_("%s: unsupported crypt method: %s\n"),
if (md5flg) {
crypt_method = "MD5";
}
-#ifdef USE_SHA_CRYPT
+#if 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)
if (sflg) {
arg = &sha_rounds;
}
+#elif defined(USE_BCRYPT)
+ if (sflg) {
+ arg = &bcrypt_rounds;
+ }
#endif
salt = crypt_make_salt (crypt_method, arg);
cp = pw_encrypt (newpwd, salt);
#ifndef USE_PAM
static /*@null@*//*@observer@*/char *crypt_method = NULL;
#define cflg (NULL != crypt_method)
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
static bool sflg = false;
+#endif
+#ifdef USE_SHA_CRYPT
static long sha_rounds = 5000;
#endif /* USE_SHA_CRYPT */
+#ifdef USE_BCRYPT
+static long bcrypt_rounds = 13;
+#endif /* USE_BCRYPT */
#endif /* !USE_PAM */
static bool is_shadow;
#ifndef USE_PAM
(void) fprintf (usageout,
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
-#ifndef USE_SHA_CRYPT
+#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
"NONE DES MD5"
-#else /* USE_SHA_CRYPT */
+#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
+ "NONE DES MD5 SHA256 SHA512 BCRYPT"
+#elif defined(USE_SHA_CRYPT)
"NONE DES MD5 SHA256 SHA512"
-#endif /* USE_SHA_CRYPT */
+#else
+ "NONE DES MD5 BCRYPT"
+#endif
);
#endif /* !USE_PAM */
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
(void) fputs (_(" -r, --system create system accounts\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
#ifndef USE_PAM
-#ifdef USE_SHA_CRYPT
- (void) fputs (_(" -s, --sha-rounds number of SHA rounds for the SHA*\n"
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
+ (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n"
" crypt algorithms\n"),
usageout);
-#endif /* USE_SHA_CRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
#endif /* !USE_PAM */
(void) fputs ("\n", usageout);
{
void *crypt_arg = NULL;
char *cp;
- if (crypt_method != NULL) {
-#ifdef USE_SHA_CRYPT
+ if (NULL != crypt_method) {
+#if 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)
if (sflg) {
crypt_arg = &sha_rounds;
}
+#elif defined(USE_BCRYPT)
+ if (sflg) {
+ crypt_arg = &bcrypt_rounds;
+ }
#endif
}
- if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) {
+ if ((NULL != crypt_method) && (0 == strcmp(crypt_method, "NONE"))) {
pwd->pw_passwd = (char *)password;
} else {
const char *salt = crypt_make_salt (crypt_method, crypt_arg);
#ifndef USE_PAM
void *crypt_arg = NULL;
- if (crypt_method != NULL) {
-#ifdef USE_SHA_CRYPT
+ if (NULL != crypt_method) {
+#if 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)
if (sflg) {
crypt_arg = &sha_rounds;
}
-#endif /* USE_SHA_CRYPT */
+#elif defined(USE_BCRYPT)
+ if (sflg) {
+ crypt_arg = &bcrypt_rounds;
+ }
+#endif
}
/*
{"system", no_argument, NULL, 'r'},
{"root", required_argument, NULL, 'R'},
#ifndef USE_PAM
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
{"sha-rounds", required_argument, NULL, 's'},
-#endif /* USE_SHA_CRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
#endif /* !USE_PAM */
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv,
#ifndef USE_PAM
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
"c:bhrs:",
-#else /* !USE_SHA_CRYPT */
+#else /* !USE_SHA_CRYPT && !USE_BCRYPT */
"c:bhr",
-#endif /* !USE_SHA_CRYPT */
+#endif /* USE_SHA_CRYPT || USE_BCRYPT */
#else /* USE_PAM */
"bhr",
#endif
case 'R': /* no-op, handled in process_root_flag () */
break;
#ifndef USE_PAM
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
case 's':
sflg = true;
- if (getlong(optarg, &sha_rounds) == 0) {
+ 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;
-#endif /* USE_SHA_CRYPT */
+#elif defined(USE_SHA_CRYPT)
+ 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 */
default:
usage (EXIT_FAILURE);
static void check_flags (void)
{
#ifndef USE_PAM
-#ifdef USE_SHA_CRYPT
+#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
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 */
+#endif
if (cflg) {
if ( (0 != strcmp (crypt_method, "DES"))
&& (0 != strcmp (crypt_method, "SHA256"))
&& (0 != strcmp (crypt_method, "SHA512"))
#endif /* USE_SHA_CRYPT */
+#ifdef USE_BCRYPT
+ && (0 != strcmp (crypt_method, "BCRYPT"))
+#endif /* USE_BCRYPT */
) {
fprintf (stderr,
_("%s: unsupported crypt method: %s\n"),
#ifdef USE_SHA_CRYPT
|| (strcmp (method, "SHA256") == 0)
|| (strcmp (method, "SHA512") == 0)
-#endif /* USE_SHA_CRYPT */
+#endif /* USE_SHA_CRYPT */
+#ifdef USE_BCRYPT
+ || (strcmp (method, "BCRYPT") == 0)
+#endif /* USE_SHA_CRYPT */
+
) {
pass_max_len = -1;
} else {