* libmisc/salt.c: The salt has a random size (between 8 and 16
bytes). * lib/getdef.c, etc/login.defs: Add definitions for SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS. * libmisc/salt.c: Use SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS to add a random number of rounds if needed.
This commit is contained in:
parent
c214b26ee6
commit
e406b7fe4a
@ -1,3 +1,12 @@
|
||||
2007-11-19 Nicolas François <nicolas.francois@centraliens.net>
|
||||
|
||||
* libmisc/salt.c: The salt has a random size (between 8 and 16
|
||||
bytes).
|
||||
* lib/getdef.c, etc/login.defs: Add definitions for
|
||||
SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS.
|
||||
* libmisc/salt.c: Use SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS
|
||||
to add a random number of rounds if needed.
|
||||
|
||||
2007-11-19 Nicolas François <nicolas.francois@centraliens.net>
|
||||
|
||||
* libmisc/salt.c (MAGNUM): Terminate the array with nul (the array
|
||||
|
@ -288,6 +288,22 @@ CHFN_RESTRICT rwh
|
||||
#
|
||||
#ENCRYPT_METHOD DES
|
||||
|
||||
#
|
||||
# Only works if ENCRYPT_METHOD is set to SHA256 or SHA512.
|
||||
#
|
||||
# Define the number of SHA rounds.
|
||||
# With a lot of rounds, it is more difficult to brute forcing the password.
|
||||
# But note also that it more CPU resources will be needed to authenticate
|
||||
# users.
|
||||
#
|
||||
# If not specified, the libc will choose the default number of rounds (5000).
|
||||
# The values must be inside 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.
|
||||
#
|
||||
# SHA_CRYPT_MIN_ROUNDS 5000
|
||||
# SHA_CRYPT_MAX_ROUNDS 5000
|
||||
|
||||
#
|
||||
# List of groups to add to the user's supplementary group set
|
||||
# when logging in on the console (as determined by the CONSOLE
|
||||
|
@ -104,6 +104,8 @@ static struct itemdef def_table[] = {
|
||||
{"PASS_MIN_LEN", NULL},
|
||||
{"PORTTIME_CHECKS_ENAB", NULL},
|
||||
{"QUOTAS_ENAB", NULL},
|
||||
{"SHA_CRYPT_MAX_ROUNDS", NULL},
|
||||
{"SHA_CRYPT_MIN_ROUNDS", NULL},
|
||||
{"SU_WHEEL_ONLY", NULL},
|
||||
{"ULIMIT", NULL},
|
||||
#endif
|
||||
|
@ -53,19 +53,91 @@ char *l64a(long value)
|
||||
#endif /* !HAVE_L64A */
|
||||
|
||||
/*
|
||||
* Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB
|
||||
* in /etc/login.defs is "yes", the salt string will be prefixed by "$1$"
|
||||
* (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible
|
||||
* version of crypt() instead of the standard one.
|
||||
* Add the salt prefix.
|
||||
*/
|
||||
|
||||
#define MAGNUM(array,ch) (array)[0]= (array)[2] = '$',\
|
||||
(array)[1]=(ch),\
|
||||
(array)[2]='\0'
|
||||
|
||||
/*
|
||||
* Return the salt size.
|
||||
* The size of the salt string is between 8 and 16 bytes for the SHA crypt
|
||||
* methods.
|
||||
*/
|
||||
static unsigned int SHA_salt_size (void)
|
||||
{
|
||||
return 8 + 8*rand ()/(RAND_MAX+1);
|
||||
}
|
||||
|
||||
/* ! Arguments evaluated twice ! */
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
static char *SHA_salt_rounds (void)
|
||||
{
|
||||
static char *rounds_prefix[18];
|
||||
long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1);
|
||||
long max_rounds = getdef_long ("SHA_CRYPT_MAX_ROUNDS", -1);
|
||||
long rounds;
|
||||
|
||||
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 = min_rounds + (max_rounds - min_rounds)*rand ()/(RAND_MAX+1);
|
||||
|
||||
/* 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;
|
||||
|
||||
snprintf (rounds_prefix, 18, "rounds=%ld$", rounds);
|
||||
|
||||
/* Sanity checks. That should not be necessary. */
|
||||
rounds_prefix[17] = '\0';
|
||||
if ('$' != rounds_prefix[16])
|
||||
rounds_prefix[17] = '$';
|
||||
|
||||
return rounds_prefix;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB
|
||||
* in /etc/login.defs is "yes", the salt string will be prefixed by "$1$"
|
||||
* (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible
|
||||
* version of crypt() instead of the standard one.
|
||||
* Other methods can be set with ENCRYPT_METHOD
|
||||
*/
|
||||
char *crypt_make_salt (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
/* Max result size for the SHA methods:
|
||||
* +3 $5$
|
||||
* +17 rounds=999999999$
|
||||
* +16 salt
|
||||
* +1 \0
|
||||
*/
|
||||
static char result[40];
|
||||
int max_salt_len = 8;
|
||||
char *method;
|
||||
@ -87,10 +159,12 @@ char *crypt_make_salt (void)
|
||||
max_salt_len = 11;
|
||||
} else if (!strncmp (method, "SHA256", 6)) {
|
||||
MAGNUM(result, '5');
|
||||
max_salt_len = 11; /* XXX: should not be fixed */
|
||||
strcat(result, SHA_salt_rounds());
|
||||
max_salt_len = strlen(result) + SHA_salt_size();
|
||||
} else if (!strncmp (method, "SHA512", 6)) {
|
||||
MAGNUM(result, '6');
|
||||
max_salt_len = 11; /* XXX: should not be fixed */
|
||||
strcat(result, SHA_salt_rounds());
|
||||
max_salt_len = strlen(result) + SHA_salt_size();
|
||||
} else if (0 != strncmp (method, "DES", 3)) {
|
||||
fprintf (stderr,
|
||||
_("Invalid ENCRYPT_METHOD value: '%s'.\n"
|
||||
@ -101,12 +175,14 @@ char *crypt_make_salt (void)
|
||||
}
|
||||
#endif /* ENCRYPTMETHOD_SELECT */
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/*
|
||||
* Generate 8 chars of salt, the old crypt() will use only first 2.
|
||||
* Concatenate a pseudo random salt.
|
||||
*/
|
||||
gettimeofday (&tv, (struct timezone *) 0);
|
||||
strcat (result, l64a (tv.tv_usec));
|
||||
strcat (result, l64a (tv.tv_sec + getpid () + clock ()));
|
||||
strncat (result, sizeof(result), l64a (tv.tv_usec));
|
||||
strncat (result, sizeof(result),
|
||||
l64a (tv.tv_sec + getpid () + clock ()));
|
||||
|
||||
if (strlen (result) > max_salt_len) /* magic+salt */
|
||||
result[max_salt_len] = '\0';
|
||||
|
Loading…
Reference in New Issue
Block a user