settings.define("lns_server.modem_location", { description = "Modem location", type = "string", default = "right" }) modem_location = settings.get("lns_server.modem_location") settings.define("lns_server.rednet_hostname", { description = "Rednet hostname", type = "string", default = "test" }) settings.define("lns_server.require_auth", { description = "Require authentication", type = "boolean", default = false }) require_auth = settings.get("lns_server.require_auth") settings.define("lns_server.auth_group", { description = "Authentication group", type = "string", default = "admin" }) local auth_group = settings.get("lns_server.auth_group") settings.define("lns_server.auth_server", { description = "Authentication server", type = "string", default = "auth.box" }) auth_server = settings.get("lns_server.auth_server") settings.define("lns_server.log_level", { description = "Log Level", type = "string", default = "info" }) log_level = settings.get("lns_server.log_level") rednet.host("lns", settings.get("lns_server.rednet_hostname")) rednet.open(modem_location) local data = {} function log(str) io.write("[" .. os.time() .. "] " .. str .. "\n") end function log_debug(str) if log_level == "debug" then log(str) end end function save_data() db = fs.open("lns.db", "w") db.write(textutils.serialize(data)) db.close() end function load_data() if fs.exists("lns.db") then db = fs.open("lns.db", "r") db_contents = db.readAll() db.close() data = textutils.unserialize(db_contents) end end function split (inputstr, sep) if sep == nil then sep = "%s" end local t={} for str in string.gmatch(inputstr, "([^"..sep.."]+)") do table.insert(t, str) end return t end function check_user_in_group(username, group) local package = { ["action"] = "check_group", ["username"] = username, ["group"] = group } local authID = data[auth_server] rednet.send(authID, package, "auth") while true do id, msg = rednet.receive("auth") if id == authID then if msg == "invalid request" then io.write("Invalid request\n") return false elseif msg == true then return true else return false end end end end load_data() while true do client_id, msg = rednet.receive("lns") request = msg if request.action == nil or request.hostname == nil then rednet.send(client_id, "invalid request", "lns") end if request.action == "lookup" then -- check if hostname in data if request.hostname == nil then rednet.send(client_id, nil, "lns") log("Sent nil to " .. client_id) else rednet.send(client_id, data[request.hostname], "lns") log("Sent " .. request.hostname .. " to " .. client_id) end end if request.action == "reload" then load_data() rednet.send(client_id, "ok", "lns") log("Reloaded data") end if request.action == "register" then local auth_passed = false if require_auth then local authID = data[auth_server] if request.token == nil then rednet.send(client_id, "invalid auth", "lns") elseif authID ~= nil then rednet.send(authID, { ["action"] = "token", ["token"] = request.token }, "auth") local responseServerID = nil while responseServerID ~= authID do responseServerID, auth_response = rednet.receive("auth") end local errorPos, errorEnd = string.find(auth_response, "invalid") if errorPos then log("Error: " .. auth_response) else if check_user_in_group(auth_response, auth_group) then auth_passed = true else rednet.send(client_id, "invalid auth", "lns") end end else log("Error: Auth server not found to " .. client_id) end else auth_passed = true end if auth_passed then data[request.hostname] = client_id log("Registered " .. request.hostname .. " as " .. client_id) save_data() rednet.send(client_id, "ok", "lns") else rednet.send(client_id, "auth required", "lns") end end end