108 lines
5 KiB
Shell
108 lines
5 KiB
Shell
|
|
#!/usr/bin/env bash
|
||
|
|
# deploy-secrets-phone.sh — make souveraine-secrets the Pixel 3's Secret
|
||
|
|
# Service, replacing gnome-keyring's secrets component.
|
||
|
|
#
|
||
|
|
# Idempotent: every step converges to the same state fresh or re-run. The
|
||
|
|
# binary is cross-built on archdev (never this laptop) by
|
||
|
|
# SOUVERAINE_AARCH64_SYSROOT=~/aarch64-sysroot ./scripts/build-cross.sh \
|
||
|
|
# --features secrets --bin souveraine-secrets
|
||
|
|
# and pulled from there unless SECRETS_BIN points at a local copy.
|
||
|
|
#
|
||
|
|
# What "replace" means here, precisely:
|
||
|
|
# * our binary in /usr/local/bin, our user unit in /etc/systemd/user,
|
||
|
|
# enabled at default.target — the name is claimed at login, before any
|
||
|
|
# client asks;
|
||
|
|
# * a D-Bus activation file in /usr/local/share/dbus-1/services shadows
|
||
|
|
# gnome-keyring's copy in /usr/share (XDG_DATA_DIRS order, verified on
|
||
|
|
# the phone) for on-demand activation;
|
||
|
|
# * gnome-keyring-daemon.{service,socket} masked, its autostart entries
|
||
|
|
# hidden per-user — pacman-owned files in /usr/share are never touched,
|
||
|
|
# so a gnome-keyring package upgrade cannot resurrect it.
|
||
|
|
#
|
||
|
|
# Verified at the end with a live secret-tool round-trip against the running
|
||
|
|
# provider; the script fails loudly if the name is owned by anything else.
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
cd "$(dirname "$0")/.."
|
||
|
|
|
||
|
|
SSH=(ssh -F /dev/null -i "$HOME/.ssh/ani" -o BatchMode=yes -o ConnectTimeout=5)
|
||
|
|
SCP=(scp -F /dev/null -i "$HOME/.ssh/ani" -o BatchMode=yes)
|
||
|
|
USB_IP=172.16.42.1
|
||
|
|
WIFI_IP=10.10.20.154
|
||
|
|
ARCHDEV="${ARCHDEV:-casey@10.10.20.123}"
|
||
|
|
ARCHDEV_BIN="Projects/souveraine/target/aarch64-unknown-linux-gnu/release/souveraine-secrets"
|
||
|
|
LOCAL_CACHE="target/phone/souveraine-secrets"
|
||
|
|
|
||
|
|
# --- binary: pull the archdev cross-build unless one was handed to us ---
|
||
|
|
BIN="${SECRETS_BIN:-}"
|
||
|
|
if [[ -z "$BIN" ]]; then
|
||
|
|
mkdir -p "$(dirname "$LOCAL_CACHE")"
|
||
|
|
echo "== pulling cross-built binary from $ARCHDEV =="
|
||
|
|
"${SCP[@]}" "$ARCHDEV:$ARCHDEV_BIN" "$LOCAL_CACHE"
|
||
|
|
BIN="$LOCAL_CACHE"
|
||
|
|
fi
|
||
|
|
file "$BIN" | grep -q aarch64 || { echo "$BIN is not an aarch64 binary" >&2; exit 1; }
|
||
|
|
|
||
|
|
# --- reach the phone ---
|
||
|
|
ip=""
|
||
|
|
for cand in "$USB_IP" "$WIFI_IP"; do
|
||
|
|
if ping -c1 -W1 "$cand" >/dev/null 2>&1; then ip="$cand"; break; fi
|
||
|
|
done
|
||
|
|
[[ -n "$ip" ]] || { echo "phone unreachable (tried $USB_IP, $WIFI_IP)" >&2; exit 1; }
|
||
|
|
PHONE="casey@$ip"
|
||
|
|
echo "== phone: $ip =="
|
||
|
|
|
||
|
|
# --- ship binary + units ---
|
||
|
|
"${SCP[@]}" "$BIN" "$PHONE:/tmp/souveraine-secrets-xdev"
|
||
|
|
"${SCP[@]}" packaging/souveraine-secrets.service "$PHONE:/tmp/souveraine-secrets.service"
|
||
|
|
"${SCP[@]}" packaging/org.freedesktop.secrets.service "$PHONE:/tmp/org.freedesktop.secrets.service"
|
||
|
|
|
||
|
|
"${SSH[@]}" "$PHONE" 'bash -s' <<'EOF'
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
sudo install -Dm755 /tmp/souveraine-secrets-xdev /usr/local/bin/souveraine-secrets
|
||
|
|
sudo install -Dm644 /tmp/souveraine-secrets.service /etc/systemd/user/souveraine-secrets.service
|
||
|
|
sudo install -Dm644 /tmp/org.freedesktop.secrets.service /usr/local/share/dbus-1/services/org.freedesktop.secrets.service
|
||
|
|
rm -f /tmp/souveraine-secrets-xdev /tmp/souveraine-secrets.service /tmp/org.freedesktop.secrets.service
|
||
|
|
|
||
|
|
# Retire gnome-keyring's secrets component: mask its units, hide its
|
||
|
|
# autostart entries per-user. /usr/share stays pacman's.
|
||
|
|
systemctl --user mask --now gnome-keyring-daemon.service gnome-keyring-daemon.socket >/dev/null 2>&1 || true
|
||
|
|
mkdir -p ~/.config/autostart
|
||
|
|
for entry in gnome-keyring-secrets gnome-keyring-pkcs11; do
|
||
|
|
printf '[Desktop Entry]\nType=Application\nName=%s (disabled: souveraine-secrets is the provider)\nHidden=true\n' \
|
||
|
|
"$entry" > ~/.config/autostart/$entry.desktop
|
||
|
|
done
|
||
|
|
|
||
|
|
# Stop any live gnome-keyring instances (dbus-activated transients included).
|
||
|
|
systemctl --user stop 'dbus-:*org.freedesktop.secrets*' >/dev/null 2>&1 || true
|
||
|
|
pkill -u "$(id -u)" -f gnome-keyring-daemon >/dev/null 2>&1 || true
|
||
|
|
|
||
|
|
systemctl --user daemon-reload
|
||
|
|
systemctl --user enable souveraine-secrets.service >/dev/null
|
||
|
|
systemctl --user restart souveraine-secrets.service
|
||
|
|
|
||
|
|
# --- verify: name ownership ---
|
||
|
|
sleep 1
|
||
|
|
owner_pid=$(busctl --user status org.freedesktop.secrets 2>/dev/null | awk -F= '/^PID=/{print $2}')
|
||
|
|
# /proc/<pid>/comm truncates to 15 chars → "souveraine-secr"
|
||
|
|
owner_comm=$(cat /proc/"$owner_pid"/comm 2>/dev/null || echo unknown)
|
||
|
|
if [[ "$owner_comm" != souveraine-secr* ]]; then
|
||
|
|
echo "FAIL: org.freedesktop.secrets is owned by '$owner_comm' (pid $owner_pid), not souveraine-secrets" >&2
|
||
|
|
systemctl --user status souveraine-secrets.service --no-pager | tail -20 >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
echo "== org.freedesktop.secrets owned by $owner_comm (pid $owner_pid) =="
|
||
|
|
|
||
|
|
# --- verify: live round-trip through the standard client ---
|
||
|
|
printf 'deploy-probe' | secret-tool store --label='souveraine deploy probe' app souveraine-deploy probe roundtrip
|
||
|
|
got=$(secret-tool lookup app souveraine-deploy probe roundtrip)
|
||
|
|
if [[ "$got" != "deploy-probe" ]]; then
|
||
|
|
echo "FAIL: secret-tool round-trip returned '$got'" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
secret-tool clear app souveraine-deploy probe roundtrip
|
||
|
|
echo "== secret-tool round-trip OK =="
|
||
|
|
EOF
|
||
|
|
|
||
|
|
echo "== deployed: souveraine-secrets is the phone's Secret Service =="
|