rpc.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. -- Copyright 2008 Steven Barth <steven@midlink.org>
  2. -- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
  3. -- Licensed to the public under the Apache License 2.0.
  4. local require = require
  5. local pairs = pairs
  6. local print = print
  7. local pcall = pcall
  8. local table = table
  9. module "luci.controller.rpc"
  10. function index()
  11. local function authenticator(validator, accs)
  12. local auth = luci.http.formvalue("auth", true)
  13. if auth then -- if authentication token was given
  14. local sdat = (luci.util.ubus("session", "get", { ubus_rpc_session = auth }) or { }).values
  15. if sdat then -- if given token is valid
  16. if sdat.user and luci.util.contains(accs, sdat.user) then
  17. return sdat.user, auth
  18. end
  19. end
  20. end
  21. luci.http.status(403, "Forbidden")
  22. end
  23. local rpc = node("rpc")
  24. rpc.sysauth = "root"
  25. rpc.sysauth_authenticator = authenticator
  26. rpc.notemplate = true
  27. entry({"rpc", "uci"}, call("rpc_uci"))
  28. entry({"rpc", "fs"}, call("rpc_fs"))
  29. entry({"rpc", "sys"}, call("rpc_sys"))
  30. entry({"rpc", "ipkg"}, call("rpc_ipkg"))
  31. entry({"rpc", "auth"}, call("rpc_auth")).sysauth = false
  32. end
  33. function rpc_auth()
  34. local jsonrpc = require "luci.jsonrpc"
  35. local http = require "luci.http"
  36. local sys = require "luci.sys"
  37. local ltn12 = require "luci.ltn12"
  38. local util = require "luci.util"
  39. local loginstat
  40. local server = {}
  41. server.challenge = function(user, pass)
  42. local sid, token, secret
  43. local config = require "luci.config"
  44. if sys.user.checkpasswd(user, pass) then
  45. local sdat = util.ubus("session", "create", { timeout = config.sauth.sessiontime })
  46. if sdat then
  47. sid = sdat.ubus_rpc_session
  48. token = sys.uniqueid(16)
  49. secret = sys.uniqueid(16)
  50. http.header("Set-Cookie", "sysauth="..sid.."; path=/")
  51. util.ubus("session", "set", {
  52. ubus_rpc_session = sid,
  53. values = {
  54. user = user,
  55. token = token,
  56. secret = secret
  57. }
  58. })
  59. end
  60. end
  61. return sid and {sid=sid, token=token, secret=secret}
  62. end
  63. server.login = function(...)
  64. local challenge = server.challenge(...)
  65. return challenge and challenge.sid
  66. end
  67. http.prepare_content("application/json")
  68. ltn12.pump.all(jsonrpc.handle(server, http.source()), http.write)
  69. end
  70. function rpc_uci()
  71. if not pcall(require, "luci.model.uci") then
  72. luci.http.status(404, "Not Found")
  73. return nil
  74. end
  75. local uci = require "luci.jsonrpcbind.uci"
  76. local jsonrpc = require "luci.jsonrpc"
  77. local http = require "luci.http"
  78. local ltn12 = require "luci.ltn12"
  79. http.prepare_content("application/json")
  80. ltn12.pump.all(jsonrpc.handle(uci, http.source()), http.write)
  81. end
  82. function rpc_fs()
  83. local util = require "luci.util"
  84. local io = require "io"
  85. local fs2 = util.clone(require "nixio.fs")
  86. local jsonrpc = require "luci.jsonrpc"
  87. local http = require "luci.http"
  88. local ltn12 = require "luci.ltn12"
  89. function fs2.readfile(filename)
  90. local stat, mime = pcall(require, "mime")
  91. if not stat then
  92. error("Base64 support not available. Please install LuaSocket.")
  93. end
  94. local fp = io.open(filename)
  95. if not fp then
  96. return nil
  97. end
  98. local output = {}
  99. local sink = ltn12.sink.table(output)
  100. local source = ltn12.source.chain(ltn12.source.file(fp), mime.encode("base64"))
  101. return ltn12.pump.all(source, sink) and table.concat(output)
  102. end
  103. function fs2.writefile(filename, data)
  104. local stat, mime = pcall(require, "mime")
  105. if not stat then
  106. error("Base64 support not available. Please install LuaSocket.")
  107. end
  108. local file = io.open(filename, "w")
  109. local sink = file and ltn12.sink.chain(mime.decode("base64"), ltn12.sink.file(file))
  110. return sink and ltn12.pump.all(ltn12.source.string(data), sink) or false
  111. end
  112. http.prepare_content("application/json")
  113. ltn12.pump.all(jsonrpc.handle(fs2, http.source()), http.write)
  114. end
  115. function rpc_sys()
  116. local sys = require "luci.sys"
  117. local jsonrpc = require "luci.jsonrpc"
  118. local http = require "luci.http"
  119. local ltn12 = require "luci.ltn12"
  120. http.prepare_content("application/json")
  121. ltn12.pump.all(jsonrpc.handle(sys, http.source()), http.write)
  122. end
  123. function rpc_ipkg()
  124. if not pcall(require, "luci.model.ipkg") then
  125. luci.http.status(404, "Not Found")
  126. return nil
  127. end
  128. local ipkg = require "luci.model.ipkg"
  129. local jsonrpc = require "luci.jsonrpc"
  130. local http = require "luci.http"
  131. local ltn12 = require "luci.ltn12"
  132. http.prepare_content("application/json")
  133. ltn12.pump.all(jsonrpc.handle(ipkg, http.source()), http.write)
  134. end