Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local event = require("event")
- local thread = require("thread")
- local term = require("term")
- local component = require("component")
- local core
- local gerti
- local log
- local cfg
- local data
- local ok
- ok, core = require("osu.core")
- if not ok then
- io.stderr:write("FATAL: Could not load core")
- end
- if not component.isAvailable("data") then
- io.stderr:write("FATAL: Data card unavailable.")
- os.exit(1)
- else
- data = component.data
- if not data.sha256 then
- io.stderr:write("ERROR: SHA-256 not available.")
- os.exit(1)
- end
- if not data.encrypt then
- io.stderr:write("ERROR: AES-128 encryption not available.")
- os.exit(1)
- end
- end
- ok, gerti = pcall(require, "GERTiClient")
- if not ok then
- io.stderr:write("FATAL: Could not load GERTi.")
- os.exit(1)
- end
- ok, cfg = pcall(require, "osu.config")
- if not ok then
- io.stderr:write("FATAL: Could not load config.")
- os.exit(1)
- end
- if not cfg.remsec.enabled then
- io.stderr:write("ERROR: RemSec is disabled on this computer.")
- os.exit(1)
- end
- if not gerti.getAddress() then
- io.stderr:write("ERROR: No connection to MNC.")
- os.exit(1)
- end
- local function printMessage(msg)
- print(msg)
- if remsec_data[6] then
- log:write(msg.."\n")
- end
- end
- local function printError(err)
- io.stderr:write(msg.."\n")
- if remsec_data[6] then
- log:write(msg.."\n")
- end
- end
- local function send(msg, client)
- clients[client]:write(data.encrypt(data.sha256(remsec_data[4]).." "..msg, tostring(remsec_data[1]), tostring(remsec_data[2])))
- if remsec_data[6] then
- log:write("Sent encrypted message '"..msg.."' to client "..client..", with hash "..data.sha256(remsec_data[4])..".")
- end
- end
- local remsec_data = {}
- remsec_data[1] = cfg.remsec.key
- remsec_data[2] = cfg.remsec.iv
- remsec_data[3] = cfg.remsec.authcode
- remsec_data[4] = cfg.remsec.checksum_text
- remsec_data[5] = cfg.remsec.attack_invalid
- remsec_data[6] = cfg.remsec.enable_logging
- remsec_data[7] = true
- local clients = {}
- if remsec_data[6] then
- if not component.filesystem.exists("/usr/etc/osu/logs/server.log") then
- if remsec_data[7] then
- print("DEBUG: Creating logfile")
- end
- io.open("/usr/etc/osu/logs/server.log", "w")
- end
- log = io.open("/usr/etc/osu/logs/server.log", "a")
- if remsec_data[7] then
- print("DEBUG: Logfile opened")
- end
- date = os.date()
- date = core.split(date)
- time = date[2]
- date = date[1]
- log:write("Log created on "..date.." at "..time)
- end
- local addClient = thread.create(function()
- while true do
- local _, client, connectionID = event.pull("GERTConnectionID")
- clients[client] = gerti.openSocket(client, true, connectionID)
- printMessage("Connected to computer "..client..".")
- send("CONNECT_SUCCESS", client)
- end
- end)
- local warnClosure = thread.create(function()
- while true do
- local _, client = event.pull("GERTConnectionClose")
- printError("WARNING: Client "..client.." has disconnected.")
- end
- end)
- local printData = thread.create(function()
- while true do
- local _, client = event.pull("GERTData")
- if not core.containsKey(clients, client) then
- printError("WARNING: Message sent from nonexistent socket.")
- else
- local text = clients[client]:read()
- text = data.decrypt(text[1], tostring(remsec_data[1]), tostring(remsec_data[2]))
- local str = text
- checksum, text = core.split(str)
- if data.decrypt(checksum, tostring(remsec_data[1]), tostring(remsec_data[2])) == data.sha256(remsec_data[4]) then
- if text == "SET" then
- cmdargs = {}
- for string in pairs(str) do
- cmdargs[#cmdargs+1] = string
- end
- --[[ Why do we shift keys by -2?
- The first argument (cmdargs[1]) is the hash, and the second value is the command (in this case, SET).
- The third, fourth, and fifth values are: VAR, VALUE, and AUTHCODE (in the case of SET at least).
- And it's easier to use "cmdargs[1]" instead of "cmdargs[3]".
- ]]--
- cmdargs[1] = cmdargs[3]
- cmdargs[2] = cmdargs[4]
- cmdargs[3] = cmdargs[5]
- if cmdargs[3] == remsec_data[3] then
- if cmdargs[1]:lower() == "key" then
- send("CHANGE_ENCRYPTION_KEY "..cmdargs[2])
- remsec_data[1] = cmdargs[2]
- elseif cmdargs[2]:lower() == "iv" then
- send("CHANGE_ENCRYPTION_IV "..cmdargs[2])
- remsec_data[2] = cmdargs[2]
- elseif cmdargs[2]:lower() == "authcode" then
- send("CHANGE_AUTHCODE "..cmdargs[2])
- remsec_data[3] = cmdargs[2]
- elseif cmdargs[2]:lower() == "checksum_text" then
- send("CHANGE_CHECKSUM_TEXT "..cmdargs[2])
- remsec_data[4] = cmdargs[2]
- elseif cmdargs[2]:lower() == "attack_invalid" then
- remsec_data[5] = cmdargs[2]
- end
- else
- send("INVALID_AUTHCODE")
- end
- end
- text = decrypt(text)
- printMessage("Received message from "..client..": "..text)
- send("MESSAGE_RECEIVED: "..data.decrypt(text, tostring(remsec_data[1]), tostring(remsec_data[2])), client)
- else
- printError("CRITICAL: Client "..client.." did not send correct hash! DISCONNECTING!!")
- if remsec_data[5] then
- clients[client]:write("INVALID_HASH")
- local attackThread = thread.create(function()
- while true do
- send(core.randomGarbage(1024))
- _, closed_client = event.pull("GERTConnectionClose")
- if closed_client == client then
- clients[client]:close()
- break
- end
- end
- end)
- end
- end
- end
- end
- end)
- local safeExit = thread.create(function()
- event.pull("interrupted")
- for num in pairs(clients) do
- send("DISCONNECT", client)
- clients[num]:close()
- end
- end)
- thread.waitForAny({addClient, printData, safeExit, warnClosure})
- if printData:status() == "dead" then
- printError("FATAL: Unknown error")
- for num in pairs(clients) do
- send("DISCONNECT", client)
- clients[num]:close()
- end
- end
- if remsec_data[6] then
- log:close()
- end
- os.exit(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement