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:
parent
4f127c3254
commit
d6360bf81e
1 changed files with 84 additions and 78 deletions
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue