* 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>
|
2007-11-19 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
* libmisc/salt.c (MAGNUM): Terminate the array with nul (the array
|
* libmisc/salt.c (MAGNUM): Terminate the array with nul (the array
|
||||||
|
@ -288,6 +288,22 @@ CHFN_RESTRICT rwh
|
|||||||
#
|
#
|
||||||
#ENCRYPT_METHOD DES
|
#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
|
# List of groups to add to the user's supplementary group set
|
||||||
# when logging in on the console (as determined by the CONSOLE
|
# when logging in on the console (as determined by the CONSOLE
|
||||||
|
@ -104,6 +104,8 @@ static struct itemdef def_table[] = {
|
|||||||
{"PASS_MIN_LEN", NULL},
|
{"PASS_MIN_LEN", NULL},
|
||||||
{"PORTTIME_CHECKS_ENAB", NULL},
|
{"PORTTIME_CHECKS_ENAB", NULL},
|
||||||
{"QUOTAS_ENAB", NULL},
|
{"QUOTAS_ENAB", NULL},
|
||||||
|
{"SHA_CRYPT_MAX_ROUNDS", NULL},
|
||||||
|
{"SHA_CRYPT_MIN_ROUNDS", NULL},
|
||||||
{"SU_WHEEL_ONLY", NULL},
|
{"SU_WHEEL_ONLY", NULL},
|
||||||
{"ULIMIT", NULL},
|
{"ULIMIT", NULL},
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,19 +53,91 @@ char *l64a(long value)
|
|||||||
#endif /* !HAVE_L64A */
|
#endif /* !HAVE_L64A */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB
|
* Add the salt prefix.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAGNUM(array,ch) (array)[0]= (array)[2] = '$',\
|
#define MAGNUM(array,ch) (array)[0]= (array)[2] = '$',\
|
||||||
(array)[1]=(ch),\
|
(array)[1]=(ch),\
|
||||||
(array)[2]='\0'
|
(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)
|
char *crypt_make_salt (void)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
/* Max result size for the SHA methods:
|
||||||
|
* +3 $5$
|
||||||
|
* +17 rounds=999999999$
|
||||||
|
* +16 salt
|
||||||
|
* +1 \0
|
||||||
|
*/
|
||||||
static char result[40];
|
static char result[40];
|
||||||
int max_salt_len = 8;
|
int max_salt_len = 8;
|
||||||
char *method;
|
char *method;
|
||||||
@ -87,10 +159,12 @@ char *crypt_make_salt (void)
|
|||||||
max_salt_len = 11;
|
max_salt_len = 11;
|
||||||
} else if (!strncmp (method, "SHA256", 6)) {
|
} else if (!strncmp (method, "SHA256", 6)) {
|
||||||
MAGNUM(result, '5');
|
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)) {
|
} else if (!strncmp (method, "SHA512", 6)) {
|
||||||
MAGNUM(result, '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)) {
|
} else if (0 != strncmp (method, "DES", 3)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("Invalid ENCRYPT_METHOD value: '%s'.\n"
|
_("Invalid ENCRYPT_METHOD value: '%s'.\n"
|
||||||
@ -101,12 +175,14 @@ char *crypt_make_salt (void)
|
|||||||
}
|
}
|
||||||
#endif /* ENCRYPTMETHOD_SELECT */
|
#endif /* ENCRYPTMETHOD_SELECT */
|
||||||
#endif /* USE_PAM */
|
#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);
|
gettimeofday (&tv, (struct timezone *) 0);
|
||||||
strcat (result, l64a (tv.tv_usec));
|
strncat (result, sizeof(result), l64a (tv.tv_usec));
|
||||||
strcat (result, l64a (tv.tv_sec + getpid () + clock ()));
|
strncat (result, sizeof(result),
|
||||||
|
l64a (tv.tv_sec + getpid () + clock ()));
|
||||||
|
|
||||||
if (strlen (result) > max_salt_len) /* magic+salt */
|
if (strlen (result) > max_salt_len) /* magic+salt */
|
||||||
result[max_salt_len] = '\0';
|
result[max_salt_len] = '\0';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user