Refined urltokens and XSRF protection
This commit is contained in:
parent
73109f3e46
commit
1ee5ba632a
4 changed files with 19 additions and 15 deletions
|
@ -47,7 +47,12 @@ local fi
|
||||||
-- @param ... Virtual path
|
-- @param ... Virtual path
|
||||||
-- @return Relative URL
|
-- @return Relative URL
|
||||||
function build_url(...)
|
function build_url(...)
|
||||||
return context.scriptname .. "/" .. table.concat(arg, "/")
|
local path = {...}
|
||||||
|
local sn = http.getenv("SCRIPT_NAME") or ""
|
||||||
|
for k, v in pairs(context.urltoken) do
|
||||||
|
sn = sn .. "/;" .. k .. "=" .. http.urlencode(v)
|
||||||
|
end
|
||||||
|
return sn .. ((#path > 0) and "/" .. table.concat(path, "/") or "")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Send a 404 error code and render the "error404" template if available.
|
--- Send a 404 error code and render the "error404" template if available.
|
||||||
|
@ -123,7 +128,6 @@ function dispatch(request)
|
||||||
--context._disable_memtrace = require "luci.debug".trap_memtrace()
|
--context._disable_memtrace = require "luci.debug".trap_memtrace()
|
||||||
local ctx = context
|
local ctx = context
|
||||||
ctx.path = request
|
ctx.path = request
|
||||||
ctx.scriptname = luci.http.getenv("SCRIPT_NAME") or ""
|
|
||||||
ctx.urltoken = ctx.urltoken or {}
|
ctx.urltoken = ctx.urltoken or {}
|
||||||
|
|
||||||
require "luci.i18n".setlanguage(require "luci.config".main.lang)
|
require "luci.i18n".setlanguage(require "luci.config".main.lang)
|
||||||
|
@ -174,11 +178,6 @@ function dispatch(request)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for k, v in pairs(token) do
|
|
||||||
ctx.scriptname = ctx.scriptname .. "/;" .. k .. "=" ..
|
|
||||||
http.urlencode(v)
|
|
||||||
end
|
|
||||||
|
|
||||||
ctx.path = preq
|
ctx.path = preq
|
||||||
|
|
||||||
if track.i18n then
|
if track.i18n then
|
||||||
|
@ -202,9 +201,9 @@ function dispatch(request)
|
||||||
|
|
||||||
local viewns = setmetatable({}, {__index=function(table, key)
|
local viewns = setmetatable({}, {__index=function(table, key)
|
||||||
if key == "controller" then
|
if key == "controller" then
|
||||||
return ctx.scriptname
|
return build_url()
|
||||||
elseif key == "REQUEST_URI" then
|
elseif key == "REQUEST_URI" then
|
||||||
return ctx.scriptname .. "/" .. table.concat(ctx.requested, "/")
|
return build_url(ctx.requested)
|
||||||
else
|
else
|
||||||
return rawget(table, key) or _G[key]
|
return rawget(table, key) or _G[key]
|
||||||
end
|
end
|
||||||
|
@ -232,10 +231,11 @@ function dispatch(request)
|
||||||
local def = (type(track.sysauth) == "string") and track.sysauth
|
local def = (type(track.sysauth) == "string") and track.sysauth
|
||||||
local accs = def and {track.sysauth} or track.sysauth
|
local accs = def and {track.sysauth} or track.sysauth
|
||||||
local sess = ctx.authsession
|
local sess = ctx.authsession
|
||||||
local verifytoken = true
|
local verifytoken = false
|
||||||
if not sess then
|
if not sess then
|
||||||
sess = luci.http.getcookie("sysauth")
|
sess = luci.http.getcookie("sysauth")
|
||||||
sess = sess and sess:match("^[A-F0-9]+$")
|
sess = sess and sess:match("^[A-F0-9]+$")
|
||||||
|
verifytoken = true
|
||||||
end
|
end
|
||||||
|
|
||||||
local sdat = sauth.read(sess)
|
local sdat = sauth.read(sess)
|
||||||
|
@ -250,12 +250,12 @@ function dispatch(request)
|
||||||
|
|
||||||
if not util.contains(accs, user) then
|
if not util.contains(accs, user) then
|
||||||
if authen then
|
if authen then
|
||||||
|
ctx.urltoken.stok = nil
|
||||||
local user, sess = authen(luci.sys.user.checkpasswd, accs, def)
|
local user, sess = authen(luci.sys.user.checkpasswd, accs, def)
|
||||||
if not user or not util.contains(accs, user) then
|
if not user or not util.contains(accs, user) then
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
local sid = sess or luci.sys.uniqueid(16)
|
local sid = sess or luci.sys.uniqueid(16)
|
||||||
luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path=/")
|
|
||||||
if not sess then
|
if not sess then
|
||||||
local token = luci.sys.uniqueid(16)
|
local token = luci.sys.uniqueid(16)
|
||||||
sauth.write(sid, util.get_bytecode({
|
sauth.write(sid, util.get_bytecode({
|
||||||
|
@ -263,8 +263,9 @@ function dispatch(request)
|
||||||
token=token,
|
token=token,
|
||||||
secret=luci.sys.uniqueid(16)
|
secret=luci.sys.uniqueid(16)
|
||||||
}))
|
}))
|
||||||
ctx.scriptname = ctx.scriptname .. "/;stok="..token
|
ctx.urltoken.stok = token
|
||||||
end
|
end
|
||||||
|
luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path="..build_url())
|
||||||
ctx.authsession = sid
|
ctx.authsession = sid
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
|
@ -53,8 +53,9 @@ function action_logout()
|
||||||
local sauth = require "luci.sauth"
|
local sauth = require "luci.sauth"
|
||||||
if dsp.context.authsession then
|
if dsp.context.authsession then
|
||||||
sauth.kill(dsp.context.authsession)
|
sauth.kill(dsp.context.authsession)
|
||||||
|
dsp.context.urltoken.stok = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
luci.http.header("Set-Cookie", "sysauth=; path=/")
|
luci.http.header("Set-Cookie", "sysauth=; path=" .. dsp.build_url())
|
||||||
luci.http.redirect(luci.dispatcher.build_url())
|
luci.http.redirect(luci.dispatcher.build_url())
|
||||||
end
|
end
|
|
@ -44,8 +44,9 @@ function action_logout()
|
||||||
local sauth = require "luci.sauth"
|
local sauth = require "luci.sauth"
|
||||||
if dsp.context.authsession then
|
if dsp.context.authsession then
|
||||||
sauth.kill(dsp.context.authsession)
|
sauth.kill(dsp.context.authsession)
|
||||||
|
dsp.context.urltoken.stok = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
luci.http.header("Set-Cookie", "sysauth=; path=/")
|
luci.http.header("Set-Cookie", "sysauth=; path=" .. dsp.build_url())
|
||||||
luci.http.redirect(luci.dispatcher.build_url())
|
luci.http.redirect(luci.dispatcher.build_url())
|
||||||
end
|
end
|
|
@ -25,7 +25,8 @@ function index()
|
||||||
local function authenticator(validator, accs)
|
local function authenticator(validator, accs)
|
||||||
local auth = luci.http.formvalue("auth", true)
|
local auth = luci.http.formvalue("auth", true)
|
||||||
if auth then
|
if auth then
|
||||||
local user = luci.sauth.read(auth)
|
local sdat = luci.sauth.read(auth)
|
||||||
|
user = loadstring(sdat)().user
|
||||||
if user and luci.util.contains(accs, user) then
|
if user and luci.util.contains(accs, user) then
|
||||||
return user, auth
|
return user, auth
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue