From 199c8cbc4c32506ecfe89850615b88a3f0276dd3 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Thu, 15 Jan 2015 10:55:53 +0100 Subject: [PATCH] luci-base: switch to ubus sessions Remove luci.sauth session storage implementation and offload the session management to the rpcd ubus backend. Also depend on rpcd due to this. --- modules/luci-base/Makefile | 2 +- modules/luci-base/luasrc/dispatcher.lua | 36 +++--- modules/luci-base/luasrc/sauth.lua | 127 --------------------- .../luasrc/controller/admin/index.lua | 6 +- .../luasrc/controller/mini/index.lua | 6 +- modules/luci-mod-rpc/luasrc/controller/rpc.lua | 30 ++--- 6 files changed, 47 insertions(+), 160 deletions(-) delete mode 100644 modules/luci-base/luasrc/sauth.lua diff --git a/modules/luci-base/Makefile b/modules/luci-base/Makefile index 15aababbb..8337fea71 100644 --- a/modules/luci-base/Makefile +++ b/modules/luci-base/Makefile @@ -12,7 +12,7 @@ LUCI_TYPE:=mod LUCI_BASENAME:=base LUCI_TITLE:=LuCI core libraries -LUCI_DEPENDS:=+lua +libuci-lua +luci-lib-nixio +LUCI_DEPENDS:=+lua +libuci-lua +luci-lib-nixio +rpcd PKG_SOURCE:=LuaSrcDiet-0.12.1.tar.bz2 PKG_SOURCE_URL:=https://luasrcdiet.googlecode.com/files diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua index f7e16e77b..4bbd58f9d 100644 --- a/modules/luci-base/luasrc/dispatcher.lua +++ b/modules/luci-base/luasrc/dispatcher.lua @@ -333,8 +333,6 @@ function dispatch(request) ) if track.sysauth then - local sauth = require "luci.sauth" - local authen = type(track.sysauth_authenticator) == "function" and track.sysauth_authenticator or authenticator[track.sysauth_authenticator] @@ -349,7 +347,7 @@ function dispatch(request) verifytoken = true end - local sdat = sauth.read(sess) + local sdat = (util.ubus("session", "get", { ubus_rpc_session = sess }) or { }).values local user if sdat then @@ -371,20 +369,28 @@ function dispatch(request) if not user or not util.contains(accs, user) then return else - local sid = sess or luci.sys.uniqueid(16) if not sess then - local token = luci.sys.uniqueid(16) - sauth.reap() - sauth.write(sid, { - user=user, - token=token, - secret=luci.sys.uniqueid(16) - }) - ctx.urltoken.stok = token + local sdat = util.ubus("session", "create", { timeout = luci.config.sauth.sessiontime }) + if sdat then + local token = luci.sys.uniqueid(16) + util.ubus("session", "set", { + ubus_rpc_session = sdat.ubus_rpc_session, + values = { + user = user, + token = token, + section = luci.sys.uniqueid(16) + } + }) + sess = sdat.ubus_rpc_session + ctx.urltoken.stok = token + end + end + + if sess then + luci.http.header("Set-Cookie", "sysauth=" .. sess.."; path="..build_url()) + ctx.authsession = sess + ctx.authuser = user end - luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path="..build_url()) - ctx.authsession = sid - ctx.authuser = user end else luci.http.status(403, "Forbidden") diff --git a/modules/luci-base/luasrc/sauth.lua b/modules/luci-base/luasrc/sauth.lua deleted file mode 100644 index 32f172dcd..000000000 --- a/modules/luci-base/luasrc/sauth.lua +++ /dev/null @@ -1,127 +0,0 @@ ---[[ - -Session authentication -(c) 2008 Steven Barth - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -$Id$ - -]]-- - ---- LuCI session library. -module("luci.sauth", package.seeall) -require("luci.util") -require("luci.sys") -require("luci.config") -local nixio = require "nixio", require "nixio.util" -local fs = require "nixio.fs" - - -luci.config.sauth = luci.config.sauth or {} -sessionpath = luci.config.sauth.sessionpath -sessiontime = tonumber(luci.config.sauth.sessiontime) or 15 * 60 - ---- Prepare session storage by creating the session directory. -function prepare() - fs.mkdir(sessionpath, 700) - if not sane() then - error("Security Exception: Session path is not sane!") - end -end - -local function _read(id) - local blob = fs.readfile(sessionpath .. "/" .. id) - return blob -end - -local function _write(id, data) - local f = nixio.open(sessionpath .. "/" .. id, "w", 600) - f:writeall(data) - f:close() -end - -local function _checkid(id) - return not not (id and #id == 32 and id:match("^[a-fA-F0-9]+$")) -end - ---- Write session data to a session file. --- @param id Session identifier --- @param data Session data table -function write(id, data) - if not sane() then - prepare() - end - - assert(_checkid(id), "Security Exception: Session ID is invalid!") - assert(type(data) == "table", "Security Exception: Session data invalid!") - - data.atime = luci.sys.uptime() - - _write(id, luci.util.get_bytecode(data)) -end - ---- Read a session and return its content. --- @param id Session identifier --- @return Session data table or nil if the given id is not found -function read(id) - if not id or #id == 0 then - return nil - end - - assert(_checkid(id), "Security Exception: Session ID is invalid!") - - if not sane(sessionpath .. "/" .. id) then - return nil - end - - local blob = _read(id) - local func = loadstring(blob) - setfenv(func, {}) - - local sess = func() - assert(type(sess) == "table", "Session data invalid!") - - if sess.atime and sess.atime + sessiontime < luci.sys.uptime() then - kill(id) - return nil - end - - -- refresh atime in session - write(id, sess) - - return sess -end - ---- Check whether Session environment is sane. --- @return Boolean status -function sane(file) - return luci.sys.process.info("uid") - == fs.stat(file or sessionpath, "uid") - and fs.stat(file or sessionpath, "modestr") - == (file and "rw-------" or "rwx------") -end - ---- Kills a session --- @param id Session identifier -function kill(id) - assert(_checkid(id), "Security Exception: Session ID is invalid!") - fs.unlink(sessionpath .. "/" .. id) -end - ---- Remove all expired session data files -function reap() - if sane() then - local id - for id in nixio.fs.dir(sessionpath) do - if _checkid(id) then - -- reading the session will kill it if it is expired - read(id) - end - end - end -end diff --git a/modules/luci-mod-admin-full/luasrc/controller/admin/index.lua b/modules/luci-mod-admin-full/luasrc/controller/admin/index.lua index 4e832529d..64a620ca2 100644 --- a/modules/luci-mod-admin-full/luasrc/controller/admin/index.lua +++ b/modules/luci-mod-admin-full/luasrc/controller/admin/index.lua @@ -38,9 +38,11 @@ end function action_logout() local dsp = require "luci.dispatcher" - local sauth = require "luci.sauth" + local utl = require "luci.util" if dsp.context.authsession then - sauth.kill(dsp.context.authsession) + utl.ubus("session", "destroy", { + ubus_rpc_session = dsp.context.authsession + }) dsp.context.urltoken.stok = nil end diff --git a/modules/luci-mod-admin-mini/luasrc/controller/mini/index.lua b/modules/luci-mod-admin-mini/luasrc/controller/mini/index.lua index 9d6a38ed4..6800f9bfd 100644 --- a/modules/luci-mod-admin-mini/luasrc/controller/mini/index.lua +++ b/modules/luci-mod-admin-mini/luasrc/controller/mini/index.lua @@ -37,9 +37,11 @@ end function action_logout() local dsp = require "luci.dispatcher" - local sauth = require "luci.sauth" + local utl = require "luci.util" if dsp.context.authsession then - sauth.kill(dsp.context.authsession) + utl.ubus("session", "destroy", { + ubus_rpc_session = dsp.context.authsession + }) dsp.context.urltoken.stok = nil end diff --git a/modules/luci-mod-rpc/luasrc/controller/rpc.lua b/modules/luci-mod-rpc/luasrc/controller/rpc.lua index 359184c74..92947168e 100644 --- a/modules/luci-mod-rpc/luasrc/controller/rpc.lua +++ b/modules/luci-mod-rpc/luasrc/controller/rpc.lua @@ -25,7 +25,7 @@ function index() local function authenticator(validator, accs) local auth = luci.http.formvalue("auth", true) if auth then -- if authentication token was given - local sdat = luci.sauth.read(auth) + local sdat = (luci.util.ubus("session", "get", { ubus_rpc_session = auth }) or { }).values if sdat then -- if given token is valid if sdat.user and luci.util.contains(accs, sdat.user) then return sdat.user, auth @@ -49,7 +49,6 @@ end function rpc_auth() local jsonrpc = require "luci.jsonrpc" - local sauth = require "luci.sauth" local http = require "luci.http" local sys = require "luci.sys" local ltn12 = require "luci.ltn12" @@ -62,17 +61,22 @@ function rpc_auth() local sid, token, secret if sys.user.checkpasswd(user, pass) then - sid = sys.uniqueid(16) - token = sys.uniqueid(16) - secret = sys.uniqueid(16) - - http.header("Set-Cookie", "sysauth=" .. sid.."; path=/") - sauth.reap() - sauth.write(sid, { - user=user, - token=token, - secret=secret - }) + local sdat = util.ubus("session", "create", { timeout = luci.config.sauth.sessiontime }) + if sdat then + sid = sdat.ubus_rpc_session + token = sys.uniqueid(16) + secret = sys.uniqueid(16) + + http.header("Set-Cookie", "sysauth="..sid.."; path=/") + util.ubus("session", "set", { + ubus_rpc_session = sid, + values = { + user = user, + token = token, + secret = secret + } + }) + end end return sid and {sid=sid, token=token, secret=secret} -- 2.11.0