diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2020-12-15 23:19:22 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-12-15 23:19:22 +0100 |
commit | 73d93d9f83180a6149f363aaca131e281d2a52ff (patch) | |
tree | ae75b7d6f386436586943ab16434ab29e60a6e5d | |
parent | f3d6711c971cde8ed3890a47020c5083a383e606 (diff) | |
download | busybox-73d93d9f83180a6149f363aaca131e281d2a52ff.tar.gz |
libbb: make pw_encrypt() die if supplied salt is bad (e.g. emply)
Fished from 520-loginutils-handle-crypt-failures.patch in openwrt
function old new delta
pw_encrypt 913 927 +14
des_crypt 1327 1318 -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 14/-9) Total: 5 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | libbb/pw_encrypt.c | 11 | ||||
-rw-r--r-- | libbb/pw_encrypt_des.c | 25 |
2 files changed, 19 insertions, 17 deletions
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 47c20690f..a60c33c35 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -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 diff --git a/libbb/pw_encrypt_des.c b/libbb/pw_encrypt_des.c index c6fc328d8..dcd3521e2 100644 --- a/libbb/pw_encrypt_des.c +++ b/libbb/pw_encrypt_des.c @@ -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 */); |