bash/core/50_upgrade.bash
raw ยท 3049 bytes
rbash_verify_upgrade() {
local new_rbashrc="$1"
local sig_file="$2"
local key_file="$3"
local gnupg_home key_fpr rc
command -v gpg >/dev/null 2>&1 || {
echo "gpg is required for rbash upgrade verification"
return 1
}
[ -n "${RBASH_SIGNING_FPR:-}" ] || {
echo "RBASH_SIGNING_FPR is not set"
echo "Refusing to upgrade without a pinned signing key fingerprint"
return 1
}
[ -f "$new_rbashrc" ] || {
echo "missing rbashrc: $new_rbashrc"
return 1
}
[ -f "$sig_file" ] || {
echo "missing signature: $sig_file"
return 1
}
[ -f "$key_file" ] || {
echo "missing public key: $key_file"
return 1
}
gnupg_home="$(mktemp -d)"
chmod 700 "$gnupg_home"
GNUPGHOME="$gnupg_home" gpg --quiet --batch --import "$key_file" >/dev/null 2>&1 || {
rc=$?
rm -rf "$gnupg_home"
echo "failed to import rbash signing key"
return "$rc"
}
key_fpr="$(
GNUPGHOME="$gnupg_home" gpg --with-colons --fingerprint 2>/dev/null |
awk -F: '$1 == "fpr" { print $10; exit }'
)"
if [ "$key_fpr" != "$RBASH_SIGNING_FPR" ]; then
rm -rf "$gnupg_home"
echo "rbash signing key fingerprint mismatch"
echo "expected: $RBASH_SIGNING_FPR"
echo "got: ${key_fpr:-<none>}"
return 1
fi
GNUPGHOME="$gnupg_home" gpg \
--quiet \
--batch \
--verify "$sig_file" "$new_rbashrc" >/dev/null 2>&1
rc=$?
rm -rf "$gnupg_home"
if [ "$rc" -ne 0 ]; then
echo "rbash signature verification failed"
return "$rc"
fi
return 0
}
rbash-upgrade() {
local target backup backup_suffix
local tmp_dir tmp_rbashrc tmp_sig tmp_key
local base_url rbashrc_url sig_url key_url
local rc
target="${__RBASH_SCRIPT:-$HOME/.bashrc}"
base_url="$(rbash_url "dist")"
rbashrc_url="$base_url/rbashrc"
sig_url="$base_url/rbashrc.asc"
key_url="$base_url/rbash-signing-key.asc"
command -v gpg >/dev/null 2>&1 || {
echo "gpg is required"
return 1
}
tmp_dir="$(mktemp -d)"
tmp_rbashrc="$tmp_dir/rbashrc"
tmp_sig="$tmp_dir/rbashrc.asc"
tmp_key="$tmp_dir/rbash-signing-key.asc"
__rbash_upgrade_cleanup() {
rm -rf "$tmp_dir"
}
trap __rbash_upgrade_cleanup RETURN
echo "Downloading rbashrc..."
rbash_download "$rbashrc_url" > "$tmp_rbashrc" || return 1
echo "Downloading rbashrc signature..."
rbash_download "$sig_url" > "$tmp_sig" || return 1
echo "Downloading rbash signing public key..."
rbash_download "$key_url" > "$tmp_key" || return 1
echo "Verifying rbashrc signature..."
rbash_verify_upgrade "$tmp_rbashrc" "$tmp_sig" "$tmp_key" || {
echo "rbash upgrade aborted"
return 1
}
backup_suffix="$(date +%Y%m%d%H%M%S)"
backup="$target.bak.$backup_suffix"
echo "Updating $target"
echo "Backup: $backup"
if [ -f "$target" ]; then
cp "$target" "$backup" || {
echo "failed to create backup: $backup"
return 1
}
fi
cp "$tmp_rbashrc" "$target" || {
rc=$?
echo "failed to install new rbashrc"
if [ -f "$backup" ]; then
echo "restoring backup"
cp "$backup" "$target" || true
fi
return "$rc"
}
chmod 600 "$target" 2>/dev/null || true
echo "rbash upgrade complete"
}