httpd: fix MD5-encrypted-in-httpd.conf password logic
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 1 Feb 2012 01:42:54 +0000 (02:42 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 1 Feb 2012 01:42:54 +0000 (02:42 +0100)
function                                             old     new   delta
check_user_passwd                                    467     492     +25

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
networking/Config.src
networking/httpd.c

index 8aeba0ef9565840eab9709cf078d97f82199894c..fb7dca7d49146c2395e3e6afdb58c77720477fbf 100644 (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
index 3f4e6aab7c9f4c8881f563d95fe8e4035ac4b8d2..0e4c697f84fdf54b5880421adbe63b727dd0f54c 100644 (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 */
                        }
-
-                       /* 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: