23 Commits

Author SHA1 Message Date
817a9547ad Rewrite moonlock from Python to Rust (v0.4.0)
Complete rewrite of the Wayland lockscreen from Python/PyGObject to
Rust/gtk4-rs for memory safety in security-critical PAM code and
consistency with the moonset/moongreet Rust ecosystem.

Modules: main, lockscreen, auth (PAM FFI), fingerprint (fprintd D-Bus),
config, i18n, users, power. 37 unit tests.

Security: PAM conversation callback with Zeroizing password, panic hook
that never unlocks, root check, ext-session-lock-v1 compositor policy,
absolute loginctl path, avatar symlink rejection.
2026-03-27 23:09:54 +01:00
7de3737a61 Revert "feat: fade-in animation for panel and wallpaper windows"
This reverts commit 4a2bbb3e98adfeded7fa88332e60e1ab3e3b14b0.
2026-03-27 15:12:26 +01:00
4a2bbb3e98 feat: fade-in animation for panel and wallpaper windows
CSS opacity transition (350ms ease-in) triggered via adding
a 'visible' class after the window is mapped.
2026-03-27 14:45:10 +01:00
fe6421c582 Move power confirmation below fingerprint label with own text
Confirmation prompt is now a self-contained box (label + buttons)
appended at the bottom of the login box instead of reusing the
error label above the fingerprint text.
2026-03-26 22:18:58 +01:00
fb11c551bd Security hardening based on triple audit (security, quality, performance)
- Remove SIGUSR1 unlock handler (unauthenticated unlock vector)
- Sanitize LD_PRELOAD (discard inherited environment)
- Refuse to run as root
- Validate D-Bus signal sender against fprintd proxy owner
- Pass bytearray (not str) to PAM conversation callback for wipeable password
- Resolve libc before returning CFUNCTYPE callback
- Bundle fingerprint success idle_add into single atomic callback
- Add running/device_proxy guards to VerifyStart retries with error handling
- Add fingerprint attempt counter (max 10 before disabling)
- Add power button confirmation dialog (inline yes/cancel)
- Move fingerprint D-Bus init before session lock to avoid mainloop blocking
- Resolve wallpaper path once, share across all monitor windows
- Document faillock as UI-only (pam_faillock handles real brute-force protection)
- Fix type hints (Callable), remove dead import (c_char), fix import order
v0.3.0
2026-03-26 22:11:00 +01:00
5fda0dce0c Replace crash guard with SIGUSR1 unlock and crash logging
Remove sys.excepthook that unlocked on crash — this violated
ext-session-lock-v1 security model where the compositor must keep
the screen locked if the client dies (per protocol spec and hyprlock
reference). Now: crashes are logged but session stays locked.
SIGUSR1 handler added for external recovery (e.g. wrapper script).
v0.2.2
2026-03-26 21:11:42 +01:00
3f31387305 Add crash guard, logging, and defensive error handling to prevent lockout
Global sys.excepthook unlocks the session on unhandled exceptions.
Structured logging to stderr and optional file at /var/cache/moonlock/.
Window creation, CSS loading, and fingerprint start wrapped in
try/except with automatic session unlock when all windows fail.
v0.2.1
2026-03-26 17:56:45 +01:00
7cee4f4f8d Bump version to 0.2.0 v0.2.0 2026-03-26 16:31:20 +01:00
1ed42d51d1 Make login box background transparent v0.1.1 2026-03-26 16:31:01 +01:00
a05c2030e8 Clean dist/ before wheel build to prevent stale artifacts
Version bumps leave old wheels in dist/, causing the glob to
expand to multiple files and python-installer to fail.
2026-03-26 15:49:37 +01:00
22f725e4ac Bump version to 0.1.1 2026-03-26 15:44:37 +01:00
b8e060b850 Fix fprintd AlreadyInUse error by respecting done flag
VerifyStart was called unconditionally on retry/no-match statuses,
ignoring the done parameter from fprintd's VerifyStatus signal.
When done=False the verify session is still active, causing
AlreadyInUse errors. Now only restarts verification when done=True.
2026-03-26 15:43:27 +01:00
c759919367 Simplify pkgver() to require tags v0.1.0 2026-03-26 14:02:06 +01:00
9539d83c85 Fix pkgver() stdout leak in PKGBUILD 2026-03-26 14:00:16 +01:00
b365572033 Show login UI on all monitors for compositor-agnostic focus
Wayland does not expose absolute pointer coordinates to clients,
so we cannot reliably detect which monitor has focus. Instead,
show the full lockscreen UI on every monitor — the compositor
assigns keyboard focus to the surface under the pointer via
ext-session-lock-v1.

