mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-03 04:38:48 +00:00
fix(installer): verify checksums on FreeBSD without coreutils
FreeBSD base ships sha256(1) but not GNU sha256sum or Perl shasum, so a fresh pfSense/FreeBSD host without coreutils failed the download checksum and refused to install. Route every installer checksum through installer_file_sha256 and fall back through sha256sum, sha256 -q, shasum and openssl dgst. install-mcp.sh gets the same sha256 branch. Add a focused test that hides sha256sum/shasum and asserts the FreeBSD fallback returns the digest. Change-source: pulse-maintainer
This commit is contained in:
parent
838ca6f26d
commit
84b2787ba6
3 changed files with 54 additions and 6 deletions
|
|
@ -146,10 +146,13 @@ Build from source: go install github.com/rcourtman/pulse-go-rewrite/cmd/pulse-mc
|
|||
local sha_cmd
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
sha_cmd="sha256sum"
|
||||
elif command -v sha256 >/dev/null 2>&1; then
|
||||
# FreeBSD base ships sha256(1) rather than GNU sha256sum.
|
||||
sha_cmd="sha256 -q"
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
sha_cmd="shasum -a 256"
|
||||
else
|
||||
err "no sha256 tool found (sha256sum or shasum); refusing unverified install"
|
||||
err "no sha256 tool found (sha256sum, sha256 or shasum); refusing unverified install"
|
||||
fi
|
||||
|
||||
checksums_url="${base}/checksums.txt"
|
||||
|
|
|
|||
|
|
@ -3075,8 +3075,20 @@ trusted_private_lifecycle_regular_file() {
|
|||
}
|
||||
|
||||
installer_file_sha256() {
|
||||
sha256sum "$1" 2>/dev/null | awk '{print $1}' ||
|
||||
shasum -a 256 "$1" 2>/dev/null | awk '{print $1}'
|
||||
# FreeBSD base ships neither GNU sha256sum nor Perl's shasum; it provides
|
||||
# sha256(1) instead, which prints only the digest with -q. macOS and Linux
|
||||
# provide sha256sum or shasum. Fall back through whichever exists so a
|
||||
# pfSense/FreeBSD install without coreutils can still verify downloads.
|
||||
local file="$1"
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
sha256sum "$file" 2>/dev/null | awk '{print $1}'
|
||||
elif command -v sha256 >/dev/null 2>&1; then
|
||||
sha256 -q "$file" 2>/dev/null | awk '{print $1}'
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
shasum -a 256 "$file" 2>/dev/null | awk '{print $1}'
|
||||
elif command -v openssl >/dev/null 2>&1; then
|
||||
openssl dgst -sha256 "$file" 2>/dev/null | awk '{print $NF}'
|
||||
fi
|
||||
}
|
||||
|
||||
sync_lifecycle_path() {
|
||||
|
|
@ -6216,7 +6228,7 @@ download_verified_privileged_helper() {
|
|||
if has_pinned_installer_signature_key && [[ -z "$helper_signature" ]]; then
|
||||
fail "Typed privileged helper download omitted its signature; refusing install." "$EXIT_SIGNATURE_FAILED"
|
||||
fi
|
||||
helper_actual_sha=$(sha256sum "$TMP_HELPER_BIN" 2>/dev/null | awk '{print $1}' || shasum -a 256 "$TMP_HELPER_BIN" 2>/dev/null | awk '{print $1}')
|
||||
helper_actual_sha=$(installer_file_sha256 "$TMP_HELPER_BIN")
|
||||
if [[ -z "$helper_actual_sha" ]]; then
|
||||
fail "Could not compute typed privileged helper checksum." "$EXIT_CHECKSUM_FAILED"
|
||||
fi
|
||||
|
|
@ -6262,7 +6274,7 @@ download_verified_action_runner() {
|
|||
if has_pinned_installer_signature_key && [[ -z "$runner_signature" ]]; then
|
||||
fail "Typed action runner download omitted its signature; refusing install." "$EXIT_SIGNATURE_FAILED"
|
||||
fi
|
||||
runner_actual_sha=$(sha256sum "$TMP_ACTION_RUNNER_BIN" 2>/dev/null | awk '{print $1}' || shasum -a 256 "$TMP_ACTION_RUNNER_BIN" 2>/dev/null | awk '{print $1}')
|
||||
runner_actual_sha=$(installer_file_sha256 "$TMP_ACTION_RUNNER_BIN")
|
||||
if [[ -z "$runner_actual_sha" || "$runner_actual_sha" != "$runner_expected_sha" ]]; then
|
||||
fail "Typed action runner checksum verification failed." "$EXIT_CHECKSUM_FAILED"
|
||||
fi
|
||||
|
|
@ -6300,7 +6312,7 @@ if has_pinned_installer_signature_key && [[ -z "$SSH_SIGNATURE_HEADER" ]]; then
|
|||
fail "Server did not provide SSH signature header; refusing signed install." "$EXIT_SIGNATURE_FAILED"
|
||||
fi
|
||||
|
||||
ACTUAL_SHA=$(sha256sum "$TMP_BIN" 2>/dev/null | awk '{print $1}' || shasum -a 256 "$TMP_BIN" 2>/dev/null | awk '{print $1}')
|
||||
ACTUAL_SHA=$(installer_file_sha256 "$TMP_BIN")
|
||||
if [[ -z "$ACTUAL_SHA" ]]; then
|
||||
fail "Could not compute binary checksum." "$EXIT_CHECKSUM_FAILED"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -4009,6 +4009,39 @@ func TestInstallSHSavedInstallerTamperAndUntrustedStateFailClosed(t *testing.T)
|
|||
}
|
||||
}
|
||||
|
||||
func TestInstallSHInstallerFileSHA256FallsBackToFreeBSDsha256(t *testing.T) {
|
||||
contents := []byte("pulse-freebsd-checksum-fixture")
|
||||
file := filepath.Join(t.TempDir(), "payload.bin")
|
||||
if err := os.WriteFile(file, contents, 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := fmt.Sprintf("%x", sha256.Sum256(contents))
|
||||
|
||||
// FreeBSD base provides sha256(1) but neither GNU sha256sum nor Perl's
|
||||
// shasum. Hide those two and confirm the helper still returns the digest.
|
||||
script := `
|
||||
set -euo pipefail
|
||||
command() {
|
||||
if [[ "$1" == "-v" && ( "$2" == "sha256sum" || "$2" == "shasum" ) ]]; then
|
||||
return 1
|
||||
fi
|
||||
builtin command "$@"
|
||||
}
|
||||
sha256() {
|
||||
printf '%s\n' "` + want + `"
|
||||
}
|
||||
` + extractInstallShellFunction(t, "installer_file_sha256") + `
|
||||
installer_file_sha256 "` + file + `"
|
||||
`
|
||||
out, err := exec.Command("bash", "-c", script).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("bash: %v\n%s", err, out)
|
||||
}
|
||||
if got := strings.TrimSpace(string(out)); got != want {
|
||||
t.Fatalf("FreeBSD sha256 fallback = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstallSHPrivilegedHelperStateRemovalRequiresExactLifecycleAuthority(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue