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-w32-73d93d9f83180a6149f363aaca131e281d2a52ff.tar.gz busybox-w32-73d93d9f83180a6149f363aaca131e281d2a52ff.tar.bz2 busybox-w32-73d93d9f83180a6149f363aaca131e281d2a52ff.zip |
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) | |||
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 | ||
149 | char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) | 152 | char* 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) | |||
713 | static char * | 713 | static char * |
714 | NOINLINE | 714 | NOINLINE |
715 | des_crypt(struct des_ctx *ctx, char output[DES_OUT_BUFSIZE], | 715 | des_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 | ||