refactor: use systemd.tmpfiles for GNOME Keyring, simplify reset scripts

Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/71dab9c7-081f-4e45-80c2-080e88ae6207

Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-30 13:52:27 +00:00
committed by GitHub
parent 953fb04671
commit c450dcab9e
3 changed files with 32 additions and 76 deletions
+21 -63
View File
@@ -5,6 +5,7 @@ from __future__ import annotations
import asyncio
import base64
import contextlib
import glob
import hashlib
import hmac
import json
@@ -2060,28 +2061,14 @@ async def api_migration_password_acknowledge():
except Exception as exc:
logger.warning("chpasswd exception during migration acknowledge: %s", exc)
# Wipe the old keyring (encrypted with the pre-migration password) and
# seed the default pointer so PAM creates a fresh keyring on next login.
# Clear only the locked keyring databases, leaving the directory and 'default' pointer intact.
keyring_dir = "/home/free/.local/share/keyrings"
try:
if os.path.isdir(keyring_dir):
for entry in os.listdir(keyring_dir):
entry_path = os.path.join(keyring_dir, entry)
try:
if os.path.isfile(entry_path) or os.path.islink(entry_path):
os.unlink(entry_path)
elif os.path.isdir(entry_path):
shutil.rmtree(entry_path, ignore_errors=True)
except Exception:
pass
os.makedirs(keyring_dir, exist_ok=True)
default_file = os.path.join(keyring_dir, "default")
with open(default_file, "w") as f:
f.write("login\n")
free_pw = pwd.getpwnam("free")
os.chown(default_file, free_pw.pw_uid, free_pw.pw_gid)
except Exception as exc:
logger.warning("Keyring wipe exception during migration acknowledge: %s", exc)
keyring_files = glob.glob(os.path.join(keyring_dir, "*.keyring"))
for kf in keyring_files:
try:
os.remove(kf)
except OSError as exc:
logger.warning("Could not remove old keyring file %s: %s", kf, exc)
# Clear the pending marker
try:
@@ -3913,34 +3900,14 @@ async def api_security_reset():
except Exception as exc:
errors.append(f"write root-password: {exc}")
# Delete GNOME Keyring files so a fresh keyring is created with the new
# password on the next GDM login (PAM unlocks it automatically).
# Clear only the locked keyring databases, leaving the directory and 'default' pointer intact.
keyring_dir = "/home/free/.local/share/keyrings"
try:
if os.path.isdir(keyring_dir):
for entry in os.listdir(keyring_dir):
entry_path = os.path.join(keyring_dir, entry)
try:
if os.path.isfile(entry_path) or os.path.islink(entry_path):
os.unlink(entry_path)
elif os.path.isdir(entry_path):
shutil.rmtree(entry_path, ignore_errors=True)
except Exception:
pass
except Exception as exc:
errors.append(f"keyring wipe: {exc}")
# Recreate the default pointer so pam_gnome_keyring knows which keyring to
# unlock on the next GDM login without prompting the user.
try:
os.makedirs(keyring_dir, exist_ok=True)
default_file = os.path.join(keyring_dir, "default")
with open(default_file, "w") as f:
f.write("login\n")
free_pw = pwd.getpwnam("free")
os.chown(default_file, free_pw.pw_uid, free_pw.pw_gid)
except Exception as exc:
errors.append(f"keyring default recreation: {exc}")
keyring_files = glob.glob(os.path.join(keyring_dir, "*.keyring"))
for kf in keyring_files:
try:
os.remove(kf)
except OSError as exc:
errors.append(f"keyring wipe: {kf}: {exc}")
# The user performed a full security reset — the banner's purpose is served.
try:
@@ -4108,22 +4075,13 @@ async def api_change_password(req: ChangePasswordRequest):
except Exception as exc:
raise HTTPException(status_code=500, detail=f"Failed to write secrets file: {exc}")
# Delete GNOME Keyring files so a fresh keyring is created with the new
# password on the next GDM login (PAM will unlock it automatically).
# Clear only the locked keyring databases, leaving the directory and 'default' pointer intact.
keyring_dir = "/home/free/.local/share/keyrings"
try:
if os.path.isdir(keyring_dir):
for entry in os.listdir(keyring_dir):
entry_path = os.path.join(keyring_dir, entry)
try:
if os.path.isfile(entry_path) or os.path.islink(entry_path):
os.unlink(entry_path)
elif os.path.isdir(entry_path):
shutil.rmtree(entry_path, ignore_errors=True)
except Exception:
pass
except Exception:
pass # Non-fatal: keyring will be re-created on next login regardless
for kf in glob.glob(os.path.join(keyring_dir, "*.keyring")):
try:
os.remove(kf)
except OSError:
pass # Non-fatal: keyring will be re-created on next login regardless
return {"ok": True}