Advertisement
osmarks

RCEoR Client

Apr 25th, 2018
348
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.41 KB | None | 0 0
  1. --[[
  2. RCEoR: a secure protocol for remote code execution over rednet (ComputerCraft)
  3.  
  4. This is free and unencumbered software released into the public domain.
  5.  
  6. Anyone is free to copy, modify, publish, use, compile, sell, or
  7. distribute this software, either in source code form or as a compiled
  8. binary, for any purpose, commercial or non-commercial, and by any
  9. means.
  10.  
  11. In jurisdictions that recognize copyright laws, the author or authors
  12. of this software dedicate any and all copyright interest in the
  13. software to the public domain. We make this dedication for the benefit
  14. of the public at large and to the detriment of our heirs and
  15. successors. We intend this dedication to be an overt act of
  16. relinquishment in perpetuity of all present and future rights to this
  17. software under copyright law.
  18.  
  19. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  22. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  24. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25. OTHER DEALINGS IN THE SOFTWARE.
  26.  
  27. For more information, please refer to <http://unlicense.org/>
  28.  
  29. RCEoR v1.1
  30. Protocol: rednet protocol "rceor", messages of the format:
  31. {code = [code to run], evil = [evilness of code]}
  32. live is also accepted as an alias for evil.
  33. ]]
  34.  
  35. local secureEnv = {
  36.     print = print,
  37.     http = http,
  38.     rednet = rednet,
  39.     textutils = textutils,
  40.     bit = bit,
  41.     pcall = pcall,
  42.     colors = colors,
  43.     gps = gps,
  44.     pairs = pairs,
  45.     ipairs = ipairs,
  46.     math = math,
  47.     _HOST = _HOST .. " (RCEoR Sandbox)",
  48.     string = string
  49. }
  50.  
  51. function clone(x)
  52.     local ty = type(x)
  53.     if ty == "table" then
  54.         local new = {}
  55.         for k, v in pairs(x) do
  56.             new[k] = clone(v)
  57.         end
  58.     elseif ty == "function" then
  59.         return function(...) return x(...) end
  60.     else
  61.         return x
  62.     end
  63. end
  64.  
  65. secureEnv.rednet.close = nil
  66.  
  67. local argv = {...}
  68. local secure = true
  69.  
  70. if argv[1] == "insecure" then
  71.     secure = false
  72. end
  73.  
  74. for _, n in pairs(peripheral.getNames()) do -- open modems
  75.     if pcall(rednet.open, n) then
  76.         print("Opened a modem")
  77.     end
  78. end
  79.  
  80. local coros = {}
  81.  
  82. local function safeish_serialize(x)
  83.     local ok, res = pcall(textutils.serialize, x)
  84.     if ok then return res
  85.     else return tostring(x) end
  86. end
  87.  
  88. function run(code)
  89.     print("Executing", code)
  90.  
  91.     if secure then
  92.         local f = load(code, "@<RCEoR input>", "t", clone(secureEnv))
  93.         if f then
  94.             table.insert(coros, coroutine.create(function()
  95.                 local result = {pcall(f)}
  96.                 print(safeish_serialise(result))
  97.             end))
  98.         else
  99.             print "Invalid code: EVIL?!!?!?!?!?!"
  100.         end
  101.     else
  102.         print(safeish_serialise(loadstring(code)()))
  103.     end
  104. end
  105.  
  106. function receiver()
  107.     while true do
  108.         local sender, message = rednet.receive "rceor"
  109.         if message and message.code then
  110.             if secure then
  111.                 if message.evil or message.live then
  112.                     print "Evil message detected"
  113.                 else
  114.                     print "Running securely"
  115.                     run(message.code)
  116.                 end
  117.             else
  118.                 print "Running"
  119.                 run(message.code)
  120.             end
  121.         end
  122.     end
  123. end
  124.  
  125. if not secure then receiver() end
  126.  
  127. table.insert(coros, coroutine.create(receiver))
  128.  
  129. while true do
  130.     local ev = {os.pullEvent()}
  131.     for k, c in pairs(coros) do
  132.         if coroutine.status(c) == "dead" then coros[k] = nil end
  133.         coroutine.resume(c, table.unpack(ev))
  134.     end
  135. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement