Initial bcrypt support

This commit is contained in:
prez
2019-09-16 20:54:56 +02:00
committed by Serge Hallyn
parent 38f493aff2
commit 2958bd050b
10 changed files with 374 additions and 64 deletions

View File

@@ -61,15 +61,18 @@
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;
@@ -125,11 +128,15 @@ static /*@noreturn@*/void usage (int status)
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);
@@ -137,11 +144,11 @@ static /*@noreturn@*/void usage (int status)
" 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);
@@ -161,14 +168,13 @@ static void process_flags (int argc, char **argv)
{"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:",
@@ -189,10 +195,33 @@ static void process_flags (int argc, char **argv)
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);
@@ -200,6 +229,7 @@ static void process_flags (int argc, char **argv)
}
break;
#endif
default:
usage (E_USAGE);
/*@notreached@*/break;
@@ -217,7 +247,7 @@ static void process_flags (int argc, char **argv)
*/
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"),
@@ -241,6 +271,9 @@ static void check_flags (void)
#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,
@@ -464,10 +497,24 @@ int main (int argc, char **argv)
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);

View File

@@ -58,15 +58,18 @@
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;
@@ -118,11 +121,15 @@ static /*@noreturn@*/void usage (int status)
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);
@@ -130,11 +137,11 @@ static /*@noreturn@*/void usage (int status)
" 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);
@@ -154,18 +161,18 @@ static void process_flags (int argc, char **argv)
{"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':
@@ -182,17 +189,41 @@ static void process_flags (int argc, char **argv)
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;
@@ -210,7 +241,7 @@ static void process_flags (int argc, char **argv)
*/
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"),
@@ -235,6 +266,9 @@ static void check_flags (void)
&& (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"),
@@ -496,10 +530,24 @@ int main (int argc, char **argv)
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);

View File

@@ -80,10 +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)
#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;
@@ -134,22 +139,26 @@ static void usage (int status)
#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);
@@ -423,15 +432,29 @@ static int update_passwd (struct passwd *pwd, const char *password)
{
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);
@@ -460,12 +483,26 @@ static int add_passwd (struct passwd *pwd, const char *password)
#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
}
/*
@@ -591,20 +628,20 @@ static void process_flags (int argc, char **argv)
{"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
@@ -627,17 +664,40 @@ static void process_flags (int argc, char **argv)
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);
@@ -671,14 +731,14 @@ static void process_flags (int argc, char **argv)
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"))
@@ -688,6 +748,9 @@ static void check_flags (void)
&& (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"),

View File

@@ -279,7 +279,11 @@ static int new_password (const struct passwd *pw)
#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 {