X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=modules%2Fluci-mod-rpc%2Fluasrc%2Fcontroller%2Frpc.lua;h=5df5e375a7c2b06b2a30c07c66f5b1f48cb8a4ce;hp=129ca43b514ac1d35526829c01e68ffe638d42eb;hb=055b621cf5cdc15b24e78408d610a00f6869b8e0;hpb=c0e2255ae90145062d5966725c7ee5da3c310ce1 diff --git a/modules/luci-mod-rpc/luasrc/controller/rpc.lua b/modules/luci-mod-rpc/luasrc/controller/rpc.lua index 129ca43b5..5df5e375a 100644 --- a/modules/luci-mod-rpc/luasrc/controller/rpc.lua +++ b/modules/luci-mod-rpc/luasrc/controller/rpc.lua @@ -2,37 +2,56 @@ -- Copyright 2008 Jo-Philipp Wich -- Licensed to the public under the Apache License 2.0. -local require = require -local pairs = pairs -local print = print -local pcall = pcall -local table = table +module("luci.controller.rpc", package.seeall) + + +function session_retrieve(sid, allowed_users) + local util = require "luci.util" + 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 + type(sdat.values.secret) == "string" and + type(sdat.values.username) == "string" and + util.contains(allowed_users, sdat.values.username) + then + return sid, sdat.values + end -module "luci.controller.rpc" + return nil +end -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.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 - end - end +function authenticator(validator, accs) + local http = require "luci.http" + local ctrl = require "luci.controller.rpc" + local auth = http.formvalue("auth", true) or http.getcookie("sysauth") + + if auth then -- if authentication token was given + local sid, sdat = ctrl.session_retrieve(auth, accs) + if sdat then -- if given token is valid + return sdat.username, sid end - luci.http.status(403, "Forbidden") + http.status(403, "Forbidden") end +end + + +function index() + local ctrl = require "luci.controller.rpc" local rpc = node("rpc") rpc.sysauth = "root" - rpc.sysauth_authenticator = authenticator + rpc.sysauth_authenticator = ctrl.authenticator rpc.notemplate = true entry({"rpc", "uci"}, call("rpc_uci")) entry({"rpc", "fs"}, call("rpc_fs")) entry({"rpc", "sys"}, call("rpc_sys")) entry({"rpc", "ipkg"}, call("rpc_ipkg")) + entry({"rpc", "ip"}, call("rpc_ip")) entry({"rpc", "auth"}, call("rpc_auth")).sysauth = false end @@ -43,39 +62,48 @@ function rpc_auth() local ltn12 = require "luci.ltn12" local util = require "luci.util" - local loginstat - local server = {} server.challenge = function(user, pass) - local sid, token, secret - - require "luci.config" - - if sys.user.checkpasswd(user, pass) then - local sdat = util.ubus("session", "create", { timeout = luci.config.sauth.sessiontime }) + local config = require "luci.config" + local login = util.ubus("session", "login", { + username = user, + password = pass, + timeout = tonumber(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), + secret = sys.uniqueid(16) + } + }) + + local sid, sdat = ctrl.session_retrieve(login.ubus_rpc_session, { user }) 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 - } - }) + return { + sid = sid, + token = sdat.token, + secret = sdat.secret + } end end - return sid and {sid=sid, token=token, secret=secret} + return nil end server.login = function(...) local challenge = server.challenge(...) - return challenge and challenge.sid + if challenge then + http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ + challenge.sid, + http.getenv("SCRIPT_NAME") + }) + return challenge.sid + end end http.prepare_content("application/json") @@ -137,13 +165,40 @@ function rpc_fs() end function rpc_sys() + local util = require "luci.util" local sys = require "luci.sys" local jsonrpc = require "luci.jsonrpc" local http = require "luci.http" local ltn12 = require "luci.ltn12" + local sys2 = util.clone(sys) + sys2.net = util.clone(sys.net) + sys2.wifi = util.clone(sys.wifi) + + function sys2.wifi.getiwinfo(ifname, operation) + local iw = sys.wifi.getiwinfo(ifname) + if iw then + if operation then + assert(type(iwinfo[iw.type][operation]) == "function") + return iw[operation] + end + + local n, f + local rv = { ifname = ifname } + for n, f in pairs(iwinfo[iw.type]) do + if type(f) == "function" and + n ~= "scanlist" and n ~= "countrylist" + then + rv[n] = iw[n] + end + end + return rv + end + return nil + end + http.prepare_content("application/json") - ltn12.pump.all(jsonrpc.handle(sys, http.source()), http.write) + ltn12.pump.all(jsonrpc.handle(sys2, http.source()), http.write) end function rpc_ipkg() @@ -159,3 +214,34 @@ function rpc_ipkg() http.prepare_content("application/json") ltn12.pump.all(jsonrpc.handle(ipkg, http.source()), http.write) end + +function rpc_ip() + if not pcall(require, "luci.ip") then + luci.http.status(404, "Not Found") + return nil + end + + local util = require "luci.util" + local ip = require "luci.ip" + local jsonrpc = require "luci.jsonrpc" + local http = require "luci.http" + local ltn12 = require "luci.ltn12" + + local ip2 = util.clone(ip) + + local _, n + for _, n in ipairs({ "new", "IPv4", "IPv6", "MAC" }) do + ip2[n] = function(address, netmask, operation, argument) + local cidr = ip[n](address, netmask) + if cidr and operation then + assert(type(cidr[operation]) == "function") + local cidr2 = cidr[operation](cidr, argument) + return (type(cidr2) == "userdata") and cidr2:string() or cidr2 + end + return (type(cidr) == "userdata") and cidr:string() or cidr + end + end + + http.prepare_content("application/json") + ltn12.pump.all(jsonrpc.handle(ip2, http.source()), http.write) +end