Advertisement
DOGGYWOOF

Doggy OS loogn with domain syncying

Jan 30th, 2025 (edited)
13
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.79 KB | None | 0 0
  1. local protocol = "sync_protocol"
  2. local clientPath = "/disk/users/"
  3. local MAX_ATTEMPTS = 3 -- Maximum number of incorrect password attempts allowed
  4. local LOCKOUT_TIME = 30 -- Lockout time in seconds after reaching maximum attempts
  5. local USERS_FOLDER = "/disk/users/"
  6. local ERROR_FOLDER = "/disk/error/"
  7. local BSOD_PROGRAM = "BSOD.lua"
  8. local CURRENT_USER_FILE = ".currentusr"
  9. local SHOW_ALL_USERS_FILE = "/disk/config/security/login/ShowAllUsers.cfg"
  10.  
  11. -- Utility function to draw a centered popup window with a text-based border
  12. local function drawPopupWindow(headerText, contentLines, windowWidth, windowHeight)
  13. term.clear()
  14. local w, h = term.getSize()
  15.  
  16. -- Determine dimensions of the popup
  17. local maxLength = #headerText
  18. for _, line in ipairs(contentLines) do
  19. maxLength = math.max(maxLength, #line)
  20. end
  21. windowWidth = windowWidth or (maxLength + 4)
  22. windowHeight = windowHeight or (#contentLines + 4)
  23.  
  24. local xStart = math.floor(w / 2 - windowWidth / 2)
  25. local yStart = math.floor(h / 2 - windowHeight / 2)
  26.  
  27. -- Draw border with animation
  28. term.setCursorPos(xStart, yStart)
  29. term.write("+" .. string.rep("-", windowWidth - 2) .. "+")
  30. for i = 1, windowHeight - 2 do
  31. term.setCursorPos(xStart, yStart + i)
  32. term.write("|" .. string.rep(" ", windowWidth - 2) .. "|")
  33. os.sleep(0.05)
  34. end
  35. term.setCursorPos(xStart, yStart + windowHeight - 1)
  36. term.write("+" .. string.rep("-", windowWidth - 2) .. "+")
  37.  
  38. -- Draw header
  39. term.setCursorPos(xStart + 2, yStart + 1)
  40. term.write(headerText)
  41.  
  42. -- Draw content
  43. for i, line in ipairs(contentLines) do
  44. term.setCursorPos(xStart + 2, yStart + 1 + i + 1)
  45. term.write(line)
  46. os.sleep(0.05)
  47. end
  48. end
  49.  
  50. -- Function to list all users
  51. local function listUsers()
  52. local users = fs.list(USERS_FOLDER)
  53. local usernames = {}
  54. for _, user in ipairs(users) do
  55. local userDir = fs.combine(USERS_FOLDER, user)
  56. if fs.isDir(userDir) then
  57. table.insert(usernames, user)
  58. end
  59. end
  60. return usernames
  61. end
  62.  
  63. -- Function to handle user selection from the list
  64. local function drawUsersScreen(usernames, selectedIndex)
  65. local contentLines = {}
  66. for i, username in ipairs(usernames) do
  67. if i == selectedIndex then
  68. table.insert(contentLines, "> " .. username)
  69. else
  70. table.insert(contentLines, " " .. username)
  71. end
  72. end
  73. drawPopupWindow("Select your user account:", contentLines, 30, #contentLines + 4)
  74. end
  75.  
  76. -- Function to select a user from the list interactively
  77. local function selectUserFromList()
  78. local usernames = listUsers()
  79. local selectedIndex = 1
  80.  
  81. while true do
  82. drawUsersScreen(usernames, selectedIndex)
  83.  
  84. local event, key = os.pullEvent("key")
  85. if key == keys.up then
  86. selectedIndex = math.max(1, selectedIndex - 1)
  87. elseif key == keys.down then
  88. selectedIndex = math.min(#usernames, selectedIndex + 1)
  89. elseif key == keys.enter then
  90. return usernames[selectedIndex]
  91. end
  92. end
  93. end
  94.  
  95. -- Function to get user credentials
  96. local function getUserCredentials(username)
  97. local passwordFile = fs.combine(USERS_FOLDER .. username, "password.txt")
  98. if fs.exists(passwordFile) then
  99. local file = fs.open(passwordFile, "r")
  100. local storedPassword = file.readLine()
  101. file.close()
  102. return storedPassword
  103. else
  104. return nil
  105. end
  106. end
  107.  
  108. -- Function to save the current user
  109. local function saveCurrentUser(username)
  110. if fs.exists(CURRENT_USER_FILE) then
  111. fs.delete(CURRENT_USER_FILE)
  112. end
  113. local file = fs.open(CURRENT_USER_FILE, "w")
  114. file.write(username)
  115. file.close()
  116. end
  117.  
  118. -- Function to lock out user
  119. local function lockoutUser(username)
  120. local disabledFile = fs.combine(USERS_FOLDER .. username, "disabled.txt")
  121. local file = fs.open(disabledFile, "w")
  122. file.close()
  123. end
  124.  
  125. -- Function to check if user is disabled
  126. local function checkDisabled(username)
  127. local disabledFile = fs.combine(USERS_FOLDER .. username, "disabled.txt")
  128. return fs.exists(disabledFile)
  129. end
  130.  
  131. -- Function to check credentials for user login
  132. local function checkCredentials(username)
  133. if checkDisabled(username) then
  134. drawPopupWindow("Doggy OS Account Lockout Service", {"This user account has been disabled."})
  135. os.sleep(2)
  136. return false
  137. end
  138.  
  139. local storedPassword = getUserCredentials(username)
  140. if not storedPassword then
  141. drawPopupWindow("Doggy OS Login Failure", {"User account doesn't exist or is corrupted."})
  142. os.sleep(3)
  143. return false
  144. end
  145.  
  146. local attempts = 0
  147. repeat
  148. drawPopupWindow("Login to Doggy OS", {"Username: " .. username, "Attempts left: " .. (MAX_ATTEMPTS - attempts), "", "Enter password:"})
  149. term.setCursorPos(1, select(2, term.getSize()))
  150. term.write(":")
  151. local enteredPassword = read("*")
  152. attempts = attempts + 1
  153.  
  154. if enteredPassword == storedPassword then
  155. saveCurrentUser(username)
  156. return true
  157. else
  158. drawPopupWindow("Access Denied", {"Incorrect Password"})
  159. os.sleep(2)
  160. end
  161. until attempts >= MAX_ATTEMPTS
  162.  
  163. lockoutUser(username)
  164. drawPopupWindow("Doggy OS Account Lockout Service", {"Too many incorrect attempts."})
  165. os.sleep(2)
  166. return false
  167. end
  168.  
  169. -- Synchronization related code
  170.  
  171. local function getFileHash(filePath)
  172. if not fs.exists(filePath) then return nil end
  173. local f = fs.open(filePath, "r")
  174. local content = f.readAll()
  175. f.close()
  176. return textutils.serialize(content)
  177. end
  178.  
  179. local function getFileList(path)
  180. local files = {}
  181. local function scan(dir)
  182. for _, file in pairs(fs.list(dir)) do
  183. local fullPath = dir .. file
  184. if fs.isDir(fullPath) then
  185. scan(fullPath .. "/")
  186. else
  187. files[fullPath:sub(#clientPath + 1)] = getFileHash(fullPath)
  188. end
  189. end
  190. end
  191. scan(path)
  192. return files
  193. end
  194.  
  195. local function syncFiles(username)
  196. local userPath = clientPath .. username .. "/"
  197.  
  198. -- Ensure the username directory exists
  199. if not fs.exists(userPath) or not fs.isDir(userPath) then
  200. print("Error: User directory '" .. username .. "' not found.")
  201. return
  202. end
  203.  
  204. -- Open the modem
  205. rednet.open(peripheral.getName(peripheral.find("modem") or error("No modem found")))
  206.  
  207. -- Get server ID from the .domaincontrollerID file
  208. local function getServerID()
  209. local filePath = ".domaincontrollerID"
  210. if not fs.exists(filePath) then
  211. print("Error: .domaincontrollerID file not found.")
  212. return nil
  213. end
  214.  
  215. -- Read the server ID from the file
  216. local file = fs.open(filePath, "r")
  217. local serverID = tonumber(file.readAll())
  218. file.close()
  219.  
  220. -- If the server ID is valid, return it
  221. if serverID then
  222. return serverID
  223. else
  224. print("Error: Invalid server ID in .domaincontrollerID.")
  225. return nil
  226. end
  227. end
  228.  
  229. local serverID = getServerID()
  230. if not serverID then return end
  231.  
  232. -- Perform sync
  233. print("Syncing user: " .. username .. " with server " .. serverID)
  234.  
  235. -- Send file list to server
  236. rednet.send(serverID, { action = "sync_request", user = username, files = getFileList(userPath) }, protocol)
  237.  
  238. local id, response = rednet.receive(protocol, 5)
  239. if id == serverID and response.action == "sync_response" then
  240. -- Download files to client
  241. for file, content in pairs(response.files_to_client or {}) do
  242. local filePath = userPath .. file
  243. local f = fs.open(filePath, "w")
  244. f.write(content)
  245. f.close()
  246. print("Downloaded:", file)
  247. end
  248.  
  249. -- Upload files from client
  250. rednet.send(serverID, { action = "sync_upload", user = username, files_to_server = getFileList(userPath) }, protocol)
  251. else
  252. print("No response from server.")
  253. end
  254.  
  255. print("Sync complete.")
  256. end
  257.  
  258. -- Main function for login and sync
  259.  
  260. local function main()
  261. term.setTextColor(colors.white)
  262. term.setBackgroundColor(colors.black)
  263. term.clear()
  264.  
  265. local username
  266.  
  267. if fs.exists(SHOW_ALL_USERS_FILE) then
  268. username = selectUserFromList()
  269. else
  270. drawPopupWindow("Protected by Doggy OS Security", {"Enter username:"})
  271. username = read()
  272. end
  273.  
  274. -- Attempt login
  275. if not checkCredentials(username) then
  276. return
  277. end
  278.  
  279. -- Sync user data after login
  280. syncFiles(username)
  281. shell.run("/disk/os/gui")
  282. end
  283.  
  284. main()
  285.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement