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:
committed by
GitHub
parent
953fb04671
commit
c450dcab9e
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|||||||
import asyncio
|
import asyncio
|
||||||
import base64
|
import base64
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import glob
|
||||||
import hashlib
|
import hashlib
|
||||||
import hmac
|
import hmac
|
||||||
import json
|
import json
|
||||||
@@ -2060,28 +2061,14 @@ async def api_migration_password_acknowledge():
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.warning("chpasswd exception during migration acknowledge: %s", exc)
|
logger.warning("chpasswd exception during migration acknowledge: %s", exc)
|
||||||
|
|
||||||
# Wipe the old keyring (encrypted with the pre-migration password) and
|
# Clear only the locked keyring databases, leaving the directory and 'default' pointer intact.
|
||||||
# seed the default pointer so PAM creates a fresh keyring on next login.
|
|
||||||
keyring_dir = "/home/free/.local/share/keyrings"
|
keyring_dir = "/home/free/.local/share/keyrings"
|
||||||
try:
|
keyring_files = glob.glob(os.path.join(keyring_dir, "*.keyring"))
|
||||||
if os.path.isdir(keyring_dir):
|
for kf in keyring_files:
|
||||||
for entry in os.listdir(keyring_dir):
|
try:
|
||||||
entry_path = os.path.join(keyring_dir, entry)
|
os.remove(kf)
|
||||||
try:
|
except OSError as exc:
|
||||||
if os.path.isfile(entry_path) or os.path.islink(entry_path):
|
logger.warning("Could not remove old keyring file %s: %s", kf, exc)
|
||||||
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)
|
|
||||||
|
|
||||||
# Clear the pending marker
|
# Clear the pending marker
|
||||||
try:
|
try:
|
||||||
@@ -3913,34 +3900,14 @@ async def api_security_reset():
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
errors.append(f"write root-password: {exc}")
|
errors.append(f"write root-password: {exc}")
|
||||||
|
|
||||||
# Delete GNOME Keyring files so a fresh keyring is created with the new
|
# Clear only the locked keyring databases, leaving the directory and 'default' pointer intact.
|
||||||
# password on the next GDM login (PAM unlocks it automatically).
|
|
||||||
keyring_dir = "/home/free/.local/share/keyrings"
|
keyring_dir = "/home/free/.local/share/keyrings"
|
||||||
try:
|
keyring_files = glob.glob(os.path.join(keyring_dir, "*.keyring"))
|
||||||
if os.path.isdir(keyring_dir):
|
for kf in keyring_files:
|
||||||
for entry in os.listdir(keyring_dir):
|
try:
|
||||||
entry_path = os.path.join(keyring_dir, entry)
|
os.remove(kf)
|
||||||
try:
|
except OSError as exc:
|
||||||
if os.path.isfile(entry_path) or os.path.islink(entry_path):
|
errors.append(f"keyring wipe: {kf}: {exc}")
|
||||||
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}")
|
|
||||||
|
|
||||||
# The user performed a full security reset — the banner's purpose is served.
|
# The user performed a full security reset — the banner's purpose is served.
|
||||||
try:
|
try:
|
||||||
@@ -4108,22 +4075,13 @@ async def api_change_password(req: ChangePasswordRequest):
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise HTTPException(status_code=500, detail=f"Failed to write secrets file: {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
|
# Clear only the locked keyring databases, leaving the directory and 'default' pointer intact.
|
||||||
# password on the next GDM login (PAM will unlock it automatically).
|
|
||||||
keyring_dir = "/home/free/.local/share/keyrings"
|
keyring_dir = "/home/free/.local/share/keyrings"
|
||||||
try:
|
for kf in glob.glob(os.path.join(keyring_dir, "*.keyring")):
|
||||||
if os.path.isdir(keyring_dir):
|
try:
|
||||||
for entry in os.listdir(keyring_dir):
|
os.remove(kf)
|
||||||
entry_path = os.path.join(keyring_dir, entry)
|
except OSError:
|
||||||
try:
|
pass # Non-fatal: keyring will be re-created on next login regardless
|
||||||
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
|
|
||||||
|
|
||||||
return {"ok": True}
|
return {"ok": True}
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,15 @@
|
|||||||
security.pam.services.gdm-password.enableGnomeKeyring = true;
|
security.pam.services.gdm-password.enableGnomeKeyring = true;
|
||||||
security.pam.services.gdm-autologin.enableGnomeKeyring = true;
|
security.pam.services.gdm-autologin.enableGnomeKeyring = true;
|
||||||
|
|
||||||
|
# Declaratively guarantee the GNOME Keyring default pointer exists.
|
||||||
|
# The 'f' directive creates the file only when it is absent, so legacy
|
||||||
|
# machines that already have a valid pointer are never overwritten.
|
||||||
|
# The content 'login' tells pam_gnome_keyring which keyring to unlock on login.
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /home/free/.local/share/keyrings 0700 free free -"
|
||||||
|
"f /home/free/.local/share/keyrings/default 0600 free free - login"
|
||||||
|
];
|
||||||
|
|
||||||
# ── Audio ──────────────────────────────────────────────────
|
# ── Audio ──────────────────────────────────────────────────
|
||||||
services.pulseaudio.enable = false;
|
services.pulseaudio.enable = false;
|
||||||
security.rtkit.enable = true;
|
security.rtkit.enable = true;
|
||||||
|
|||||||
+2
-13
@@ -33,10 +33,8 @@ let
|
|||||||
echo "$NEW_PASS" > "$SECRET_FILE"
|
echo "$NEW_PASS" > "$SECRET_FILE"
|
||||||
chmod 600 "$SECRET_FILE"
|
chmod 600 "$SECRET_FILE"
|
||||||
echo "Password for 'free' updated and saved."
|
echo "Password for 'free' updated and saved."
|
||||||
# Delete the old GNOME Keyring so it is recreated with the new password on next GDM login.
|
# Delete the old GNOME Keyring databases so a fresh one is created on next GDM login.
|
||||||
rm -rf /home/free/.local/share/keyrings/*
|
rm -f /home/free/.local/share/keyrings/*.keyring
|
||||||
# Recreate the default pointer so PAM knows which keyring to unlock.
|
|
||||||
su - free -c 'echo "login" > ~/.local/share/keyrings/default'
|
|
||||||
echo "GNOME Keyring files cleared — a fresh keyring will be created on next login."
|
echo "GNOME Keyring files cleared — a fresh keyring will be created on next login."
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
@@ -184,15 +182,6 @@ in
|
|||||||
echo "$FREE_PASS" > "$SECRET_FILE"
|
echo "$FREE_PASS" > "$SECRET_FILE"
|
||||||
chmod 600 "$SECRET_FILE"
|
chmod 600 "$SECRET_FILE"
|
||||||
echo "free:$FREE_PASS" | chpasswd
|
echo "free:$FREE_PASS" | chpasswd
|
||||||
# Seed the GNOME Keyring default pointer so PAM creates a fresh keyring
|
|
||||||
# on first login without prompting the user. Guard with -f so we never
|
|
||||||
# overwrite an existing pointer on legacy machines that already have one.
|
|
||||||
su - free -c '
|
|
||||||
mkdir -p ~/.local/share/keyrings
|
|
||||||
if [ ! -f ~/.local/share/keyrings/default ]; then
|
|
||||||
echo "login" > ~/.local/share/keyrings/default
|
|
||||||
fi
|
|
||||||
'
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user