mod_auth: Add auth.deny; for user restriction, always send WWW-Authenticate header (this makes the implementation of auth.deny trivial)

personal/stbuehler/wip
Stefan Bühler 14 years ago
parent 2f06283832
commit 130a40e691

@ -35,19 +35,24 @@
* - passwords are saved as (modified) md5 hashes:
* md5hex(username + ":" + realm + ":" + password)
*
* auth.deny;
* - handles request with "401 Unauthorized"
*
* Example config:
* # /members/ is for known users only
* if request.path =^ "/members/" {
* auth ["method": "basic", "realm": "members only", "file": "/etc/lighttpd/users.txt"];
* auth.plain ["method": "basic", "realm": "members only", "file": "/etc/lighttpd/users.txt"];
* }
* if req.env["REMOTE_USER"] !~ "^(admin1|user2|user3)$" { auth.deny; }
*
*
* Tip:
* The digest method is broken in Internet Explorer < 7. Use basic instead if this is a problem for you.
* The digest method is broken in Internet Explorer < 7. Use basic instead if this is a problem for you. (not supported for now anyway)
*
* Todo:
* - method: digest
* - anti bruteforce protection
* - auth.deny ( using env[] "REMOTE_METHOD"/"REMOTE_REALM"/...? )
*
* Author:
* Copyright (c) 2009 Thomas Porzelt
@ -287,6 +292,21 @@ static liHandlerResult auth_basic(liVRequest *vr, gpointer param, gpointer *cont
UNUSED(context);
if (!li_vrequest_is_handled(vr)) {
/* only allow access restrictions as previous handlers */
switch (vr->response.http_status) { /* use same list as in auth_handle_deny */
case 401: /* Unauthorized */
case 402: /* Payment Required */
case 403: /* Forbidden */
case 405: /* Method Not Allowed */
case 407: /* Proxy Authentication Required */
case 500: /* Internal Server Error */
return LI_HANDLER_GO_ON;
default:
return LI_HANDLER_ERROR;
}
}
/* check for Authorization header */
hdr = li_http_header_lookup(vr->request.headers, CONST_STR_LEN("Authorization"));
@ -330,19 +350,26 @@ static liHandlerResult auth_basic(liVRequest *vr, gpointer param, gpointer *cont
}
}
g_string_truncate(vr->wrk->tmp_str, 0);
g_string_append_len(vr->wrk->tmp_str, CONST_STR_LEN("Basic realm=\""));
g_string_append_len(vr->wrk->tmp_str, GSTR_LEN(bdata->realm));
g_string_append_c(vr->wrk->tmp_str, '"');
/* generate header always */
if (!auth_ok) {
/* if the request already has a handler like mod_access, we assume everything is ok */
li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("WWW-Authenticate"), GSTR_LEN(vr->wrk->tmp_str));
/* we already checked for handled */
if (!li_vrequest_handle_direct(vr))
return LI_HANDLER_GO_ON;
return LI_HANDLER_ERROR;
vr->response.http_status = 401;
g_string_truncate(vr->wrk->tmp_str, 0);
g_string_append_len(vr->wrk->tmp_str, CONST_STR_LEN("Basic realm=\""));
g_string_append_len(vr->wrk->tmp_str, GSTR_LEN(bdata->realm));
g_string_append_c(vr->wrk->tmp_str, '"');
li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("WWW-Authenticate"), GSTR_LEN(vr->wrk->tmp_str));
return LI_HANDLER_GO_ON;
} else {
/* lets hope browser just ignore the header if status is not 401
* but this way it is easier to use a later "auth.deny;"
*/
li_http_header_overwrite(vr->response.headers, CONST_STR_LEN("WWW-Authenticate"), GSTR_LEN(vr->wrk->tmp_str));
}
if (debug) {
@ -432,6 +459,42 @@ static liAction* auth_htdigest_create(liServer *srv, liPlugin* p, liValue *val)
return auth_generic_create(srv, p, val, "auth.htdigest", auth_backend_htdigest, TRUE);
}
static liHandlerResult auth_handle_deny(liVRequest *vr, gpointer param, gpointer *context) {
UNUSED(param);
UNUSED(context);
if (!li_vrequest_handle_direct(vr)) {
/* only allow access restrictions as previous handlers */
switch (vr->response.http_status) { /* use same list as in auth_basic */
case 401: /* Unauthorized */
case 402: /* Payment Required */
case 403: /* Forbidden */
case 405: /* Method Not Allowed */
case 407: /* Proxy Authentication Required */
case 500: /* Internal Server Error */
return LI_HANDLER_GO_ON;
default:
return LI_HANDLER_ERROR;
}
}
vr->response.http_status = 401;
return LI_HANDLER_GO_ON;
}
static liAction* auth_deny(liServer *srv, liPlugin* p, liValue *val) {
UNUSED(srv);
UNUSED(p);
if (val) {
ERROR(srv, "%s", "'auth.deny' action doesn't have parameters");
return NULL;
}
return li_action_new_function(auth_handle_deny, NULL, NULL, NULL);
}
static const liPluginOption options[] = {
{ "auth.debug", LI_VALUE_BOOLEAN, NULL, NULL, NULL },
@ -443,6 +506,8 @@ static const liPluginAction actions[] = {
{ "auth.htpasswd", auth_htpasswd_create },
{ "auth.htdigest", auth_htdigest_create },
{ "auth.deny", auth_deny },
{ NULL, NULL }
};

Loading…
Cancel
Save