From 4e1b884157017b6729d2523e95385756898eac7c Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich <jo@mein.io> Date: Tue, 11 Jul 2017 14:12:50 +0200 Subject: [PATCH] luci-base: properly handle authentication without authenticator Some controller actions like the ones in "servicectl" require authentication but are not meant to provide an authenticator because they're only invoked by scripts. Rework the dispatcher logic to handle this situation and only bail out if an authenticator name other than "htmlauth" is set. Signed-off-by: Jo-Philipp Wich <jo@mein.io> --- modules/luci-base/luasrc/dispatcher.lua | 97 +++++++++++++------------ 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua index 2b5f7b4929..1b684aa79c 100644 --- a/modules/luci-base/luasrc/dispatcher.lua +++ b/modules/luci-base/luasrc/dispatcher.lua @@ -174,7 +174,8 @@ local function session_retrieve(sid, allowed_users) if type(sdat) == "table" and type(sdat.values) == "table" and type(sdat.values.token) == "string" and - util.contains(allowed_users, sdat.values.username) + (not allowed_users or + util.contains(allowed_users, sdat.values.username)) then return sid, sdat.values end @@ -182,25 +183,27 @@ local function session_retrieve(sid, allowed_users) return nil, nil end -local function session_setup(user, pass) - local login = util.ubus("session", "login", { - username = user, - password = pass, - timeout = tonumber(luci.config.sauth.sessiontime) - }) - - if type(login) == "table" and - type(login.ubus_rpc_session) == "string" - then - util.ubus("session", "set", { - ubus_rpc_session = login.ubus_rpc_session, - values = { token = sys.uniqueid(16) } +local function session_setup(user, pass, allowed_users) + if util.contains(allowed_users, user) then + local login = util.ubus("session", "login", { + username = user, + password = pass, + timeout = tonumber(luci.config.sauth.sessiontime) }) - return login.ubus_rpc_session + if type(login) == "table" and + type(login.ubus_rpc_session) == "string" + then + util.ubus("session", "set", { + ubus_rpc_session = login.ubus_rpc_session, + values = { token = sys.uniqueid(16) } + }) + + return session_retrieve(login.ubus_rpc_session) + end end - return nil + return nil, nil end function dispatch(request) @@ -350,6 +353,11 @@ function dispatch(request) local authen = track.sysauth_authenticator local _, sid, sdat, default_user, allowed_users + if type(authen) == "string" and authen ~= "htmlauth" then + error500("Unsupported authenticator %q configured" % authen) + return + end + if type(track.sysauth) == "table" then default_user, allowed_users = nil, track.sysauth else @@ -358,44 +366,39 @@ function dispatch(request) if type(authen) == "function" then _, sid = authen(sys.user.checkpasswd, allowed_users) - elseif authen == "htmlauth" then - sid, sdat = session_retrieve(http.getcookie("sysauth"), allowed_users) + else + sid = http.getcookie("sysauth") + end - if not sid then - local user = http.getenv("HTTP_AUTH_USER") - local pass = http.getenv("HTTP_AUTH_PASS") + sid, sdat = session_retrieve(sid, allowed_users) - if user == nil and pass == nil then - user = http.formvalue("luci_username") - pass = http.formvalue("luci_password") - end + if not (sid and sdat) and authen == "htmlauth" then + local user = http.getenv("HTTP_AUTH_USER") + local pass = http.getenv("HTTP_AUTH_PASS") - if util.contains(allowed_users, user) then - sid, sdat = session_setup(user, pass), nil - end + if user == nil and pass == nil then + user = http.formvalue("luci_username") + pass = http.formvalue("luci_password") + end - if not sid then - require("luci.i18n") - require("luci.template") - context.path = {} - http.status(403, "Forbidden") - luci.template.render(track.sysauth_template or "sysauth", { - duser = default_user, - fuser = user - }) - return - end + sid, sdat = session_setup(user, pass, allowed_users) + + if not sid then + local tmpl = require "luci.template" - http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sid, build_url() }) - http.redirect(build_url(unpack(ctx.requestpath))) + context.path = {} + + http.status(403, "Forbidden") + tmpl.render(track.sysauth_template or "sysauth", { + duser = default_user, + fuser = user + }) + + return end - else - error500("Unsupported authenticator configured") - return - end - if not sdat then - sid, sdat = session_retrieve(sid, allowed_users) + http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sid, build_url() }) + http.redirect(build_url(unpack(ctx.requestpath))) end if not sid or not sdat then -- 2.30.2