summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2017-07-09 21:26:49 +0200
committerJo-Philipp Wich <jo@mein.io>2017-07-09 21:35:26 +0200
commitd6360bf81eb350857c9c9532a413702e3a9f57be (patch)
treeab08604fc66779ce2750995678eadc3fb2cce98d
parent4f127c32544edabd420dbda114db50168a12ccfb (diff)
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>
-rw-r--r--modules/luci-base/luasrc/dispatcher.lua160
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