From a3d97fb1c032ca669f6102f1a368c7f909ae8556 Mon Sep 17 00:00:00 2001 From: mirivlad Date: Sun, 6 Sep 2026 20:51:06 +0800 Subject: [PATCH] fix: repair passwd legacy migration --- README.md | 8 ++++---- docs/releases/v0.4.2.md | 16 ++++++++++++++++ packaging/scripts/postinstall.sh | 5 +++-- packaging/scripts/test-legacy-migration.sh | 12 ++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 docs/releases/v0.4.2.md diff --git a/README.md b/README.md index 43e7134..cd5bbc0 100644 --- a/README.md +++ b/README.md @@ -72,13 +72,13 @@ Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 Debian/Ubuntu (amd64): ```bash -sudo apt install ./sshkeeper_0.4.1-1_amd64.deb +sudo apt install ./sshkeeper_0.4.2-1_amd64.deb ``` Fedora/RHEL-family (x86_64): ```bash -sudo dnf install ./sshkeeper-0.4.1-1.x86_64.rpm +sudo dnf install ./sshkeeper-0.4.2-1.x86_64.rpm ``` `arm64`/`aarch64` packages are published alongside the x86_64 builds. Native @@ -98,8 +98,8 @@ sshkeeper --version The traditional tar.gz archive remains available too: ```bash -tar -xzf sshkeeper_v0.4.1_linux_amd64.tar.gz -sudo install -m 0755 sshkeeper_v0.4.1_linux_amd64/sshkeeper /usr/local/bin/sshkeeper +tar -xzf sshkeeper_v0.4.2_linux_amd64.tar.gz +sudo install -m 0755 sshkeeper_v0.4.2_linux_amd64/sshkeeper /usr/local/bin/sshkeeper sshkeeper ``` diff --git a/docs/releases/v0.4.2.md b/docs/releases/v0.4.2.md new file mode 100644 index 0000000..ff4c39c --- /dev/null +++ b/docs/releases/v0.4.2.md @@ -0,0 +1,16 @@ +# sshkeeper v0.4.2 — Package Migration Fix + +This patch fixes the legacy binary migration added in v0.4.1. + +## Fixed + +- Debian/RPM package installation now correctly discovers `~/.local/bin/sshkeeper` from `/etc/passwd`. +- The v0.4.1 postinstall script emitted literal `\t`/`\n` text from awk, so user-home candidates were never parsed. +- `/usr/local/bin/sshkeeper` migration was unaffected. +- Added a regression test that exercises passwd-based discovery instead of only injecting legacy paths directly. + +## Result + +After installing the package, an older `~/.local/bin/sshkeeper` is backed up and replaced with a symlink to `/usr/bin/sshkeeper`, so the packaged binary wins command resolution even in an existing shell session. + +No config, database, vault, SSH keys, or other user data are modified. diff --git a/packaging/scripts/postinstall.sh b/packaging/scripts/postinstall.sh index a842984..d6d7175 100755 --- a/packaging/scripts/postinstall.sh +++ b/packaging/scripts/postinstall.sh @@ -4,6 +4,7 @@ umask 077 SYSTEM_BINARY=${SSHKEEPER_SYSTEM_BINARY:-/usr/bin/sshkeeper} STATE_FILE=${SSHKEEPER_STATE_FILE:-/var/lib/sshkeeper/package-legacy-paths} +PASSWD_FILE=${SSHKEEPER_PASSWD_FILE:-/etc/passwd} candidate_paths() { if [ -n "${SSHKEEPER_LEGACY_PATHS:-}" ]; then @@ -14,8 +15,8 @@ candidate_paths() { fi printf 'root\t%s\n' /usr/local/bin/sshkeeper - if [ -r /etc/passwd ]; then - awk -F: '$3 == 0 || $3 >= 1000 { if ($6 != "" && $6 != "/") printf "%s\\t%s/.local/bin/sshkeeper\\n", $1, $6 }' /etc/passwd + if [ -r "$PASSWD_FILE" ]; then + awk -F: '$3 == 0 || $3 >= 1000 { if ($6 != "" && $6 != "/") printf "%s\t%s/.local/bin/sshkeeper\n", $1, $6 }' "$PASSWD_FILE" fi } diff --git a/packaging/scripts/test-legacy-migration.sh b/packaging/scripts/test-legacy-migration.sh index 4b26396..7219f5e 100755 --- a/packaging/scripts/test-legacy-migration.sh +++ b/packaging/scripts/test-legacy-migration.sh @@ -15,6 +15,18 @@ printf 'old-user\n' > "$legacy_user" printf 'old-local\n' > "$legacy_local" chmod +x "$system" "$legacy_user" "$legacy_local" +# Discover ~/.local/bin/sshkeeper through passwd exactly as a real package install does. +passwd_file="$tmp/passwd" +printf 'test:x:1000:1000:test:%s:/bin/bash\n' "$tmp/home/test" > "$passwd_file" +env SSHKEEPER_MIGRATION_RUN_AS_CURRENT=1 SSHKEEPER_SYSTEM_BINARY="$system" SSHKEEPER_STATE_FILE="$state" SSHKEEPER_PASSWD_FILE="$passwd_file" \ + packaging/scripts/postinstall.sh configure +test -L "$legacy_user" +test "$(readlink "$legacy_user")" = "$system" +test -f "${legacy_user}.legacy-backup" +env SSHKEEPER_MIGRATION_RUN_AS_CURRENT=1 SSHKEEPER_SYSTEM_BINARY="$system" SSHKEEPER_STATE_FILE="$state" \ + packaging/scripts/postremove.sh remove +test "$(cat "$legacy_user")" = old-user + paths=$(printf '%s\n%s' "$legacy_user" "$legacy_local") env SSHKEEPER_MIGRATION_RUN_AS_CURRENT=1 SSHKEEPER_SYSTEM_BINARY="$system" SSHKEEPER_STATE_FILE="$state" SSHKEEPER_LEGACY_PATHS="$paths" \ packaging/scripts/postinstall.sh configure