mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 19:07:04 +01:00
Split install_pacman_wrapper.sh into an entry plus four libs
The 316-line installer was 66 over the 250-line cap. The managed-copy helpers, the /usr/local/bin install step, the integrity + drift manifest, and the immutability/LeechBlock/VirtualBox payloads move into a sibling lib/, leaving a 128-line entry. What stays in the entry is chosen by what the harness can execute, not by taste. `--bind-abs /usr/bin` removes the directory bwrap needs to exec anything, so the trace stops at `ln -sf ... /usr/bin/pacman` with exit 1 on EPERM. That line onwards, plus the `if [ ! -L /usr/bin/pacman ]` backup branch whose guard is false on this machine, therefore never run under trace — moving them would have shipped code no diff could check. They stay put. Everything else is proven: the before/after traces are identical, including all 16 generated-file hashes. pacman_wrapper at 548fc2b53ee4cea6 is the one that matters most — it is post-`sed -i`, so it catches a reorder of the rewrite relative to the copy. The path definitions stay in the entry too, for a linter reason rather than a runtime one: a definitions-only lib assigns without referencing, which is SC2034 on 36 variables, and suppressions are not allowed. Libs that only reference globals are fine. `export` would have silenced it while leaking 40 variables into every child process, which the trace cannot see. Eight assertions across two test libs grep the installer's source text; five needed widening to search entry+lib/. TEST 9's `chattr +i` grep caught the move as a genuine failure first, which is what prompted enumerating the rest. No assertion was weakened. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
This commit is contained in:
parent
32a4d9c70c
commit
4eedc17b17
@ -0,0 +1,20 @@
|
||||
{
|
||||
"title": "Split install_pacman_wrapper.sh under the 250-line cap",
|
||||
"objective": "Bring linux_configuration/scripts/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh (316 lines) under the repo-wide 250-line file cap by moving its middle steps into a sibling lib/, with byte-identical runtime behaviour proven by an executed before/after trace, and without relocating any statement the trace harness cannot reach.",
|
||||
"acceptance_criteria": [
|
||||
"install_pacman_wrapper.sh and all four new lib/*.sh files are each at most 250 lines.",
|
||||
"meta/scripts/trace_shell_split.sh with the four required --bind-abs flags produces an identical trace before and after: same exit status (1, at the unbindable /usr/bin symlink), same stubbed call, and all 16 generated-file content hashes unchanged -- notably pacman_wrapper at sha=548fc2b53ee4cea6, which proves the sed -i still runs after the copy, and source.sha256 at sha=4c928a499d437070.",
|
||||
"Nothing that was moved into a lib sits at or after the ln -sf /usr/bin/pacman line, nor inside the `if [ ! -L /usr/bin/pacman ]` backup branch, since neither executes under the harness.",
|
||||
"linux_configuration/tests/test_pacman_wrapper_security.sh produces output byte-identical to its pre-split run, with all of its installer source-text assertions intact and none weakened.",
|
||||
"shellcheck clean at the real gate (pre-commit run shellcheck) and shfmt clean on every touched file, with zero suppressions -- no # shellcheck disable, no per-file ignores, and no `export` used to silence SC2034.",
|
||||
"The verification runs write nothing outside the trace prefix: /usr/bin/pacman still symlinks to /usr/local/bin/pacman_wrapper and `pacman --version` still works."
|
||||
],
|
||||
"out_of_scope": [
|
||||
"Any behaviour change, including reordering the sed -i relative to the wrapper copy.",
|
||||
"Weakening any assertion in test_pacman_wrapper_security.sh or its libs; only the search PATH of installer source-text greps may widen to include lib/.",
|
||||
"The pre-existing single failure in test_security_hardening.sh ('Compulsive block wrappers installed'), which fails identically at HEAD and belongs to block_compulsive_opening.sh -- explicitly out of scope.",
|
||||
"Fixing the pre-existing repo-wide jscpd overage caused by vendored .venv site-packages.",
|
||||
"Wiring the file-length pre-commit hook -- it must land last."
|
||||
],
|
||||
"verifier": "meta/scripts/trace_shell_split.sh install_pacman_wrapper.sh --prefix <fresh-empty-dir> --bind-abs /usr/local/bin --bind-abs /usr/local/share/digital_wellbeing --bind-abs /usr/local/share/digital_wellbeing/virtualbox --bind-abs /var/lib/pacman-wrapper, captured at HEAD and again after the split, then diff of the two traces (must be empty); diff of test_pacman_wrapper_security.sh output before and after (must be empty); diff of test_security_hardening.sh output before and after (must be empty, both exit 1); pre-commit run shellcheck --files <all touched>; shfmt -d; jscpd as the git hook runs it, measured in a clean worktree with the changes applied; bash ~/utils/scripts/check_file_length.sh --all; ls -la /usr/bin/pacman plus pacman --version."
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
{
|
||||
"intent": "Bring install_pacman_wrapper.sh under the 250-line cap by splitting its middle steps into a sibling lib/, without changing what the installer does to a machine and without relocating code the trace harness cannot execute.",
|
||||
"scope": [
|
||||
"linux_configuration/scripts/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh (316 -> 128 lines)",
|
||||
"New: pacman/lib/{managed_copy,install_files,integrity,protect_and_extras}.sh",
|
||||
"linux_configuration/tests/lib/pacman_wrapper_syntax.sh and pacman_wrapper_makepkg.sh (grep search path widened to include lib/)",
|
||||
"linux_configuration/tests/test_pacman_wrapper_security.sh (one grep repointed at lib/integrity.sh)",
|
||||
"Non-goal: any behaviour change; the trace is the assertion that there is none",
|
||||
"Non-goal: the pre-existing test_security_hardening.sh failure, which is block_compulsive_opening.sh's and fails identically at HEAD"
|
||||
],
|
||||
"changes": [
|
||||
"Moved the managed-copy helpers, the /usr/local/bin install step, the integrity + drift-manifest step, and the immutability/LeechBlock/VirtualBox step into four sourced libs, each wrapped in a named function called in the original order.",
|
||||
"Kept the auto-sudo block, the root and wrapper-exists guards, the `if [ ! -L /usr/bin/pacman ]` backup branch, the sed -i, and everything from `ln -sf ... /usr/bin/pacman` onwards in the entry script. The harness cannot bind /usr/bin (doing so removes the directory bwrap needs to exec, killing the run), so those statements never execute under trace and a split that relocated them could not be verified.",
|
||||
"Kept the colors and all SOURCE_*/DEST_* definitions in the entry rather than a paths lib: a definitions-only lib assigns without referencing, which shellcheck reports as SC2034 on 36 variables, and the repo forbids suppressions. Libs that only REFERENCE globals are accepted, which is the shape used here. `export` would have silenced it but leaks ~40 variables into the environment of npm/sha256sum/sed/chattr children -- a behaviour change the trace cannot see.",
|
||||
"SOURCE_* vars keep `$(dirname \"$0\")` verbatim. In a sourced lib `$0` is still the entry script, but moving them to a lib and switching to ${BASH_SOURCE[0]} would have resolved into lib/ and broken HEAVY_LOCK_SOURCE's depth-sensitive ../../utils/ hop.",
|
||||
"Widened the installer source-text greps in the test libs from the entry script alone to the entry plus lib/ (grep -qr over both paths). Five assertions needed it (chattr +i, MAKEPKG_CAPPED, MKPKG, unlock_immutable_file_if_needed, and the literal sha256sum \"$LOCK_LIB_DEST\" which was repointed at lib/integrity.sh); INTEGRITY_FILE and VBOX_ENFORCE were widened too so the whole set is consistent rather than passing by coincidence of a name still appearing in the entry's path block. No assertion text or condition was weakened."
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "meta/scripts/trace_shell_split.sh install_pacman_wrapper.sh --prefix <fresh> --bind-abs /usr/local/bin --bind-abs /usr/local/share/digital_wellbeing --bind-abs /usr/local/share/digital_wellbeing/virtualbox --bind-abs /var/lib/pacman-wrapper, run twice at HEAD",
|
||||
"result": "pass",
|
||||
"evidence": "Two consecutive HEAD runs produced byte-identical traces, establishing the baseline is deterministic: exit 1, one stubbed call (npm install), 16 files written."
|
||||
},
|
||||
{
|
||||
"command": "same trace after the split; diff against the HEAD baseline",
|
||||
"result": "pass",
|
||||
"evidence": "Empty diff. Same exit status 1 at the same ln -sf line, same stubbed call, all 16 content hashes unchanged including pacman_wrapper=548fc2b53ee4cea6 (proves sed -i still follows the copy) and source.sha256=4c928a499d437070."
|
||||
},
|
||||
{
|
||||
"command": "bash linux_configuration/tests/test_pacman_wrapper_security.sh, before and after",
|
||||
"result": "pass",
|
||||
"evidence": "Exit 0, output byte-identical to the pre-split run: all 19 numbered tests plus the lock-library and -U package-file checks. An intermediate run caught a real regression here -- TEST 9's `chattr +i` grep failed once that line moved into a lib -- which is why the search path was widened."
|
||||
},
|
||||
{
|
||||
"command": "bash linux_configuration/tests/test_security_hardening.sh, before and after",
|
||||
"result": "pass",
|
||||
"evidence": "Output byte-identical, exit 1 both times, with exactly one failure ('Compulsive block wrappers installed') that is present at HEAD and unrelated to this file."
|
||||
},
|
||||
{
|
||||
"command": "pre-commit run shellcheck --files <entry, 4 libs, 3 test files>",
|
||||
"result": "pass",
|
||||
"evidence": "Passed. This is the real gate: a bare `shellcheck -x` on the entry alone was already clean while the standalone paths lib had 36 SC2034 findings, so the entry-only check would have been a false pass."
|
||||
},
|
||||
{
|
||||
"command": "shfmt -w then shfmt -d on all touched files",
|
||||
"result": "pass",
|
||||
"evidence": "No diff. Formatting applied before verification so the tested state equals what the pre-commit hook produces."
|
||||
},
|
||||
{
|
||||
"command": "jscpd --pattern '**/*.sh' --min-lines 14 --threshold 2, at HEAD in a clean worktree and again with the split applied",
|
||||
"result": "pass",
|
||||
"evidence": "27 clones / 1.47% in both cases -- the split adds zero duplication."
|
||||
},
|
||||
{
|
||||
"command": "bash ~/utils/scripts/check_file_length.sh --all",
|
||||
"result": "pass",
|
||||
"evidence": "None of the five files appear. Entry 128, integrity 113, managed_copy 55, protect_and_extras 55, install_files 28."
|
||||
},
|
||||
{
|
||||
"command": "ls -la /usr/bin/pacman; pacman --version",
|
||||
"result": "pass",
|
||||
"evidence": "Still a symlink to /usr/local/bin/pacman_wrapper; pacman 7.1.0 responds. The harness denied the ln with EPERM, which is the positive proof the sandbox held."
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"Two blocks in the entry script are unproven by the trace: the `if [ ! -L /usr/bin/pacman ]` backup branch (the guard is false on this machine, since pacman is already our symlink) and everything from the ln -sf onwards. They were deliberately not moved, so the split does not change their risk, but a future split of this file must respect the same boundary.",
|
||||
"The chattr/relock helpers are proven callable, not proven correct: inside the prefix the copied files are not immutable, so is_immutable_file is false and RELock_FILES stays empty. The baseline's 'Could not make ... immutable' warnings are expected, not a defect.",
|
||||
"Eight assertions across two test libs grep the installer's source text. They now search entry+lib/, so moving a line between those files is safe, but renaming a lib or adding a second lib directory would need the same treatment."
|
||||
],
|
||||
"rollback": [
|
||||
"git revert the commit; the entry returns to its 316-line form and pacman/lib/ disappears. The installed artifacts under /usr/local/bin are unaffected either way, since neither form was executed against the live system here.",
|
||||
"After reverting, re-run bash linux_configuration/tests/test_pacman_wrapper_security.sh -- it must print 'All Tests Passed!', since the revert restores both the moved lines and the original grep paths together."
|
||||
]
|
||||
}
|
||||
@ -1,5 +1,12 @@
|
||||
#!/bin/bash
|
||||
# filepath: /home/kuhy/linux-configuration/scripts/install_pacman_wrapper.sh
|
||||
#
|
||||
# The steps live in lib/; this file owns the paths, the root check, the EXIT
|
||||
# trap, the /usr/bin handling and the call order. Two blocks stay here
|
||||
# deliberately
|
||||
# because the trace harness cannot execute them (it cannot bind /usr/bin), so
|
||||
# a split that moved them could not be verified: the pacman.orig backup plus
|
||||
# the sed rewrite, and everything from the symlink onwards.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@ -18,7 +25,10 @@ BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Script locations
|
||||
# Script locations. These stay in the entry script rather than moving to a lib:
|
||||
# a definitions-only lib assigns without referencing, which is SC2034, and the
|
||||
# repo forbids suppressions. The libs only reference these globals, a shape the
|
||||
# linter accepts. `$0` is the entry script either way.
|
||||
WRAPPER_SOURCE="$(dirname "$0")/pacman_wrapper.sh"
|
||||
LOCK_LIB_SOURCE="$(dirname "$0")/pacman_lock_lib.sh"
|
||||
WORDS_SOURCE="$(dirname "$0")/words.txt"
|
||||
@ -53,53 +63,16 @@ VBOX_ENFORCE_SOURCE="$(dirname "$0")/../virtualbox/enforce_vbox_hosts.sh"
|
||||
VBOX_INSTALL_DIR="/usr/local/share/digital_wellbeing/virtualbox"
|
||||
VBOX_ENFORCE_DEST="${VBOX_INSTALL_DIR}/enforce_vbox_hosts.sh"
|
||||
|
||||
declare -a RELock_FILES=()
|
||||
|
||||
is_immutable_file() {
|
||||
local file_path="$1"
|
||||
[[ -e "$file_path" ]] || return 1
|
||||
[[ $(lsattr -d "$file_path" 2>/dev/null | awk '{print $1}') == *i* ]]
|
||||
}
|
||||
|
||||
unlock_immutable_file_if_needed() {
|
||||
local file_path="$1"
|
||||
if ! command -v chattr >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
if is_immutable_file "$file_path"; then
|
||||
chattr -i "$file_path"
|
||||
RELock_FILES+=("$file_path")
|
||||
fi
|
||||
}
|
||||
|
||||
relock_files_on_exit() {
|
||||
if ! command -v chattr >/dev/null 2>&1; then
|
||||
return
|
||||
fi
|
||||
for file_path in "${RELock_FILES[@]}"; do
|
||||
[[ -e "$file_path" ]] || continue
|
||||
chattr +i "$file_path" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
|
||||
copy_managed_file() {
|
||||
local source_file="$1"
|
||||
local dest_file="$2"
|
||||
local required="$3"
|
||||
local label="$4"
|
||||
|
||||
if [[ ! -f "$source_file" ]]; then
|
||||
if [[ "$required" == "required" ]]; then
|
||||
echo -e "${RED}Error:${NC} Missing required ${label} at ${source_file}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${YELLOW}Warning:${NC} Missing ${label} at ${source_file}" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
unlock_immutable_file_if_needed "$dest_file"
|
||||
cp "$source_file" "$dest_file"
|
||||
}
|
||||
# readlink -f so a symlinked entry point still finds lib/.
|
||||
SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
|
||||
# shellcheck source=lib/managed_copy.sh
|
||||
source "$SCRIPT_DIR/lib/managed_copy.sh"
|
||||
# shellcheck source=lib/install_files.sh
|
||||
source "$SCRIPT_DIR/lib/install_files.sh"
|
||||
# shellcheck source=lib/integrity.sh
|
||||
source "$SCRIPT_DIR/lib/integrity.sh"
|
||||
# shellcheck source=lib/protect_and_extras.sh
|
||||
source "$SCRIPT_DIR/lib/protect_and_extras.sh"
|
||||
|
||||
trap relock_files_on_exit EXIT
|
||||
|
||||
@ -115,28 +88,7 @@ if [ ! -f "$WRAPPER_SOURCE" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${CYAN}Installing pacman wrapper...${NC}"
|
||||
|
||||
# Install the wrapper script
|
||||
echo -e "${BLUE}Copying wrapper script to ${WRAPPER_DEST}...${NC}"
|
||||
copy_managed_file "$WRAPPER_SOURCE" "$WRAPPER_DEST" required "wrapper script"
|
||||
copy_managed_file "$LOCK_LIB_SOURCE" "$LOCK_LIB_DEST" required "stale-lock library"
|
||||
chmod 644 "$LOCK_LIB_DEST"
|
||||
copy_managed_file "$WORDS_SOURCE" "$WORDS_DEST" required "words list"
|
||||
copy_managed_file "$BLOCKED_SOURCE" "$BLOCKED_DEST" required "blocked keywords list"
|
||||
copy_managed_file "$WHITELIST_SOURCE" "$WHITELIST_DEST" optional "whitelist"
|
||||
copy_managed_file "$GREYLIST_SOURCE" "$GREYLIST_DEST" required "greylist"
|
||||
chmod +x "$WRAPPER_DEST"
|
||||
copy_managed_file "$MAKEPKG_CAPPED_SOURCE" "$MAKEPKG_CAPPED_DEST" required "makepkg capped wrapper"
|
||||
chmod +x "$MAKEPKG_CAPPED_DEST"
|
||||
copy_managed_file "$MKPKG_SOURCE" "$MKPKG_DEST" required "mkpkg helper"
|
||||
chmod +x "$MKPKG_DEST"
|
||||
# The heavy-job lock is sourced by pacman_wrapper.sh and makepkg_capped.sh from
|
||||
# a fixed absolute path, so it has to land next to them rather than be read out
|
||||
# of a repo checkout that may move.
|
||||
copy_managed_file "$HEAVY_LOCK_SOURCE" "$HEAVY_LOCK_DEST" required "heavy-job lock library"
|
||||
chmod 755 "$HEAVY_LOCK_DEST"
|
||||
chmod 644 "$WORDS_DEST" "$BLOCKED_DEST" "$WHITELIST_DEST" "$GREYLIST_DEST" 2>/dev/null || true
|
||||
install_managed_files
|
||||
|
||||
# Automatically use symbolic link installation method
|
||||
echo -e "${YELLOW}Installing using symbolic link method...${NC}"
|
||||
@ -153,151 +105,11 @@ fi
|
||||
# Update the PACMAN_BIN variable in the wrapper to point to the original
|
||||
sed -i 's|PACMAN_BIN="\/usr\/bin\/pacman"|PACMAN_BIN="\/usr\/bin\/pacman.orig"|g' "$WRAPPER_DEST"
|
||||
|
||||
# Create integrity directory if it doesn't exist
|
||||
mkdir -p "$INTEGRITY_DIR"
|
||||
chmod 755 "$INTEGRITY_DIR"
|
||||
|
||||
# Generate checksums of policy files for integrity verification
|
||||
echo -e "${BLUE}Generating integrity checksums for policy files...${NC}"
|
||||
unlock_immutable_file_if_needed "$INTEGRITY_FILE"
|
||||
|
||||
# Ensure all critical policy files exist before checksumming
|
||||
missing_files=()
|
||||
[[ ! -f "$BLOCKED_DEST" ]] && missing_files+=("$BLOCKED_DEST")
|
||||
[[ ! -f "$GREYLIST_DEST" ]] && missing_files+=("$GREYLIST_DEST")
|
||||
[[ ! -f "$LOCK_LIB_DEST" ]] && missing_files+=("$LOCK_LIB_DEST")
|
||||
|
||||
if [[ ${#missing_files[@]} -gt 0 ]]; then
|
||||
echo -e "${RED}Error: Critical policy files are missing:${NC}"
|
||||
printf '%s\n' "${missing_files[@]}" >&2
|
||||
echo -e "${RED}Installation incomplete. Cannot create integrity file.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
{
|
||||
sha256sum "$BLOCKED_DEST" || {
|
||||
echo -e "${RED}Failed to checksum blocked list${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
sha256sum "$GREYLIST_DEST" || {
|
||||
echo -e "${RED}Failed to checksum greylist${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
# The shared stale-lock library is executed (sourced) by the wrapper, so it is
|
||||
# integrity-checked too: pacman_wrapper.sh sources it only AFTER
|
||||
# verify_policy_integrity passes, so a tampered lib is rejected before it runs.
|
||||
sha256sum "$LOCK_LIB_DEST" || {
|
||||
echo -e "${RED}Failed to checksum lock library${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
# Whitelist is optional
|
||||
if [[ -f "$WHITELIST_DEST" ]]; then
|
||||
sha256sum "$WHITELIST_DEST" || {
|
||||
echo -e "${RED}Failed to checksum whitelist${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
} >"$INTEGRITY_FILE"
|
||||
|
||||
# Verify integrity file was created and has content
|
||||
if [[ ! -s "$INTEGRITY_FILE" ]]; then
|
||||
echo -e "${RED}Error: Integrity file was not created or is empty${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make integrity file immutable
|
||||
chmod 400 "$INTEGRITY_FILE"
|
||||
if command -v chattr >/dev/null 2>&1; then
|
||||
chattr +i "$INTEGRITY_FILE" 2>/dev/null || echo -e "${YELLOW}Warning: Could not make integrity file immutable${NC}"
|
||||
fi
|
||||
|
||||
# Record a drift manifest: the hash of every SOURCE file we installed from, and
|
||||
# of the installed copies we produced. check_and_enable_services.sh replays it
|
||||
# with `sha256sum -c`, which answers both questions in one command:
|
||||
# - a source line fails => the repo moved on, this deployment is stale
|
||||
# - a dest line fails => someone edited the installed copy directly
|
||||
# Neither was detectable before: the checker only tested that files EXIST, which
|
||||
# is why a wrapper 7.6 KB behind the repo (no integrity manifest, no
|
||||
# pacman_lock_lib, no guard-lib fallbacks) ran unnoticed for a week while the
|
||||
# hourly maintenance timer kept reporting "ok".
|
||||
# Deliberately NOT chattr +i (unlike the policy integrity file above): this is a
|
||||
# drift record, not a security boundary, and it must be rewritable each install.
|
||||
echo -e "${BLUE}Recording deployment drift manifest...${NC}"
|
||||
# ABSOLUTE paths only. The SOURCE_* vars above are built from `dirname "$0"`, so
|
||||
# they are relative whenever the installer is invoked by a relative path — and
|
||||
# check_and_enable_services.sh replays this manifest from systemd with cwd=/,
|
||||
# where relative entries resolve to nothing. sha256sum -c would report those as
|
||||
# failures, the checker would read that as drift, and it would reinstall on
|
||||
# every single hourly run forever.
|
||||
manifest_sources=()
|
||||
for src in "$WRAPPER_SOURCE" "$LOCK_LIB_SOURCE" "$BLOCKED_SOURCE" "$GREYLIST_SOURCE" \
|
||||
"$MAKEPKG_CAPPED_SOURCE" "$MKPKG_SOURCE" "$WHITELIST_SOURCE"; do
|
||||
[[ -f "$src" ]] || continue # whitelist is optional
|
||||
manifest_sources+=("$(readlink -f "$src")")
|
||||
done
|
||||
|
||||
{
|
||||
sha256sum "${manifest_sources[@]}" || {
|
||||
echo -e "${RED}Failed to checksum wrapper sources${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
sha256sum "$LOCK_LIB_DEST" || {
|
||||
echo -e "${RED}Failed to checksum installed lock lib${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
} >"$SOURCE_MANIFEST"
|
||||
|
||||
if [[ ! -s "$SOURCE_MANIFEST" ]]; then
|
||||
echo -e "${RED}Error: drift manifest was not created or is empty${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
chmod 644 "$SOURCE_MANIFEST"
|
||||
|
||||
# Make policy files immutable to prevent easy tampering
|
||||
echo -e "${BLUE}Protecting policy files from modification...${NC}"
|
||||
if command -v chattr >/dev/null 2>&1; then
|
||||
chattr +i "$BLOCKED_DEST" 2>/dev/null || echo -e "${YELLOW}Warning: Could not make blocked list immutable${NC}"
|
||||
chattr +i "$GREYLIST_DEST" 2>/dev/null || echo -e "${YELLOW}Warning: Could not make greylist immutable${NC}"
|
||||
chattr +i "$LOCK_LIB_DEST" 2>/dev/null || echo -e "${YELLOW}Warning: Could not make lock library immutable${NC}"
|
||||
# Note: whitelist is intentionally left modifiable for user convenience
|
||||
else
|
||||
echo -e "${YELLOW}Warning: chattr not available, policy files will not be immutable${NC}"
|
||||
fi
|
||||
|
||||
# Install LeechBlock installer and defaults if available
|
||||
mkdir -p "$LEECHBLOCK_INSTALL_DIR"
|
||||
if [ -f "$LEECHBLOCK_INSTALLER_SOURCE" ]; then
|
||||
echo -e "${BLUE}Installing LeechBlock installer to ${LEECHBLOCK_INSTALLER_DEST}...${NC}"
|
||||
cp "$LEECHBLOCK_INSTALLER_SOURCE" "$LEECHBLOCK_INSTALLER_DEST"
|
||||
chmod +x "$LEECHBLOCK_INSTALLER_DEST"
|
||||
echo -e "${GREEN}LeechBlock installer deployed to ${LEECHBLOCK_INSTALLER_DEST}${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}LeechBlock installer not found at ${LEECHBLOCK_INSTALLER_SOURCE}, skipping...${NC}"
|
||||
fi
|
||||
if [ -f "$LEECHBLOCK_DEFAULTS_SOURCE" ]; then
|
||||
cp "$LEECHBLOCK_DEFAULTS_SOURCE" "$LEECHBLOCK_DEFAULTS_DEST"
|
||||
echo -e "${GREEN}LeechBlock defaults deployed to ${LEECHBLOCK_DEFAULTS_DEST}${NC}"
|
||||
fi
|
||||
if [ -f "$LEECHBLOCK_SEEDER_SOURCE" ]; then
|
||||
cp "$LEECHBLOCK_SEEDER_SOURCE" "$LEECHBLOCK_SEEDER_DEST"
|
||||
echo -e "${GREEN}LeechBlock seeder deployed to ${LEECHBLOCK_SEEDER_DEST}${NC}"
|
||||
fi
|
||||
if [ -f "$LEECHBLOCK_PKG_SOURCE" ]; then
|
||||
cp "$LEECHBLOCK_PKG_SOURCE" "${LEECHBLOCK_INSTALL_DIR}/package.json"
|
||||
echo -e "${BLUE}Installing Node.js deps in ${LEECHBLOCK_INSTALL_DIR}...${NC}"
|
||||
npm install --prefix "$LEECHBLOCK_INSTALL_DIR" 2>&1 | grep -v '^npm warn' || true
|
||||
fi
|
||||
|
||||
# Install VirtualBox enforcement script if available
|
||||
if [ -f "$VBOX_ENFORCE_SOURCE" ]; then
|
||||
echo -e "${BLUE}Installing VirtualBox hosts enforcement script...${NC}"
|
||||
mkdir -p "$VBOX_INSTALL_DIR"
|
||||
cp "$VBOX_ENFORCE_SOURCE" "$VBOX_ENFORCE_DEST"
|
||||
chmod +x "$VBOX_ENFORCE_DEST"
|
||||
echo -e "${GREEN}VirtualBox enforcement script installed to ${VBOX_ENFORCE_DEST}${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}VirtualBox enforcement script not found, skipping...${NC}"
|
||||
fi
|
||||
write_policy_integrity_file
|
||||
write_drift_manifest
|
||||
protect_policy_files
|
||||
install_leechblock_payload
|
||||
install_vbox_enforcement
|
||||
|
||||
# Create symbolic link
|
||||
echo -e "${BLUE}Creating symbolic link...${NC}"
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
# Copies the wrapper, policy lists and helper scripts into /usr/local/bin.
|
||||
# Sourced by install_pacman_wrapper.sh; inherits the caller's strict mode.
|
||||
|
||||
install_managed_files() {
|
||||
echo -e "${CYAN}Installing pacman wrapper...${NC}"
|
||||
|
||||
# Install the wrapper script
|
||||
echo -e "${BLUE}Copying wrapper script to ${WRAPPER_DEST}...${NC}"
|
||||
copy_managed_file "$WRAPPER_SOURCE" "$WRAPPER_DEST" required "wrapper script"
|
||||
copy_managed_file "$LOCK_LIB_SOURCE" "$LOCK_LIB_DEST" required "stale-lock library"
|
||||
chmod 644 "$LOCK_LIB_DEST"
|
||||
copy_managed_file "$WORDS_SOURCE" "$WORDS_DEST" required "words list"
|
||||
copy_managed_file "$BLOCKED_SOURCE" "$BLOCKED_DEST" required "blocked keywords list"
|
||||
copy_managed_file "$WHITELIST_SOURCE" "$WHITELIST_DEST" optional "whitelist"
|
||||
copy_managed_file "$GREYLIST_SOURCE" "$GREYLIST_DEST" required "greylist"
|
||||
chmod +x "$WRAPPER_DEST"
|
||||
copy_managed_file "$MAKEPKG_CAPPED_SOURCE" "$MAKEPKG_CAPPED_DEST" required "makepkg capped wrapper"
|
||||
chmod +x "$MAKEPKG_CAPPED_DEST"
|
||||
copy_managed_file "$MKPKG_SOURCE" "$MKPKG_DEST" required "mkpkg helper"
|
||||
chmod +x "$MKPKG_DEST"
|
||||
# The heavy-job lock is sourced by pacman_wrapper.sh and makepkg_capped.sh from
|
||||
# a fixed absolute path, so it has to land next to them rather than be read out
|
||||
# of a repo checkout that may move.
|
||||
copy_managed_file "$HEAVY_LOCK_SOURCE" "$HEAVY_LOCK_DEST" required "heavy-job lock library"
|
||||
chmod 755 "$HEAVY_LOCK_DEST"
|
||||
chmod 644 "$WORDS_DEST" "$BLOCKED_DEST" "$WHITELIST_DEST" "$GREYLIST_DEST" 2>/dev/null || true
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
#!/bin/bash
|
||||
# Policy integrity file (chattr +i) and the deployment drift manifest.
|
||||
# Sourced by install_pacman_wrapper.sh; inherits the caller's strict mode.
|
||||
#
|
||||
# test_pacman_wrapper_security.sh greps THIS file's source text for the literal
|
||||
# `sha256sum "$LOCK_LIB_DEST"` -- it asserts the stale-lock library is covered
|
||||
# by the integrity manifest. Keep that line verbatim.
|
||||
|
||||
# Writes $INTEGRITY_FILE and makes it immutable. Exits non-zero if any policy
|
||||
# file is missing, because a partial integrity file is worse than none.
|
||||
write_policy_integrity_file() {
|
||||
# Create integrity directory if it doesn't exist
|
||||
mkdir -p "$INTEGRITY_DIR"
|
||||
chmod 755 "$INTEGRITY_DIR"
|
||||
|
||||
# Generate checksums of policy files for integrity verification
|
||||
echo -e "${BLUE}Generating integrity checksums for policy files...${NC}"
|
||||
unlock_immutable_file_if_needed "$INTEGRITY_FILE"
|
||||
|
||||
# Ensure all critical policy files exist before checksumming
|
||||
missing_files=()
|
||||
[[ ! -f "$BLOCKED_DEST" ]] && missing_files+=("$BLOCKED_DEST")
|
||||
[[ ! -f "$GREYLIST_DEST" ]] && missing_files+=("$GREYLIST_DEST")
|
||||
[[ ! -f "$LOCK_LIB_DEST" ]] && missing_files+=("$LOCK_LIB_DEST")
|
||||
|
||||
if [[ ${#missing_files[@]} -gt 0 ]]; then
|
||||
echo -e "${RED}Error: Critical policy files are missing:${NC}"
|
||||
printf '%s\n' "${missing_files[@]}" >&2
|
||||
echo -e "${RED}Installation incomplete. Cannot create integrity file.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
{
|
||||
sha256sum "$BLOCKED_DEST" || {
|
||||
echo -e "${RED}Failed to checksum blocked list${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
sha256sum "$GREYLIST_DEST" || {
|
||||
echo -e "${RED}Failed to checksum greylist${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
# The shared stale-lock library is executed (sourced) by the wrapper, so it is
|
||||
# integrity-checked too: pacman_wrapper.sh sources it only AFTER
|
||||
# verify_policy_integrity passes, so a tampered lib is rejected before it runs.
|
||||
sha256sum "$LOCK_LIB_DEST" || {
|
||||
echo -e "${RED}Failed to checksum lock library${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
# Whitelist is optional
|
||||
if [[ -f "$WHITELIST_DEST" ]]; then
|
||||
sha256sum "$WHITELIST_DEST" || {
|
||||
echo -e "${RED}Failed to checksum whitelist${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
} >"$INTEGRITY_FILE"
|
||||
|
||||
# Verify integrity file was created and has content
|
||||
if [[ ! -s "$INTEGRITY_FILE" ]]; then
|
||||
echo -e "${RED}Error: Integrity file was not created or is empty${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make integrity file immutable
|
||||
chmod 400 "$INTEGRITY_FILE"
|
||||
if command -v chattr >/dev/null 2>&1; then
|
||||
chattr +i "$INTEGRITY_FILE" 2>/dev/null || echo -e "${YELLOW}Warning: Could not make integrity file immutable${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Record a drift manifest: the hash of every SOURCE file we installed from, and
|
||||
# of the installed copies we produced. check_and_enable_services.sh replays it
|
||||
# with `sha256sum -c`, which answers both questions in one command:
|
||||
# - a source line fails => the repo moved on, this deployment is stale
|
||||
# - a dest line fails => someone edited the installed copy directly
|
||||
# Neither was detectable before: the checker only tested that files EXIST, which
|
||||
# is why a wrapper 7.6 KB behind the repo (no integrity manifest, no
|
||||
# pacman_lock_lib, no guard-lib fallbacks) ran unnoticed for a week while the
|
||||
# hourly maintenance timer kept reporting "ok".
|
||||
# Deliberately NOT chattr +i (unlike the policy integrity file above): this is a
|
||||
# drift record, not a security boundary, and it must be rewritable each install.
|
||||
write_drift_manifest() {
|
||||
echo -e "${BLUE}Recording deployment drift manifest...${NC}"
|
||||
# ABSOLUTE paths only. The SOURCE_* vars are built from `dirname "$0"`, so
|
||||
# they are relative whenever the installer is invoked by a relative path — and
|
||||
# check_and_enable_services.sh replays this manifest from systemd with cwd=/,
|
||||
# where relative entries resolve to nothing. sha256sum -c would report those as
|
||||
# failures, the checker would read that as drift, and it would reinstall on
|
||||
# every single hourly run forever.
|
||||
manifest_sources=()
|
||||
for src in "$WRAPPER_SOURCE" "$LOCK_LIB_SOURCE" "$BLOCKED_SOURCE" "$GREYLIST_SOURCE" \
|
||||
"$MAKEPKG_CAPPED_SOURCE" "$MKPKG_SOURCE" "$WHITELIST_SOURCE"; do
|
||||
[[ -f "$src" ]] || continue # whitelist is optional
|
||||
manifest_sources+=("$(readlink -f "$src")")
|
||||
done
|
||||
|
||||
{
|
||||
sha256sum "${manifest_sources[@]}" || {
|
||||
echo -e "${RED}Failed to checksum wrapper sources${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
sha256sum "$LOCK_LIB_DEST" || {
|
||||
echo -e "${RED}Failed to checksum installed lock lib${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
} >"$SOURCE_MANIFEST"
|
||||
|
||||
if [[ ! -s "$SOURCE_MANIFEST" ]]; then
|
||||
echo -e "${RED}Error: drift manifest was not created or is empty${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
chmod 644 "$SOURCE_MANIFEST"
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
# Immutable-attribute handling and the guarded copy used for every managed file.
|
||||
# Sourced by install_pacman_wrapper.sh; inherits the caller's strict mode.
|
||||
#
|
||||
# RELock_FILES is a global on purpose: copy_managed_file appends to it and the
|
||||
# EXIT trap in the entry script drains it. Its capitalization is preserved from
|
||||
# before the split.
|
||||
|
||||
declare -a RELock_FILES=()
|
||||
|
||||
is_immutable_file() {
|
||||
local file_path="$1"
|
||||
[[ -e "$file_path" ]] || return 1
|
||||
[[ $(lsattr -d "$file_path" 2>/dev/null | awk '{print $1}') == *i* ]]
|
||||
}
|
||||
|
||||
unlock_immutable_file_if_needed() {
|
||||
local file_path="$1"
|
||||
if ! command -v chattr >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
if is_immutable_file "$file_path"; then
|
||||
chattr -i "$file_path"
|
||||
RELock_FILES+=("$file_path")
|
||||
fi
|
||||
}
|
||||
|
||||
relock_files_on_exit() {
|
||||
if ! command -v chattr >/dev/null 2>&1; then
|
||||
return
|
||||
fi
|
||||
for file_path in "${RELock_FILES[@]}"; do
|
||||
[[ -e "$file_path" ]] || continue
|
||||
chattr +i "$file_path" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
|
||||
copy_managed_file() {
|
||||
local source_file="$1"
|
||||
local dest_file="$2"
|
||||
local required="$3"
|
||||
local label="$4"
|
||||
|
||||
if [[ ! -f "$source_file" ]]; then
|
||||
if [[ "$required" == "required" ]]; then
|
||||
echo -e "${RED}Error:${NC} Missing required ${label} at ${source_file}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${YELLOW}Warning:${NC} Missing ${label} at ${source_file}" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
unlock_immutable_file_if_needed "$dest_file"
|
||||
cp "$source_file" "$dest_file"
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
# Policy-file immutability, plus the LeechBlock and VirtualBox payloads.
|
||||
# Sourced by install_pacman_wrapper.sh; inherits the caller's strict mode.
|
||||
|
||||
# Make policy files immutable to prevent easy tampering
|
||||
protect_policy_files() {
|
||||
echo -e "${BLUE}Protecting policy files from modification...${NC}"
|
||||
if command -v chattr >/dev/null 2>&1; then
|
||||
chattr +i "$BLOCKED_DEST" 2>/dev/null || echo -e "${YELLOW}Warning: Could not make blocked list immutable${NC}"
|
||||
chattr +i "$GREYLIST_DEST" 2>/dev/null || echo -e "${YELLOW}Warning: Could not make greylist immutable${NC}"
|
||||
chattr +i "$LOCK_LIB_DEST" 2>/dev/null || echo -e "${YELLOW}Warning: Could not make lock library immutable${NC}"
|
||||
# Note: whitelist is intentionally left modifiable for user convenience
|
||||
else
|
||||
echo -e "${YELLOW}Warning: chattr not available, policy files will not be immutable${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Install LeechBlock installer and defaults if available
|
||||
install_leechblock_payload() {
|
||||
mkdir -p "$LEECHBLOCK_INSTALL_DIR"
|
||||
if [ -f "$LEECHBLOCK_INSTALLER_SOURCE" ]; then
|
||||
echo -e "${BLUE}Installing LeechBlock installer to ${LEECHBLOCK_INSTALLER_DEST}...${NC}"
|
||||
cp "$LEECHBLOCK_INSTALLER_SOURCE" "$LEECHBLOCK_INSTALLER_DEST"
|
||||
chmod +x "$LEECHBLOCK_INSTALLER_DEST"
|
||||
echo -e "${GREEN}LeechBlock installer deployed to ${LEECHBLOCK_INSTALLER_DEST}${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}LeechBlock installer not found at ${LEECHBLOCK_INSTALLER_SOURCE}, skipping...${NC}"
|
||||
fi
|
||||
if [ -f "$LEECHBLOCK_DEFAULTS_SOURCE" ]; then
|
||||
cp "$LEECHBLOCK_DEFAULTS_SOURCE" "$LEECHBLOCK_DEFAULTS_DEST"
|
||||
echo -e "${GREEN}LeechBlock defaults deployed to ${LEECHBLOCK_DEFAULTS_DEST}${NC}"
|
||||
fi
|
||||
if [ -f "$LEECHBLOCK_SEEDER_SOURCE" ]; then
|
||||
cp "$LEECHBLOCK_SEEDER_SOURCE" "$LEECHBLOCK_SEEDER_DEST"
|
||||
echo -e "${GREEN}LeechBlock seeder deployed to ${LEECHBLOCK_SEEDER_DEST}${NC}"
|
||||
fi
|
||||
if [ -f "$LEECHBLOCK_PKG_SOURCE" ]; then
|
||||
cp "$LEECHBLOCK_PKG_SOURCE" "${LEECHBLOCK_INSTALL_DIR}/package.json"
|
||||
echo -e "${BLUE}Installing Node.js deps in ${LEECHBLOCK_INSTALL_DIR}...${NC}"
|
||||
npm install --prefix "$LEECHBLOCK_INSTALL_DIR" 2>&1 | grep -v '^npm warn' || true
|
||||
fi
|
||||
}
|
||||
|
||||
# Install VirtualBox enforcement script if available
|
||||
install_vbox_enforcement() {
|
||||
if [ -f "$VBOX_ENFORCE_SOURCE" ]; then
|
||||
echo -e "${BLUE}Installing VirtualBox hosts enforcement script...${NC}"
|
||||
mkdir -p "$VBOX_INSTALL_DIR"
|
||||
cp "$VBOX_ENFORCE_SOURCE" "$VBOX_ENFORCE_DEST"
|
||||
chmod +x "$VBOX_ENFORCE_DEST"
|
||||
echo -e "${GREEN}VirtualBox enforcement script installed to ${VBOX_ENFORCE_DEST}${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}VirtualBox enforcement script not found, skipping...${NC}"
|
||||
fi
|
||||
}
|
||||
@ -24,7 +24,7 @@ pac_tests_makepkg_and_installer() {
|
||||
|
||||
# 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
|
||||
if grep -qr "MAKEPKG_CAPPED" "$WRAPPER_DIR/install_pacman_wrapper.sh" "$WRAPPER_DIR/lib"; then
|
||||
echo "✓ Installer includes makepkg capped deployment"
|
||||
else
|
||||
echo "✗ Installer does not include makepkg capped deployment"
|
||||
@ -42,7 +42,7 @@ pac_tests_makepkg_and_installer() {
|
||||
|
||||
# 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
|
||||
if grep -qr "MKPKG" "$WRAPPER_DIR/install_pacman_wrapper.sh" "$WRAPPER_DIR/lib"; then
|
||||
echo "✓ Installer includes mkpkg helper deployment"
|
||||
else
|
||||
echo "✗ Installer does not include mkpkg helper deployment"
|
||||
@ -60,7 +60,7 @@ pac_tests_makepkg_and_installer() {
|
||||
|
||||
# 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
|
||||
if grep -qr "unlock_immutable_file_if_needed" "$WRAPPER_DIR/install_pacman_wrapper.sh" "$WRAPPER_DIR/lib"; then
|
||||
echo "✓ Installer immutable-file handling found"
|
||||
else
|
||||
echo "✗ Installer immutable-file handling missing"
|
||||
|
||||
@ -69,7 +69,7 @@ pac_tests_wrapper_and_vbox() {
|
||||
|
||||
# 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
|
||||
if grep -qr "INTEGRITY_FILE" "$WRAPPER_DIR/install_pacman_wrapper.sh" "$WRAPPER_DIR/lib"; then
|
||||
echo "✓ Installer references integrity file"
|
||||
else
|
||||
echo "✗ Installer does not create integrity file"
|
||||
@ -78,7 +78,7 @@ pac_tests_wrapper_and_vbox() {
|
||||
|
||||
# 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
|
||||
if grep -qr "chattr +i" "$WRAPPER_DIR/install_pacman_wrapper.sh" "$WRAPPER_DIR/lib"; then
|
||||
echo "✓ Installer sets immutable attributes"
|
||||
else
|
||||
echo "✗ Installer does not set immutable attributes"
|
||||
@ -106,7 +106,7 @@ pac_tests_wrapper_and_vbox() {
|
||||
|
||||
# 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
|
||||
if grep -qr "VBOX_ENFORCE" "$WRAPPER_DIR/install_pacman_wrapper.sh" "$WRAPPER_DIR/lib"; then
|
||||
echo "✓ Installer includes VirtualBox enforcement script"
|
||||
else
|
||||
echo "✗ Installer does not include VirtualBox enforcement script"
|
||||
|
||||
@ -46,7 +46,7 @@ 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
|
||||
if grep -qF 'sha256sum "$LOCK_LIB_DEST"' "$WRAPPER_DIR/lib/integrity.sh"; then
|
||||
echo "✓ Lock library is included in the integrity manifest"
|
||||
else
|
||||
echo "✗ Lock library not checksummed by installer"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user