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>
This commit is contained in:
Denys Vlasenko 2012-02-01 02:42:54 +01:00
parent 428bd2d433
commit 35def51c97
2 changed files with 38 additions and 26 deletions

View File

@ -199,14 +199,22 @@ config FEATURE_HTTPD_BASIC_AUTH
help
Utilizes password settings from /etc/httpd.conf for basic
authentication on a per url basis.
Example for httpd.conf file:
/adm:toor:PaSsWd
config FEATURE_HTTPD_AUTH_MD5
bool "Support MD5 crypted passwords for http Authentication"
default y
depends on FEATURE_HTTPD_BASIC_AUTH
help
Enables basic per URL authentication from /etc/httpd.conf
using md5 passwords.
Enables encrypted passwords, and wildcard user/passwords
in httpd.conf file.
User '*' means 'any system user name is ok',
password of '*' means 'use system password for this user'
Examples:
/adm:toor:$1$P/eKnWXS$aI1aPGxT.dJD5SzqAKWrF0
/adm:root:*
/wiki:*:*
config FEATURE_HTTPD_CGI
bool "Support Common Gateway Interface (CGI)"
@ -223,8 +231,8 @@ config FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
help
This option enables support for running scripts through an
interpreter. Turn this on if you want PHP scripts to work
properly. You need to supply an additional line in your httpd
config file:
properly. You need to supply an additional line in your
httpd.conf file:
*.php:/path/to/your/php
config FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV

View File

@ -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 */
}
/* Else: passwd is from httpd.conf, it is either plaintext or encrypted */
/* 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 */
if (passwd[0] == '$' && isdigit(passwd[1])) {
char *encrypted;
check_encrypted:
/* encrypt pwd from peer and check match with local one */
{
char *encrypted = pw_encrypt(
/* pwd: */ colon_after_user + 1,
encrypted = pw_encrypt(
/* pwd (from peer): */ colon_after_user + 1,
/* salt: */ passwd,
/* cleanup: */ 0
);
r = strcmp(encrypted, passwd);
free(encrypted);
} else {
/* local passwd is from httpd.conf and it's plaintext */
r = strcmp(colon_after_user + 1, passwd);
}
goto end_check_passwd;
}
bad_input: ;
}
bad_input:
/* Comparing plaintext "user:pass" in one go */
r = strcmp(cur->after_colon, user_and_passwd);
end_check_passwd: