#!/usr/bin/env bash # # build-baseline.sh — reproducibly assemble the www.archline.hu clean CODE baseline. # # Output (out/) = the deployed docroot (code only), which the illusion/hids # baseline-diff (imrcli vanilla_ref) verifies the live server against. # # The repo stores the baseline CONSTITUENTS, not the deployed tree; this script # performs the deterministic "deployment" (Joomla manifest-mapping for packaged # extensions, direct placement for no-source ones), per RUNBOOK.md. # # Usage: ./build-baseline.sh [OUT_DIR] (default: ./out) set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" OUT="${1:-$ROOT/out}" JMAP="$ROOT/lib/jmap.py" log(){ printf '[build] %s\n' "$*"; } rm -rf "$OUT"; mkdir -p "$OUT" # 1) Joomla core — official 3.8.11 package (deployed form), minus demo assets and # runtime data dirs (cache/tmp/logs/images are data, not verified code). log "core: Joomla 3.8.11 (official package)" rsync -a \ --exclude='cache/' --exclude='tmp/' --exclude='logs/' \ --exclude='images/sampledata/' --exclude='images/banners/' --exclude='images/headers/' \ --exclude='images/joomla_black.png' --exclude='images/powered_by.png' \ "$ROOT/core/" "$OUT/" # 2) Upstream-package extensions — map the pristine package to deployed paths via # the Joomla manifest, then apply the Cadline delta patch (if the module was # legitimately modified). git diff pristine<->patch documents our delta. for pkg in "$ROOT"/packages/*/; do [ -d "$pkg" ] || continue name="$(basename "$pkg")" log "package: $name (manifest-map)" python3 "$JMAP" --package "$pkg/pristine" --out "$OUT" if [ -f "$pkg/cadline.patch" ]; then log "package: $name (apply Cadline delta)" ( cd "$OUT" && patch -p1 --no-backup-if-mismatch < "$pkg/cadline.patch" ) fi done # 3) No-source extensions — vetted deployed files (no obtainable package), # placed directly (already in deployed layout). for d in "$ROOT"/deployed/*/; do [ -d "$d" ] || continue log "deployed: $(basename "$d")" rsync -a --exclude='.provenance' "$d" "$OUT/" done # 4) Cadline own-code (components/modules/plugins/templates/docroot apps). for d in "$ROOT"/cadline/*/; do [ -d "$d" ] || continue log "cadline: $(basename "$d")" rsync -a --exclude='.provenance' "$d" "$OUT/" done # 5) Cadline core modifications — patches applied on the vanilla core. for p in "$ROOT"/overrides/*.patch; do [ -f "$p" ] || continue log "override: $(basename "$p")" ( cd "$OUT" && patch -p1 --no-backup-if-mismatch < "$p" ) done # 6) Safety net — malware IOC + scan artifacts must never appear in the baseline # (the sources above already exclude them; this is defensive, documented in # malware-iocs.md / malware-iocs.paths). log "exclude: malware IOC + scan artifacts" find "$OUT" \( -name '*.php.json' -o -name '*.phtml.json' -o -name 'h3x_*' -o -name '_h3x_*' \) -delete 2>/dev/null || true if [ -f "$ROOT/malware-iocs.paths" ]; then while IFS= read -r ioc; do [ -z "$ioc" ] && continue case "$ioc" in \#*) continue;; esac rm -rf "${OUT:?}/$ioc" done < "$ROOT/malware-iocs.paths" fi log "baseline built at: $OUT ($(find "$OUT" -type f | wc -l) files)"