libbb: make pw_encrypt() die if supplied salt is bad (e.g. emply)
No binary (build failed)
—
(log yok)
| @@ -120,6 +120,7 @@ static char *my_crypt(const char *key, const char *salt) | |
| if (!des_cctx) | |
| des_cctx = const_des_init(); | |
| des_ctx = des_init(des_ctx, des_cctx); | |
| + | /* Can return NULL if salt is bad ("" or "<one_char>") */ |
| return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); | |
| } | |
| @@ -137,6 +138,8 @@ char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) | |
| char *encrypted; | |
| encrypted = my_crypt(clear, salt); | |
| + | if (!encrypted) |
| + | bb_simple_error_msg_and_die("bad salt"); |
| if (cleanup) | |
| my_crypt_cleanup(); | |
| @@ -148,14 +151,16 @@ char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) | |
| char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) | |
| { | |
| - | char *s; |
| + | char *encrypted; |
| - | s = crypt(clear, salt); |
| + | encrypted = crypt(clear, salt); |
| /* | |
| * glibc used to return "" on malformed salts (for example, ""), | |
| * but since 2.17 it returns NULL. | |
| */ | |
| - | return xstrdup(s ? s : ""); |
| + | if (!encrypted || !encrypted[0]) |
| + | bb_simple_error_msg_and_die("bad salt"); |
| + | return xstrdup(encrypted); |
| } | |
| #endif | |
| @@ -713,11 +713,15 @@ to64_msb_first(char *s, unsigned v) | |
| static char * | |
| NOINLINE | |
| des_crypt(struct des_ctx *ctx, char output[DES_OUT_BUFSIZE], | |
| - | const unsigned char *key, const unsigned char *setting) |
| + | const unsigned char *key, const unsigned char *salt_str) |
| { | |
| uint32_t salt, r0, r1, keybuf[2]; | |
| uint8_t *q; | |
| + | /* Bad salt? Mimic crypt() API - return NULL */ |
| + | if (!salt_str[0] || !salt_str[1]) |
| + | return NULL; |
| + | |
| /* | |
| * Copy the key, shifting each character up by one bit | |
| * and padding with zeros. | |
| @@ -732,22 +736,15 @@ des_crypt(struct des_ctx *ctx, char output[DES_OUT_BUFSIZE], | |
| des_setkey(ctx, (char *)keybuf); | |
| /* | |
| - | * setting - 2 bytes of salt |
| + | * salt_str - 2 bytes of salt |
| * key - up to 8 characters | |
| */ | |
| - | salt = (ascii_to_bin(setting[1]) << 6) |
| - | | ascii_to_bin(setting[0]); |
| - | |
| - | output[0] = setting[0]; |
| - | /* |
| - | * If the encrypted password that the salt was extracted from |
| - | * is only 1 character long, the salt will be corrupted. We |
| - | * need to ensure that the output string doesn't have an extra |
| - | * NUL in it! |
| - | */ |
| - | output[1] = setting[1] ? setting[1] : output[0]; |
| - | |
| + | output[0] = salt_str[0]; |
| + | output[1] = salt_str[1]; |
| + | salt = (ascii_to_bin(salt_str[1]) << 6) |
| + | | ascii_to_bin(salt_str[0]); |
| setup_salt(ctx, salt); | |
| + | |
| /* Do it. */ | |
| do_des(ctx, /*0, 0,*/ &r0, &r1, 25 /* count */); | |