Commit Graph
17 Commits
Author SHA1 Message Date
nevaforget 0c9773123b fix: audit LOW fixes — docs, rustdoc, scope, debug gate, lto fat (v0.6.12)
- Update CLAUDE.md and README.md to reflect the blur range [0,200] that
  the code has clamped to since v0.6.8.
- Move the // SYNC: comment above the /// doc on MAX_BLUR_DIMENSION so
  rustdoc renders one coherent paragraph instead of a truncated sentence.
- Narrow check_account visibility to pub(crate) and document the caller
  precondition (username must come from users::get_current_user()).
- Gate MOONLOCK_DEBUG behind #[cfg(debug_assertions)]. Release builds
  always run at LevelFilter::Info so a session script cannot escalate
  journal verbosity to leak fprintd / D-Bus internals.
- Document why pam_setcred is deliberately not called in authenticate().
- Release profile: lto = "fat" instead of "thin" — doubles release build
  time for better cross-crate inlining on the auth + i18n hot paths.
2026-04-24 14:05:17 +02:00
nevaforget d0df3392da fix: audit MEDIUM fixes — D-Bus race, TOCTOU, FP reset, entry clear (v0.6.11)
- fingerprint: split cleanup_dbus into a sync take_cleanup_proxy() + async
  perform_dbus_cleanup(). resume_async now awaits VerifyStop+Release before
  re-claiming, so fprintd cannot reject the Claim on a slow bus. stop()
  still spawns the cleanup fire-and-forget.
- fingerprint: remove failed_attempts = 0 from resume_async. An attacker
  with sensor control could otherwise cycle verify-match → account-fail →
  resume and never trip the 10-attempt cap.
- lockscreen: open the wallpaper with O_NOFOLLOW and build the texture
  from bytes, closing the TOCTOU between the symlink check and Texture::
  from_file.
- lockscreen: clear password_entry immediately after extracting the
  Zeroizing<String>, shortening the window the GLib GString copy stays in
  libc-malloc'd memory.
2026-04-24 13:21:19 +02:00
nevaforget da7c713c6b fix: audit fixes — RefCell across await, async avatar decode (v0.6.10)
- init_fingerprint_async: hoist username before the await so a concurrent
  connect_monitor signal (hotplug / suspend-resume) cannot cause a RefCell
  panic. Re-borrow after the await for signal wiring.
- set_avatar_from_file: decode via gio::File::read_future +
  Pixbuf::from_stream_at_scale_future so the GTK main thread stays
  responsive during monitor hotplug. Default icon shown while loading.
2026-04-24 12:34:00 +02:00
nevaforget 4b3dbecd5c fix: audit fixes — peek icon, blur limit, GResource compression, sync markers (v0.6.8)
- Enable peek icon on password entry (consistent with moongreet)
- Raise blur limit from 100 to 200 (consistent with moongreet/moonset)
- Add compressed="true" to GResource CSS/SVG entries
- Add SYNC comments to duplicated blur/background functions
2026-03-31 11:08:36 +02:00
nevaforget 4d803f8469 fix: audit fixes — blur offset, lock-before-IO, FP signal lifecycle, TOCTOU (v0.6.6)
Third triple audit (quality, performance, security). Key fixes:
- Blur padding offset: texture at (-pad,-pad) prevents edge darkening on all sides
- Wallpaper loads after lock.lock() — disk I/O no longer delays lock acquisition
- begin_verification disconnects old signal handler before registering new one
- resume_async resets failed_attempts to prevent premature exhaustion
- Unknown VerifyStatus with done=true triggers restart instead of hanging
- symlink_metadata() replaces separate is_file()+is_symlink() (TOCTOU)
- faillock_warning dead code removed, blur sigma clamped to [0,100]
- Redundant Zeroizing<Vec<u8>> removed, on_verify_status restricted to pub(crate)
- Warn logging for non-UTF-8 GECOS and avatar path errors
- Default impl for FingerprintListener, 3 new tests (47 total)
2026-03-30 13:09:02 +02:00
nevaforget e83b5149bb fix: audit fixes — CString zeroize, FP account check, PAM timeout, blur downscale (v0.6.5)
Address findings from second triple audit (quality, performance, security):

- Wrap PAM CString password in Zeroizing<CString> to wipe on drop (S-H1)
- Add check_account() for pam_acct_mgmt after fingerprint unlock,
  with resume_async() to restart FP on transient failure (S-M1)
- 30s PAM timeout with generation counter to prevent stale result
  interference from parallel auth attempts (S-M3)
- Downscale wallpaper to max 1920px before GPU blur, reducing work
  by ~4x on 4K wallpapers (P-M1)
