working login
This commit is contained in:
parent
36a53f343e
commit
21859bcfb3
1 changed files with 260 additions and 1 deletions
107
unity-ssh.sh
Executable file
107
unity-ssh.sh
Executable file
|
|
@ -0,0 +1,107 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
unity_cli="${UNITY_CLI:-$HOME/.local/bin/unity}"
|
||||
if [[ ! -x "$unity_cli" ]]; then
|
||||
echo "Set UNITY_CLI to the installed Unity CLI executable." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Always use a private bus, including when SSH inherited a desktop bus.
|
||||
if [[ "${1:-}" != --keyring-session ]]; then
|
||||
exec dbus-run-session -- bash "$0" --keyring-session "$@"
|
||||
fi
|
||||
shift
|
||||
unset GNOME_KEYRING_CONTROL
|
||||
|
||||
# Give Unity its own credential collection. Do not read or modify the user's
|
||||
# desktop login.keyring, which may be locked, damaged, or in use elsewhere.
|
||||
keyring_data_dir="${UNITY_SSH_KEYRING_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/unity-ssh}"
|
||||
umask 077
|
||||
mkdir -p "$keyring_data_dir"
|
||||
exec 9>"$keyring_data_dir/session.lock"
|
||||
if ! flock -n 9; then
|
||||
echo "A Unity SSH keyring session is already open. Exit it before starting another." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -r -s -p "Unity keyring password (choose one on first use): " unity_keyring_password
|
||||
echo
|
||||
if [[ -z "$unity_keyring_password" ]]; then
|
||||
echo "A nonempty password is required for the encrypted keyring." >&2
|
||||
exit 1
|
||||
fi
|
||||
runtime_dir="$(mktemp -d "${TMPDIR:-/tmp}/unity-keyring.XXXXXX")"
|
||||
daemon_pid=""
|
||||
cleanup() {
|
||||
if [[ -n "$daemon_pid" ]]; then
|
||||
kill "$daemon_pid" 2>/dev/null || true
|
||||
wait "$daemon_pid" 2>/dev/null || true
|
||||
fi
|
||||
rm -rf -- "$runtime_dir"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
trap 'exit 130' INT
|
||||
trap 'exit 143' TERM
|
||||
|
||||
# Keep the daemon on this bus, wait for it to register, and stop it on exit.
|
||||
# Only the daemon sees the alternate data directory; Unity keeps its normal
|
||||
# configuration and license-file locations.
|
||||
XDG_DATA_HOME="$keyring_data_dir" gnome-keyring-daemon \
|
||||
--foreground --unlock --components=secrets --control-directory="$runtime_dir" \
|
||||
< <(printf '%s' "$unity_keyring_password") >"$runtime_dir/daemon.log" 2>&1 &
|
||||
daemon_pid=$!
|
||||
unset unity_keyring_password
|
||||
|
||||
owner='(false,)'
|
||||
for (( attempt=0; attempt<100; attempt++ )); do
|
||||
owner="$(gdbus call --session --dest org.freedesktop.DBus \
|
||||
--object-path /org/freedesktop/DBus \
|
||||
--method org.freedesktop.DBus.NameHasOwner org.freedesktop.secrets)"
|
||||
[[ "$owner" != '(true,)' ]] || break
|
||||
kill -0 "$daemon_pid" 2>/dev/null || break
|
||||
sleep 0.1
|
||||
done
|
||||
if [[ "$owner" != '(true,)' ]]; then
|
||||
echo "The Unity keyring service did not start." >&2
|
||||
cat "$runtime_dir/daemon.log" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
locked="$(gdbus call --session --dest org.freedesktop.secrets \
|
||||
--object-path /org/freedesktop/secrets/collection/login \
|
||||
--method org.freedesktop.DBus.Properties.Get org.freedesktop.Secret.Collection Locked 2>/dev/null)" || locked='missing'
|
||||
if [[ "$locked" != '(<false>,)' ]]; then
|
||||
echo "Could not unlock the Unity keyring at $keyring_data_dir/keyrings." >&2
|
||||
echo "Use the password chosen for this helper. No credential files were removed." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check persistence before asking the user to complete a browser sign-in.
|
||||
probe="unity-ssh-$$-$RANDOM"
|
||||
printf '%s' "$probe" | timeout 10 secret-tool store --label='Unity SSH keyring check' unity-ssh-check "$probe"
|
||||
saved="$(timeout 10 secret-tool lookup unity-ssh-check "$probe")"
|
||||
timeout 10 secret-tool clear unity-ssh-check "$probe"
|
||||
if [[ "$saved" != "$probe" ]]; then
|
||||
echo "The Unity keyring could not save and retrieve a test credential." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Unity keyring storage check passed."
|
||||
|
||||
export PATH="$(dirname -- "$unity_cli"):$PATH"
|
||||
export UNITY_NO_CLI_INVOKED_TELEMETRY=1
|
||||
if [[ "${1:-}" == --check ]]; then
|
||||
exit 0
|
||||
fi
|
||||
if (( $# )); then
|
||||
"$unity_cli" "$@"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
echo "Unity login shell ready. Run: unity auth login"
|
||||
echo "Open the printed sign-in URL in your own computer's browser."
|
||||
echo "After signing in and reviewing the Personal terms, run:"
|
||||
echo " unity license activate --personal --accept-eula"
|
||||
echo " unity license status"
|
||||
echo "Type exit to close this shell and its keyring session."
|
||||
bash --noprofile --norc -i
|
||||
Loading…
Reference in a new issue