feat: blocked and allowed list for pacman wrapper

This commit is contained in:
Krzysztof kuhy Rudnicki 2025-10-16 19:48:12 +02:00
parent 1e85350d5a
commit 3dd6a06e3a
4 changed files with 131 additions and 28 deletions

View File

@ -20,9 +20,13 @@ NC='\033[0m' # No Color
# Script locations # Script locations
WRAPPER_SOURCE="$(dirname "$0")/pacman_wrapper.sh" WRAPPER_SOURCE="$(dirname "$0")/pacman_wrapper.sh"
WORDS_SOURCE="$(dirname "$0")/words.txt" WORDS_SOURCE="$(dirname "$0")/words.txt"
BLOCKED_SOURCE="$(dirname "$0")/pacman_blocked_keywords.txt"
WHITELIST_SOURCE="$(dirname "$0")/pacman_whitelist.txt"
INSTALL_DIR="/usr/local/bin" INSTALL_DIR="/usr/local/bin"
WRAPPER_DEST="${INSTALL_DIR}/pacman_wrapper" WRAPPER_DEST="${INSTALL_DIR}/pacman_wrapper"
WORDS_DEST="${INSTALL_DIR}/words.txt" WORDS_DEST="${INSTALL_DIR}/words.txt"
BLOCKED_DEST="${INSTALL_DIR}/pacman_blocked_keywords.txt"
WHITELIST_DEST="${INSTALL_DIR}/pacman_whitelist.txt"
# Check if script is run as root # Check if script is run as root
if [ "$EUID" -ne 0 ]; then if [ "$EUID" -ne 0 ]; then
echo -e "${RED}Please run as root${NC}" echo -e "${RED}Please run as root${NC}"
@ -41,7 +45,19 @@ echo -e "${CYAN}Installing pacman wrapper...${NC}"
echo -e "${BLUE}Copying wrapper script to ${WRAPPER_DEST}...${NC}" echo -e "${BLUE}Copying wrapper script to ${WRAPPER_DEST}...${NC}"
cp "$WRAPPER_SOURCE" "$WRAPPER_DEST" cp "$WRAPPER_SOURCE" "$WRAPPER_DEST"
cp "$WORDS_SOURCE" "$WORDS_DEST" cp "$WORDS_SOURCE" "$WORDS_DEST"
if [ -f "$BLOCKED_SOURCE" ]; then
cp "$BLOCKED_SOURCE" "$BLOCKED_DEST"
else
echo -e "${YELLOW}Warning:${NC} Missing blocked keywords source at ${BLOCKED_SOURCE}${NC}"
fi
if [ -f "$WHITELIST_SOURCE" ]; then
cp "$WHITELIST_SOURCE" "$WHITELIST_DEST"
else
echo -e "${YELLOW}Warning:${NC} Missing whitelist source at ${WHITELIST_SOURCE}${NC}"
fi
chmod +x "$WRAPPER_DEST" chmod +x "$WRAPPER_DEST"
chmod 644 "$WORDS_DEST" "$BLOCKED_DEST" "$WHITELIST_DEST" 2>/dev/null || true
# Automatically use symbolic link installation method # Automatically use symbolic link installation method
echo -e "${YELLOW}Installing using symbolic link method...${NC}" echo -e "${YELLOW}Installing using symbolic link method...${NC}"
@ -49,7 +65,6 @@ echo -e "${YELLOW}Installing using symbolic link method...${NC}"
# Backup original pacman # Backup original pacman
if [ ! -f "/usr/bin/pacman.orig" ]; then if [ ! -f "/usr/bin/pacman.orig" ]; then
echo -e "${BLUE}Backing up original pacman to /usr/bin/pacman.orig...${NC}" echo -e "${BLUE}Backing up original pacman to /usr/bin/pacman.orig...${NC}"
cp ./
cp /usr/bin/pacman /usr/bin/pacman.orig cp /usr/bin/pacman /usr/bin/pacman.orig
fi fi

View File

@ -0,0 +1,54 @@
# Packages matching any of these substrings are blocked.
# Lines starting with # are comments.
firefox
librewolf
waterfox
icecat
floorp
zen-browser
tor-browser
torbrowser
mullvad-browser
basilisk
palemoon
iceweasel
abrowser
cliqz
brave
freetube
seamonkey
min-browser
beaker-browser
catalyst-browser
hamsket
min
vieb
yt-dlp
stremio
angelfish
dooble
eric
falkon
fiery
maui
konqueror
liri
otter
quotebrowser
beaker
catalyst
badwolf
eolie
epiphany
surf
uzbl
vimb
web-browser
luakit
nyxt
tangram
dillo
links
netsurf
amfora
tartube

View File

@ -0,0 +1,13 @@
# Exact package names that should bypass the block even if matching a keyword.
minizip
miniupnpc
haskell-generically
haskell-streaming-commons
haskell-prettyprinter-ansi-terminal
haskell-generics-sop
haskell-ansi-terminal
minizip-ng
ruby-mini_portile2
texlive-plaingeneric
haskell-ansi-terminal-types
terminator