- exit(1) instead of return on no-monitor after lock.lock() (Q-2.1)
2026-03-30 00:24:43 +02:00
nevaforget 11e7cc438b fix: prevent edge darkening on GPU-blurred wallpaper (v0.6.3)
GskBlurNode samples pixels outside texture bounds as transparent,
causing visible darkening at wallpaper edges. Fix renders the texture
with 3x-sigma padding before blur, then clips back to original size.
Symmetric fix with moonset v0.7.1.
2026-03-28 23:28:40 +01:00
nevaforget c286a9e77e refactor: remove embedded wallpaper from binary (v0.6.2)
Wallpaper is installed by moonarch to /usr/share/moonarch/wallpaper.jpg.
Embedding a 374K JPEG in the binary was redundant. Without a wallpaper
file, GTK background color (Catppuccin Mocha base) shows through.
2026-03-28 23:23:02 +01:00
nevaforget ce6739d174 fix: audit fixes — D-Bus sender validation, fp lifecycle, multi-monitor caching (v0.6.0)
Close the only exploitable auth bypass: validate VerifyStatus signal sender
against fprintd's unique bus name. Fix fingerprint D-Bus lifecycle so devices
are properly released on verify-match and async restarts check the running
flag between awaits.

Security: num_msg guard in PAM callback, symlink rejection for background_path,
peek icon disabled, TOML parse errors logged, panic hook before logging.

Performance: blur and avatar textures cached across monitors, release profile
with LTO/strip.
2026-03-28 22:47:09 +01:00
nevaforget 44f0e0cec0 fix: audit fixes — double-unlock guard, PAM OOM code, GPU blur, async fp stop (v0.5.1)
Security: prevent double unlock() when PAM and fingerprint succeed
simultaneously (ext-session-lock protocol error). Fix PAM callback
returning PAM_AUTH_ERR instead of PAM_BUF_ERR on calloc OOM.

Performance: replace CPU-side Gaussian blur (image crate) with GPU blur
via GskBlurNode + GskRenderer::render_texture(). Eliminates 500ms-2s
main-thread blocking on cold cache for 4K wallpapers. Remove image and
dirs dependencies (~15 transitive crates). Make fingerprint stop()
fire-and-forget async to avoid 6s UI block after successful auth.
2026-03-28 22:06:38 +01:00
nevaforget 89a6a5c371 perf: cache blurred wallpaper to disk to avoid re-blur on startup
First launch with blur blurs and saves to ~/.cache/moonlock/.
Subsequent starts load the cached PNG directly. Cache invalidates
when wallpaper path, size, mtime, or sigma changes.
Adds dirs crate for cache directory resolution.
2026-03-28 21:23:43 +01:00
nevaforget 15ac79260d feat: add optional background blur, align to shared texture pattern
Gaussian blur applied at texture load time when `background_blur` is
set in moonlock.toml. Refactored wallpaper loading from per-window
Picture::for_filename() to shared gdk::Texture pattern (matching
moonset/moongreet), avoiding redundant JPEG decoding on multi-monitor.
2026-03-28 14:53:27 +01:00
nevaforget d59a1de076 fix: audit fixes — async restart_verify, locale caching, panic safety (v0.5.0)
- restart_verify() now async via spawn_future_local (was blocking main thread)
- stop() uses 3s timeout instead of unbounded
- load_strings() caches locale detection in OnceLock (was reading /etc/locale.conf on every call)
- child_get() replaced with child_value().get() for graceful D-Bus type mismatch handling
- Eliminate redundant password clone in auth path (direct move into spawn_blocking)
- Add on_exhausted callback: hides fp_label after MAX_FP_ATTEMPTS
- Set running=false before on_success callback (prevent double-unlock)
- Add 4 unit tests for on_verify_status state machine
- Document GLib-GString/CString zeroize limitation in CLAUDE.md
2026-03-28 10:16:06 +01:00
nevaforget bb48d38efb perf: async fprintd initialization for instant window display
Move all fprintd D-Bus calls (init, availability check, claim, verify)
from synchronous to async using gio futures. Windows now appear
immediately without waiting for D-Bus — fingerprint label fades in
once fprintd is ready. Single shared FingerprintListener across all
monitors instead of one per monitor.
2026-03-28 09:57:56 +01:00
nevaforget d2710ad0c5 fix: security and correctness audit fixes (v0.4.1)
PAM conv callback: check msg_style (password only for ECHO_OFF),
handle strdup OOM with proper cleanup, null-check PAM handle.

Fingerprint: self-wire D-Bus g-signal in start() via Rc<RefCell<>>
and connect_local — VerifyStatus signals are now actually dispatched.
VerifyStop before VerifyStart in restart_verify.

Lockscreen: password entry stays active after faillock threshold
(PAM decides lockout, not UI), use Zeroizing<String> from GTK entry.

Release builds exit(1) without ext-session-lock-v1 support.

Config: fingerprint_enabled as Option<bool> so empty user config
does not override system config.

Dead code: remove unused i18n strings and fingerprint accessors,
parameterize faillock_warning max_attempts.
2026-03-28 00:06:27 +01:00
nevaforget 9aa516f873 Fix Rust 2024 unsafe block warnings in PAM callback
Wrap raw pointer operations in explicit unsafe blocks inside
the unsafe extern "C" conv callback, as required by Rust 2024
edition. Remove unused mut binding.
2026-03-27 23:13:23 +01:00
nevaforget 09382b3bd2 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