cat / goq
clone

turns a linux box into a private steam streaming appliance: plug in, tap your key, play from another computer

fix/architecture-review-findings
goq / scripts / tests / package-bazzite-provenance.sh
package-bazzite-provenance.sh 5.5K executable
1#!/usr/bin/env bash23set -euo pipefail45script_dir="$(CDPATH='' cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"6repo_dir="$(CDPATH='' cd -- "$script_dir/../.." && pwd -P)"7package_script="$repo_dir/scripts/package-bazzite-release.sh"8temp_parent="${TMPDIR:-/tmp}"9temp_parent="${temp_parent%/}"10temp_root="$(mktemp -d "$temp_parent/sigil-package-provenance.XXXXXX")"1112cleanup() {13 local status=$?14 trap - EXIT INT TERM HUP15 case "$temp_root" in16 "$temp_parent"/sigil-package-provenance.??????) rm -rf -- "$temp_root" ;;17 esac18 exit "$status"19}20trap cleanup EXIT INT TERM HUP2122host_binary="$temp_root/sigil"23probe_binary="$temp_root/sigil-probe"24printf '#!/usr/bin/env bash\nexit 0\n' >"$host_binary"25printf '#!/usr/bin/env bash\nexit 0\n' >"$probe_binary"26chmod 0755 "$host_binary" "$probe_binary"2728assert_rejected() {29 local case_name="$1"30 local expected="$2"31 local output_path="$temp_root/$case_name.tar.gz"32 local log_path="$temp_root/$case_name.log"33 shift 23435 if "$package_script" --output "$output_path" "$@" >"$log_path" 2>&1; then36 printf 'FAIL: %s unexpectedly succeeded\n' "$case_name" >&237 exit 138 fi39 grep -Fq -- "$expected" "$log_path" || {40 printf 'FAIL: %s did not report %s\n' "$case_name" "$expected" >&241 sed -n '1,120p' "$log_path" >&242 exit 143 }44 [[ ! -e "$output_path" && ! -e "$output_path.sha256" && ! -e "$output_path.minisig" ]] || {45 printf 'FAIL: %s created package output before rejecting supplied binaries\n' "$case_name" >&246 exit 147 }48}4950both_flags_message='caller-supplied binaries require both --allow-dirty and --allow-unsigned'51assert_rejected product-supplied "$both_flags_message" \52 --host-binary "$host_binary" --probe-binary "$probe_binary"53assert_rejected dirty-only-supplied "$both_flags_message" \54 --allow-dirty --host-binary "$host_binary" --probe-binary "$probe_binary"55assert_rejected unsigned-only-supplied "$both_flags_message" \56 --allow-unsigned --host-binary "$host_binary" --probe-binary "$probe_binary"57assert_rejected partial-development-pair \58 '--host-binary and --probe-binary must be supplied together' \59 --allow-dirty --allow-unsigned --host-binary "$host_binary"60assert_rejected dirty-without-unsigned \61 'development packaging requires both --allow-dirty and --allow-unsigned' \62 --allow-dirty63assert_rejected unsigned-without-dirty \64 'development packaging requires both --allow-dirty and --allow-unsigned' \65 --allow-unsigned66assert_rejected inline-secret-key \67 'unknown argument: --minisign-key' \68 --minisign-key "$temp_root/not-a-key"69assert_rejected missing-release-tag \70 'product mode requires --release-tag vVERSION'71assert_rejected wrong-product-name \72 'product output must be named sigil-v0.1.0-linux-glibc2.17-x86_64.tar.gz' \73 --release-tag v0.1.074legacy_contract="bazzite""-x86_64"75legacy_output="$temp_root/sigil-v0.1.0-$legacy_contract.tar.gz"76legacy_log="$temp_root/legacy-product-name.log"77if "$package_script" --output "$legacy_output" --release-tag v0.1.0 \78 >"$legacy_log" 2>&179then80 printf 'FAIL: distro-named product output unexpectedly succeeded\n' >&281 exit 182fi83grep -Fq \84 'product output must be named sigil-v0.1.0-linux-glibc2.17-x86_64.tar.gz' \85 "$legacy_log"86[[ ! -e "$legacy_output" && ! -e "$legacy_output.sha256" \87 && ! -e "$legacy_output.minisig" ]]8889development_output="$temp_root/development-supplied.tar.gz"90development_log="$temp_root/development-supplied.log"91"$package_script" \92 --output "$development_output" \93 --allow-dirty --allow-unsigned \94 --host-binary "$host_binary" --probe-binary "$probe_binary" \95 >"$development_log"96grep -Fq 'publisher_signature=absent-development' "$development_log"97python3 - "$development_output" <<'PY'98import json99import sys100import tarfile101102with tarfile.open(sys.argv[1], "r:gz") as archive:103 manifest_file = archive.extractfile("payload/release/release-manifest.json")104 if manifest_file is None:105 raise SystemExit("release manifest is missing")106 manifest = json.load(manifest_file)107 primary = archive.extractfile("payload/release/sigil")108 compatibility = archive.extractfile("payload/release/sigil-host")109 service = archive.extractfile("payload/release/assets/sigil-host.service")110 if primary is None or compatibility is None:111 raise SystemExit("primary or compatibility host executable is missing")112 if service is None:113 raise SystemExit("service asset is missing")114 if primary.read() != compatibility.read():115 raise SystemExit("sigil-host compatibility executable differs from sigil")116 service_text = service.read().decode("utf-8")117 if "current/sigil-host serve" not in service_text:118 raise SystemExit("service does not retain the compatibility executable")119 if "current/sigil serve" in service_text:120 raise SystemExit("service bypasses the legacy compatibility executable")121122if manifest.get("binary_provenance") != "caller-supplied-unverified":123 raise SystemExit("caller-supplied binary provenance is not marked unverified")124if manifest.get("binary_provenance_verified") is not False:125 raise SystemExit("caller-supplied binary provenance must not be verified")126if manifest.get("primary_executable") != "sigil":127 raise SystemExit("primary executable is not sigil")128if manifest.get("compatibility_executable") != "sigil-host":129 raise SystemExit("compatibility executable is not sigil-host")130if manifest.get("release_tag") != "development":131 raise SystemExit("development package claims a release tag")132if manifest.get("release_kind") != "development":133 raise SystemExit("development release kind is missing")134PY135136printf 'package_bazzite_provenance_tests=ok\n'