View File

@ -12,6 +12,44 @@ BOLD='\033[1m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
PACMAN_BIN="/usr/bin/pacman" PACMAN_BIN="/usr/bin/pacman"
declare -a BLOCKED_KEYWORDS_LIST=()
declare -a WHITELISTED_NAMES_LIST=()
POLICY_LISTS_LOADED=0
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"
if [[ -f "$blocked_file" ]]; then
mapfile -t BLOCKED_KEYWORDS_LIST < <(sed 's/\r$//' "$blocked_file" | grep -Ev '^[[:space:]]*(#|$)' || true)
else
BLOCKED_KEYWORDS_LIST=()
echo -e "${YELLOW}Warning:${NC} Missing blocked keywords file at $blocked_file" >&2
fi
if [[ -f "$whitelist_file" ]]; then
mapfile -t WHITELISTED_NAMES_LIST < <(sed 's/\r$//' "$whitelist_file" | grep -Ev '^[[:space:]]*(#|$)' || true)
else
WHITELISTED_NAMES_LIST=()
fi
for i in "${!BLOCKED_KEYWORDS_LIST[@]}"; do
BLOCKED_KEYWORDS_LIST[$i]="${BLOCKED_KEYWORDS_LIST[$i],,}"
done
for i in "${!WHITELISTED_NAMES_LIST[@]}"; do
WHITELISTED_NAMES_LIST[$i]="${WHITELISTED_NAMES_LIST[$i],,}"
done
POLICY_LISTS_LOADED=1
}
# Determine if this invocation may perform a transaction (upgrade/install/remove) # Determine if this invocation may perform a transaction (upgrade/install/remove)
needs_unlock() { needs_unlock() {
# If args include -S (install/upgrade), -U (local install), or -R (remove), we unlock # If args include -S (install/upgrade), -U (local install), or -R (remove), we unlock
@ -138,38 +176,21 @@ function display_operation() {
# Helper: return 0 if the given package name is blocked by policy # Helper: return 0 if the given package name is blocked by policy
function is_blocked_package_name() { function is_blocked_package_name() {
local name="$1" load_policy_lists
# Normalize to package base (strip any repo prefix already done by caller) local normalized="${1,,}"
# Broad block: Firefox family and derivatives (covers -bin/-git and similar suffixes)
if [[ $name =~ ^firefox($|[-_]) ]]; then
return 0
fi
if [[ $name =~ ^(librewolf|waterfox|icecat|floorp|zen-browser|tor-browser|mullvad-browser|basilisk|palemoon|iceweasel|abrowser|cliqz)($|[-_]) ]]; then
return 0
fi
# Explicitly blocked names list for allowed in "${WHITELISTED_NAMES_LIST[@]}"; do
local blocked=( if [[ "$normalized" == "$allowed" ]]; then
"brave" "brave-bin" "freetube" "seamonkey-bin" "seamonkey" "min-browser-bin" "min-browser" "beaker-browser" "catalyst-browser-bin" "hamsket" "min" return 1
"vieb-bin" "yt-dlp" "yt-dlp-git" "stremio" "stremio-git" "angelfish" "dooble" "eric" "falkon" "fiery" "maui" "konqueror" "liri" "otter" fi
"quotebrowser" "beaker" "catalyst" "badwolf" "eolie" "epiphany" "surf" "uzbl" "vimb" "vimb-git" "web-browser" "web-browser-git" done
"web-browser-bin" "web-browser-bin-git" "web-browser-bin-git" "luakit" "nyxt" "tangram" "vimb" "dillo" "links" "netsurf" "amfora" "tartube"
# Firefox and prominent Firefox-based browsers/variants (explicit names) for keyword in "${BLOCKED_KEYWORDS_LIST[@]}"; do
"firefox" "firefox-bin" "firefox-esr" "firefox-esr-bin" "firefox-beta" "firefox-beta-bin" if [[ -n "$keyword" && "$normalized" == *"$keyword"* ]]; then
"firefox-developer-edition" "firefox-developer-edition-bin" "firefox-nightly" "firefox-nightly-bin"
"firefox-appmenu" "firefox-appmenu-bin" "firefox-kde-opensuse"
"librewolf" "librewolf-bin" "waterfox" "waterfox-bin" "waterfox-current-bin" "waterfox-classic-bin" "waterfox-g3-bin"
"icecat" "icecat-bin" "floorp" "floorp-bin" "zen-browser" "zen-browser-bin"
"tor-browser" "tor-browser-bin" "torbrowser-launcher" "mullvad-browser" "mullvad-browser-bin"
"basilisk" "basilisk-bin" "palemoon" "palemoon-bin" "iceweasel" "iceweasel-bin" "abrowser" "cliqz"
)
for pkg in "${blocked[@]}"; do
if [[ "$name" == "$pkg" ]]; then
return 0 return 0
fi fi
done done
return 1 return 1
} }