Compare commits

..
10 Commits
Author SHA1 Message Date
juhnsa 3ebb2d08d6 Fix issue 2025-08-27 13:37:00 +02:00
juhnsa b76c21bf74 Add feedback 2025-08-27 13:31:20 +02:00
juhnsa 1ad962d223 Fix issues 2025-08-27 13:27:36 +02:00
Juhn-Vitus Saß dca01a4116 Merge pull request 'issue-2 Resolves #2' (#4) from issue-2 into main
Reviewed-on: #4
2025-08-27 13:11:27 +02:00
juhnsa c16da21d63 Add cli to add and remove cards 2025-08-27 13:09:04 +02:00
juhnsa b01b0d4eb5 outsource hash function 2025-08-26 16:14:10 +02:00
juhnsa a64c72d4fc Extend client api by authentication 2025-08-26 14:55:19 +02:00
Juhn-Vitus Saß 41cfa4c9c6 tg_server/tg_server.lua aktualisiert 2025-08-26 13:40:20 +02:00
Juhn-Vitus Saß 6d063ddf97 Merge pull request 'Resolve #1' (#3) from issue-1 into main
Reviewed-on: #3
2025-08-26 13:35:40 +02:00
juhnsa 6fa2e49578 Resolve #1 2025-08-26 13:33:03 +02:00
3 changed files with 169 additions and 77 deletions

No files matched your search

+56 -24
View File
@@ -1,3 +1,5 @@
tg_server_name = "tg_server"
local args = {...} local args = {...}
local function split(str, divider) local function split(str, divider)
@@ -13,18 +15,16 @@ local function establish_connection()
for _, side in ipairs(peripherals) do for _, side in ipairs(peripherals) do
if peripheral.getType(side) == "modem" then if peripheral.getType(side) == "modem" then
rednet.open(side) rednet.open(side)
print("Opened modem: "..side)
return true return true
end end
end end
print("No modem found!")
return false return false
end end
function validate_clearance(computer_id, clearance_level, tg_server_name) function validate_clearance(computer_id, clearance_level)
if establish_connection() then if establish_connection() then
tg_server_id = rednet.lookup("tg", tg_server_name) tg_server_id = rednet.lookup('tg', tg_server_name)
rednet.send(tg_server_id, "validate_clearance,"..computer_id..","..clearance_level) rednet.send(tg_server_id, "validate_clearance,"..computer_id..","..clearance_level,"tg")
local id, msg, proto = rednet.receive("tg") local id, msg, proto = rednet.receive("tg")
if msg == "granted" then if msg == "granted" then
return true return true
@@ -36,29 +36,61 @@ function validate_clearance(computer_id, clearance_level, tg_server_name)
end end
end end
if fs.exists('/disk/key') then function validate_key(minimum_clearance)
key_file = fs.open('/disk/key', 'r')
key = key_file.readLine()
if establish_connection() then if establish_connection() then
local tg_server_name = "tg_server" if fs.exists("/disk/key") then
local key_file = fs.open("/disk/key","r")
tg_server_id = rednet.lookup("tg", tg_server_name) local key = key_file.readLine()
rednet.send(tg_server_id, "authenticate,"..key,"tg") tg_server_id = rednet.lookup('tg', tg_server_name)
local id, msg, proto = rednet.receive("tg") rednet.send(tg_server_id, "validate_key,"..key..","..minimum_clearance, "tg")
local id, msg, _ = rednet.receive("tg")
if msg == "authentication successful" then if msg == "authentication successful" then
key_parts = split(key,',') return true
local card_holder = key_parts[1] else
local card_clearance = key_parts[2] return false, "authentication error: "..msg
print("Authentication was successful.") end
print("Hello "..card_holder..", you were granted clearance level "..card_clearance.." for this computer.")
else else
print("Authentication failed.") return false, "key file not found"
end end
else else
return false, "modem not found" return false, "modem not found"
end end
key_file.close() end
else
print("Key file not found. Aborting.") function authenticate()
if fs.exists('/disk/key') then
local key_file = fs.open('/disk/key', 'r')
local key = key_file.readLine()
if establish_connection() then
tg_server_id = rednet.lookup("tg", tg_server_name)
rednet.send(tg_server_id, "authenticate,"..key,"tg")
local id, msg, proto = rednet.receive("tg")
if msg == "authentication successful" then
local key_parts = split(key,',')
local card_holder = key_parts[1]
local card_clearance = key_parts[2]
return true, _, card_holder, card_clearance
else
print("Authentication failed.")
return false, "authentication failed"
end
else
return false, "modem not found"
end
key_file.close()
else
print("Key file not found. Aborting.")
return false, "key file not found"
end
end
if args[1] == "auth" or args[1] == "authenticate" then
local success, error, card_holder, card_clearance = authenticate()
if success then
print("Authentication was successful.")
print("Hello "..card_holder..", you were granted clearance level "..card_clearance.." for this computer.")
else
print("Authentication failed: "..error)
end
end end
+7
View File
@@ -0,0 +1,7 @@
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
+106 -53
View File
@@ -1,9 +1,10 @@
local fullPath = shell.getRunningProgram() local fullPath = shell.getRunningProgram()
local dir = fullPath:match("^(.*/)") or "" local dir = fullPath:match("^(.*/)") or ""
local args = {...}
local config = dofile(dir..'taskguard.cfg') local config = dofile(dir..'taskguard.cfg')
local clearances = { { computer_id = 1, clearance_level = 1, time_granted = os.clock() } } local clearances = { } -- { computer_id = 1, clearance_level = 1, time_granted = os.clock() }
local function split(str, divider) local function split(str, divider)
local t = {} local t = {}
@@ -13,14 +14,7 @@ local function split(str, divider)
return t return t
end end
local function hash(str) dofile(dir..'hash.lua')
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 function check_for_outdated_sessions()
local expired = 0 local expired = 0
@@ -34,63 +28,122 @@ local function check_for_outdated_sessions()
#clearances .. " active session(s) remain.") #clearances .. " active session(s) remain.")
end 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')
while true do
local trusted_hash = key_file.readLine()
if trusted_hash == card_hash then
print("Valid card "..card_hash)
key_file.close()
return true, card_hash
end
if not trusted_hash then break end -- Stop when EOF reached
end
rednet.open(config.modem_side) key_file.close()
rednet.host('tg', config.name)
print("Server started, waiting for requests...")
while true do print("Unknown card "..card_hash)
local id, msg, proto = rednet.receive('tg') return false
check_for_outdated_sessions() end
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 args[1] == "serve" then
if entry.computer_id == target_id and entry.clearance_level >= requested_clearance then rednet.open(config.modem_side)
-- Auth granted rednet.host('tg', config.name)
rednet.send(id, 'granted', 'tg') print("Server started, waiting for requests...")
print('Finished transaction, granted') while true do
has_clearance = true 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 end
end
if has_clearance == false then if has_clearance == false then
-- Auth not granted -- Auth not granted
rednet.send(id, 'failed', 'tg') rednet.send(id, 'failed', 'tg')
print('Finished transaction, failed') print('Finished transaction, failed')
end end
print("EOP") print("EOP")
elseif msg_parts[1] == 'authenticate' then elseif msg_parts[1] == 'authenticate' then
print("Beginning transaction for authentication with "..id) print("Beginning transaction for authentication with "..id)
local card_holder = msg_parts[2] local card_holder = msg_parts[2]
local card_clearance = msg_parts[3] 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 is_authentic, card_hash = validate_key(card_holder, card_clearance, msg_parts[4])
local trusted_hash = key_file.readLine()
if trusted_hash == card_hash then if is_authentic then
table.insert(clearances, { computer_id = tonumber(id), clearance_level = tonumber(card_clearance), time_granted = os.clock() }) 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") rednet.send(id, "authentication successful", "tg")
print("Granted card "..card_hash.." clearance level "..card_clearance) else
rednet.send(id, "authentication failed", "tg")
card_authentic = true
end end
if not line then break end -- Stop when EOF reached print("Transaction finished")
end end
end
elseif args[1] == "add_card" then
if args[2] then
local new_card = args[2]
local new_card_parts = split(new_card, ',')
local card_holder = new_card_parts[1]
local card_hash = hash(new_card)
local key_file = fs.open(card_hash..'.key', 'w')
key_file.write(new_card..'\n')
key_file.close() key_file.close()
if card_authentic == false then local trusted_keys = fs.open(dir..config.key_file, 'a')
print("Unknown card "..card_hash) trusted_keys.write(card_hash)
rednet.send(id, "authentication failed", "tg") trusted_keys.close()
print("Created key "..card_hash..".key in root dir")
end
elseif args[1] == "remove_card" then
if args[2] then
local key_hash = args[2]
local trusted_keys = fs.open(dir..config.key_file, 'r')
local new_key_table = {}
while true do
local trusted_hash = trusted_keys.readLine()
if trusted_hash ~= key_hash then
table.insert(new_key_table, trusted_hash)
else
print("Removed "..key_hash)
end
if not trusted_hash then break end -- Stop when EOF reached
end end
print("Transaction finished") trusted_keys.close()
local trusted_keys = fs.open(dir..config.key_file, 'w+')
for _, entry in ipairs(new_key_table) do
trusted_keys.write(entry .. '\n')
end
trusted_keys.close()
end end
end end