Index: loginutils/passwd.c =================================================================== --- loginutils/passwd.c (revision 13886) +++ loginutils/passwd.c (working copy) @@ -21,16 +21,6 @@ static void set_filesize_limit(int blocks); -static int get_algo(char *a) -{ - int x = 1; /* standard: MD5 */ - - if (strcasecmp(a, "des") == 0) - x = 0; - return x; -} - - static int update_passwd(const struct passwd *pw, const char *crypt_pw) { char filename[1024]; @@ -132,6 +122,13 @@ } +/* + * get_algo() returns: + * FALSE: in case of traditional MD5 + * TRUE : in case of short SALT MD5 + */ +#define get_algo(a) (!strcasecmp(a, "des")) + extern int passwd_main(int argc, char **argv) { int amroot; @@ -287,36 +284,21 @@ return 0; } -static int i64c(int i) -{ - if (i <= 0) - return ('.'); - if (i == 1) - return ('/'); - if (i >= 2 && i < 12) - return ('0' - 2 + i); - if (i >= 12 && i < 38) - return ('A' - 12 + i); - if (i >= 38 && i < 63) - return ('a' - 38 + i); - return ('z'); -} +const unsigned char bb_base64[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789./"; +#define bb_i64c(a) (bb_base64[((unsigned char)(a))%64]) -static char *crypt_make_salt(void) +static void bb_read_random64_string(unsigned char *str, int len) { - time_t now; - static unsigned long x; - static char result[3]; - - time(&now); - x += now + getpid() + clock(); - result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077); - result[1] = i64c(((x >> 12) ^ x) & 077); - result[2] = '\0'; - return result; + int i; + FILE *fp; + if(!(fp = fopen("/dev/random", "r"))) + bb_perror_msg_and_die("open /dev/random"); + bb_xread_all(fileno(fp), str, len); + for(i = 0; i < len; i++) + str[i] = bb_i64c(str[i]); + str[i] = 0; //close the string } - static int new_password(const struct passwd *pw, int amroot, int algo) { char *clear; @@ -324,6 +306,7 @@ char *cp; char orig[200]; char pass[200]; + unsigned char salt[12] = "$1$"; if (!amroot && crypt_passwd[0]) { if (!(clear = bb_askpass(0, "Old password:"))) { @@ -377,10 +360,12 @@ memset(cp, 0, strlen(cp)); memset(orig, 0, sizeof(orig)); - if (algo == 1) { - cp = pw_encrypt(pass, "$1$"); - } else - cp = pw_encrypt(pass, crypt_make_salt()); + if (algo) + bb_read_random64_string(&salt[3], 8); + else + bb_read_random64_string(salt, 2); + cp = pw_encrypt(pass, salt); + memset(pass, 0, sizeof pass); safe_strncpy(crypt_passwd, cp, sizeof(crypt_passwd)); return 0;