# Ah ah ah, you didn't say the magic word `ahfail` is a screen locker. Get the password wrong and a looping animation of **the author's face photoshopped onto Dennis Nedry's body** appears on screen while the "ah ah ah, you didn't say the magic word" clip from Jurassic Park plays. Every wrong guess adds another Nedry. The volume is forced to 100% on the first failure and restored when you unlock. ```bash ahfail # lock the screen ahfail test # show the effect once, without locking anything ahfail doctor # check this machine and explain what is missing ``` One command on Linux: `ahfail` works out whether you run Wayland or X11 and does the right thing. On macOS the effect comes from a PAM hook on the system lock screen (see below). --- > **Security disclaimer** > > This is a screen locker, so it sits directly in the authentication path. A bug in it could lock you out of your session or, in the worst case, weaken the lock. > > The author makes no guarantees about the security or correctness of this software. By installing it you accept that you are running a security-sensitive component of your system and take full responsibility for any vulnerabilities or instability that result. **Use at your own discretion.** --- ## Install ### Arch Linux ```bash yay -S ahfail ``` (Once it is published on the AUR.) The package installs the `ahfail` binary and its own PAM service file, `/etc/pam.d/ahfail`. Nothing in any other package's PAM configuration is touched, the same way swaylock and gtklock ship theirs. ### From source ```bash sudo pacman -S meson ninja rust gtk3 gtk-session-lock gstreamer gst-plugins-base gst-plugins-good pam meson setup builddir --prefix=/usr meson compile -C builddir sudo meson install -C builddir ``` `--prefix=/usr` matches Arch conventions and puts the PAM file where PAM looks for it. Then run `ahfail doctor`. It tells you whether the session type is supported, whether `/etc/pam.d/ahfail` is in place, whether GStreamer can play the clip and whether the volume can be controlled, with the exact fix for anything that is missing. --- ## Platform support | Platform | How it locks | Notes | |---|---|---| | Linux, **Wayland** | ext-session-lock-v1 (through gtk-session-lock) | sway, Hyprland, niri, river, labwc and KDE Plasma 6. **Not GNOME**: GNOME does not let third-party programs lock the screen. | | Linux, **X11** | full-screen windows on every monitor plus a keyboard and pointer grab | The i3lock model. Works with any X11 window manager. | | **macOS** | the system lock screen | Lock the Mac as usual; the effect comes from the PAM hook installed via Homebrew (see below). The `ahfail` command itself is Linux only for now. | ## Locking automatically Point your idle daemon at `ahfail`. Running it while already locked is harmless: a second instance exits quietly. ```bash # Wayland swayidle -w timeout 300 'ahfail' before-sleep 'ahfail' # X11 xss-lock -- ahfail ``` Pass `--no-max-volume` to leave the volume alone. ## Security - **Wayland:** once the compositor confirms the lock, only the lock surfaces are shown. If `ahfail` crashes or is killed, the session **stays locked** (the compositor shows its own fallback), it never opens up. - **X11:** the lock is the input grab. If the grab cannot be taken (a menu or another program holds it), `ahfail` refuses to lock rather than show a lock screen your keystrokes pass through. Like i3lock, nothing on X11 keeps the screen locked if the locker process dies. - `ahfail` refuses to run as root, and the password is checked in a separate thread through PAM service `ahfail` and wiped from memory afterwards. - **Too many wrong passwords can lock your account.** `/etc/pam.d/ahfail` includes `login`, so the system's `pam_faillock` policy applies. On Arch that means 3 wrong passwords within 15 minutes lock the account for 10 minutes (see `/etc/security/faillock.conf`). That is the system's rule, not ahfail's, and every PAM-based locker behaves the same, but it is worth knowing before you invite colleagues to try their luck. --- ## macOS ### Homebrew (recommended) ```bash brew tap agw/ahfail https://gitea.weircon.dk/agw/homebrew-ahfail brew install ahfail ``` After install, Homebrew prints the PAM line to add to `/etc/pam.d/screensaverui` (macOS 13+) or `/etc/pam.d/screensaver` (macOS 12 and earlier). That one-line edit is the only manual step. Enable "Require password immediately" in System Settings so the lock screen asks for the password straight away. To upgrade: `brew upgrade ahfail`. To uninstall: `sudo sed -i '' '/ahfail/d' /etc/pam.d/screensaverui` (or `screensaver`), then `brew uninstall ahfail`. `bash scripts/install-macos.sh` and `bash scripts/uninstall-macos.sh` do the same from a source checkout. --- ## Legacy integrations Before `ahfail` became its own locker it hooked into other lockers. These still work and are still built, for anyone who wants to keep their current locker. | File | Used by | |---|---| | `ahfail-module.so` | a module for **gtklock** (Wayland) | | `libahfail_pam.so` + `ahfail-display` | a PAM hook for **X11 lockers** (i3lock, i3lock-color, betterlockscreen, xscreensaver, lightdm) | **gtklock:** ```bash gtklock -m /usr/lib/gtklock/ahfail-module.so -- --deadzone=860,440,200,200 ``` `--deadzone=X,Y,W,H` keeps sprites away from your password field, `--audio-uri=URI` swaps the clip. **X11 PAM hook:** add this line to the locker's PAM file (for example `/etc/pam.d/i3lock`) **before** `auth include system-auth`. After it, `pam_faillock`'s `[default=die]` inside `system-auth` means the module is never reached on a failed attempt. ``` #%PAM-1.0 auth optional /usr/lib/ahfail/libahfail_pam.so auth include system-auth ``` Fedora and RHEL use `/usr/lib64/ahfail/`, Debian and Ubuntu `/usr/lib/x86_64-linux-gnu/ahfail/`; the full path is required. Add `display_path=/path/to/ahfail-display` if the display binary lives elsewhere. The hook never starts the display from a root process (a display manager, for example), so it cannot affect a login screen. `bash scripts/uninstall-linux-x11.sh` removes the line and the files again. Pre-built binaries of the legacy files are on the [releases page](https://gitea.weircon.dk/agw/gtk-ahfail/releases). On swaylock and hyprlock the PAM hook fires, but the compositor hides everything except the locker itself, so only the audio plays. Use `ahfail` instead. --- ## Customization The sprite is the author's face on Nedry's body. To use your own: 1. Replace the sprite frames in `assets/` with your own PNG sequence. 2. Update `assets/ahfail.gresource.xml` if you add or remove files. 3. Rebuild with Meson. To replace the audio clip, swap `assets/magic-word.mp3` and rebuild. --- ## Development ```bash cargo test # unit + integration tests (some need a display) cargo test --test benchmarks -- --nocapture # sprite placement benchmarks cargo clippy # lint meson setup builddir && meson compile -C builddir # full build including the .so files xvfb-run meson test -C builddir --verbose # Meson tests headless ``` The update check (a daily look at the releases page with a desktop notification) is a cargo feature, `update-check`, on by default. Distro packages build without it, since the package manager handles updates there.