luci-base: use native ubus-rpc authorization protocol
authorJo-Philipp Wich <jo@mein.io>
Thu, 15 Aug 2019 14:07:48 +0000 (16:07 +0200)
committerJo-Philipp Wich <jo@mein.io>
Thu, 15 Aug 2019 14:10:42 +0000 (16:10 +0200)
Instead of granting complete ubus access under the active sysauth session,
implement the ubus-rpc authorization mechanism and make the ubus proxy
endpoint unauthenticated.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/luasrc/controller/admin/index.lua

index 3f2b465879500cdc2e11a450b37e9adbe062458f..b0427d6c058515197bae8ff61133dffbd0baa80f 100644 (file)
@@ -96,6 +96,7 @@ function index()
        page.leaf = true
 
        page = entry({"admin", "ubus"}, call("action_ubus"), nil)
+       page.sysauth = false
        page.leaf = true
 
        -- Logout is last
@@ -165,6 +166,17 @@ local ubus_types = {
        "double"
 }
 
+local function ubus_access(sid, obj, fun)
+       local res, code = luci.util.ubus("session", "access", {
+               ubus_rpc_session = sid,
+               scope            = "ubus",
+               object           = obj,
+               ["function"]     = fun
+       })
+
+       return (type(res) == "table" and res.access == true)
+end
+
 local function ubus_request(req)
        if type(req) ~= "table" or type(req.method) ~= "string" or type(req.params) ~= "table" or
           #req.params < 2 or req.jsonrpc ~= "2.0" or req.id == nil then
@@ -177,10 +189,14 @@ local function ubus_request(req)
                        return ubus_reply(req.id, nil, -32602, "Invalid parameters")
                end
 
-               if sid == "00000000000000000000000000000000" then
+               if sid == "00000000000000000000000000000000" and luci.dispatcher.context.authsession then
                        sid = luci.dispatcher.context.authsession
                end
 
+               if not ubus_access(sid, obj, fun) then
+                       return ubus_reply(req.id, nil, -32002, "Access denied")
+               end
+
                arg.ubus_rpc_session = sid
 
                local res, code = luci.util.ubus(obj, fun, arg)