Advertisement
Guest User

remsec_server.lua

a guest
Jul 23rd, 2019
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.19 KB | None | 0 0
  1. local event = require("event")
  2. local component = require("component")
  3. local thread = require("thread")
  4. local term = require("term")
  5. local debug = true
  6. local gerti
  7. local cfg
  8. local data
  9. local encrypt
  10. local decrypt
  11. local ok
  12. local hash
  13. local key
  14. local iv
  15. local timesHit
  16. local attack_invalid
  17. local attack_amount
  18. local checksumtext
  19. local commands = {[1] = "SET"}
  20. ok, gerti = pcall(require, "GERTiClient")
  21. if not ok then
  22.   io.stderr:write("Could not load GERTi.")
  23.   os.exit(1)
  24. end
  25. ok, cfg = pcall(require, "osu.config")
  26. if not ok then
  27.   io.stderr:write("Could not load config.")
  28.   os.exit(1)
  29. end
  30. if not cfg.remsec.enabled then
  31.   io.stderr:write("RemSec is disabled on this computer.")
  32.   os.exit(1)
  33. end
  34. if gerti.getAddress() == nil then
  35.   io.stderr:write("No connection to MNC.")
  36.   os.exit(1)
  37. end
  38. local function containsKey(table, element)
  39.   for key, _ in pairs(table) do
  40.     if key == element then
  41.       return true
  42.     end
  43.   end
  44.   return false
  45. end
  46. key = cfg.remsec.key
  47. iv = cfg.remsec.iv
  48. attack_amount = cfg.remsec.attack_amount
  49. attack_invalid = cfg.remsec.attack_invalid
  50. checksumtext = cfg.remsec.checksumtext
  51. local function containsValue(table, element)
  52.   for _, value in pairs(table) do
  53.     if value == element then
  54.       return true
  55.     end
  56.   end
  57.   return false
  58. end
  59. if not component.isAvailable("data") then
  60.   io.stderr:write("Data card unavailable.")
  61.   os.exit(1)
  62. else
  63.   data = component.data
  64.   if not data.sha256 then
  65.     io.stderr:write("SHA-256 not available.")
  66.     os.exit(1)
  67.   end
  68.   if not data.encrypt then
  69.     io.stderr:write("AES-128 encryption not available.")
  70.     os.exit(1)
  71.   end
  72.   hash = data.sha256
  73.   encrypt = function(text)
  74.     if debug then
  75.       print("DEBUG: Encrypting data")
  76.     end
  77.     encrypted = data.encrypt(tostring(text), tostring(key), tostring(iv))
  78.     if debug then
  79.       print("DEBUG: Done")
  80.     end
  81.     return encrypted
  82.   end
  83.   decrypt = function(binary)
  84.     if debug then
  85.       print("DEBUG: Decrypting data")
  86.     end
  87.     decrypted = data.decrypt(binary, tostring(key), tostring(iv))
  88.     if debug then
  89.       print("DEBUG: Done")
  90.     end
  91.     return decrypted
  92.   end
  93. end
  94. local clients = {}
  95. term.clear()
  96. local addClient = thread.create(function()
  97.   while true do
  98.     local _, client, connectionID = event.pull("GERTConnectionID")
  99.     clients[client] = gerti.openSocket(client, true, connectionID)
  100.     print("Connected to computer "..client..".")
  101.     clients[client]:write("CONNECT_SUCCESS")
  102.   end
  103. end)
  104. local warnClosure = thread.create(function()
  105.   while true do
  106.     local _, client = event.pull("GERTConnectionClose")
  107.     print("!! WARNING !! Client "..client.." has disconnected.")
  108.   end
  109. end)
  110. local printData = thread.create(function()  
  111.   while true do
  112.     local _, client = event.pull("GERTData")
  113.     if debug then
  114.       print("DEBUG: Received GERTData event")
  115.     end
  116.     if not containsKey(clients, client) then
  117.       print("!! WARNING !! Message sent from nonexistent socket.")
  118.     else
  119.       text = clients[client]:read()
  120.       if debug then
  121.         print("DEBUG: Read from socket to computer "..client)
  122.       end
  123.       if decrypt(text[1]) == hash(checksumtext) then
  124.         if debug then
  125.           print("DEBUG: Decrypted hash and it is correct, waiting for data...")
  126.         end
  127.         _, client = event.pull("GERTData")
  128.         if debug then
  129.           print("DEBUG: Received second GERTData event")
  130.         end
  131.         text = clients[client]:read()
  132.         if debug then
  133.           print("DEBUG: Read from socket to computer "..client)
  134.         end
  135.         txt = decrypt(text[1])
  136.         if containsValue(commands, txt:gmatch("%S+")():upper()) then
  137.           command = txt:gmatch("%S+")():upper()
  138.           if command == "SET" then
  139.             _, var, newVal, pass = txt:gmatch("%S+")
  140.             var = var:lower()
  141.             if var == "key" then
  142.               if pass == key then
  143.                 for num in pairs(clients) do
  144.                   clients[num]:write("CHANGE_ENCRYPTION_KEY "..pass)
  145.                 end
  146.                 key = newVal
  147.               else
  148.                 clients[client]:write("NEW_KEY_INVALID")
  149.               end
  150.             end
  151.             if var == "iv" then
  152.               if pass == iv then
  153.                 for num in pairs(clients) do
  154.                   clients[num]:write(encrypt("CHANGE_ENCRYPTION_IV "..pass))
  155.                 end
  156.                 key = newVal
  157.               else
  158.                 clients[client]:write("NEW_IV_INVALID")
  159.               end
  160.             end
  161.           end
  162.         else
  163.           print("Received message from "..client..": "..txt)
  164.           clients[client]:write(encrypt("MESSAGE_RECEIVED: "..decrypt(text[1])))
  165.         end
  166.       else
  167.         print("!! CRITICAL !! Client "..client.." did not send correct checksum!")
  168.         if attack_invalid then
  169.           local timesHit = 0
  170.           repeat
  171.             clients[client]:write("REMSEC_INVALID_CLIENT")
  172.             timesHit = timesHit + 1
  173.           until timesHit == attack_amount
  174.         end
  175.         clients[client]:close()
  176.       end
  177.     end
  178.   end
  179. end)
  180. local safeExit = thread.create(function()
  181.   event.pull("interrupted")
  182.   for num in pairs(clients) do
  183.     clients[num]:write("DISCONNECT")
  184.     clients[num]:close()
  185.   end
  186. end)
  187. thread.waitForAny({addClient, printData, safeExit, warnClosure})
  188. if printData:status() == "dead" then
  189.   print("Fatal error!")
  190. end
  191. os.exit(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement