LibrePortal/scripts/cli/commands/verify/cli_verify_commands.sh
librelad b28268a61f feat(system): "Verified" integrity check against the signed release manifest
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>
2026-05-28 19:41:22 +01:00

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
}