luajitos

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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.