fix(artifacts): propagate LP_INDEX_SIGSTATE to callers via lpFetchIndexInto
Every caller captured the index with var=$(lpFetchIndex), which runs the fetch in a command-substitution subshell — the LP_INDEX_SIGSTATE global it sets never reached the caller. On a box with real signing active the artifactApply/apply-auto gates would therefore refuse a correctly signed index (fail-closed, but the apply path would be dead on arrival the day signing activates), and artifact index / the WebUI scan would report a verified feed as UNSIGNED. New lpFetchIndexInto <var> [cache] runs the fetch in the calling shell and assigns via printf -v; all four call sites converted. Verified with a source-and-mock harness against a locally served index: 10/10 (sigstate reaches caller, serial high-water, anti-rollback refuse, staleness refuse, id enumeration, envelope round-trip). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
b0a194dd48
commit
36a5c87397
@ -75,7 +75,7 @@ _artifactRmFile() {
|
||||
# ----------------------------------------------------------------------------
|
||||
_artifactResolve() {
|
||||
local id="$1"
|
||||
_ART_INDEX="$(lpFetchIndex)" || { isError "artifact: could not fetch/verify the index."; return 1; }
|
||||
lpFetchIndexInto _ART_INDEX || { isError "artifact: could not fetch/verify the index."; return 1; }
|
||||
|
||||
local art; art="$(printf '%s' "$_ART_INDEX" | jq -ce --arg id "$id" '.artifacts[]? | select(.id==$id)' 2>/dev/null)"
|
||||
[[ -n "$art" ]] || { isError "artifact: id '$id' not found in the signed index."; return 1; }
|
||||
@ -534,7 +534,7 @@ artifactApplyAuto() {
|
||||
local policy="${CFG_HOTFIX_AUTO:-security-breakage}"
|
||||
[[ "$policy" == "off" ]] && { isNotice "Hotfix auto-apply is off (CFG_HOTFIX_AUTO=off)."; return 0; }
|
||||
|
||||
local index; index="$(lpFetchIndex)" || { isNotice "artifact apply-auto: no index available."; return 0; }
|
||||
local index; lpFetchIndexInto index || { isNotice "artifact apply-auto: no index available."; return 0; }
|
||||
if [[ "$LP_INDEX_SIGSTATE" != "verified" ]]; then
|
||||
isNotice "artifact apply-auto: index is unsigned (signing not activated) — not auto-applying."; return 0
|
||||
fi
|
||||
|
||||
@ -97,7 +97,7 @@ artifactListIndex()
|
||||
isHeader "Artifact index ($(lpReleaseChannel))"
|
||||
|
||||
local json
|
||||
if ! json="$(lpFetchIndex)"; then
|
||||
if ! lpFetchIndexInto json; then
|
||||
isError "Could not fetch or verify the artifact index from $(lpArtifactIndexUrl)."
|
||||
isNotice "Nothing is published yet, or the channel is unreachable. (This is expected before the first index ships.)"
|
||||
return 1
|
||||
|
||||
@ -108,6 +108,23 @@ lpFetchIndex() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# lpFetchIndexInto <varname> [cache_path] — lpFetchIndex run IN THIS SHELL so
|
||||
# the LP_INDEX_SIGSTATE global actually reaches the caller. A plain
|
||||
# var="$(lpFetchIndex)" capture strands that assignment in the substitution's
|
||||
# subshell: the caller then reads the file-scope "" and the apply-path gate
|
||||
# refuses even a correctly signed index. Any caller that inspects
|
||||
# LP_INDEX_SIGSTATE after fetching MUST use this wrapper, not $(…).
|
||||
lpFetchIndexInto() {
|
||||
local __lpfi_var="$1" __lpfi_tmp __lpfi_rc=0
|
||||
__lpfi_tmp="$(mktemp)"
|
||||
lpFetchIndex "${2:-}" > "$__lpfi_tmp" || __lpfi_rc=$?
|
||||
if (( __lpfi_rc == 0 )); then
|
||||
printf -v "$__lpfi_var" '%s' "$(cat "$__lpfi_tmp")"
|
||||
fi
|
||||
rm -f "$__lpfi_tmp"
|
||||
return "$__lpfi_rc"
|
||||
}
|
||||
|
||||
# --- Parsing accessors -------------------------------------------------------
|
||||
# The trust-critical fields (index_serial / valid_until / signature) are read
|
||||
# jq-free above so the security core has no jq dependency. Enumerating the
|
||||
|
||||
@ -596,6 +596,7 @@ declare -gA LP_FN_MAP=(
|
||||
[lpArtifactSerialFile]="source/artifacts.sh"
|
||||
[_lpDownload]="source/fetch.sh"
|
||||
[lpFetchIndex]="source/artifacts.sh"
|
||||
[lpFetchIndexInto]="source/artifacts.sh"
|
||||
[lpFetchRelease]="source/fetch.sh"
|
||||
[lpFetchSource]="source/fetch.sh"
|
||||
[_lpFetchTool]="source/fetch.sh"
|
||||
@ -1554,6 +1555,7 @@ declare -gA LP_FN_ROOT=(
|
||||
[lpArtifactSerialFile]="scripts"
|
||||
[_lpDownload]="scripts"
|
||||
[lpFetchIndex]="scripts"
|
||||
[lpFetchIndexInto]="scripts"
|
||||
[lpFetchRelease]="scripts"
|
||||
[lpFetchSource]="scripts"
|
||||
[_lpFetchTool]="scripts"
|
||||
@ -2533,6 +2535,7 @@ lpArtifactRecordSerial() { source "${install_scripts_dir}source/artifacts.sh"; l
|
||||
lpArtifactSerialFile() { source "${install_scripts_dir}source/artifacts.sh"; lpArtifactSerialFile "$@"; }
|
||||
_lpDownload() { source "${install_scripts_dir}source/fetch.sh"; _lpDownload "$@"; }
|
||||
lpFetchIndex() { source "${install_scripts_dir}source/artifacts.sh"; lpFetchIndex "$@"; }
|
||||
lpFetchIndexInto() { source "${install_scripts_dir}source/artifacts.sh"; lpFetchIndexInto "$@"; }
|
||||
lpFetchRelease() { source "${install_scripts_dir}source/fetch.sh"; lpFetchRelease "$@"; }
|
||||
lpFetchSource() { source "${install_scripts_dir}source/fetch.sh"; lpFetchSource "$@"; }
|
||||
_lpFetchTool() { source "${install_scripts_dir}source/fetch.sh"; _lpFetchTool "$@"; }
|
||||
|
||||
@ -29,7 +29,7 @@ webuiArtifactScan() {
|
||||
fi
|
||||
|
||||
local index
|
||||
if ! index="$(lpFetchIndex)"; then
|
||||
if ! lpFetchIndexInto index; then
|
||||
isNotice "webuiArtifactScan: no verified index available — keeping the prior file."
|
||||
return 0
|
||||
fi
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user