Remove the Nyx persona block from CLAUDE.md and rewrite prior DECISIONS entries from Nyx and leftover Ragnar to ClaudeCode for consistency with the rest of the ecosystem.
4.2 KiB
4.2 KiB
Moonlock
Projekt
Moonlock ist ein sicherer Wayland-Lockscreen, gebaut mit Rust + gtk4-rs + ext-session-lock-v1. Teil des Moonarch-Ökosystems.
Tech-Stack
- Rust (Edition 2024), gtk4-rs 0.11, glib 0.22
- gtk4-session-lock 0.4 für ext-session-lock-v1 Protokoll
- PAM-Authentifizierung via Raw FFI (libc, libpam.so)
- fprintd D-Bus Integration (gio::DBusProxy) für Fingerabdruck-Unlock
- zeroize für sicheres Passwort-Wiping
cargo testfür Unit-Tests
Projektstruktur
src/— Rust-Quellcode (main.rs, lockscreen.rs, auth.rs, fingerprint.rs, config.rs, i18n.rs, users.rs, power.rs)resources/— GResource-Assets (style.css, default-avatar.svg)config/— PAM-Konfiguration und Beispiel-Config
Kommandos
# Tests ausführen
cargo test
# Release-Build
cargo build --release
# Lockscreen starten (zum Testen)
LD_PRELOAD=/usr/lib/libgtk4-layer-shell.so ./target/release/moonlock
Architektur
auth.rs— PAM-Authentifizierung via Raw FFI (unsafe extern "C" conv callback, msg_style-aware, Zeroizing), check_account() für pam_acct_mgmt-Only-Checks nach Fingerprint-Unlockfingerprint.rs— fprintd D-Bus Listener, async init/claim/verify via gio futures, sender-validated signal handler, cleanup_dbus() für sauberen D-Bus-Lifecycle, running_flag für Race-Safety in async restarts, on_exhausted callback after MAX_FP_ATTEMPTS, resume_async() für Neustart nach transientem Fehler (mit failed_attempts-Reset und Signal-Handler-Cleanup)users.rs— Aktuellen User via nix getuid, Avatar-Loading mit Symlink-Rejectionpower.rs— Reboot/Shutdown via /usr/bin/systemctli18n.rs— Locale-Erkennung (OnceLock-cached) und String-Tabellen (DE/EN), faillock_warning mit konfigurierbarem max_attemptsconfig.rs— TOML-Config (background_path, background_blur clamped [0,100], fingerprint_enabled als Option) + Wallpaper-Fallback + Symlink-Rejection via symlink_metadata + Parse-Error-Logginglockscreen.rs— GTK4 UI via LockscreenHandles, PAM-Auth via gio::spawn_blocking mit 30s Timeout und Generation Counter, FP-Label/Start separat verdrahtet mit pam_acct_mgmt-Check und auto-resume, Zeroizing für Passwort, Power-Confirm, GPU-Blur via GskBlurNode (Downscale auf max 1920px), Blur/Avatar-Cache für Multi-Monitormain.rs— Entry Point, Panic-Hook (vor Logging), Root-Check, ext-session-lock-v1 (Pflicht in Release), Monitor-Hotplug viaconnect_monitor-Signal (v1_2), shared Blur/Avatar-Caches in Rc, systemd-Journal-Logging, Debug-Level perMOONLOCK_DEBUGEnv-Var, async fprintd-Init nach window.present()
Sicherheit
- ext-session-lock-v1 garantiert: Compositor sperrt alle Surfaces bei lock()
- Release-Build: Ohne ext-session-lock-v1 wird
exit(1)aufgerufen — kein Fenster-Fallback - Panic-Hook: Bei Crash wird geloggt, aber NIEMALS unlock() aufgerufen — Screen bleibt schwarz. Hook wird vor Logging installiert.
- PAM-Callback: msg_style-aware (Passwort nur bei PAM_PROMPT_ECHO_OFF), strdup-OOM-sicher, num_msg-Guard gegen negative Werte
- fprintd: D-Bus Signal-Sender wird gegen fprintd's unique bus name validiert (Anti-Spoofing)
- Passwort: Zeroizing ab GTK-Entry-Extraktion, Zeroizing im PAM-FFI-Layer (bekannte Einschränkung: GLib-GString und strdup-Kopie in PAM werden nicht gezeroized — inhärente GTK/libc-Limitierung)
- Fingerprint-Unlock: pam_acct_mgmt-Check nach verify-match erzwingt Account-Policies (Lockout, Ablauf), resume_async() startet FP bei transientem Fehler neu (mit failed_attempts-Reset und Signal-Handler-Cleanup)
- Wallpaper wird vor lock() geladen — connect_monitor feuert während lock() und braucht die Textur; lokales JPEG-Laden ist schnell genug
- PAM-Timeout: 30s Timeout verhindert permanentes Aussperren bei hängenden PAM-Modulen, Generation Counter verhindert Interferenz paralleler Auth-Versuche
- Root-Check: Exit mit Fehler wenn als root gestartet
- Faillock: UI-Warnung nach 3 Fehlversuchen, aber PAM entscheidet über Lockout (Entry bleibt aktiv)
- Kein Schließen per Escape/Alt-F4 — nur durch erfolgreiche PAM-Auth oder Fingerprint
- Peek-Icon am Passwortfeld aktiv (UX-Entscheidung, konsistent mit moongreet)
- GResource-Bundle: CSS/Assets in der Binary kompiliert