fix(hub): don't let password verification crash the System Passwords tile
The passwords update made the System Passwords tile the only tile whose credential resolution calls system_password.verify_system_password(). That loaded libcrypt with no error handling: an unloadable LIBCRYPT (e.g. a stale Nix store path) raised OSError through _resolve_credential(), so GET /api/service-detail/root-password-setup.service returned 500 and the Hub showed only 'Could not load service details.' Verification now fails closed, never fatal: _crypt() falls back through LIBCRYPT / find_library / libcrypt.so.1/.so.2, verify_system_password() returns False on any load or crypt failure, _resolve_credential() degrades that one credential to the 'Changed outside the Hub' hint instead of 500-ing the modal, and the login-time display-copy heal is best-effort. Adds tests/test_system_password.py regression tests.
This commit is contained in:
1 parent
07566c6a28
commit
e718404e84
3 files changed
+164
-11
No files matched your search
@@ -728,7 +728,10 @@ def _check_password(submitted: str) -> bool:
|
||||
proved (e.g. changed in GNOME Settings or the pre-upgrade Hub)."""
|
||||
if not sp.verify_system_password(submitted):
|
||||
return False
|
||||
sp.record_known_password(submitted, only_if_stale=True)
|
||||
try:
|
||||
sp.record_known_password(submitted, only_if_stale=True)
|
||||
except Exception as exc: # healing the display copy is best-effort
|
||||
logger.warning("Could not heal stale password display copy: %s", exc)
|
||||
return True
|
||||
|
||||
|
||||
@@ -1808,11 +1811,19 @@ def _resolve_credential(cred: dict) -> dict | None:
|
||||
# free/root login passwords: shown only if the display copy really is the
|
||||
# current one (system_password verifies it against /etc/shadow).
|
||||
if filepath in (sp.DISPLAY_FILE, sp.ROOT_DISPLAY_FILE):
|
||||
pw = (sp.read_display_password() if filepath == sp.DISPLAY_FILE
|
||||
else sp.read_root_display_password())
|
||||
try:
|
||||
pw = (sp.read_display_password() if filepath == sp.DISPLAY_FILE
|
||||
else sp.read_root_display_password())
|
||||
migration = sp.migration_pending() if pw is None else None
|
||||
except Exception as exc:
|
||||
# Never let one credential 500 the whole service-detail modal:
|
||||
# the System Passwords tile must still open and say the password
|
||||
# is unavailable instead of "Could not load service details."
|
||||
logger.warning("Could not resolve %s for display: %s", filepath, exc)
|
||||
pw, migration = None, None
|
||||
if pw is None:
|
||||
hint = ("Changed outside the Hub — finish the password step in onboarding to see it here."
|
||||
if sp.migration_pending() else
|
||||
if migration else
|
||||
"Changed outside the Hub — sign out and back in to show it here.")
|
||||
return {"label": label, "value": "", "unknown": True, "hint": hint}
|
||||
return {"label": label, "value": prefix + pw + suffix, "multiline": multiline}
|
||||
|
||||
Reference in new issue
Block a user