mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 18:07:06 +01:00
Two levels of pure taxonomy carrying no information, and a 2-directory
cap leaves no room for them. Categories now sit directly under
linux_configuration/: features, fixes, utils, misc, fresh-install,
installers, diagnostics, gaming, boot_recovery, periodic_background, lib,
meta, tests. A script's own lib/ and tests/ are exempt from the cap, so
those stay put.
Depth violations 248 -> 139; roughly 40 of the remainder are inside
digital_wellbeing and hosts, deferred until the guard-lib repoint.
The moves are the easy half. What breaks is every path that counted
levels, and three classes of it had to be found by resolving paths rather
than reading diffs:
- 52 relative `source` lines for lib/common.sh and lib/android.sh. The
correct prefix differs per file: 40 were ../../ and 12 were ../../../,
so a blanket replace would have fixed one set and broken the other.
- REPO_ROOT in 7 fixes/lib/tests harnesses and setup_syncyomi_guard.sh,
each walking up four levels from a directory now two levels shallower.
This caused a real regression -- the fixes suite went red with
"log_warn: command not found" -- caught by running it and comparing
against the pre-move baseline worktree.
- conftest.py's sys.path entries, which took the pytest gate down with
14 collection errors, and the `# shellcheck source=` directives, which
took shellcheck down with SC1091.
16 symlinks in $HOME broke, including the entire i3blocks bar. All
repointed, and cpu_monitor/memory/disk/time/volume were run to confirm
they emit real output rather than merely resolving.
Verified: 1798 tests pass at 100% coverage, 8 of 9 lib/tests suites pass
(the ninth needs the coverage jail, identically at baseline), pre-commit
is clean, and the two untracked secret configs are still ignored after
their gitignore paths changed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
199 lines
6.2 KiB
Bash
Executable File
199 lines
6.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Helpers sourced by the entry script.
|
|
|
|
# Declared here rather than in the entry script: this is the only file that
|
|
# reads or writes them, and a cross-file global the sourcing script cannot
|
|
# see is a genuine SC2034 (the hook runs shellcheck without -x).
|
|
declare -a BLOCKED_KEYWORDS_LIST=()
|
|
declare -a WHITELISTED_NAMES_LIST=()
|
|
declare -a GREYLISTED_KEYWORDS_LIST=()
|
|
POLICY_LISTS_LOADED=0
|
|
INTEGRITY_DIR="/var/lib/pacman-wrapper"
|
|
INTEGRITY_FILE="${INTEGRITY_DIR}/policy.sha256"
|
|
|
|
# Verify integrity of policy files
|
|
verify_policy_integrity() {
|
|
if [[ ! -f $INTEGRITY_FILE ]]; then
|
|
echo -e "${RED}SECURITY WARNING: Policy integrity file missing!${NC}" >&2
|
|
echo -e "${RED}The pacman wrapper may have been tampered with.${NC}" >&2
|
|
echo -e "${RED}Please reinstall the wrapper using: sudo install_pacman_wrapper.sh${NC}" >&2
|
|
return 1
|
|
fi
|
|
|
|
local script_dir
|
|
script_dir="$(dirname "$(readlink -f "$0")")"
|
|
local blocked_file="$script_dir/pacman_blocked_keywords.txt"
|
|
local greylist_file="$script_dir/pacman_greylist.txt"
|
|
local whitelist_file="$script_dir/pacman_whitelist.txt"
|
|
|
|
# Verify checksums
|
|
local failed=0
|
|
while IFS= read -r line; do
|
|
local expected_hash expected_file
|
|
expected_hash=$(echo "$line" | awk '{print $1}')
|
|
expected_file=$(echo "$line" | awk '{print $2}')
|
|
|
|
if [[ -f $expected_file ]]; then
|
|
local actual_hash
|
|
actual_hash=$(sha256sum "$expected_file" 2>/dev/null | awk '{print $1}')
|
|
if [[ $actual_hash != "$expected_hash" ]]; then
|
|
echo -e "${RED}SECURITY WARNING: Policy file integrity check failed for $expected_file${NC}" >&2
|
|
failed=1
|
|
fi
|
|
fi
|
|
done <"$INTEGRITY_FILE"
|
|
|
|
if [[ $failed -eq 1 ]]; then
|
|
echo -e "${RED}CRITICAL: Policy files have been tampered with!${NC}" >&2
|
|
echo -e "${RED}This could be an attempt to bypass security restrictions.${NC}" >&2
|
|
echo -e "${RED}Wrapper operation DENIED. Please reinstall using: sudo install_pacman_wrapper.sh${NC}" >&2
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# shellcheck disable=SC2329 # invoked indirectly, see is_blocked_package_name/is_greylisted_package_name callers below
|
|
load_policy_lists() {
|
|
if [[ $POLICY_LISTS_LOADED -eq 1 ]]; then
|
|
return
|
|
fi
|
|
|
|
local script_dir
|
|
script_dir="$(dirname "$(readlink -f "$0")")"
|
|
local blocked_file="$script_dir/pacman_blocked_keywords.txt"
|
|
local whitelist_file="$script_dir/pacman_whitelist.txt"
|
|
local greylist_file="$script_dir/pacman_greylist.txt"
|
|
|
|
read_policy_list_file() {
|
|
local file_path="$1"
|
|
local -n target_array="$2"
|
|
local line=""
|
|
|
|
target_array=()
|
|
while IFS= read -r line || [[ -n $line ]]; do
|
|
line="${line%$'\r'}"
|
|
if [[ $line =~ ^[[:space:]]*(#|$) ]]; then
|
|
continue
|
|
fi
|
|
target_array+=("${line,,}")
|
|
done <"$file_path"
|
|
}
|
|
|
|
if [[ -f $blocked_file ]]; then
|
|
read_policy_list_file "$blocked_file" BLOCKED_KEYWORDS_LIST
|
|
else
|
|
BLOCKED_KEYWORDS_LIST=()
|
|
echo -e "${YELLOW}Warning:${NC} Missing blocked keywords file at $blocked_file" >&2
|
|
fi
|
|
|
|
if [[ -f $whitelist_file ]]; then
|
|
read_policy_list_file "$whitelist_file" WHITELISTED_NAMES_LIST
|
|
else
|
|
WHITELISTED_NAMES_LIST=()
|
|
fi
|
|
|
|
if [[ -f $greylist_file ]]; then
|
|
read_policy_list_file "$greylist_file" GREYLISTED_KEYWORDS_LIST
|
|
else
|
|
GREYLISTED_KEYWORDS_LIST=()
|
|
fi
|
|
|
|
POLICY_LISTS_LOADED=1
|
|
}
|
|
|
|
# Helper: strip a pacman package-file suffix (-<pkgver>-<pkgrel>-<arch>.pkg.tar.<ext>)
|
|
# down to the bare package name, if present. `pacman -U <path>` (what `yay`
|
|
# always uses to install a package it just built locally) passes a filename
|
|
# like "ungoogled-chromium-bin-150.0.7871.186-1-x86_64.pkg.tar.zst", not the
|
|
# bare name — without this, an exact-match whitelist entry for
|
|
# "ungoogled-chromium-bin" could never match a `-U` install and would always
|
|
# fall through to the (correctly still-substring) blocked-keywords check.
|
|
# Leaves package names without this suffix (the `-S` case) untouched.
|
|
# shellcheck disable=SC2329 # invoked indirectly by name (is_blocked_package_name)
|
|
function strip_pkgfile_suffix() {
|
|
local name="$1"
|
|
if [[ $name =~ ^(.+)-[^-]+-[0-9]+-(x86_64|any|i686|aarch64)\.pkg\.tar\.(zst|xz|gz|bz2|lrz|lzo|Z)$ ]]; then
|
|
printf '%s' "${BASH_REMATCH[1]}"
|
|
else
|
|
printf '%s' "$name"
|
|
fi
|
|
}
|
|
|
|
# Helper: return 0 if the given package name is blocked by policy
|
|
# shellcheck disable=SC2329 # invoked indirectly by name (remove_installed_packages_matching, check_install_for)
|
|
function is_blocked_package_name() {
|
|
load_policy_lists
|
|
local normalized="${1,,}"
|
|
local bare_name
|
|
bare_name="$(strip_pkgfile_suffix "$normalized")"
|
|
|
|
for allowed in "${WHITELISTED_NAMES_LIST[@]}"; do
|
|
if [[ $normalized == "$allowed" || $bare_name == "$allowed" ]]; then
|
|
return 1
|
|
fi
|
|
done
|
|
|
|
for keyword in "${BLOCKED_KEYWORDS_LIST[@]}"; do
|
|
if [[ $normalized == *"$keyword"* ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
# Helper: return 0 if the given package name is greylisted (challenge required)
|
|
# shellcheck disable=SC2329 # invoked indirectly by name (remove_installed_packages_matching, check_install_for)
|
|
function is_greylisted_package_name() {
|
|
load_policy_lists
|
|
local normalized="${1,,}"
|
|
|
|
for keyword in "${GREYLISTED_KEYWORDS_LIST[@]}"; do
|
|
if [[ $normalized == *"$keyword"* ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
# Helper: Check if this is an install command and run a filter on each package name
|
|
# Usage: check_install_for filter_func "$@"
|
|
# Returns 0 if filter_func matches any package
|
|
function check_install_for() {
|
|
local filter_func="$1"
|
|
shift
|
|
# Check if the command is an installation command
|
|
if [[ ${1:-} == "-S" || ${1:-} == "-Sy" || ${1:-} == "-Syu" || ${1:-} == "-Syyu" || ${1:-} == "-U" ]]; then
|
|
for arg in "$@"; do
|
|
# Strip repository prefix if present (like extra/ or community/)
|
|
local package_name="${arg##*/}"
|
|
if "$filter_func" "$package_name"; then
|
|
return 0
|
|
fi
|
|
done
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Function to check if user is trying to install packages that are always blocked
|
|
function check_for_always_blocked() {
|
|
check_install_for is_blocked_package_name "$@"
|
|
}
|
|
|
|
# Helper to check if a package name is steam
|
|
# shellcheck disable=SC2329 # invoked indirectly by name (check_install_for)
|
|
function is_steam_package() {
|
|
[[ $1 == "steam" ]]
|
|
}
|
|
|
|
# Function to check if user is trying to install steam (challenge-eligible package)
|
|
function check_for_steam() {
|
|
check_install_for is_steam_package "$@"
|
|
}
|
|
|
|
function check_for_greylisted() {
|
|
check_install_for is_greylisted_package_name "$@"
|
|
}
|