Adds per-file integrity attestation on top of the existing signed-tarball release flow. make_release now generates a SHA256SUMS manifest over the shipped tree and (when a key is configured) signs it, riding both inside the release tarball so they land in the install tree with no extra download. lpVerifyInstall (scripts/source/verify.sh) re-hashes the install tree against that manifest and verifies the manifest's minisign signature against the root-owned footprint pubkey, yielding states: verified / modified / tampered / unsigned / unverifiable / development. webuiSystemVerify writes verify_status.json (throttled daily, force on demand, also after each update apply), surfaced as an Integrity line + "Verify now" button on the Admin → Overview Updates card and a row in the update details panel. `libreportal verify` exposes the same check on the CLI. Honest framing: this is a self-check (run by the software it verifies), so red fires only for genuine modified/tampered states; the badge tooltip points to out-of-band `minisign -Vm` for an independent guarantee. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
66 lines
2.3 KiB
Bash
66 lines
2.3 KiB
Bash
#!/bin/bash
|
|
|
|
# Verify Commands Handler
|
|
# Re-checks the installed code against the signed release manifest and refreshes
|
|
# the integrity status the WebUI "Updates" card reads (verify_status.json).
|
|
|
|
cliHandleVerifyCommands()
|
|
{
|
|
local verify_type="$initial_command2"
|
|
|
|
case "$verify_type" in
|
|
""|"now"|"check")
|
|
# Run the integrity check, print a human summary, and (re)write
|
|
# verify_status.json so the WebUI badge reflects the result.
|
|
cliRunVerify
|
|
;;
|
|
"json"|"status")
|
|
# Non-interactive: just (re)write verify_status.json. This is what
|
|
# the WebUI "Verify now" button runs through the task pipeline.
|
|
webuiSystemVerify "force"
|
|
;;
|
|
*)
|
|
isNotice "Invalid verify command: ${RED}$verify_type${NC}"
|
|
cliShowVerifyHelp
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Run the check (via webuiSystemVerify, which also rewrites verify_status.json
|
|
# and leaves the LP_VERIFY_* globals set) and print a readable summary.
|
|
cliRunVerify()
|
|
{
|
|
isHeader "LibrePortal Integrity Check"
|
|
|
|
if ! declare -f webuiSystemVerify >/dev/null 2>&1; then
|
|
isError "Verification is unavailable on this install."
|
|
return 1
|
|
fi
|
|
webuiSystemVerify "force"
|
|
|
|
case "$LP_VERIFY_STATE" in
|
|
verified)
|
|
isSuccessful "Verified — all ${LP_VERIFY_TOTAL} files match the signed release."
|
|
;;
|
|
modified)
|
|
isError "Modified — ${LP_VERIFY_MODIFIED} changed, ${LP_VERIFY_MISSING} missing of ${LP_VERIFY_TOTAL} files."
|
|
if [[ -n "$LP_VERIFY_SAMPLE" ]]; then
|
|
isNotice "Affected files (sample):"
|
|
while IFS= read -r _p; do [[ -n "$_p" ]] && echo " - $_p"; done <<< "$LP_VERIFY_SAMPLE"
|
|
fi
|
|
;;
|
|
tampered)
|
|
isError "Manifest signature invalid — ${LP_VERIFY_ERROR:-the release manifest cannot be trusted}."
|
|
;;
|
|
unsigned)
|
|
isNotice "Files match the manifest, but it isn't signed yet (no production key) — can't fully vouch for it."
|
|
;;
|
|
unverifiable)
|
|
isNotice "${LP_VERIFY_ERROR:-The signed manifest could not be checked.}"
|
|
;;
|
|
*)
|
|
isNotice "Development build (${CFG_INSTALL_MODE:-git} install) — no signed manifest to verify against."
|
|
;;
|
|
esac
|
|
}
|