#!/bin/bash
# vega-verify-package
# Checks a downloaded vega-software .deb BEFORE dpkg is ever invoked.
#
# Usage:
#   vega-verify-package <path-to-deb>
#
# Needs <deb>.sha256 and <deb>.asc next to the .deb. Every check is mandatory;
# a missing file is a failure.
#
# Exit codes (callers map these to the reason shown in the UI):
#   0  — all checks passed
#   1  — package structurally corrupt (dpkg-deb could not read it)
#   2  — SHA256 checksum missing or wrong
#   3  — signature missing, or not made by the FL5 release key
#   10 — usage error (no argument, file not found)
#
# The signature is checked against KEYRING only: the FL5 release key installed
# by the vega-software package running now. A new package's own key never
# vouches for that package; it takes over for the update after it.
#
# Log filter:  journalctl -t vega-verify

set -e

KEYRING="/usr/share/vega/keys/fl5-release.pub.gpg"

if [ -z "$1" ] || [ ! -f "$1" ]; then
    echo "Usage: vega-verify-package <path-to-deb>" >&2
    exit 10
fi

DEB="$1"

log() {
    echo "vega-verify-package: $*" | systemd-cat -t vega-verify -p "${LOG_PRIORITY:-info}"
}

log "Verifying: $DEB"

# ── SHA256 checksum (exit 2) ──────────────────────────────────────────────────
# First, so a truncated or damaged download is reported as exactly that.

if [ ! -f "${DEB}.sha256" ]; then
    LOG_PRIORITY=err log "FAIL [2]: checksum file not found: ${DEB}.sha256"
    exit 2
fi
EXPECTED=$(awk '{print $1; exit}' "${DEB}.sha256")
ACTUAL=$(sha256sum "$DEB" | awk '{print $1}')
if [ "$EXPECTED" != "$ACTUAL" ]; then
    LOG_PRIORITY=err log "FAIL [2]: SHA256 mismatch"
    LOG_PRIORITY=err log "  Expected: $EXPECTED"
    LOG_PRIORITY=err log "  Actual:   $ACTUAL"
    exit 2
fi
log "PASS [2]: SHA256 checksum OK"

# ── Detached signature (exit 3) ───────────────────────────────────────────────
# Before dpkg-deb reads anything: an unauthenticated package is never parsed.
# gpgv trusts only the keyring passed to it. --ignore-time-conflict: a unit
# whose clock is behind the key's creation date must still verify (as apt does).

if [ ! -f "${DEB}.asc" ]; then
    LOG_PRIORITY=err log "FAIL [3]: signature file not found: ${DEB}.asc"
    exit 3
fi
if ! command -v gpgv > /dev/null 2>&1; then
    LOG_PRIORITY=err log "FAIL [3]: gpgv is not installed"
    exit 3
fi
if [ ! -f "$KEYRING" ]; then
    LOG_PRIORITY=err log "FAIL [3]: release keyring not found: $KEYRING"
    exit 3
fi

gpgv --ignore-time-conflict --keyring "$KEYRING" "${DEB}.asc" "$DEB" 2>&1 \
    | systemd-cat -t vega-verify -p info
GPGV_RC=${PIPESTATUS[0]}
if [ "$GPGV_RC" != "0" ]; then
    LOG_PRIORITY=err log "FAIL [3]: signature not valid for the FL5 release key (gpgv exit $GPGV_RC) — $DEB"
    exit 3
fi
log "PASS [3]: signature valid"

# ── Package structure (exit 1) ────────────────────────────────────────────────
# dpkg-deb --fsys-tarfile reads the whole payload (xz, zstd, gz, bz2).

if ! dpkg-deb --fsys-tarfile "$DEB" > /dev/null 2>&1; then
    LOG_PRIORITY=err log "FAIL [1]: package structurally corrupt — $DEB"
    exit 1
fi
log "PASS [1]: package structure OK"

log "All verification checks passed: $DEB"
exit 0
