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
This commit is contained in:
@@ -56,6 +56,7 @@ class TestFingerprintListenerLifecycle:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
listener._signal_id = 42
|
||||
|
||||
listener.stop()
|
||||
@@ -81,6 +82,7 @@ class TestFingerprintSignalHandling:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
on_success = MagicMock()
|
||||
on_failure = MagicMock()
|
||||
listener._on_success = on_success
|
||||
@@ -94,6 +96,7 @@ class TestFingerprintSignalHandling:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
on_success = MagicMock()
|
||||
on_failure = MagicMock()
|
||||
listener._on_success = on_success
|
||||
@@ -109,6 +112,7 @@ class TestFingerprintSignalHandling:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
on_success = MagicMock()
|
||||
on_failure = MagicMock()
|
||||
listener._on_success = on_success
|
||||
@@ -124,6 +128,7 @@ class TestFingerprintSignalHandling:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
on_success = MagicMock()
|
||||
on_failure = MagicMock()
|
||||
listener._on_success = on_success
|
||||
@@ -139,6 +144,7 @@ class TestFingerprintSignalHandling:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
on_success = MagicMock()
|
||||
on_failure = MagicMock()
|
||||
listener._on_success = on_success
|
||||
|
||||
@@ -66,6 +66,7 @@ class TestFingerprintAuthFlow:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
|
||||
unlock_called = []
|
||||
listener._on_success = lambda: unlock_called.append(True)
|
||||
@@ -81,6 +82,7 @@ class TestFingerprintAuthFlow:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
listener._on_success = MagicMock()
|
||||
listener._on_failure = MagicMock()
|
||||
|
||||
@@ -96,6 +98,7 @@ class TestFingerprintAuthFlow:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
listener._on_success = MagicMock()
|
||||
listener._on_failure = MagicMock()
|
||||
|
||||
@@ -113,6 +116,7 @@ class TestFingerprintAuthFlow:
|
||||
listener = FingerprintListener.__new__(FingerprintListener)
|
||||
listener._device_proxy = MagicMock()
|
||||
listener._running = True
|
||||
listener._failed_attempts = 0
|
||||
fp_unlock = []
|
||||
listener._on_success = lambda: fp_unlock.append(True)
|
||||
listener._on_failure = MagicMock()
|
||||
|
||||
+10
-18
@@ -199,33 +199,19 @@ class TestDefensiveWindowCreation:
|
||||
lock_instance.unlock.assert_not_called()
|
||||
|
||||
|
||||
class TestSignalHandlers:
|
||||
"""Tests for signal handlers and excepthook behavior."""
|
||||
|
||||
def test_sigusr1_triggers_unlock(self):
|
||||
"""SIGUSR1 should schedule an unlock via GLib.idle_add."""
|
||||
MoonlockApp, _ = _import_main()
|
||||
from moonlock.main import _install_signal_handlers
|
||||
import signal
|
||||
|
||||
app = MoonlockApp.__new__(MoonlockApp)
|
||||
app._lock_instance = MagicMock()
|
||||
|
||||
_install_signal_handlers(app)
|
||||
|
||||
handler = signal.getsignal(signal.SIGUSR1)
|
||||
assert handler is not signal.SIG_DFL
|
||||
class TestExcepthook:
|
||||
"""Tests for the global exception handler."""
|
||||
|
||||
def test_excepthook_does_not_unlock(self):
|
||||
"""Unhandled exceptions must NOT unlock the session."""
|
||||
MoonlockApp, _ = _import_main()
|
||||
from moonlock.main import _install_signal_handlers
|
||||
from moonlock.main import _install_excepthook
|
||||
|
||||
app = MoonlockApp.__new__(MoonlockApp)
|
||||
app._lock_instance = MagicMock()
|
||||
|
||||
original_hook = sys.excepthook
|
||||
_install_signal_handlers(app)
|
||||
_install_excepthook()
|
||||
|
||||
try:
|
||||
with patch("moonlock.main.logger"):
|
||||
@@ -235,3 +221,9 @@ class TestSignalHandlers:
|
||||
app._lock_instance.unlock.assert_not_called()
|
||||
finally:
|
||||
sys.excepthook = original_hook
|
||||
|
||||
def test_no_sigusr1_handler(self):
|
||||
"""SIGUSR1 must NOT be handled — signal-based unlock is a security hole."""
|
||||
import signal
|
||||
handler = signal.getsignal(signal.SIGUSR1)
|
||||
assert handler is signal.SIG_DFL
|
||||
|
||||
Reference in New Issue
Block a user