summaryrefslogtreecommitdiff
path: root/networking/httpd.c
diff options
context:
space:
mode:
authorDenys Vlasenko2012-02-01 02:42:54 +0100
committerDenys Vlasenko2012-02-01 02:42:54 +0100
commit35def51c9747895d38c11e3c41e62c3c68c92438 (patch)
tree7123ee794725e9d904a7d98865ad07f61e46cd6d /networking/httpd.c
parent428bd2d4337dbd83feb3c7d1fc04d840f548003c (diff)
downloadbusybox-35def51c9747895d38c11e3c41e62c3c68c92438.zip
busybox-35def51c9747895d38c11e3c41e62c3c68c92438.tar.gz
httpd: fix MD5-encrypted-in-httpd.conf password logic
function old new delta check_user_passwd 467 492 +25 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/httpd.c')
-rw-r--r--networking/httpd.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index 3f4e6aa..0e4c697 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -1776,6 +1776,16 @@ static int check_user_passwd(const char *path, char *user_and_passwd)
colon_after_user = strchr(user_and_passwd, ':');
if (!colon_after_user)
goto bad_input;
+
+ /* compare "user:" */
+ if (cur->after_colon[0] != '*'
+ && strncmp(cur->after_colon, user_and_passwd,
+ colon_after_user - user_and_passwd + 1) != 0
+ ) {
+ continue;
+ }
+ /* this cfg entry is '*' or matches username from peer */
+
passwd = strchr(cur->after_colon, ':');
if (!passwd)
goto bad_input;
@@ -1786,13 +1796,6 @@ static int check_user_passwd(const char *path, char *user_and_passwd)
struct pam_conv conv_info = { &pam_talker, (void *) &userinfo };
pam_handle_t *pamh;
- /* compare "user:" */
- if (cur->after_colon[0] != '*'
- && strncmp(cur->after_colon, user_and_passwd, colon_after_user - user_and_passwd + 1) != 0
- ) {
- continue;
- }
- /* this cfg entry is '*' or matches username from peer */
*colon_after_user = '\0';
userinfo.name = user_and_passwd;
userinfo.pw = colon_after_user + 1;
@@ -1828,31 +1831,32 @@ static int check_user_passwd(const char *path, char *user_and_passwd)
passwd = result->sp_pwdp;
}
# endif
+ /* In this case, passwd is ALWAYS encrypted:
+ * it came from /etc/passwd or /etc/shadow!
+ */
+ goto check_encrypted;
# endif /* ENABLE_PAM */
}
-
- /* compare "user:" */
- if (cur->after_colon[0] != '*'
- && strncmp(cur->after_colon, user_and_passwd, colon_after_user - user_and_passwd + 1) != 0
- ) {
- continue;
- }
- /* this cfg entry is '*' or matches username from peer */
-
- /* encrypt pwd from peer and check match with local one */
- {
- char *encrypted = pw_encrypt(
- /* pwd: */ colon_after_user + 1,
+ /* Else: passwd is from httpd.conf, it is either plaintext or encrypted */
+
+ if (passwd[0] == '$' && isdigit(passwd[1])) {
+ char *encrypted;
+ check_encrypted:
+ /* encrypt pwd from peer and check match with local one */
+ encrypted = pw_encrypt(
+ /* pwd (from peer): */ colon_after_user + 1,
/* salt: */ passwd,
/* cleanup: */ 0
);
r = strcmp(encrypted, passwd);
free(encrypted);
- goto end_check_passwd;
+ } else {
+ /* local passwd is from httpd.conf and it's plaintext */
+ r = strcmp(colon_after_user + 1, passwd);
}
- bad_input: ;
+ goto end_check_passwd;
}
-
+ bad_input:
/* Comparing plaintext "user:pass" in one go */
r = strcmp(cur->after_colon, user_and_passwd);
end_check_passwd: