Files
latchd/README.md

6.2 KiB
Raw Blame History

latchd

Want a TUI-based login manager because you are tired of GDM or Plasma Login? Latchd gives you a small, keyboard-first login screen on a Linux virtual terminal. It uses PAM for authentication and can start a TTY shell, an X11 desktop, or a Wayland desktop.

Latchd is written in Rust. The old Go prototype is kept in legacy/go/ for reference and is not built or shipped.

What it does

  • Finds normal login accounts through NSS.
  • Shows password, account-expiry, locked-account, and faillock status without replacing PAM's decision.
  • Runs PAM password changes for accounts that require a new password before login.
  • Lets you switch users and sessions without leaving the login screen.
  • Finds X11 and Wayland desktop entries and can include a TTY shell.
  • Starts sessions with a cleared, explicit environment and drops privileges before running the user process.
  • Records user sessions with UTMPX when the platform provides it.
  • Provides a Ratatui TUI with filtering, keyboard help, refresh, notifications, wallpaper, and reduced-motion support.
  • Runs safely in preview mode for UI work and configuration checks.

The real login handoff still needs a Linux system with PAM, a virtual terminal, and the display/session services you want to use. The Docker tests cover builds, unit tests, rendering, configuration, and capability probes; they do not pretend to be a real VT or systemd-logind session.

Build

On Debian or Ubuntu, install the build dependencies first:

sudo apt-get install build-essential pkg-config libpam0g-dev libpam-modules

Then run:

make check
make docker-test
make integration-test

make build writes the optimized binary to build/latchd. make package creates a deterministic archive and SHA-256 file in dist/.

Try the UI

Preview mode does not call PAM, start a session, or run power actions:

make run-preview
# or
./build/latchd --preview --no-log

Use LATCHD_ASCII=1 for terminals without reliable Unicode support, NO_COLOR=1 for monochrome output, and LATCHD_HIGH_CONTRAST=1 for a stronger focus palette.

Install on a test machine

Do this on a disposable machine first. Keep another login path available while changing a display manager.

sudo make install
sudo systemctl enable latchd.service

This installs:

  • /usr/bin/latchd
  • /etc/latchd/config.toml
  • /etc/pam.d/latchd
  • /usr/lib/systemd/system/latchd.service

The default service owns /dev/tty2. Change the tty setting and the unit's TTYPath together when using another virtual terminal.

Configuration

The complete example is in extra/config.toml. Important sections are:

  • [accounts] controls NSS discovery, the faillock helper, faillock policy, and /etc/shadow account-age checks.
  • [x11] and [wayland] select desktop-entry and administrator script directories.
  • [environment_switcher] controls session choices and the optional TTY shell.
  • [visual] controls wallpaper size, animation, notifications, and reduced motion.
  • [power_controls] contains absolute program paths and argv arrays. Commands are never passed through a shell.

Configuration files used by a real root service must be root-owned and not writable by group or other users. Use a variables file for deployment-specific values instead of putting secrets in command arguments.

Controls

Key Action
Tab / Shift-Tab Move focus
Up / Down Move focus or move in a filtered list
Left / Right Change the selected session
/ Filter sessions or discovered accounts
Ctrl-R Refresh account and session discovery
Ctrl-N / Ctrl-P Select the next or previous account
Ctrl-B Toggle wallpaper and ambient effects
Ctrl-M Toggle reduced motion
Enter Authenticate, or submit a PAM password change when requested
Esc Clear the password or close a popup
? Show keyboard help
Ctrl-C Restore the terminal and quit
F1–F12 Confirm a configured power action

The filter is smart-case: lowercase searches ignore case; a search containing uppercase characters is case-sensitive. The account-age and faillock messages are advisory. PAM remains the only authorization decision.

Testing a deployment

The ordinary tests do not need a privileged container:

make check
make audit
make docker-test
make integration-test
make system-e2e

make system-e2e reports real host capabilities as PASS, SKIP, or FAIL. It does not call an account password or claim that a pseudo-terminal is a virtual terminal. make system-e2e-strict is for a prepared disposable VM with a test PAM policy, a real VT, systemd-logind, and the X11 or Wayland stack under test. See docs/e2e-testing.md.

Security notes

  • PAM handles stay on one worker thread.
  • Password buffers are zeroized and never placed in argv, logs, or the TUI.
  • Security audit events contain only the account name and stable outcome/reason fields; PAM's free-form error text and password material are not logged.
  • Session environments are rebuilt from an allowlist.
  • Desktop files, scripts, binaries, homes, logs, and configuration sources are checked before use.
  • Xauthority files and session logs use private permissions and cleanup guards.
  • Power actions require confirmation and are disabled in preview mode.
  • Account status and faillock output never bypass PAM or provide an administrator unlock shortcut.

Project layout

crates/latchd-core/  configuration, account discovery, sessions, UTMPX
crates/latchd-auth/  PAM FFI, password changes, and the authentication worker
crates/latchd-tui/   Ratatui state, rendering, filtering, and effects
rust/main.rs         command-line entry point and service orchestration
extra/               example configuration, PAM policy, and systemd unit
scripts/             Docker and CLI/system capability tests
legacy/go/           non-production Go reference

Releases

GitLab CI runs formatting, tests, Clippy, rustdoc, RustSec auditing, CLI integration tests, capability probes, and the Docker suite. SemVer tags produce a reproducible Linux archive with checksums. Live VT, PAM-policy, X11, Wayland, and logind validation belongs in the isolated VM gate described above.

License

Apache-2.0. See LICENSE.