README.md (6819B)
1 # Administrative Password Prompt 2 3 Secure password verification system for LuajitOS that provides admin-level permission and path access control. 4 5 ## Features 6 7 - **Overlay Authentication**: Password prompt draws on top of all windows (including taskbar) 8 - **Argon2id Hashing**: Uses Argon2id for secure password hashing 9 - **Permission Requests**: Allows apps to request additional permissions at runtime 10 - **Path Access Requests**: Allows apps to request additional filesystem paths at runtime 11 12 ## Setup 13 14 ### 1. Generate Password Hash 15 16 You need to create `/os/password.hash` with a base64-encoded Argon2id hash of your admin password. 17 18 To generate the hash, boot into LuajitOS and run: 19 20 ```lua 21 -- In the shell or a test app: 22 local password = "admin" -- Change this to your desired password 23 local salt = "LuajitOS-AdminSalt-v1" 24 25 -- Use the crypto library 26 local hash = crypto.Argon2id(password, salt) 27 28 -- Encode to base64 29 local function base64_encode(data) 30 local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' 31 if not data or #data == 0 then return "" end 32 local result = {} 33 for i = 1, #data, 3 do 34 local b1 = string.byte(data, i) 35 local b2 = string.byte(data, i + 1) or 0 36 local b3 = string.byte(data, i + 2) or 0 37 local n = b1 * 65536 + b2 * 256 + b3 38 local c1 = bit.band(bit.rshift(n, 18), 63) + 1 39 local c2 = bit.band(bit.rshift(n, 12), 63) + 1 40 local c3 = bit.band(bit.rshift(n, 6), 63) + 1 41 local c4 = bit.band(n, 63) + 1 42 table.insert(result, b64chars:sub(c1, c1)) 43 table.insert(result, b64chars:sub(c2, c2)) 44 if i + 1 <= #data then table.insert(result, b64chars:sub(c3, c3)) else table.insert(result, '=') end 45 if i + 2 <= #data then table.insert(result, b64chars:sub(c4, c4)) else table.insert(result, '=') end 46 end 47 return table.concat(result) 48 end 49 50 local hash_b64 = base64_encode(hash) 51 print("Password hash (base64): " .. hash_b64) 52 53 -- Write to file (requires filesystem permission) 54 -- fs:write("/os/password.hash", hash_b64) 55 ``` 56 57 Or use the crypto CLI app: 58 59 ```bash 60 # This will show you the hash 61 crypto Argon2id "admin" -salt "LuajitOS-AdminSalt-v1" -b64 62 ``` 63 64 Then manually create the file with that hash. 65 66 ### 2. Create Password File 67 68 Create `/os/password.hash` in the ISO directory before building: 69 70 ```bash 71 echo "YOUR_HASH_HERE" > iso_includes/os/password.hash 72 ``` 73 74 **Default Test Password**: For testing purposes, you can use password `"admin"` with this hash: 75 ``` 76 # This is a placeholder - generate the actual hash using the method above 77 ``` 78 79 ## Usage 80 81 ### For App Developers 82 83 #### Request Additional Permission 84 85 ```lua 86 -- Import the passprompt app exports 87 local passprompt = apps["com.luajitos.passprompt"] 88 89 if passprompt and passprompt.exports["admin.requestPermission"] then 90 local requestPerm = passprompt.exports["admin.requestPermission"].func 91 92 -- Request network permission for current app 93 requestPerm(app.pid, "network", function(granted) 94 if granted then 95 print("Permission granted!") 96 -- Now you can use network APIs 97 else 98 print("Permission denied") 99 end 100 end) 101 end 102 ``` 103 104 #### Request Additional Path Access 105 106 ```lua 107 -- Import the passprompt app exports 108 local passprompt = apps["com.luajitos.passprompt"] 109 110 if passprompt and passprompt.exports["admin.requestPath"] then 111 local requestPath = passprompt.exports["admin.requestPath"].func 112 113 -- Request access to system logs 114 requestPath(app.pid, "/var/log/*", function(granted) 115 if granted then 116 print("Path access granted!") 117 -- Now you can read/write to /var/log/* 118 else 119 print("Path access denied") 120 end 121 end) 122 end 123 ``` 124 125 ## Security Considerations 126 127 ### Password Storage 128 - Password hash is stored in `/os/password.hash` as base64-encoded Argon2id output 129 - Uses fixed salt `"LuajitOS-AdminSalt-v1"` (for verification purposes) 130 - **Production**: Should use per-installation random salt stored separately 131 132 ### Hashing Algorithm 133 - **Argon2id**: Memory-hard function resistant to GPU/ASIC attacks 134 - Default parameters: 3 iterations, 64MB memory (from `crypto.Argon2id`) 135 136 ### Permissions Required 137 The passprompt app requires: 138 - `"draw"` - Display password prompt window 139 - `"filesystem"` - Read `/os/password.hash` 140 - `"crypto"` - Access Argon2id hashing 141 - `"system-all"` - Call `sys.ADMIN_AppAddPermission` and `sys.ADMIN_AppAddPath` 142 - `"export"` - Export request functions to other apps 143 144 ### Attack Vectors to Consider 145 146 1. **Password File Access**: `/os/password.hash` should be read-only 147 2. **Timing Attacks**: Hash comparison uses simple string equality (could leak timing info) 148 3. **Brute Force**: No rate limiting on password attempts 149 4. **UI Spoofing**: `alwaysOnTop` prevents most spoofing, but not all 150 5. **Memory Inspection**: Password stored in plaintext memory during verification 151 152 ### Improvements for Production 153 154 1. **Rate Limiting**: Implement exponential backoff after failed attempts 155 2. **Constant-Time Comparison**: Use constant-time string comparison 156 3. **Random Salt**: Generate unique salt per installation 157 4. **Audit Logging**: Log all permission grant attempts 158 5. **Session Timeout**: Auto-lock after period of inactivity 159 6. **Secure Memory**: Clear password from memory after verification 160 7. **Challenge-Response**: Use challenge-response instead of direct password entry 161 162 ## Architecture 163 164 ### Window Properties 165 - `alwaysOnTop = true`: Ensures overlay draws above all other windows 166 - `noTaskbar = true`: Doesn't appear in taskbar list 167 - `resizable = false`: Fixed size for consistent UI 168 169 ### Flow 170 171 1. App calls `admin.requestPermission(pid, permission, callback)` or `admin.requestPath(pid, path, callback)` 172 2. Password prompt window displays (blocking all input) 173 3. User enters password 174 4. Password hashed with Argon2id + fixed salt 175 5. Hash compared to stored hash in `/os/password.hash` 176 6. On success: 177 - Calls `sys.ADMIN_AppAddPermission(pid, permission)` or `sys.ADMIN_AppAddPath(pid, path)` 178 - Invokes callback with `true` 179 - Closes window 180 7. On failure: 181 - Shows error message 182 - Clears password field 183 - Invokes callback with `false` (on cancel) 184 185 ## Testing 186 187 1. Build the OS with passprompt app included 188 2. Create password hash file 189 3. Boot into LuajitOS 190 4. Run passprompt app (it stays in background) 191 5. From another app, call the exported functions 192 6. Verify password prompt appears on top 193 7. Test correct and incorrect passwords 194 8. Verify permissions/paths are actually granted 195 196 ## Debug Output 197 198 The app logs to serial console (`osprint`) for debugging: 199 - Password hash attempts (base64) 200 - Stored hash comparison 201 - Permission/path grant operations 202 - Function call parameters 203 204 To view debug output, connect to serial console or check boot logs.