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 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 card_hash = hash(card_holder..','..card_clearance..','..msg_parts[4]) 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 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) card_authentic = true 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) rednet.send(id, "authentication failed", "tg") end print("Transaction finished") end end