Files
cc-taskguard/tg_server/tg_server.lua
T

118 lines
4.0 KiB
Lua

local fullPath = shell.getRunningProgram()
local dir = fullPath:match("^(.*/)") or ""
local config = dofile(dir..'taskguard.cfg')
local clearances = { } -- { computer_id = 1, clearance_level = 1, time_granted = os.clock() }
local function split(str, divider)
local t = {}
for part in string.gmatch(str, "([^" .. divider .. "]+)") do
table.insert(t, part)
end
return t
end
local function hash(str)
local hash = 0
for i = 1, #str do
hash = (hash * 31 + string.byte(str, i)) % 65536
end
return string.format("%04X", hash)
end
local function check_for_outdated_sessions()
local expired = 0
for i = #clearances, 1, -1 do
if (os.clock() - clearances[i].time_granted) > config.clearance_expiry then
table.remove(clearances, i)
expired = expired + 1
end
end
print("Removed " .. expired .. " expired clearance(s). " ..
#clearances .. " active session(s) remain.")
end
local function validate_key(card_holder, card_clearance, random_chars)
local card_hash = hash(card_holder..','..card_clearance..','..random_chars)
local key_file = fs.open(dir..config.key_file, 'r')
local card_authentic = false
while true do
local trusted_hash = key_file.readLine()
if trusted_hash == card_hash then
print("Valid card "..card_hash)
card_authentic = true
return true, card_hash
end
if not line then break end -- Stop when EOF reached
end
key_file.close()
if card_authentic == false then
print("Unknown card "..card_hash)
return false
end
end
rednet.open(config.modem_side)
rednet.host('tg', config.name)
print("Server started, waiting for requests...")
while true do
local id, msg, proto = rednet.receive('tg')
check_for_outdated_sessions()
msg_parts = split(msg, ',')
if msg_parts[1] == 'validate_clearance' then
print("Beginning transaction for clearance query with "..id)
local target_id = tonumber(msg_parts[2])
local requested_clearance = tonumber(msg_parts[3])
local has_clearance = false
for i, entry in ipairs(clearances) do
if entry.computer_id == target_id and entry.clearance_level >= requested_clearance then
-- Auth granted
rednet.send(id, 'granted', 'tg')
print('Finished transaction, granted')
has_clearance = true
end
end
if has_clearance == false then
-- Auth not granted
rednet.send(id, 'failed', 'tg')
print('Finished transaction, failed')
end
print("EOP")
elseif msg_parts[1] == 'authenticate' then
print("Beginning transaction for authentication with "..id)
local card_holder = msg_parts[2]
local card_clearance = msg_parts[3]
local is_authentic, card_hash = validate_key(card_holder, card_clearance, msg_parts[4])
if is_authentic then
table.insert(clearances, { computer_id = tonumber(id), clearance_level = tonumber(card_clearance), time_granted = os.clock() })
rednet.send(id, "authentication successful", "tg")
print("Granted card "..card_hash.." clearance level "..card_clearance)
else
print("Unknown card "..card_hash)
rednet.send(id, "authentication failed", "tg")
end
print("Transaction finished")
elseif msg_parts[1] == 'validate_key' then
print("Beginning transaction for single-validation with "..id)
local card_holder = msg_parts[2]
local card_clearance = msg_parts[3]
local minimum_clearance = msg_parts[5]
if validate_key(card_holder, card_clearance, msg_parts[4]) and tonumber(card_clearance) >= tonumber(minimum_clearance) then
rednet.send(id, "authentication successful", "tg")
else
rednet.send(id, "authentication failed", "tg")
end
print("Transaction finished")
end
end