Quellcode durchsuchen

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>
Denys Vlasenko vor 3 Jahren
Ursprung
Commit
73d93d9f83
2 geänderte Dateien mit 19 neuen und 17 gelöschten Zeilen
  1. 8 3
      libbb/pw_encrypt.c
  2. 11 14
      libbb/pw_encrypt_des.c

+ 8 - 3
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

+ 11 - 14
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 */);