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 if not sid then
else local user = http.getenv("HTTP_AUTH_USER")
if not sess then local pass = http.getenv("HTTP_AUTH_PASS")
local sdat = util.ubus("session", "create", { timeout = tonumber(luci.config.sauth.sessiontime) })
if sdat then if user == nil and pass == nil then
token = sys.uniqueid(16) user = http.formvalue("luci_username")
util.ubus("session", "set", { pass = http.formvalue("luci_password")
ubus_rpc_session = sdat.ubus_rpc_session, end
values = {
user = user, if util.contains(allowed_users, user) then
token = token, sid, sdat = session_setup(user, pass), nil
section = sys.uniqueid(16) 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
}) })
sess = sdat.ubus_rpc_session return
end
end end
if sess and token then http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sid, build_url() })
http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sess, build_url() })
ctx.authsession = sess
ctx.authtoken = token
ctx.authuser = user
http.redirect(build_url(unpack(ctx.requestpath))) http.redirect(build_url(unpack(ctx.requestpath)))
end end
end
else else
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") http.status(403, "Forbidden")
return return
end end
else
ctx.authsession = sess ctx.authsession = sid
ctx.authtoken = token ctx.authtoken = sdat.token
ctx.authuser = user ctx.authuser = sdat.username
end
end end
if c and require_post_security(c.target) then if c and require_post_security(c.target) then