[git commit] httpd: fix MD5-encrypted-in-httpd.conf password logic

Denys Vlasenko vda.linux at googlemail.com
Wed Feb 1 01:42:54 UTC 2012


commit: http://git.busybox.net/busybox/commit/?id=35def51c9747895d38c11e3c41e62c3c68c92438
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
check_user_passwd                                    467     492     +25

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 networking/Config.src |   16 +++++++++++---
 networking/httpd.c    |   50 ++++++++++++++++++++++++++----------------------
 2 files changed, 39 insertions(+), 27 deletions(-)

diff --git a/networking/Config.src b/networking/Config.src
index 8aeba0e..fb7dca7 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -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
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:


More information about the busybox-cvs mailing list