diff options
-rw-r--r-- | modules/luci-base/luasrc/dispatcher.lua | 160 |
1 files changed, 83 insertions, 77 deletions
diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua index 0bd19456f..2b5f7b492 100644 --- a/modules/luci-base/luasrc/dispatcher.lua +++ b/modules/luci-base/luasrc/dispatcher.lua @@ -14,8 +14,6 @@ uci = require "luci.model.uci" i18n = require "luci.i18n" _M.fs = fs -authenticator = {} - -- Index table local index = nil @@ -101,24 +99,6 @@ function error500(message) return false end -function authenticator.htmlauth(validator, accs, default, template) - local user = http.formvalue("luci_username") - local pass = http.formvalue("luci_password") - - if user and validator(user, pass) then - return user - end - - require("luci.i18n") - require("luci.template") - context.path = {} - http.status(403, "Forbidden") - luci.template.render(template or "sysauth", {duser=default, fuser=user}) - - return false - -end - function httpdispatch(request, prefix) http.context.request = request @@ -188,6 +168,41 @@ function test_post_security() return true end +local function session_retrieve(sid, allowed_users) + local sdat = util.ubus("session", "get", { ubus_rpc_session = sid }) + + if type(sdat) == "table" and + type(sdat.values) == "table" and + type(sdat.values.token) == "string" and + util.contains(allowed_users, sdat.values.username) + then + return sid, sdat.values + end + + 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) } + }) + + return login.ubus_rpc_session + end + + return nil +end + function dispatch(request) --context._disable_memtrace = require "luci.debug".trap_memtrace("l") local ctx = context @@ -332,74 +347,65 @@ function dispatch(request) ) if track.sysauth then - local authen = type(track.sysauth_authenticator) == "function" - and track.sysauth_authenticator - or authenticator[track.sysauth_authenticator] - - local def = (type(track.sysauth) == "string") and track.sysauth - local accs = def and {track.sysauth} or track.sysauth - local sess = ctx.authsession - if not sess then - sess = http.getcookie("sysauth") - sess = sess and sess:match("^[a-f0-9]*$") - end + local authen = track.sysauth_authenticator + local _, sid, sdat, default_user, allowed_users - local sdat = (util.ubus("session", "get", { ubus_rpc_session = sess }) or { }).values - local user, token - - if sdat then - user = sdat.user - token = sdat.token + if type(track.sysauth) == "table" then + default_user, allowed_users = nil, track.sysauth else - local eu = http.getenv("HTTP_AUTH_USER") - local ep = http.getenv("HTTP_AUTH_PASS") - if eu and ep and sys.user.checkpasswd(eu, ep) then - authen = function() return eu end - end + default_user, allowed_users = track.sysauth, { track.sysauth } end - if not util.contains(accs, user) then - if authen then - local user, sess = authen(sys.user.checkpasswd, accs, def, track.sysauth_template) - local token - if not user or not util.contains(accs, user) then - return - else - if not sess then - local sdat = util.ubus("session", "create", { timeout = tonumber(luci.config.sauth.sessiontime) }) - if sdat then - token = sys.uniqueid(16) - util.ubus("session", "set", { - ubus_rpc_session = sdat.ubus_rpc_session, - values = { - user = user, - token = token, - section = sys.uniqueid(16) - } - }) - sess = sdat.ubus_rpc_session - end - end + 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) - if sess and token then - http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sess, build_url() }) + if not sid then + local user = http.getenv("HTTP_AUTH_USER") + local pass = http.getenv("HTTP_AUTH_PASS") - ctx.authsession = sess - ctx.authtoken = token - ctx.authuser = user + if user == nil and pass == nil then + user = http.formvalue("luci_username") + pass = http.formvalue("luci_password") + end - http.redirect(build_url(unpack(ctx.requestpath))) - end + if util.contains(allowed_users, user) then + sid, sdat = session_setup(user, pass), nil end - else - http.status(403, "Forbidden") - return + + 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 + + http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sid, build_url() }) + http.redirect(build_url(unpack(ctx.requestpath))) end else - ctx.authsession = sess - ctx.authtoken = token - ctx.authuser = user + error500("Unsupported authenticator configured") + return + end + + if not sdat then + sid, sdat = session_retrieve(sid, allowed_users) end + + if not sid or not sdat then + http.status(403, "Forbidden") + return + end + + ctx.authsession = sid + ctx.authtoken = sdat.token + ctx.authuser = sdat.username end if c and require_post_security(c.target) then |