luci-base: use rpcd session logins

Drop the custom credentials checking in favor to perform proper session
logins via rpcd. This is needed to properly setup ACLs when spawning
rpcd sessions in order to support direct client side ubus access in the
future.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
Jo-Philipp Wich 2017-07-09 21:26:49 +02:00
parent 4f127c3254
commit d6360bf81e

View file

@ -14,8 +14,6 @@ uci = require "luci.model.uci"
i18n = require "luci.i18n" i18n = require "luci.i18n"
_M.fs = fs _M.fs = fs
authenticator = {}
-- Index table -- Index table
local index = nil local index = nil
@ -101,24 +99,6 @@ function error500(message)
return false return false
end 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) function httpdispatch(request, prefix)
http.context.request = request http.context.request = request
@ -188,6 +168,41 @@ function test_post_security()
return true return true
end 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) function dispatch(request)
--context._disable_memtrace = require "luci.debug".trap_memtrace("l") --context._disable_memtrace = require "luci.debug".trap_memtrace("l")
local ctx = context local ctx = context
@ -332,74 +347,65 @@ function dispatch(request)
) )
if track.sysauth then if track.sysauth then
local authen = type(track.sysauth_authenticator) == "function" local authen = track.sysauth_authenticator
and track.sysauth_authenticator local _, sid, sdat, default_user, allowed_users
or authenticator[track.sysauth_authenticator]
local def = (type(track.sysauth) == "string") and track.sysauth if type(track.sysauth) == "table" then
local accs = def and {track.sysauth} or track.sysauth default_user, allowed_users = nil, track.sysauth
local sess = ctx.authsession
if not sess then
sess = http.getcookie("sysauth")
sess = sess and sess:match("^[a-f0-9]*$")
end
local sdat = (util.ubus("session", "get", { ubus_rpc_session = sess }) or { }).values
local user, token
if sdat then
user = sdat.user
token = sdat.token
else else
local eu = http.getenv("HTTP_AUTH_USER") default_user, allowed_users = track.sysauth, { track.sysauth }
local ep = http.getenv("HTTP_AUTH_PASS")
if eu and ep and sys.user.checkpasswd(eu, ep) then
authen = function() return eu end
end
end end
if not util.contains(accs, user) then if type(authen) == "function" then
if authen then _, sid = authen(sys.user.checkpasswd, allowed_users)
local user, sess = authen(sys.user.checkpasswd, accs, def, track.sysauth_template) elseif authen == "htmlauth" then
local token sid, sdat = session_retrieve(http.getcookie("sysauth"), allowed_users)
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 sess and token then if not sid then
http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sess, build_url() }) local user = http.getenv("HTTP_AUTH_USER")
local pass = http.getenv("HTTP_AUTH_PASS")
ctx.authsession = sess if user == nil and pass == nil then
ctx.authtoken = token user = http.formvalue("luci_username")
ctx.authuser = user pass = http.formvalue("luci_password")
http.redirect(build_url(unpack(ctx.requestpath)))
end
end end
else
http.status(403, "Forbidden") if util.contains(allowed_users, user) then
return sid, sdat = session_setup(user, pass), nil
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
http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sid, build_url() })
http.redirect(build_url(unpack(ctx.requestpath)))
end end
else else
ctx.authsession = sess error500("Unsupported authenticator configured")
ctx.authtoken = token return
ctx.authuser = user
end 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 end
if c and require_post_security(c.target) then if c and require_post_security(c.target) then