Fix: Enforce effective repository trust preflight
This commit is contained in:
@@ -445,6 +445,71 @@ STUB
|
||||
|
||||
cat > "$case_root/bin/dnf" <<'STUB'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ "$*" == '--quiet --no-plugins --dump-repo-config=terra*' ]]; then
|
||||
printf 'dnf:dump-terra\n' >> "$COMMAND_LOG"
|
||||
mode="${STUB_TERRA_EFFECTIVE_MODE:-auto}"
|
||||
if [[ "$mode" == auto ]]; then
|
||||
case "${STUB_TERRA_REPO_MODE:-absent}" in
|
||||
trusted|wrong-key) mode=trusted ;;
|
||||
nogpg) mode=legacy ;;
|
||||
wrong-url) mode=override-url ;;
|
||||
esac
|
||||
if [[ "$mode" == auto && -f "$STUB_ETC/yum.repos.d/terra.repo" ]] \
|
||||
&& grep -q '^baseurl=https://repos.fyralabs.com/terra44$' "$STUB_ETC/yum.repos.d/terra.repo"; then
|
||||
mode=trusted
|
||||
elif [[ "$mode" == auto ]]; then
|
||||
mode=absent
|
||||
fi
|
||||
fi
|
||||
case "$mode" in
|
||||
absent) exit 0 ;;
|
||||
trusted)
|
||||
printf '======== "terra" repository configuration: ========\n'
|
||||
printf 'baseurl = https://repos.fyralabs.com/terra44\n'
|
||||
printf 'enabled = 1\n'
|
||||
printf 'gpgcheck = 1\n'
|
||||
printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
|
||||
printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
|
||||
;;
|
||||
legacy)
|
||||
printf '======== "terra" repository configuration: ========\n'
|
||||
printf 'baseurl = \nenabled = 1\ngpgcheck = 0\n'
|
||||
printf 'gpgkey = https://repos.fyralabs.com/terra44.key\n'
|
||||
printf 'metalink = https://tetsudou.fyralabs.com/terra44\nmirrorlist = \n'
|
||||
printf 'pkg_gpgcheck = 0\nrepo_gpgcheck = 0\n'
|
||||
;;
|
||||
override-url)
|
||||
printf '======== "terra" repository configuration: ========\n'
|
||||
printf 'baseurl = https://evil.invalid/terra44\nenabled = 1\ngpgcheck = 1\n'
|
||||
printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
|
||||
printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
|
||||
;;
|
||||
override-gpg)
|
||||
printf '======== "terra" repository configuration: ========\n'
|
||||
printf 'baseurl = https://repos.fyralabs.com/terra44\nenabled = 1\ngpgcheck = 0\n'
|
||||
printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
|
||||
printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 0\nrepo_gpgcheck = 0\n'
|
||||
;;
|
||||
duplicate)
|
||||
for id in terra terra; do
|
||||
printf '======== "%s" repository configuration: ========\n' "$id"
|
||||
printf 'baseurl = https://repos.fyralabs.com/terra44\nenabled = 1\ngpgcheck = 1\n'
|
||||
printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
|
||||
printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
|
||||
done
|
||||
;;
|
||||
alternate)
|
||||
for id in terra terra-legacy; do
|
||||
printf '======== "%s" repository configuration: ========\n' "$id"
|
||||
printf 'baseurl = https://repos.fyralabs.com/terra44\nenabled = 1\ngpgcheck = 1\n'
|
||||
printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
|
||||
printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
|
||||
done
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
fi
|
||||
exit 69
|
||||
STUB
|
||||
|
||||
@@ -537,6 +602,23 @@ run_installer_function() {
|
||||
cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
|
||||
"$case_root/flatpak-repo/flathub.trustedkeys.gpg"
|
||||
;;
|
||||
alternate-key)
|
||||
printf '[core]\nrepo_version=1\n\n[remote "flathub"]\nurl=https://dl.flathub.org/repo/\ngpg-verify=true\ngpg-verify-summary=true\ngpgkeypath=/unreviewed/keyring.gpg\n' \
|
||||
> "$case_root/flatpak-repo/config"
|
||||
cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
|
||||
"$case_root/flatpak-repo/flathub.trustedkeys.gpg"
|
||||
;;
|
||||
empty-alternate-key|duplicate-alternate-key|malformed-alternate-key)
|
||||
printf '[core]\nrepo_version=1\n\n[remote "flathub"]\nurl=https://dl.flathub.org/repo/\ngpg-verify=true\ngpg-verify-summary=true\n' \
|
||||
> "$case_root/flatpak-repo/config"
|
||||
case "$STUB_FLATPAK_REMOTE_MODE" in
|
||||
empty-alternate-key) printf 'gpgkeypath=\n' ;;
|
||||
duplicate-alternate-key) printf 'gpgkeypath=\ngpgkeypath=/unreviewed/keyring.gpg\n' ;;
|
||||
malformed-alternate-key) printf 'gpgkeypath /unreviewed/keyring.gpg\n' ;;
|
||||
esac >> "$case_root/flatpak-repo/config"
|
||||
cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
|
||||
"$case_root/flatpak-repo/flathub.trustedkeys.gpg"
|
||||
;;
|
||||
esac
|
||||
case "${STUB_CLAUDE_DESKTOP_REPO_MODE:-absent}" in
|
||||
trusted)
|
||||
@@ -602,11 +684,13 @@ reset_installer_fixture
|
||||
expect_success run_installer_function terra install_terra_repository
|
||||
assert_log terra "$(cat <<'EXPECTED'
|
||||
rpm:release
|
||||
dnf:dump-terra
|
||||
rpm:query:terra-release
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
sudo:install:terra44.asc:/etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama
|
||||
sudo:dnf install -y --repofrompath terra,https://repos.fyralabs.com/terra44 --setopt=terra.pkg_gpgcheck=1 --setopt=terra.repo_gpgcheck=1 --setopt=terra.gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama terra-release
|
||||
sudo:install:terra.repo:/etc/yum.repos.d/terra.repo
|
||||
dnf:dump-terra
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
EXPECTED
|
||||
@@ -713,7 +797,8 @@ EXPECTED
|
||||
)"
|
||||
assert_file_bytes "$test_tmp/cases/flathub-existing-trusted/flatpak-state" 'preserved'
|
||||
|
||||
for mode in wrong-url wrong-key no-gpg; do
|
||||
for mode in wrong-url wrong-key no-gpg alternate-key empty-alternate-key \
|
||||
duplicate-alternate-key malformed-alternate-key; do
|
||||
reset_installer_fixture
|
||||
name="flathub-existing-$mode"
|
||||
STUB_FLATPAK_REMOTE_MODE="$mode" \
|
||||
@@ -729,7 +814,7 @@ STUB_TERRA_INSTALLED=1 STUB_TERRA_REPO_MODE=trusted \
|
||||
expect_success run_installer_function terra-existing-trusted install_terra_repository
|
||||
assert_log terra-existing-trusted "$(cat <<'EXPECTED'
|
||||
rpm:release
|
||||
rpm:query:terra-release
|
||||
dnf:dump-terra
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
EXPECTED
|
||||
@@ -748,7 +833,11 @@ done
|
||||
# when one copy looks safe. These cases catch the absent/duplicate conflation.
|
||||
for duplicate_case in \
|
||||
$'duplicate-no-gpg NoGPGVerify=false\nNoGPGVerify=true' \
|
||||
$'duplicate-gpg-verify GPGVerify=true\nGPGVerify=false'; do
|
||||
$'duplicate-gpg-verify GPGVerify=true\nGPGVerify=false' \
|
||||
'alternate-gpg-key-path GPGKeyPath=/unreviewed/keyring.gpg' \
|
||||
'empty-gpg-key-path GPGKeyPath=' \
|
||||
$'duplicate-gpg-key-path GPGKeyPath=\nGPGKeyPath=/unreviewed/keyring.gpg' \
|
||||
'malformed-gpg-key-path GPGKeyPath /unreviewed/keyring.gpg'; do
|
||||
name="${duplicate_case%% *}"
|
||||
lines="${duplicate_case#* }"
|
||||
reset_installer_fixture
|
||||
@@ -759,6 +848,35 @@ for duplicate_case in \
|
||||
|| fail "$name descriptor reached remote activation"
|
||||
done
|
||||
|
||||
# DNF's non-networking effective configuration dump, rather than any one repo
|
||||
# file, decides whether Terra is absent, trusted, overridden, or duplicated.
|
||||
reset_installer_fixture
|
||||
STUB_TERRA_EFFECTIVE_MODE=absent \
|
||||
expect_success run_installer_function terra-effective-absent preflight_terra_trust
|
||||
assert_log terra-effective-absent 'dnf:dump-terra'
|
||||
|
||||
reset_installer_fixture
|
||||
STUB_TERRA_EFFECTIVE_MODE=trusted STUB_TERRA_REPO_MODE=trusted \
|
||||
expect_success run_installer_function terra-effective-trusted preflight_terra_trust
|
||||
assert_log terra-effective-trusted "$(cat <<'EXPECTED'
|
||||
dnf:dump-terra
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
EXPECTED
|
||||
)"
|
||||
|
||||
for mode in legacy override-url override-gpg duplicate alternate; do
|
||||
reset_installer_fixture
|
||||
name="terra-effective-$mode"
|
||||
status=0
|
||||
STUB_TERRA_EFFECTIVE_MODE="$mode" STUB_TERRA_REPO_MODE=trusted \
|
||||
run_installer_function "$name" preflight_terra_trust || status=$?
|
||||
[[ "$status" -eq 78 ]] \
|
||||
|| fail "effective Terra $mode returned $status instead of hard trust status 78"
|
||||
[[ "$(<"$test_tmp/cases/$name/commands.log")" != *'sudo:'* ]] \
|
||||
|| fail "effective Terra $mode reached a transaction"
|
||||
done
|
||||
|
||||
assert_pair_rollback() {
|
||||
local name="$1" pair="$2" prior="$3" key repo
|
||||
case "$pair" in
|
||||
|
||||
@@ -43,7 +43,7 @@ STAGE_NAMES=(install-packages link-dotfiles link-skills link-user change-setting
|
||||
# A PANAMA_PATH that looks enough like the real one for install to run, and
|
||||
# records what it was asked to do instead of doing it.
|
||||
build_fixture() {
|
||||
local root="$1" packages_rc="${2:-0}"
|
||||
local root="$1" packages_rc="${2:-0}" trust_rc="${3:-0}"
|
||||
rm -rf "$root"
|
||||
mkdir -p "$root/bin" "$root/setup/scripts" "$root/setup/packages" \
|
||||
"$root/config/dot/quickshell/scripts"
|
||||
@@ -63,6 +63,10 @@ EOF
|
||||
# The one stage whose exit code the caller wants to control.
|
||||
cat >"$root/setup/scripts/install-packages" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
if [[ "\${1:-}" == --trust-preflight ]]; then
|
||||
printf 'trust-preflight\n' >>"\$PANAMA_RAN"
|
||||
exit $trust_rc
|
||||
fi
|
||||
printf 'install-packages\n' >>"\$PANAMA_RAN"
|
||||
exit $packages_rc
|
||||
EOF
|
||||
@@ -103,6 +107,14 @@ EOF
|
||||
#!/usr/bin/env bash
|
||||
exit 0
|
||||
EOF
|
||||
cat >"$root/shim/dnf" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
printf 'dnf-transaction\n' >>"$PANAMA_RAN"
|
||||
exit 0
|
||||
EOF
|
||||
for prerequisite in gum lspci mokutil fwupdmgr; do
|
||||
ln -s gsettings "$root/shim/$prerequisite"
|
||||
done
|
||||
chmod +x "$root/shim"/*
|
||||
}
|
||||
|
||||
@@ -215,6 +227,44 @@ run_install "$tmp/c" --upgrade >/dev/null || install_status=$?
|
||||
if [[ -r "$tmp/c/state/panama/packages-hash" ]]; then
|
||||
note 'install-packages failed but its hash was recorded, so it will never be retried'
|
||||
fi
|
||||
grep -qx 'link-dotfiles' "$tmp/c/ran" \
|
||||
|| note 'an ordinary package-stage failure no longer allows later safe stages'
|
||||
|
||||
# An invalid enabled Terra root is not an ordinary package failure. It must
|
||||
# stop before the installer's bootstrap DNF and before every stage.
|
||||
build_fixture "$tmp/terra-preflight-hard" 0 78
|
||||
install_status=0
|
||||
run_install "$tmp/terra-preflight-hard" >/dev/null || install_status=$?
|
||||
[[ "$install_status" -eq 78 ]] \
|
||||
|| note "initial Terra trust failure returned $install_status instead of 78"
|
||||
asserted_preflight="$(<"$tmp/terra-preflight-hard/ran")"
|
||||
[[ "$asserted_preflight" == trust-preflight ]] \
|
||||
|| note "initial Terra trust failure allowed later work: ${asserted_preflight//$'\n'/,}"
|
||||
|
||||
# The trust verifier is itself mandatory. Losing its executable adapter must
|
||||
# fail closed before interview, bootstrap, or stage work.
|
||||
build_fixture "$tmp/terra-preflight-missing"
|
||||
rm "$tmp/terra-preflight-missing/setup/scripts/install-packages"
|
||||
install_status=0
|
||||
run_install "$tmp/terra-preflight-missing" >/dev/null || install_status=$?
|
||||
[[ "$install_status" -eq 78 ]] \
|
||||
|| note "missing Terra trust verifier returned $install_status instead of 78"
|
||||
[[ ! -s "$tmp/terra-preflight-missing/ran" ]] \
|
||||
|| note 'missing Terra trust verifier allowed later work'
|
||||
|
||||
# The package stage repeats the preflight to close a configuration-change race.
|
||||
# Its hard status must also stop link stages and install-hardware immediately.
|
||||
build_fixture "$tmp/terra-stage-hard" 78 0
|
||||
install_status=0
|
||||
run_install "$tmp/terra-stage-hard" >/dev/null || install_status=$?
|
||||
[[ "$install_status" -eq 78 ]] \
|
||||
|| note "stage-time Terra trust failure returned $install_status instead of 78"
|
||||
grep -qx 'install-packages' "$tmp/terra-stage-hard/ran" \
|
||||
|| note 'stage-time Terra trust fixture never reached install-packages'
|
||||
for suppressed in link-dotfiles link-skills link-user change-settings install-hardware dnf-transaction; do
|
||||
grep -qx "$suppressed" "$tmp/terra-stage-hard/ran" \
|
||||
&& note "stage-time Terra trust failure still ran $suppressed"
|
||||
done
|
||||
|
||||
# A full install always runs the stage, whatever any recorded hash says.
|
||||
build_fixture "$tmp/d"
|
||||
|
||||
Reference in New Issue
Block a user