testsAndMisc/linux_configuration/tests/test_pacman_wrapper_security.sh
Krzysztof Rudnicki b83ce5d3c7
Some checks failed
Pre-commit checks / pre-commit (push) Waiting to run
Python tests / test (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
billsplit CI / quality (push) Has been cancelled
reverse-survivors CI / check (push) Has been cancelled
Fail the build on any shellcheck finding; fix the 222 the old gate hid
The shellcheck hook ran with --severity=warning, so info- and style-level
findings never failed a commit. 222 had accumulated across 94 of 244 shell
files. They were not all style noise -- six were bugs:

  - Five scripts in single_use/misc/testsAndMisc-bash/ sourced
    $SCRIPT_DIR/../../lib/common.sh, one directory too shallow. Nothing exists
    at that path, so all five failed at runtime.
  - setup_personal_website.sh and setup_kcd2_dice_solver.sh called usage()
    (which ends in `exit 0`) and then `exit 1` for an unknown command. The
    exit 1 was unreachable, so a typo'd subcommand reported SUCCESS.
  - Six i3blocks scripts had a `# shellcheck source=` directive missing the
    scripts/periodic_background/ path segment. The stale path had silently
    disabled source-following for all of them.
  - diagnose_arch_performance.sh word-split a newline-joined file list; when
    the find came back empty, awk got no file operands, fell through to
    reading stdin, and the diagnostic hung.
  - lib/common.sh's handle_arg_help_or_unknown ended in an unreachable
    `return 0` while documenting "Returns: 0 if handled" -- a contract no code
    path could satisfy.
  - deploy.sh's SCRIPT_DIR is reassigned by config.sh, which it sources at top
    level, and config.sh can repoint it at the on-device path
    /data/local/tmp/focus_mode. Renamed to DEPLOY_DIR.

The SC1091 bulk (81 findings) was resolved rather than silenced: .shellcheckrc
sets external-sources + source-path=SCRIPTDIR so sourced files are actually
followed and analysed. That is what surfaced the i3blocks and deploy.sh bugs.

17 `# shellcheck disable=` directives remain, each with a written reason, and
only where the finding is provably wrong: injection-test payloads that must not
expand, literal source text being grepped for, POSIX sh scripts on the phone
where arrays do not exist, and source paths that only exist at runtime.
Everything else was fixed in code.

Verified in a CLEAN worktree, not just my own tree. config.sh sources the
gitignored config_secrets.sh, which exists locally but not in a fresh checkout;
a working-tree-only check passed while ci_mirror.sh -- which lints HEAD in a
clean worktree, exactly as CI does -- failed on it.

The gate is verified to bite: a file whose only finding is SC2016 (info) fails
the hook, while the old --severity=warning gate exits 0 on it.

third_party/ is excluded -- vendored upstream, matching the prettier hook.

Not fixed, reported: check_polling_antipatterns.sh carries a pre-existing
SC2034 disable that hides a real bug -- its `patterns` array is never used, so
the checker detects nothing. Confirmed unchanged by this commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 19:49:11 +02:00

237 lines
8.5 KiB
Bash
Executable File

#!/bin/bash
# Test script for pacman wrapper integrity checks and VirtualBox enforcement
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
WRAPPER_DIR="$SCRIPT_DIR/../scripts/periodic_background/digital_wellbeing/pacman"
VBOX_DIR="$SCRIPT_DIR/../scripts/periodic_background/digital_wellbeing/virtualbox"
echo "=== Testing Pacman Wrapper Security Enhancements ==="
echo ""
# Test 1: Check wrapper syntax
echo "[TEST 1] Checking wrapper script syntax..."
if bash -n "$WRAPPER_DIR/pacman_wrapper.sh"; then
echo "✓ Wrapper script syntax is valid"
else
echo "✗ Wrapper script has syntax errors"
exit 1
fi
# Test 2: Check installer syntax
echo "[TEST 2] Checking installer script syntax..."
if bash -n "$WRAPPER_DIR/install_pacman_wrapper.sh"; then
echo "✓ Installer script syntax is valid"
else
echo "✗ Installer script has syntax errors"
exit 1
fi
# Test 3: Check VirtualBox enforcement script syntax
echo "[TEST 3] Checking VirtualBox enforcement script syntax..."
if bash -n "$VBOX_DIR/enforce_vbox_hosts.sh"; then
echo "✓ VirtualBox enforcement script syntax is valid"
else
echo "✗ VirtualBox enforcement script has syntax errors"
exit 1
fi
# Test 4: Verify integrity check function exists
echo "[TEST 4] Verifying integrity check function exists in wrapper..."
if grep -q "verify_policy_integrity()" "$WRAPPER_DIR/pacman_wrapper.sh"; then
echo "✓ Integrity verification function found"
else
echo "✗ Integrity verification function not found"
exit 1
fi
# Test 5: Verify hardcoded VirtualBox cleanup function exists
echo "[TEST 5] Verifying hardcoded VirtualBox cleanup function exists..."
if grep -q "auto_remove_virtualbox_vms()" "$WRAPPER_DIR/pacman_wrapper.sh"; then
echo "✓ Hardcoded VirtualBox cleanup function found"
else
echo "✗ Hardcoded VirtualBox cleanup function not found"
exit 1
fi
# Test 6: Verify VirtualBox cleanup uses VBoxManage directly
echo "[TEST 6] Verifying VirtualBox cleanup uses VBoxManage directly..."
if grep -q "VBoxManage" "$WRAPPER_DIR/pacman_wrapper.sh"; then
echo "✓ VirtualBox cleanup logic found"
else
echo "✗ VirtualBox cleanup logic not found"
exit 1
fi
# Test 7: Verify integrity check is called early in execution
echo "[TEST 7] Verifying integrity check is called before operations..."
if grep -B 2 -A 2 "verify_policy_integrity" "$WRAPPER_DIR/pacman_wrapper.sh" | grep -q "CRITICAL"; then
echo "✓ Integrity check is called early in execution"
else
echo "✗ Integrity check not found in early execution"
exit 1
fi
# Test 8: Verify installer creates integrity file
echo "[TEST 8] Verifying installer creates integrity checksums..."
if grep -q "INTEGRITY_FILE" "$WRAPPER_DIR/install_pacman_wrapper.sh"; then
echo "✓ Installer references integrity file"
else
echo "✗ Installer does not create integrity file"
exit 1
fi
# Test 9: Verify installer uses chattr to make files immutable
echo "[TEST 9] Verifying installer makes policy files immutable..."
if grep -q "chattr +i" "$WRAPPER_DIR/install_pacman_wrapper.sh"; then
echo "✓ Installer sets immutable attributes"
else
echo "✗ Installer does not set immutable attributes"
exit 1
fi
# Test 10: Verify VirtualBox cleanup enforcement is integrated
echo "[TEST 10] Verifying VirtualBox cleanup is integrated into wrapper..."
if grep -q "auto_remove_virtualbox_vms" "$WRAPPER_DIR/pacman_wrapper.sh"; then
echo "✓ VirtualBox cleanup integration found"
else
echo "✗ VirtualBox cleanup integration not found"
exit 1
fi
# Test 11: Verify VirtualBox script can show help
echo "[TEST 11] Testing VirtualBox enforcement script help..."
# Run without invoking sudo by setting EUID check (or just check for the help text in the file)
if grep -q "VirtualBox /etc/hosts Enforcement Tool" "$VBOX_DIR/enforce_vbox_hosts.sh"; then
echo "✓ VirtualBox enforcement script has help text"
else
echo "✗ VirtualBox enforcement script help text not found"
exit 1
fi
# Test 12: Verify installer installs VirtualBox enforcement script
echo "[TEST 12] Verifying installer handles VirtualBox enforcement script..."
if grep -q "VBOX_ENFORCE" "$WRAPPER_DIR/install_pacman_wrapper.sh"; then
echo "✓ Installer includes VirtualBox enforcement script"
else
echo "✗ Installer does not include VirtualBox enforcement script"
exit 1
fi
# Test 13: Verify makepkg capped wrapper script syntax
echo "[TEST 13] Checking makepkg capped wrapper syntax..."
if bash -n "$WRAPPER_DIR/makepkg_capped.sh"; then
echo "✓ makepkg capped wrapper syntax is valid"
else
echo "✗ makepkg capped wrapper has syntax errors"
exit 1
fi
# Test 14: Verify pacman wrapper exposes makepkg capped command
echo "[TEST 14] Verifying pacman wrapper supports --makepkg-capped..."
if grep -q -- "--makepkg-capped" "$WRAPPER_DIR/pacman_wrapper.sh"; then
echo "✓ pacman wrapper makepkg capped command found"
else
echo "✗ pacman wrapper makepkg capped command missing"
exit 1
fi
# Test 15: Verify installer deploys makepkg capped wrapper
echo "[TEST 15] Verifying installer deploys makepkg capped wrapper..."
if grep -q "MAKEPKG_CAPPED" "$WRAPPER_DIR/install_pacman_wrapper.sh"; then
echo "✓ Installer includes makepkg capped deployment"
else
echo "✗ Installer does not include makepkg capped deployment"
exit 1
fi
# Test 16: Verify mkpkg helper script syntax
echo "[TEST 16] Checking mkpkg helper script syntax..."
if bash -n "$WRAPPER_DIR/mkpkg.sh"; then
echo "✓ mkpkg helper script syntax is valid"
else
echo "✗ mkpkg helper script has syntax errors"
exit 1
fi
# Test 17: Verify installer deploys mkpkg helper
echo "[TEST 17] Verifying installer deploys mkpkg helper..."
if grep -q "MKPKG" "$WRAPPER_DIR/install_pacman_wrapper.sh"; then
echo "✓ Installer includes mkpkg helper deployment"
else
echo "✗ Installer does not include mkpkg helper deployment"
exit 1
fi
# Test 18: Verify installer runs in strict mode
echo "[TEST 18] Verifying installer uses strict shell mode..."
if grep -q "set -euo pipefail" "$WRAPPER_DIR/install_pacman_wrapper.sh"; then
echo "✓ Installer strict mode enabled"
else
echo "✗ Installer strict mode not enabled"
exit 1
fi
# Test 19: Verify installer handles immutable files during updates
echo "[TEST 19] Verifying installer unlocks immutable files before copy/write..."
if grep -q "unlock_immutable_file_if_needed" "$WRAPPER_DIR/install_pacman_wrapper.sh"; then
echo "✓ Installer immutable-file handling found"
else
echo "✗ Installer immutable-file handling missing"
exit 1
fi
# Test: shared lock library syntax
echo "[TEST] Checking shared lock library syntax..."
if bash -n "$WRAPPER_DIR/pacman_lock_lib.sh"; then
echo "✓ pacman_lock_lib.sh syntax is valid"
else
echo "✗ pacman_lock_lib.sh has syntax errors"
exit 1
fi
# Test: wrapper sources the shared lock library
echo "[TEST] Verifying wrapper sources the shared lock library..."
if grep -q 'source .*pacman_lock_lib.sh' "$WRAPPER_DIR/pacman_wrapper.sh"; then
echo "✓ Wrapper sources pacman_lock_lib.sh"
else
echo "✗ Wrapper does not source pacman_lock_lib.sh"
exit 1
fi
# Test: the lock library is covered by the integrity manifest
echo "[TEST] Verifying installer checksums the lock library..."
# Literal source text being searched for; expanding $SCRIPT_DIR /
# $LOCK_LIB_DEST here would search for this machine's values instead.
# shellcheck disable=SC2016
if grep -qF 'sha256sum "$LOCK_LIB_DEST"' "$WRAPPER_DIR/install_pacman_wrapper.sh"; then
echo "✓ Lock library is included in the integrity manifest"
else
echo "✗ Lock library not checksummed by installer"
exit 1
fi
# Test: lib is sourced AFTER integrity verification (tamper caught before source)
echo "[TEST] Verifying lock library is sourced after integrity check..."
if awk '/verify_policy_integrity/{v=NR} /source .*pacman_lock_lib.sh/{s=NR} END{exit !(v && s && s>v)}' "$WRAPPER_DIR/pacman_wrapper.sh"; then
echo "✓ Lock library sourced after verify_policy_integrity"
else
echo "✗ Lock library not sourced after integrity verification"
exit 1
fi
echo ""
echo "=== All Tests Passed! ==="
echo ""
echo "Summary of security enhancements:"
echo " ✓ Policy files are protected with SHA256 checksums"
echo " ✓ Integrity checks run on every wrapper invocation"
echo " ✓ Policy files are made immutable with chattr +i"
echo " ✓ VirtualBox has hardcoded restrictions (cannot bypass via file editing)"
echo " ✓ VirtualBox VMs are automatically configured to use host's /etc/hosts"
echo " ✓ Difficult word challenge for VirtualBox installation (7-letter words, 150 words, 120s)"
echo " ✓ makepkg capped runner is integrated via wrapper and installer"
echo " ✓ mkpkg convenience helper is deployed by installer"
echo " ✓ installer fails fast and handles immutable policy files safely"