Share a single FingerprintListener across all windows to avoid
multiple device claims. Also add makepkg build artifacts to
gitignore.
2026-03-26 13:58:45 +01:00
0eefe76a3a Add PKGBUILD and remove stale moongreet icon
Add Arch Linux PKGBUILD for makepkg installation. Installs the
Python package, PAM config, and example config file. Fix pkgver()
to handle repos without tags (sed always exits 0 on empty input).

Remove leftover moongreet icon that was accidentally included in
the data directory.
2026-03-26 13:48:07 +01:00
e7ab4c2e73 Harden auth, user detection, faillock, and LD_PRELOAD handling
- Replace os.getlogin() with pwd.getpwuid(os.getuid()) to prevent
  crashes in systemd/display-manager sessions without a controlling tty
- Cache libpam and libc at module level instead of calling find_library()
  on every auth attempt (spawned ldconfig subprocess each time)
- Disable password entry permanently after FAILLOCK_MAX_ATTEMPTS instead
  of just showing a warning while allowing unlimited retries
- Fix LD_PRELOAD logic to append gtk4-layer-shell instead of skipping
  when LD_PRELOAD is already set (caused silent session lock fallback)
- Ensure password entry keeps focus after errors and escape
2026-03-26 13:35:26 +01:00
dd9937b020 Add wallpaper and default avatar support
Wallpaper with fallback hierarchy: config path > Moonarch system
default (/usr/share/moonarch/wallpaper.jpg) > package fallback.
Applied to both primary and secondary monitors.

Default avatar from Moongreet ecosystem with theme-colored SVG
rendering via PixbufLoader and proper clipping frame (Gtk.Box
with overflow hidden), matching the Moongreet avatar pattern.
2026-03-26 13:01:25 +01:00
d0d390d0cb Fix PAM conversation segfault causing unrecoverable red lockscreen
ctypes auto-converts c_char_p return values to Python bytes, losing
the original malloc'd pointer from strdup(). When PAM called free()
on the response, it hit a ctypes-internal buffer instead — segfault.
Use c_void_p for PamResponse.resp and strdup restype to preserve raw
pointers. Also use calloc/strdup for proper malloc'd memory that PAM
can safely free().

Add try/except in auth thread so UI stays interactive on PAM errors.
2026-03-26 12:43:53 +01:00
db05df36d4 Add security hardening, config system, and integration tests
- Password wiping after PAM auth (bytearray zeroed)
- TOML config loading (/etc/moonlock/ and ~/.config/moonlock/)
- Config controls fingerprint_enabled and background_path
- Integration tests for password/fingerprint auth flows
- Security tests for bypass prevention and data cleanup
- 51 tests passing
2026-03-26 12:36:58 +01:00
dd4ef6aa1c Fix GTK4 API issues and auto-preload gtk4-layer-shell
- Use property setter for PasswordEntry placeholder text
- Remove unsupported max-width/max-height from CSS
- Set avatar size via set_size_request()
- Auto re-exec with LD_PRELOAD for gtk4-layer-shell linking order
2026-03-26 12:33:27 +01:00
0ee451de9e Add GTK4 lockscreen UI and ext-session-lock-v1 integration
Lockscreen window with avatar, password entry, fingerprint indicator,
power buttons. Session locking via Gtk4SessionLock (ext-session-lock-v1)
with multi-monitor support and dev fallback mode.
2026-03-26 12:29:38 +01:00
d1c0b741fa Initial project setup with core modules
Moonlock lockscreen scaffolding: PAM auth (ctypes), fprintd D-Bus
listener, i18n (DE/EN), user detection, power actions.
33 tests passing.
2026-03-26 12:28:17 +01:00