Advertisement
Guest User

remsec_server.lua

a guest
Jul 27th, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.00 KB | None | 0 0
  1. local event = require("event")
  2. local thread = require("thread")
  3. local term = require("term")
  4. local component = require("component")
  5. local core
  6. local gerti
  7. local log
  8. local cfg
  9. local data
  10. local ok
  11. ok, core = require("osu.core")
  12. if not ok then
  13.   io.stderr:write("FATAL: Could not load core")
  14. end
  15. if not component.isAvailable("data") then
  16.   io.stderr:write("FATAL: Data card unavailable.")
  17.   os.exit(1)
  18. else
  19.   data = component.data
  20.   if not data.sha256 then
  21.     io.stderr:write("ERROR: SHA-256 not available.")
  22.     os.exit(1)
  23.   end
  24.   if not data.encrypt then
  25.     io.stderr:write("ERROR: AES-128 encryption not available.")
  26.     os.exit(1)
  27.   end
  28. end
  29. ok, gerti = pcall(require, "GERTiClient")
  30. if not ok then
  31.   io.stderr:write("FATAL: Could not load GERTi.")
  32.   os.exit(1)
  33. end
  34. ok, cfg = pcall(require, "osu.config")
  35. if not ok then
  36.   io.stderr:write("FATAL: Could not load config.")
  37.   os.exit(1)
  38. end
  39. if not cfg.remsec.enabled then
  40.   io.stderr:write("ERROR: RemSec is disabled on this computer.")
  41.   os.exit(1)
  42. end
  43. if not gerti.getAddress() then
  44.   io.stderr:write("ERROR: No connection to MNC.")
  45.   os.exit(1)
  46. end
  47. local function printMessage(msg)
  48.   print(msg)
  49.   if remsec_data[6] then
  50.     log:write(msg.."\n")
  51.   end
  52. end
  53. local function printError(err)
  54.   io.stderr:write(msg.."\n")
  55.   if remsec_data[6] then
  56.     log:write(msg.."\n")
  57.   end
  58. end
  59. local function send(msg, client)
  60.   clients[client]:write(data.encrypt(data.sha256(remsec_data[4]).." "..msg, tostring(remsec_data[1]), tostring(remsec_data[2])))
  61.   if remsec_data[6] then
  62.     log:write("Sent encrypted message '"..msg.."' to client "..client..", with hash "..data.sha256(remsec_data[4])..".")
  63.   end
  64. end
  65. local remsec_data = {}
  66. remsec_data[1] = cfg.remsec.key
  67. remsec_data[2] = cfg.remsec.iv
  68. remsec_data[3] = cfg.remsec.authcode
  69. remsec_data[4] = cfg.remsec.checksum_text
  70. remsec_data[5] = cfg.remsec.attack_invalid
  71. remsec_data[6] = cfg.remsec.enable_logging
  72. remsec_data[7] = true
  73. local clients = {}
  74. if remsec_data[6] then
  75.   if not component.filesystem.exists("/usr/etc/osu/logs/server.log") then
  76.     if remsec_data[7] then
  77.       print("DEBUG: Creating logfile")
  78.     end
  79.     io.open("/usr/etc/osu/logs/server.log", "w")
  80.   end
  81.   log = io.open("/usr/etc/osu/logs/server.log", "a")
  82.   if remsec_data[7] then
  83.     print("DEBUG: Logfile opened")
  84.   end
  85.   date = os.date()
  86.   date = core.split(date)
  87.   time = date[2]
  88.   date = date[1]
  89.   log:write("Log created on "..date.." at "..time)
  90. end
  91. local addClient = thread.create(function()
  92.   while true do
  93.     local _, client, connectionID = event.pull("GERTConnectionID")
  94.     clients[client] = gerti.openSocket(client, true, connectionID)
  95.     printMessage("Connected to computer "..client..".")
  96.     send("CONNECT_SUCCESS", client)
  97.   end
  98. end)
  99. local warnClosure = thread.create(function()
  100.   while true do
  101.     local _, client = event.pull("GERTConnectionClose")
  102.     printError("WARNING: Client "..client.." has disconnected.")
  103.   end
  104. end)
  105. local printData = thread.create(function()  
  106.   while true do
  107.     local _, client = event.pull("GERTData")
  108.     if not core.containsKey(clients, client) then
  109.       printError("WARNING: Message sent from nonexistent socket.")
  110.     else
  111.       local text = clients[client]:read()
  112.       text = data.decrypt(text[1], tostring(remsec_data[1]), tostring(remsec_data[2]))
  113.       local str = text
  114.       checksum, text = core.split(str)
  115.       if data.decrypt(checksum, tostring(remsec_data[1]), tostring(remsec_data[2])) == data.sha256(remsec_data[4]) then
  116.         if text == "SET" then
  117.           cmdargs = {}
  118.           for string in pairs(str) do
  119.             cmdargs[#cmdargs+1] = string
  120.           end
  121.           --[[ Why do we shift keys by -2?
  122.             The first argument (cmdargs[1]) is the hash, and the second value is the command (in this case, SET).
  123.             The third, fourth, and fifth values are: VAR, VALUE, and AUTHCODE (in the case of SET at least).
  124.             And it's easier to use "cmdargs[1]" instead of "cmdargs[3]".
  125.           ]]--
  126.           cmdargs[1] = cmdargs[3]
  127.           cmdargs[2] = cmdargs[4]
  128.           cmdargs[3] = cmdargs[5]
  129.           if cmdargs[3] == remsec_data[3] then
  130.             if cmdargs[1]:lower() == "key" then
  131.               send("CHANGE_ENCRYPTION_KEY "..cmdargs[2])
  132.               remsec_data[1] = cmdargs[2]
  133.             elseif cmdargs[2]:lower() == "iv" then
  134.               send("CHANGE_ENCRYPTION_IV "..cmdargs[2])
  135.               remsec_data[2] = cmdargs[2]
  136.             elseif cmdargs[2]:lower() == "authcode" then
  137.               send("CHANGE_AUTHCODE "..cmdargs[2])
  138.               remsec_data[3] = cmdargs[2]
  139.             elseif cmdargs[2]:lower() == "checksum_text" then
  140.               send("CHANGE_CHECKSUM_TEXT "..cmdargs[2])
  141.               remsec_data[4] = cmdargs[2]
  142.             elseif cmdargs[2]:lower() == "attack_invalid" then
  143.               remsec_data[5] = cmdargs[2]
  144.             end
  145.           else
  146.             send("INVALID_AUTHCODE")
  147.           end
  148.         end
  149.         text = decrypt(text)
  150.         printMessage("Received message from "..client..": "..text)
  151.         send("MESSAGE_RECEIVED: "..data.decrypt(text, tostring(remsec_data[1]), tostring(remsec_data[2])), client)
  152.       else
  153.         printError("CRITICAL: Client "..client.." did not send correct hash! DISCONNECTING!!")
  154.         if remsec_data[5] then
  155.           clients[client]:write("INVALID_HASH")
  156.           local attackThread = thread.create(function()
  157.             while true do
  158.               send(core.randomGarbage(1024))
  159.               _, closed_client = event.pull("GERTConnectionClose")
  160.               if closed_client == client then
  161.                 clients[client]:close()
  162.                 break
  163.               end
  164.             end
  165.           end)
  166.         end
  167.       end
  168.     end
  169.   end
  170. end)
  171. local safeExit = thread.create(function()
  172.   event.pull("interrupted")
  173.   for num in pairs(clients) do
  174.     send("DISCONNECT", client)
  175.     clients[num]:close()
  176.   end
  177. end)
  178. thread.waitForAny({addClient, printData, safeExit, warnClosure})
  179. if printData:status() == "dead" then
  180.   printError("FATAL: Unknown error")
  181.   for num in pairs(clients) do
  182.     send("DISCONNECT", client)
  183.     clients[num]:close()
  184.   end
  185. end
  186. if remsec_data[6] then
  187.   log:close()
  188. end
  189. os.exit(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement