Repository navigation
PIN lock screen, with one counted door for every PIN check - #4
Merged
Merged
Conversation
…ypad under calls, ordered lock state
…hy-pin, no setuid password checkers
…ccess, boot window and removal safety
…a lock, sturdier undo
… silently not apply
… from the script, for Ubuntu runners
…ounce its release
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The phone now has a real lock: a 6 to 12 digit PIN, chosen at first boot, asked for on a keypad drawn on the lock surface. It locks at boot, on a power press and after the idle timeout. The PIN is the account's password, so every way of checking it goes through one counted door. Passwordless sudo is unchanged here; removing it is the next PR.
Change
Lock screen
default/omarchy/plugins/moarchy.lock: an ext-session-lock plugin built on upstream's lock service (late outputs, recovering a lock left by a crashed shell). It draws its own keypad, because the on-screen keyboard is hidden under a session lock. The decisions live inLock.jsand are unit-tested intests/tst_lock.qml.moarchy-pin first. There is no way past it without choosing one.moarchy.phonereports every call-state change, so a lock taken mid-call still shows the call.shell.jsonsays, and never offered as a switch (port-4x.patch).When it locks
autostart.luablanks the panel, switches touch off and puts the keyboard in a submap that swallows every key until the lock is secure.moarchy-idle-lockhonors Stay Awake.$XDG_RUNTIME_DIRis tagged with the compositor it was written under, so a state left by an earlier Hyprland is ignored.One door to the PIN
bin/moarchy-pinis the only place a PIN is checked:checkfrom the lock screen through a narrow sudoers rule, andpamfromsystem-auththroughpam_execfor sudo, polkit and console logins.bin/moarchy-harden-authrewritessystem-authand strips setuid fromunix_chkpwd,su,chfn,chsh,passwdandksu, which would each check a password uncounted. It runs from the image build, a pacman hook and a boot-time unit, and--undoruns before the package is removed. It warns about any PAM stack added later that checks passwords outside the count.ReadWritePaths=-/var/lib/moarchy/pin). logind starts no gettys on spare consoles.Verification
image/verify.shchecks:moarchy-pin;system-auth, and that no other PAM stack checks passwords outside the count;image/negative-test.shplants six new defects, and the verifier catches each one.scripts/test-moarchy-pin.sh(44 cases),test-harden-auth.sh(14) andtest-power-press.sh(18), run fromscripts/style-check.sh;scripts/test-qml.shruns all 41 plugin QML test files;scripts/test-pam-door.shruns real sudo through PAM, with controls proving the closed doors were open before.Code running as the user can still capture the PIN when it is typed, and can spend tries so that entry stays paused. That is the Unix user model, and only sandboxing apps changes it (
docs/structure.mdI8).Testing
Built in an isolated VM: release and dev images, both verified (apart from the online resize2fs check, which needs a native arm64 kernel and runs in CI). The negative tests caught all 31 planted defects across both images. In the image container, all 41 QML test files and the real-PAM door test pass. The helper and hardening tests pass under both their bwrap and sudo backends. The lock plugin was driven offscreen in Quickshell through setup, wrong and right PINs, a pause, a late PIN and six startup cases. Every operation the helper performs was run on the phone under polkit's exact unit sandbox.
Flashed to a Pixel 3a. First boot came up dark, then on the setup keypad, and set the PIN through
moarchy-pin first. With the phone locked, a wrong PIN through the helper was refused (exit 4) and counted, and the owner's PIN on the keypad unlocked the phone and reset the count. A single power press locked the session with the panel dark: the lock reported secure and the state file readlocked. The next press brought up the keypad, which unlocked it. After a reboot the phone came up on the keypad, not setup, and unlocked. On the device:unix_chkpwd,su,chfn,chshandpasswdare not setuid;system-authroutes through moarchy-pin; polkit's agent helper has the count's directory writable; the boot-time hardening unit succeeded; Hyprland reports no config errors; the boot submap is released; no units failed. The device found one bug that offscreen testing could not: Quickshell does not announce WlSessionLock's release, solockedstayed true after an unlock, which would have stopped every later lock. It is fixed in the last commit, and that file was verified on the phone.