Project

General

Profile

[Solved] mod_auth (configuration): Change of behavior in user name handling

Added by dirk4000 12 months ago

Until lighttpd 1.4.41 it was possible to have a user database for digest authentication containing a user name "Admin" and "admin" and setup some rules to allow both users to access a given resource.

After upgrading the lighty webserver from 1.4.41 to 1.4.64 I recognized a change of behavior when authorization is being performed.
A simple test case failed with the given test configuration (see attachment):

curl http://127.0.0.1/test1/ http://127.0.0.1/test2/ --user admin:admin --digest

expected result:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>

actual result:

user@buster64:~$ curl http://127.0.0.1/test1/ http://127.0.0.1/test2/ --user admin:admin --digest

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 Not Found</title>
</head>
<body>
<h1>404 Not Found</h1>
</body>
</html>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>401 Unauthorized</title>
</head>
<body>
<h1>401 Unauthorized</h1>
</body>
</html>

Is there a workaround for solving this behavior change?


Replies (3)

RE: mod_auth (configuration): Change of behavior in user name handling - Added by gstrauss 11 months ago

var.auth_test1 = ("method" => "digest", "realm" => "secret zone","require" => "user=admin|user=test1|user=Admin" )
var.auth_test2 = ("method" => "digest", "realm" => "secret zone","require" => "user=Admin|user=test2|user=admin" )
var.auth = (
  "/test1/" => auth_test1,
  "/test2/" => auth_test2
)

Thank you for the precise description of the issue and the reproducible test case. The behavior change you see looks like a bug. Storing the config list into a data structure with case-insensitive keys meant that if the list contained multiple entries which differed in case-only, then only one entry would survive. The following patch stores the list in a data structure which matches how the data is used: as a value list.

--- a/src/mod_auth.c
+++ b/src/mod_auth.c
@@ -392,12 +392,12 @@ static int mod_auth_require_parse (http_auth_require_t * const require, const bu
           case 4:
             if (0 == memcmp(str, CONST_STR_LEN("user"))) {
                 /*("user=" is 5)*/
-                array_set_key_value(&require->user, str+5, len-5, CONST_STR_LEN(""));
+                array_insert_value(&require->user, str+5, len-5);
                 continue;
             }
             else if (0 == memcmp(str, CONST_STR_LEN("host"))) {
                 /*("host=" is 5)*/
-                array_set_key_value(&require->host, str+5, len-5, CONST_STR_LEN(""));
+                array_insert_value(&require->host, str+5, len-5);
                 log_error(errh, __FILE__, __LINE__,
                   "warning parsing auth.require 'require' field: " 
                   "'host' not implemented; field value: %s", b->ptr);
@@ -407,7 +407,7 @@ static int mod_auth_require_parse (http_auth_require_t * const require, const bu
           case 5:
             if (0 == memcmp(str, CONST_STR_LEN("group"))) {
                 /*("group=" is 6)*/
-                array_set_key_value(&require->group, str+6, len-6, CONST_STR_LEN(""));
+                array_insert_value(&require->group, str+6, len-6);
               #if 0/*(supported by mod_authn_ldap, but not all other backends)*/
                 log_error(errh, __FILE__, __LINE__,
                   "warning parsing auth.require 'require' field: " 
diff --git a/src/mod_auth_api.c b/src/mod_auth_api.c
index b3d0064d..99607953 100644
--- a/src/mod_auth_api.c
+++ b/src/mod_auth_api.c
@@ -87,9 +87,8 @@ __attribute_pure__
 static int http_auth_array_contains (const array * const a, const char * const k, const size_t klen)
 {
     for (size_t i = 0, used = a->used; i < used; ++i) {
-        if (buffer_is_equal_string(&a->data[i]->key, k, klen)) {
+        if (buffer_eq_slen(&((data_string *)a->data[i])->value, k, klen))
             return 1;
-        }
     }
     return 0;
 }

RE: mod_auth (configuration): Change of behavior in user name handling - Added by gstrauss 11 months ago

Aside: case-sensitivity of username matters with HTTP Digest auth in how the hashes are calculated. At the same time, spoofing and confusion can result when multiple valid usernames exist, differing only in letter-case. Whether or not to allow such configurations is up to each web server admin.

RE: [Solved] mod_auth (configuration): Change of behavior in user name handling - Added by dirk4000 11 months ago

The reported problem could no longer be reproduced in the current released version 1.4.65.
Thank you for the great work you do for the community!

    (1-3/3)