aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-12-15 23:19:22 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-12-15 23:19:22 +0100
commit73d93d9f83180a6149f363aaca131e281d2a52ff (patch)
treeae75b7d6f386436586943ab16434ab29e60a6e5d
parentf3d6711c971cde8ed3890a47020c5083a383e606 (diff)
downloadbusybox-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.c11
-rw-r--r--libbb/pw_encrypt_des.c25
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 */);