aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)
120 if (!des_cctx) 120 if (!des_cctx)
121 des_cctx = const_des_init(); 121 des_cctx = const_des_init();
122 des_ctx = des_init(des_ctx, des_cctx); 122 des_ctx = des_init(des_ctx, des_cctx);
123 /* Can return NULL if salt is bad ("" or "<one_char>") */
123 return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); 124 return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
124} 125}
125 126
@@ -137,6 +138,8 @@ char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
137 char *encrypted; 138 char *encrypted;
138 139
139 encrypted = my_crypt(clear, salt); 140 encrypted = my_crypt(clear, salt);
141 if (!encrypted)
142 bb_simple_error_msg_and_die("bad salt");
140 143
141 if (cleanup) 144 if (cleanup)
142 my_crypt_cleanup(); 145 my_crypt_cleanup();
@@ -148,14 +151,16 @@ char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
148 151
149char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) 152char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
150{ 153{
151 char *s; 154 char *encrypted;
152 155
153 s = crypt(clear, salt); 156 encrypted = crypt(clear, salt);
154 /* 157 /*
155 * glibc used to return "" on malformed salts (for example, ""), 158 * glibc used to return "" on malformed salts (for example, ""),
156 * but since 2.17 it returns NULL. 159 * but since 2.17 it returns NULL.
157 */ 160 */
158 return xstrdup(s ? s : ""); 161 if (!encrypted || !encrypted[0])
162 bb_simple_error_msg_and_die("bad salt");
163 return xstrdup(encrypted);
159} 164}
160 165
161#endif 166#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)
713static char * 713static char *
714NOINLINE 714NOINLINE
715des_crypt(struct des_ctx *ctx, char output[DES_OUT_BUFSIZE], 715des_crypt(struct des_ctx *ctx, char output[DES_OUT_BUFSIZE],
716 const unsigned char *key, const unsigned char *setting) 716 const unsigned char *key, const unsigned char *salt_str)
717{ 717{
718 uint32_t salt, r0, r1, keybuf[2]; 718 uint32_t salt, r0, r1, keybuf[2];
719 uint8_t *q; 719 uint8_t *q;
720 720
721 /* Bad salt? Mimic crypt() API - return NULL */
722 if (!salt_str[0] || !salt_str[1])
723 return NULL;
724
721 /* 725 /*
722 * Copy the key, shifting each character up by one bit 726 * Copy the key, shifting each character up by one bit
723 * and padding with zeros. 727 * and padding with zeros.
@@ -732,22 +736,15 @@ des_crypt(struct des_ctx *ctx, char output[DES_OUT_BUFSIZE],
732 des_setkey(ctx, (char *)keybuf); 736 des_setkey(ctx, (char *)keybuf);
733 737
734 /* 738 /*
735 * setting - 2 bytes of salt 739 * salt_str - 2 bytes of salt
736 * key - up to 8 characters 740 * key - up to 8 characters
737 */ 741 */
738 salt = (ascii_to_bin(setting[1]) << 6) 742 output[0] = salt_str[0];
739 | ascii_to_bin(setting[0]); 743 output[1] = salt_str[1];
740 744 salt = (ascii_to_bin(salt_str[1]) << 6)
741 output[0] = setting[0]; 745 | ascii_to_bin(salt_str[0]);
742 /*
743 * If the encrypted password that the salt was extracted from
744 * is only 1 character long, the salt will be corrupted. We
745 * need to ensure that the output string doesn't have an extra
746 * NUL in it!
747 */
748 output[1] = setting[1] ? setting[1] : output[0];
749
750 setup_salt(ctx, salt); 746 setup_salt(ctx, salt);
747
751 /* Do it. */ 748 /* Do it. */
752 do_des(ctx, /*0, 0,*/ &r0, &r1, 25 /* count */); 749 do_des(ctx, /*0, 0,*/ &r0, &r1, 25 /* count */);
753 750