Files
latchd/CHANGELOG.md

129 lines
9.5 KiB
Markdown

# Changelog
## Unreleased
- Preview mode now loads `$XDG_CONFIG_HOME/latchd/config.toml` or
`~/.config/latchd/config.toml` when no `--config` path is set.
- Added `make install-user` to create a user configuration without replacing
an existing file.
- Added Docker PTY screenshots and a short UI guide.
- Fixed Wayland compositors launched through user services, including Niri, by
providing the selected session type, desktop, seat, and VT to PAM before
`pam_open_session`.
- Session children now receive allowlisted runtime values produced by PAM,
including the real logind session ID, runtime directory, and user D-Bus
address. Latchd no longer fabricates `XDG_SESSION_ID=latchd`.
- Extended the disposable PAM fixture to verify both sides of the handoff:
selected session metadata entering PAM and PAM-generated values reaching the
session child.
## 0.5.0 — PAM password policy flow
- Added PAM password-change handling for accounts that return
`PAM_NEW_AUTHTOK_REQD` or `PAM_AUTHTOK_EXPIRED` during login.
- Added an explicit TUI new-password state. PAM still enforces password
history, strength, and token policy; the login screen never implements its
own password rules.
- Added zeroizing old/new password buffers and conversation tests for the
current-password/new-password prompt sequence.
- Added redacted structured audit events for authentication, password changes,
and session handoff. Raw PAM messages and password material are excluded.
- Added TUI, core, and preference tests; the workspace now contains 37
Rust unit tests.
- Added bounded, atomic last-session preferences per account with owner-only
file permissions and a safe fallback when the state file is unavailable.
- Added disposable PAM deny-policy fault-injection tests. Docker runs them as
root; ordinary host runs skip them without touching the host PAM policy.
## 0.4.0 — Advanced login workflow
- Added account policy inspection for locked passwords, password expiry,
account expiry, inactivity, and missing shadow data without exposing hashes.
- Added active UTMPX session discovery and systemd-logind capability detection
with an explicit UTMPX fallback.
- Improved faillock parsing for legacy, username-prefixed, and timestamped
helper output. PAM remains authoritative for every login decision.
- Added smart-case filtering for users and sessions, non-blocking Ctrl-R discovery
refresh, contextual footer hints, high-contrast mode, and policy notices in
the TUI.
- Added bounded local authentication backoff after repeated failures and reset
it when switching accounts.
- Added CLI integration tests and host capability probes. Docker now runs the
release binary through the safe CLI and capability suites.
- Added documented strict VM validation for PAM policy, VT, X11, Wayland, and
systemd-logind; missing capabilities are reported as skips in ordinary CI.
- Bumped the workspace release version to 0.4.0.
## 0.3.0 — Rust workspace release preparation
- Rust is the supported login manager; the Go/cgo prototype is quarantined at
`legacy/go/` and excluded from normal builds and release archives.
- Added workspace crates for PAM authentication, session/config/account
management, and the TUI, including account switching and advisory faillock.
- Added optional terminal-cell wallpapers, cellular automata effects, and
accessible motion/background controls.
- Added GitLab CI verification, version-checked tag releases, optimized
single-version Cargo builds, deterministic installation archives, SHA-256
checksums, and embedded build metadata.
- Live VT, logind, PAM-policy, X11, and Wayland validation remains a deployment
requirement on an isolated VM or target host.
## Legacy Go history (not the Rust release)
## 0.1.0 — Unreleased
first public release
### What's In
- tui login screen with username/password fields, session switcher, and status messages
- supports x11, wayland, and tty sessions
- pam authentication via cgo (thread-locked for safety)
- faillock integration — detects lockouts, shows remaining attempts, admin bypass via ctrl+u
- conway's game of life background rendered at 30 fps with unicode half-block characters
- spring animation on switcher transitions
- shake animation on failed login
- caps lock indicator via ioctl
- configurable power controls (shutdown/reboot on f1/f2 by default)
- toml configuration with `$VARIABLE` substitution
- preview mode (`--preview`) to test the login screen without leaving your session
- utmpx user accounting (glibc only)
- x11 session setup — xauthority cookies, sigusr1 handshake, server timeout
- privilege dropping for child processes
- log piping with 64 mb cap
### Recent Fixes
- **DesktopNames parsing** — `.desktop` files now parse the `DesktopNames` field. the first semicolon-delimited entry becomes `XDG_SESSION_DESKTOP`, and the full list with `:` separators becomes `XDG_CURRENT_DESKTOP`. fixes GNOME/KDE sessions not getting proper environment variables
- **utmpx accounting wired** — `AddUtmpx` and `Close` are now called from `spawnSession` so user logins appear in `who`/`w`/`last`
- **fixed hardcoded shell** — `Credentials.Shell` now reads from `/etc/passwd` instead of always returning `/bin/sh`. removes duplicate `userShell` logic in exec.go
- **automata background wired** — `Automata.Frame()` is now rendered in `View()` as the base layer with the login form card overlaid using ANSI cursor positioning. the form has a dark card background for readability
- **clock widget** — added a datetime display (`Mon Jan 02 15:04:05`) to the top bar, updated every tick
- **session specifier label** — the environment switcher now shows the session type (`x11`, `wayland`) above the session name, like ly's specifier
- **form card background** — login content is rendered inside a padded card with a dark background so it reads cleanly over the animated automata
- **utmpx time field portability** — replaced hardcoded `C.__uint32_t` / `C.__int32_t` casts with a C helper function (`auth/utmpx_time.h`) that lets the compiler handle type conversion. fixes build failure on systems where `ut_tv` uses `struct timeval` instead of the 32/64 compat struct
- **cgo pointer safety for pam** — replaced `unsafe.Pointer(&h)` (Go stack pointer passed to C) with `storeHandle`/`loadHandle` helpers that keep the `cgo.Handle` in C-heap memory. fixes `cgo argument has Go pointer to unpinned Go pointer` panic on Go 1.22+
- **pam conversation callback** — fixed `unsafe.Slice` using `&r` (pointer-to-pointer) as the backing array instead of `r` (the calloc'd response array), which wrote password bytes into random stack memory. also now only responds to `PAM_PROMPT_ECHO_OFF`/`PAM_PROMPT_ECHO_ON` messages — info and error messages get nil. fixes `pam_unix: auth could not identify password`
- **cgo handle lifecycle** — moved `cgo.Handle` and its C-heap backing from `Validate` (where they were `defer`-freed on return) into the `Credentials` struct so they stay alive through `OpenSession` and until `CloseSession`. fixes `misuse of an invalid Handle` panic
- **session spawning** — replaced the broken `ForkExec` (which relaunched the same binary with made-up flags) with a direct `session.Spawn` call that drops privileges and runs the desktop in-process. fixes `flag provided but not defined: -user`
- **renamed extra/ files** — `lemurs.pam` → `latchd.pam`, `lemurs.service` → `latchd.service`
- **readme credits** — added a credits section acknowledging lemurs for the `extra/` directory structure and session scanning approach
- **makefile `enable` and `update` targets** — `make enable` stops any running DM, disables the aliased display-manager, and enables latchd. `make update` runs uninstall → git pull → reinstall in one command
- **missing `extra/` directory** — added `extra/config.toml`, `extra/xsetup.sh`, `extra/lemurs.pam`, and `extra/lemurs.service` so `make install` can find them
- **makefile `deps` target** — added `make deps` to automatically install `libpam0g-dev` and `build-essential`, and verify go is present
- **readme overhaul** — rewrote for clarity: added "what problem does this solve", "how it works", known issues, simpler install instructions, and proper dependency listing
- **view cleanup** — removed the non-functional automata background overlay from `View()` (the `Frame()` was never called, and the black-space placeholder caused `EEEE` garbage characters on some terminals). also removed a hardcoded 80-char width on the top bar so it adapts to the terminal
- **session environment setup** — `spawnSession` now calls `SetBasicVariables`, `SetDisplay`, `SetSessionParams`, `SetSeatVars`, `SetSessionVars`, and `SetXDGCommonPaths` before spawning the desktop. fixes `setupX` failing immediately with `missing DISPLAY/XDG_VTNR/HOME env vars` because none were set
- **pam session error made non-fatal** — `pam_open_session` failure (e.g. `pam_systemd` rejecting the DM process as session leader) is now logged as a warning instead of blocking the entire session spawn. also removed `session include login` from `latchd.pam` since the DM process can't register user sessions with systemd-logind
- **global session switching with `,` and `.`** — sessions can now be switched from any mode (not just when the switcher is focused). arrows still work when switcher is focused
### What's Missing
- no tests
- session leader is the latchd process, not the desktop — pam session tracking via systemd-logind may be imperfect
- not all config options affect the rendering yet
- occasional terminal state corruption on abrupt exit
- automata background visible at screen edges; form card covers the center