Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local MAX_ATTEMPTS = 3 -- Maximum number of incorrect password attempts allowed
- local LOCKOUT_TIME = 30 -- Lockout time in seconds after reaching maximum attempts
- local USERS_FOLDER = "/disk/users/"
- local ERROR_FOLDER = "/disk/error/"
- local BSOD_PROGRAM = "BSOD.lua"
- -- Utility function to draw a centered popup window with a text-based border
- local function drawPopupWindow(headerText, contentLines)
- term.clear() -- Clear the screen before drawing the popup window
- local w, h = term.getSize()
- local maxLength = #headerText
- for _, line in ipairs(contentLines) do
- maxLength = math.max(maxLength, #line)
- end
- local windowWidth = maxLength + 4 -- Width of the popup window
- local windowHeight = #contentLines + 4 -- Height of the popup window
- local xStart = math.floor(w / 2 - windowWidth / 2)
- local yStart = math.floor(h / 2 - windowHeight / 2)
- -- Draw border
- term.setCursorPos(xStart, yStart)
- term.write("+" .. string.rep("-", windowWidth - 2) .. "+")
- for i = 1, windowHeight - 2 do
- term.setCursorPos(xStart, yStart + i)
- term.write("|" .. string.rep(" ", windowWidth - 2) .. "|")
- end
- term.setCursorPos(xStart, yStart + windowHeight - 1)
- term.write("+" .. string.rep("-", windowWidth - 2) .. "+")
- -- Draw header
- term.setCursorPos(xStart + 2, yStart + 1)
- term.write(headerText)
- -- Draw content
- for i, line in ipairs(contentLines) do
- term.setCursorPos(xStart + 2, yStart + 1 + i + 1)
- term.write(line)
- end
- end
- local function generateKey()
- local chars = {}
- for i = 32, 126 do -- ASCII range for printable characters
- table.insert(chars, string.char(i))
- end
- local key = {}
- while #chars > 0 do
- local index = math.random(#chars)
- table.insert(key, table.remove(chars, index))
- end
- return table.concat(key)
- end
- local function createMap(key)
- local map = {}
- for i = 32, 126 do
- map[string.char(i)] = key:sub(i - 31, i - 31)
- end
- return map
- end
- local function invertMap(map)
- local invMap = {}
- for k, v in pairs(map) do
- invMap[v] = k
- end
- return invMap
- end
- local function encrypt(text, key)
- local map = createMap(key)
- local encrypted = {}
- for i = 1, #text do
- local char = text:sub(i, i)
- table.insert(encrypted, map[char] or char)
- end
- return table.concat(encrypted)
- end
- local function decrypt(text, key)
- local map = invertMap(createMap(key))
- local decrypted = {}
- for i = 1, #text do
- local char = text:sub(i, i)
- table.insert(decrypted, map[char] or char)
- end
- return table.concat(decrypted)
- end
- local function saveKeyToFile(key, dir)
- local randomNumber = math.random(1, 1000)
- local fileName = dir .. "/key" .. randomNumber .. ".txt"
- local file = fs.open(fileName, "w")
- file.write(key)
- file.close()
- return fileName
- end
- local function loadKeyFromFile(fileName)
- local file = fs.open(fileName, "r")
- local key = file.readAll()
- file.close()
- return key
- end
- local function findKeyFile(dir)
- local files = fs.list(dir)
- for _, file in ipairs(files) do
- if file:match("^key%d+%.txt$") then
- return dir .. "/" .. file
- end
- end
- return nil
- end
- local function loadEncryptedText(userDir)
- local fileName = userDir .. "/password.txt"
- if not fs.exists(fileName) then
- return nil
- end
- local file = fs.open(fileName, "r")
- local encryptedText = file.readAll()
- file.close()
- return encryptedText
- end
- local function getUserCredentials(username)
- local userDir = fs.combine(USERS_FOLDER, username)
- local encryptedText = loadEncryptedText(userDir)
- if not encryptedText then
- return nil -- User does not exist
- end
- local keyFile = findKeyFile(userDir)
- if not keyFile then
- return nil -- Key file not found
- end
- local key = loadKeyFromFile(keyFile)
- local decryptedPassword = decrypt(encryptedText, key)
- return decryptedPassword
- end
- local function drawLoginScreen(username, attemptsLeft)
- local contentLines = {
- "Username: " .. username,
- "Attempts left: " .. attemptsLeft,
- "",
- "Enter password:"
- }
- drawPopupWindow("Login to Doggy OS", contentLines)
- term.setCursorPos(math.floor(term.getSize() / 2) - 2, math.floor(term.getSize() / 2) + 1) -- Position cursor for password input
- end
- local function lockoutUser(username)
- local disabledFile = fs.combine(USERS_FOLDER .. username, "disabled.txt")
- local file = fs.open(disabledFile, "w")
- file.close()
- end
- local function checkDisabled(username)
- local disabledFile = fs.combine(USERS_FOLDER .. username, "disabled.txt")
- return fs.exists(disabledFile)
- end
- local function checkCredentials(username)
- if checkDisabled(username) then
- drawPopupWindow("Access Denied", {"This user has been disabled due to security reasons.", "", "Contact your administrator for help."})
- os.sleep(5) -- Display the disabled message for 5 seconds
- shell.run("/disk/os/lock.lua") -- Run the lock.lua program
- return false
- end
- local storedPassword = getUserCredentials(username)
- if not storedPassword then
- return false -- User does not exist
- end
- local attempts = 0
- repeat
- drawLoginScreen(username, MAX_ATTEMPTS - attempts)
- local enteredPassword = read("*")
- attempts = attempts + 1
- if enteredPassword == storedPassword then
- return true
- else
- drawPopupWindow("Access Denied", {"Incorrect password. Please try again."})
- os.sleep(2) -- Display the error message for 2 seconds
- end
- until attempts > MAX_ATTEMPTS
- drawPopupWindow("Account Disabled", {"Too many incorrect attempts. User has been disabled."})
- lockoutUser(username)
- os.sleep(2) -- Display the lockout message for 2 seconds
- return false
- end
- local function checkDiskIDs()
- -- Get a list of all connected peripherals
- local peripherals = peripheral.getNames()
- -- Array to store disk IDs
- local diskIDs = {}
- -- Loop through all peripherals
- for _, name in ipairs(peripherals) do
- -- Check if the peripheral is a disk drive
- if peripheral.getType(name) == "drive" then
- -- Get the disk ID from the disk drive
- local diskID = disk.getID(name)
- -- If a disk is inserted, add its ID to the array
- if diskID then
- table.insert(diskIDs, {id = diskID, name = name})
- end
- end
- end
- -- Check if any disks were found
- if #diskIDs > 0 then
- return diskIDs
- else
- return nil
- end
- end
- local function drawSecurityCardPrompt()
- local contentLines = {
- "Please insert your security card.",
- "Press ENTER to use password instead."
- }
- drawPopupWindow("Insert Security Card", contentLines)
- end
- local function drawErrorMessage(message)
- drawPopupWindow("Error", {message})
- end
- local function drawMessage(header, message)
- drawPopupWindow(header, {message})
- end
- local function ejectDisk(diskName)
- peripheral.call(diskName, "ejectDisk")
- end
- local function checkSecurityCard(username)
- local idFolder = fs.combine(USERS_FOLDER .. username, "ID")
- if not fs.exists(idFolder) then
- return false
- end
- while true do
- drawSecurityCardPrompt()
- local event, key = os.pullEvent()
- if event == "key" and key == keys.enter then
- return false
- elseif event == "disk" or event == "disk_insert" then
- local diskIDs = checkDiskIDs()
- if diskIDs then
- for _, disk in ipairs(diskIDs) do
- ejectDisk(disk.name) -- Eject the disk
- local idFile = fs.combine(idFolder, tostring(disk.id) .. ".file")
- if fs.exists(idFile) then
- return true -- Allow access if a valid ID is found
- end
- end
- drawErrorMessage("Error: Unregistered security key.")
- os.sleep(2)
- end
- end
- end
- end
- local function main()
- term.setBackgroundColor(colors.black) -- Set overall background color to black
- term.clear()
- drawPopupWindow("Protected by Doggy OS Security", {"Enter username:"})
- local enteredUsername = read()
- if checkDisabled(enteredUsername) then
- drawErrorMessage("Account disabled")
- os.sleep(3) -- Display the disabled message for 3 seconds
- shell.run("/disk/os/lock.lua") -- Run the lock.lua program
- return
- end
- local users = fs.list(USERS_FOLDER)
- if not users or #users == 0 then
- -- No users detected, run the BSOD program
- shell.run(ERROR_FOLDER .. BSOD_PROGRAM)
- elseif checkSecurityCard(enteredUsername) then
- drawMessage("Welcome", "Access granted. Welcome, " .. enteredUsername .. "!")
- os.sleep(2) -- Display the success message for 2 seconds
- shell.run("/disk/os/gui")
- -- Your main OS code goes here
- elseif checkCredentials(enteredUsername) then
- drawMessage("Welcome", "Access granted. Welcome, " .. enteredUsername .. "!")
- os.sleep(2) -- Display the success message for 2 seconds
- shell.run("/disk/os/gui")
- -- Your main OS code goes here
- else
- drawErrorMessage("Access denied.")
- os.sleep(2) -- Display the access denied message for 2 seconds
- shell.run("/disk/os/lock.lua")
- end
- end
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement