Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local event = require("event")
- local component = require("component")
- local thread = require("thread")
- local term = require("term")
- local debug = true
- local gerti
- local cfg
- local data
- local encrypt
- local decrypt
- local ok
- local hash
- local key
- local iv
- local timesHit
- local attack_invalid
- local attack_amount
- local checksumtext
- local commands = {[1] = "SET"}
- ok, gerti = pcall(require, "GERTiClient")
- if not ok then
- io.stderr:write("Could not load GERTi.")
- os.exit(1)
- end
- ok, cfg = pcall(require, "osu.config")
- if not ok then
- io.stderr:write("Could not load config.")
- os.exit(1)
- end
- if not cfg.remsec.enabled then
- io.stderr:write("RemSec is disabled on this computer.")
- os.exit(1)
- end
- if gerti.getAddress() == nil then
- io.stderr:write("No connection to MNC.")
- os.exit(1)
- end
- local function containsKey(table, element)
- for key, _ in pairs(table) do
- if key == element then
- return true
- end
- end
- return false
- end
- key = cfg.remsec.key
- iv = cfg.remsec.iv
- attack_amount = cfg.remsec.attack_amount
- attack_invalid = cfg.remsec.attack_invalid
- checksumtext = cfg.remsec.checksumtext
- local function containsValue(table, element)
- for _, value in pairs(table) do
- if value == element then
- return true
- end
- end
- return false
- end
- if not component.isAvailable("data") then
- io.stderr:write("Data card unavailable.")
- os.exit(1)
- else
- data = component.data
- if not data.sha256 then
- io.stderr:write("SHA-256 not available.")
- os.exit(1)
- end
- if not data.encrypt then
- io.stderr:write("AES-128 encryption not available.")
- os.exit(1)
- end
- hash = data.sha256
- encrypt = function(text)
- if debug then
- print("DEBUG: Encrypting data")
- end
- encrypted = data.encrypt(tostring(text), tostring(key), tostring(iv))
- if debug then
- print("DEBUG: Done")
- end
- return encrypted
- end
- decrypt = function(binary)
- if debug then
- print("DEBUG: Decrypting data")
- end
- decrypted = data.decrypt(binary, tostring(key), tostring(iv))
- if debug then
- print("DEBUG: Done")
- end
- return decrypted
- end
- end
- local clients = {}
- term.clear()
- local addClient = thread.create(function()
- while true do
- local _, client, connectionID = event.pull("GERTConnectionID")
- clients[client] = gerti.openSocket(client, true, connectionID)
- print("Connected to computer "..client..".")
- clients[client]:write("CONNECT_SUCCESS")
- end
- end)
- local warnClosure = thread.create(function()
- while true do
- local _, client = event.pull("GERTConnectionClose")
- print("!! WARNING !! Client "..client.." has disconnected.")
- end
- end)
- local printData = thread.create(function()
- while true do
- local _, client = event.pull("GERTData")
- if debug then
- print("DEBUG: Received GERTData event")
- end
- if not containsKey(clients, client) then
- print("!! WARNING !! Message sent from nonexistent socket.")
- else
- text = clients[client]:read()
- if debug then
- print("DEBUG: Read from socket to computer "..client)
- end
- if decrypt(text[1]) == hash(checksumtext) then
- if debug then
- print("DEBUG: Decrypted hash and it is correct, waiting for data...")
- end
- _, client = event.pull("GERTData")
- if debug then
- print("DEBUG: Received second GERTData event")
- end
- text = clients[client]:read()
- if debug then
- print("DEBUG: Read from socket to computer "..client)
- end
- txt = decrypt(text[1])
- if containsValue(commands, txt:gmatch("%S+")():upper()) then
- command = txt:gmatch("%S+")():upper()
- if command == "SET" then
- _, var, newVal, pass = txt:gmatch("%S+")
- var = var:lower()
- if var == "key" then
- if pass == key then
- for num in pairs(clients) do
- clients[num]:write("CHANGE_ENCRYPTION_KEY "..pass)
- end
- key = newVal
- else
- clients[client]:write("NEW_KEY_INVALID")
- end
- end
- if var == "iv" then
- if pass == iv then
- for num in pairs(clients) do
- clients[num]:write(encrypt("CHANGE_ENCRYPTION_IV "..pass))
- end
- key = newVal
- else
- clients[client]:write("NEW_IV_INVALID")
- end
- end
- end
- else
- print("Received message from "..client..": "..txt)
- clients[client]:write(encrypt("MESSAGE_RECEIVED: "..decrypt(text[1])))
- end
- else
- print("!! CRITICAL !! Client "..client.." did not send correct checksum!")
- if attack_invalid then
- local timesHit = 0
- repeat
- clients[client]:write("REMSEC_INVALID_CLIENT")
- timesHit = timesHit + 1
- until timesHit == attack_amount
- end
- clients[client]:close()
- end
- end
- end
- end)
- local safeExit = thread.create(function()
- event.pull("interrupted")
- for num in pairs(clients) do
- clients[num]:write("DISCONNECT")
- clients[num]:close()
- end
- end)
- thread.waitForAny({addClient, printData, safeExit, warnClosure})
- if printData:status() == "dead" then
- print("Fatal error!")
- end
- os.exit(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement