From 3b2f9946e5cf50f1f681a26b0c1474615938cb42 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 7 Jun 2026 03:00:18 +0000 Subject: [PATCH] setup: add enable-stoa-greetd.sh (tuigreet greeter with PAM keyring) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an alternative boot greeter that uses greetd + tuigreet themed in the Stoa palette. Because greetd opens a real PAM session, pam_gnome_keyring runs and unlocks the GNOME keyring with the login password — Brave and other libsecret clients no longer prompt for the keyring on first launch. The script is idempotent and reversible (--disable). Enabling it tears down the hyprlock-as-greeter wiring (autologin drop-in, .zprofile hooks) and comments out exec-once = hyprlock so the user isn't asked for the password twice on boot. --disable restores everything. README documents the new option alongside the existing Stoa Greeter and explains the trade-off (PAM session vs. graphical lockscreen). --- README.md | 30 ++++++ setup/enable-stoa-greetd.sh | 210 ++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100755 setup/enable-stoa-greetd.sh diff --git a/README.md b/README.md index b406397..2730a94 100644 --- a/README.md +++ b/README.md @@ -240,6 +240,36 @@ What it wires up: `post-install.sh` offers to run it interactively at the end. +### Stoa Greetd (alternative — unlocks the keyring on login) + +Same idea as the Stoa Greeter, but using `greetd` + `tuigreet` themed in +bronze on tty1. Because greetd opens a real PAM session, +`pam_gnome_keyring` runs and unlocks the GNOME keyring with the login +password — so Brave (and any other libsecret client) stops asking for +the keyring password the first time it opens. + +```bash +bash setup/enable-stoa-greetd.sh # enable +bash setup/enable-stoa-greetd.sh --disable # undo +``` + +What it wires up: + +- **`/etc/greetd/config.toml`** — `tuigreet --time --remember --asterisks --cmd Hyprland` themed in the Stoa palette +- **`/etc/pam.d/greetd`** — `pam_gnome_keyring.so` in both `auth` and `session` so the keyring destrava sozinho on every login +- **`greetd.service`** enabled on boot +- **Stoa Greeter teardown** — autologin drop-in and `.zprofile` / `.bash_profile` hooks are removed automatically (the two flows are mutually exclusive) +- **`exec-once = hyprlock`** in `hyprland.conf` is commented out (greetd already authenticated; locking again would force a double password). `--disable` restores it. + +Pick one or the other: + +| | Stoa Greeter (hyprlock) | Stoa Greetd (tuigreet) | +|---|---|---| +| Visual | hyprlock graphical lockscreen | TUI in tty1, bronze prompt | +| PAM session | no (auth only) | yes | +| Keyring unlocks on login | no | yes | +| Boot weight | lighter (autologin + lock) | a touch heavier (greetd daemon) | + ### System Resilience - **Package snapshots** — pacman pre-transaction hook saves `pacman -Q` before every install/upgrade/remove (`~/.config/stoa/pkg-snapshots/`, last 20, auto-rotates). Compare snapshots with current state to see exactly what changed. diff --git a/setup/enable-stoa-greetd.sh b/setup/enable-stoa-greetd.sh new file mode 100755 index 0000000..fd2f349 --- /dev/null +++ b/setup/enable-stoa-greetd.sh @@ -0,0 +1,210 @@ +#!/bin/bash +# ╔══════════════════════════════════════════════════════════════╗ +# ║ STOA LINUX — Enable Stoa Greetd (tuigreet + PAM keyring) ║ +# ║ "The form is the function." ║ +# ║ ║ +# ║ Replaces the hyprlock-as-greeter flow with a real PAM ║ +# ║ login via greetd + tuigreet, themed in the Stoa palette. ║ +# ║ Side effect: pam_gnome_keyring runs inside the PAM session, ║ +# ║ so the keyring (browser passwords, etc.) destrava sozinho. ║ +# ║ ║ +# ║ Wires: ║ +# ║ 1. /etc/greetd/config.toml — tuigreet bronze, exec ║ +# ║ Hyprland on successful auth ║ +# ║ 2. /etc/pam.d/greetd — pam_gnome_keyring auth + session ║ +# ║ 3. greetd.service enabled ║ +# ║ 4. Stoa autologin drop-in removed (if present) ║ +# ║ 5. Hyprland exec-once = hyprlock commented out (boot- ║ +# ║ lock is now greetd's job — uncommented on --disable). ║ +# ║ ║ +# ║ Idempotent. Re-run safely. Pass --disable to undo. ║ +# ╚══════════════════════════════════════════════════════════════╝ + +set -e + +STOA_DIR="$(cd "$(dirname "$0")/.." && pwd)" +TARGET_USER="${SUDO_USER:-$(whoami)}" + +# Colors +B='\033[38;2;196;154;92m' +S='\033[38;2;110;106;98m' +F='\033[38;2;212;207;196m' +O='\033[38;2;138;154;108m' +T='\033[38;2;179;107;90m' +R='\033[0m' + +# Stoa palette (mirrors theme/colors.sh) +BRONZE="#c49a5c" +GOLD="#d4a84b" +MARBLE="#d4cfc4" +STONE="#6e6a62" +BG="#211e19" + +GREETD_CONF="/etc/greetd/config.toml" +GREETD_PAM="/etc/pam.d/greetd" +DROPIN_FILE="/etc/systemd/system/getty@tty1.service.d/stoa-autologin.conf" +DROPIN_DIR="/etc/systemd/system/getty@tty1.service.d" +HYPR_CONF="${HOME}/.config/hypr/hyprland.conf" +PROFILE_MARK="# StoaLinux: autostart Hyprland on tty1" +PAM_MARK="# StoaLinux: pam_gnome_keyring (added by enable-stoa-greetd.sh)" +HYPR_MARK="# disabled by stoa-greetd" + +_unseed_profile() { + local rc="$1" + [ -f "$rc" ] || return 0 + if grep -q "stoa-autostart-hyprland" "$rc" 2>/dev/null; then + sed -i "/${PROFILE_MARK//\//\\/}/,+1d" "$rc" + echo -e " ${O}[✓] $(basename "$rc") snippet removed.${R}" + fi +} + +_disable_autologin() { + if [ -e "$DROPIN_FILE" ]; then + sudo rm -f "$DROPIN_FILE" + sudo rmdir "$DROPIN_DIR" 2>/dev/null || true + sudo systemctl daemon-reload + echo -e " ${O}[✓] Autologin drop-in removed.${R}" + fi +} + +_comment_hyprlock_exec_once() { + [ -f "$HYPR_CONF" ] || return 0 + if grep -qE "^exec-once = hyprlock\s*$" "$HYPR_CONF"; then + sed -i "s|^exec-once = hyprlock\s*$|# exec-once = hyprlock ${HYPR_MARK}|" "$HYPR_CONF" + echo -e " ${O}[✓] hyprland.conf: exec-once = hyprlock commented (greetd handles boot login).${R}" + fi +} + +_uncomment_hyprlock_exec_once() { + [ -f "$HYPR_CONF" ] || return 0 + if grep -qE "^# exec-once = hyprlock\s+${HYPR_MARK}" "$HYPR_CONF"; then + sed -i "s|^# exec-once = hyprlock\s\+${HYPR_MARK}|exec-once = hyprlock|" "$HYPR_CONF" + echo -e " ${O}[✓] hyprland.conf: exec-once = hyprlock restored.${R}" + fi +} + +_install_pkgs() { + local need=() + command -v greetd >/dev/null 2>&1 || need+=(greetd) + command -v tuigreet >/dev/null 2>&1 || need+=(greetd-tuigreet) + # gnome-keyring is the package; pam_gnome_keyring.so ships with it + [ -f /usr/lib/security/pam_gnome_keyring.so ] || need+=(gnome-keyring libsecret) + if [ ${#need[@]} -gt 0 ]; then + echo -e " ${F}Installing: ${need[*]}${R}" + sudo pacman -S --needed --noconfirm "${need[@]}" + fi +} + +_write_greetd_conf() { + local theme="border=${BRONZE};text=${MARBLE};prompt=${BRONZE};time=${GOLD};container=${BG};greet=${MARBLE};input=${MARBLE};action=${GOLD};button=${BRONZE}" + sudo mkdir -p "$(dirname "$GREETD_CONF")" + sudo tee "$GREETD_CONF" >/dev/null </dev/null; then + echo -e " ${S}[~] /etc/pam.d/greetd already wired for gnome-keyring.${R}" + return + fi + + # If the file doesn't exist, write a minimal stack that includes system-login + # plus the keyring hooks. If it exists, append our two lines at the end. + if [ ! -f "$GREETD_PAM" ]; then + sudo tee "$GREETD_PAM" >/dev/null </dev/null </dev/null; then + # Strip our marker block (marker line + the next 2 lines). + sudo sed -i "/${PAM_MARK//\//\\/}/,+2d" "$GREETD_PAM" + echo -e " ${O}[✓] pam_gnome_keyring lines removed from ${GREETD_PAM}.${R}" + fi +} + +if [ "${1:-}" = "--disable" ]; then + echo "" + echo -e " ${B}╔══════════════════════════════════════════════════════╗${R}" + echo -e " ${B}║ Disabling Stoa Greetd ║${R}" + echo -e " ${B}╚══════════════════════════════════════════════════════╝${R}" + echo "" + sudo systemctl disable --now greetd.service 2>/dev/null || true + echo -e " ${O}[✓] greetd.service stopped and disabled.${R}" + _unwrite_greetd_pam + _uncomment_hyprlock_exec_once + echo "" + echo -e " ${F}Note:${R} ${S}${GREETD_CONF} kept on disk for reference.${R}" + echo -e " ${S}Re-enable with: ${F}bash ${STOA_DIR}/setup/enable-stoa-greetd.sh${R}" + echo -e " ${S}To go back to hyprlock-as-greeter (no PAM keyring):${R}" + echo -e " ${F}bash ${STOA_DIR}/setup/enable-stoa-greeter.sh${R}" + echo "" + exit 0 +fi + +echo "" +echo -e " ${B}╔══════════════════════════════════════════════════════╗${R}" +echo -e " ${B}║ Enabling Stoa Greetd ║${R}" +echo -e " ${B}║ greetd → tuigreet (bronze) → PAM → Hyprland ║${R}" +echo -e " ${B}╚══════════════════════════════════════════════════════╝${R}" +echo "" + +if ! command -v Hyprland >/dev/null 2>&1; then + echo -e " ${T}[!] Hyprland not found in PATH. Install it before enabling greetd.${R}" + exit 1 +fi + +_install_pkgs + +# Tear down the hyprlock-as-greeter wiring if it's currently active — +# the two flows are mutually exclusive (both fight over tty1). +_disable_autologin +_unseed_profile "$HOME/.zprofile" +_unseed_profile "$HOME/.bash_profile" + +_write_greetd_conf +_write_greetd_pam +_comment_hyprlock_exec_once + +sudo systemctl enable --now greetd.service +echo -e " ${O}[✓] greetd.service enabled.${R}" + +echo "" +echo -e " ${F}Done. On next boot:${R}" +echo -e " ${S}1. greetd renders tuigreet in Stoa bronze on tty1${R}" +echo -e " ${S}2. you type your password — PAM authenticates the session${R}" +echo -e " ${S}3. pam_gnome_keyring unlocks the keyring with that password${R}" +echo -e " ${S}4. Hyprland starts; browsers stop asking for the keyring${R}" +echo "" +echo -e " ${S}To undo: ${F}bash ${STOA_DIR}/setup/enable-stoa-greetd.sh --disable${R}" +echo ""