diff --git a/ChangeLog b/ChangeLog index bb11c4fa..ede28d4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-05-20 Nicolas François + + * NEWS, libmisc/salt.c (SHA_salt_size): Seed the RNG, and fix a + overflow. These caused the SHA salt size to always be 8 bytes, + instead of being in the 8-16 range. Thanks to Peter Vrabec + pvrabec@redhat.com for noticing. + * NEWS, libmisc/salt.c (SHA_salt_rounds): Seed the RNG with + seedRNG instead of srand, and fix the same overflow. This caused + the number of rounds to always be the smallest one. + 2008-05-20 Nicolas François * man/newusers.8.xml man/groupmems.8.xml man/groupdel.8.xml diff --git a/NEWS b/NEWS index fb7e6c25..e0b5c401 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,15 @@ $Id$ shadow-4.1.1 -> shadow-4.1.2 UNRELEASED +*** security: +- generation of SHA encrypted passwords (chpasswd, gpasswd, newusers, + chgpasswd; and also passwd if configured without PAM support). + The number of rounds and number of salt bytes was fixed to their lower + allowed values (resp. configurable and 8), hence voiding some of the + advantages of this encryption method. Dictionary attacks with + precomputed tables were easier than expected, but still harder than with + the MD5 (or DES) methods. + *** general: - packaging * Distribute the chfn, chsh, and userdel PAM configuration file. diff --git a/libmisc/salt.c b/libmisc/salt.c index ca35d3e9..cda89de5 100644 --- a/libmisc/salt.c +++ b/libmisc/salt.c @@ -90,9 +90,10 @@ static void seedRNG (void) */ static unsigned int SHA_salt_size (void) { - double rand_rounds = 9 * random (); - rand_rounds /= RAND_MAX; - return 8 + rand_rounds; + double rand_size; + seedRNG (); + rand_size = (double) 9.0 * random () / RAND_MAX; + return 8 + rand_size; } /* ! Arguments evaluated twice ! */ @@ -131,8 +132,8 @@ static const char *SHA_salt_rounds (int *prefered_rounds) if (min_rounds > max_rounds) max_rounds = min_rounds; - srand (time (NULL)); - rand_rounds = (max_rounds-min_rounds+1) * random (); + seedRNG (); + rand_rounds = (double) (max_rounds-min_rounds+1.0) * random (); rand_rounds /= RAND_MAX; rounds = min_rounds + rand_rounds; } else if (0 == *prefered_rounds)