apparmor.d/configure

198 lines
5.1 KiB
Plaintext
Raw Normal View History

2021-04-02 19:12:15 +02:00
#!/usr/bin/env bash
# Configure the apparmor.d package
# Copyright (C) 2021 Alexandre Pujol <alexandre@pujol.io>
# SPDX-License-Identifier: GPL-2.0-only
2022-02-22 23:08:58 +01:00
set -eu
2022-02-16 14:29:53 +01:00
2022-06-14 20:39:04 +02:00
DISTRIBUTION="${DIST:-$(lsb_release --id --short)}"
2021-12-04 23:09:20 +01:00
readonly DISTRIBUTION="${DISTRIBUTION,,}"
2021-05-01 15:27:14 +02:00
readonly ROOT=.build
2021-04-02 19:12:15 +02:00
2022-05-02 18:28:26 +02:00
_die() { printf 'Error: %s\n' "$*" >&2 && exit 1; }
2021-12-04 23:09:20 +01:00
_warning() { printf ' Warning: %s\n' "$*" >&2; }
_title() { printf '%s\n' "$*" >&2; }
_msg() { printf ' - %s\n' "$*" >&2; }
2021-04-02 19:12:15 +02:00
2021-09-19 21:39:13 +02:00
# Displace files in the package sources
# $@ List of files to displace
_displace_files() {
for path in "$@"; do
mv "${ROOT:?}/$path" "${ROOT:?}/$path.apparmor.d"
2021-04-02 19:12:15 +02:00
done
}
# Initialize a new clean apparmor.d build directory
initialize() {
2021-12-04 23:09:20 +01:00
rm -rf "${ROOT:?}"
rsync -a ./apparmor.d "$ROOT"
rsync -a ./root "$ROOT"
2021-04-02 19:12:15 +02:00
}
2021-12-04 23:09:20 +01:00
# Ignore profiles and files as defined in dists/ignore/
ignore() {
2021-12-04 23:09:20 +01:00
for name in main.ignore "$DISTRIBUTION.ignore"; do
_msg "Ignore profiles/files in dists/ignore/$name"
while read -r profile; do
[[ "$profile" =~ ^\# ]] && continue
2021-12-05 20:42:42 +01:00
[[ -z "$profile" ]] && continue
2022-05-02 18:28:26 +02:00
if [[ -e "${ROOT:?}/$profile" ]]; then
2021-12-04 23:09:20 +01:00
rm -r "${ROOT:?}/$profile"
else
find "$ROOT/apparmor.d" -iname "$profile" -type f -exec rm {} \;
fi
done <"dists/ignore/$name"
done
}
# Synchronise all profiles in a new apparmor.d directory.
synchronise() {
_msg "Synchronise all profiles."
mv "${ROOT:?}/apparmor.d/groups/"*/* "${ROOT:?}/apparmor.d/"
rm -rf "${ROOT:?}/apparmor.d/groups/"
mv "${ROOT:?}/apparmor.d/profiles-"*-*/* "${ROOT:?}/apparmor.d/"
rm -rf "${ROOT:?}/apparmor.d/profiles-"*
}
# Set the distribution specificities
configure() {
2021-09-19 21:39:13 +02:00
case "$DISTRIBUTION" in
2021-12-04 23:09:20 +01:00
arch)
_msg "Configure libexec."
sed -i -e '/Debian/d' "$ROOT/apparmor.d/tunables/extend"
2021-09-19 21:39:13 +02:00
;;
2022-06-14 20:39:04 +02:00
debian|ubuntu|whonix)
if [[ "$DISTRIBUTION" != "ubuntu" ]]; then
_msg "$DISTRIBUTION does not support abi 3.0 yet."
find "$ROOT/apparmor.d" -type f -exec sed -e '/abi /d' -i {} \;
cp -a dists/debian/abstractions/* $ROOT/apparmor.d/abstractions
2022-06-14 20:39:04 +02:00
cp -a dists/debian/tunables/* $ROOT/apparmor.d/tunables
fi
2021-09-19 21:39:13 +02:00
_msg "Configure libexec."
sed -i -e '/Archlinux/d' "$ROOT/apparmor.d/tunables/extend"
2021-09-19 21:39:13 +02:00
2021-12-04 23:09:20 +01:00
_msg "Displace overwritten files."
2021-09-19 21:39:13 +02:00
_displace_files apparmor.d/tunables/global apparmor.d/tunables/xdg-user-dirs
;;
2022-05-02 18:28:26 +02:00
*) _die "$DISTRIBUTION is not a supported distribution." ;;
2021-09-19 21:39:13 +02:00
esac
}
# Set flags on some profile
2021-12-04 23:09:20 +01:00
flags() {
for name in main.flags "$DISTRIBUTION.flags"; do
_msg "Set profiles flags from dists/flags/$name"
while read -r profile; do
2022-05-02 18:28:26 +02:00
IFS=' ' read -r -a manifest <<<"$profile"
2022-02-22 23:08:58 +01:00
profile="${manifest[0]:-}" flags="${manifest[1]:-}"
2021-12-04 23:09:20 +01:00
[[ "$profile" =~ ^\# || -z "$profile" ]] && continue
path="${ROOT:?}/apparmor.d/$profile"
if [[ ! -f "$path" ]]; then
_warning "Profile $profile not found"
continue
fi
2021-12-04 23:09:20 +01:00
# If flags is set, overwrite profile flag
if [[ -n "$flags" ]]; then
# Remove all flags definition, then set manifest' flags
sed -e "s/flags=(.*)//" \
-e "s/ {$/ flags=(${flags//,/ }) {/" \
-i "$path"
fi
2021-12-04 23:09:20 +01:00
done <"dists/flags/$name"
done
}
# Internal complain process
_complain() {
local start="$1" end="$2"; shift 2
files=("$@")
ii="$start"
while [[ $ii -le $end && $ii -lt $len ]]; do
path="${files[$ii]}"
(( ii = ii + 1 ))
[[ -f "$path" ]] || continue
flags="$(grep -o -m 1 'flags=(.*)' "$path" | cut -d '(' -f2 | cut -d ')' -f1)"
[[ "$flags" =~ complain ]] && continue
sed -e "s/flags=(.*)//" \
2022-05-02 18:28:26 +02:00
-e "s/ {$/ flags=(complain $flags) {/" \
-i "$path"
done
}
# Set complain flag on all profile (Dev only)
complain() {
local len nprof nproc
_msg "Set complain flag on all profiles"
mapfile -t files < <(find "${ROOT:?}/apparmor.d" -type f)
len="${#files[@]}"
nproc=$(nproc)
(( nprof = len/nproc + 1 ))
start=0
end=$nprof
for ((ii = 0 ; ii < nproc ; ii++)); do
_complain $start $end "${files[@]}" &
(( start = end + 1 ))
(( end = end + nprof ))
done
wait
echo
2021-04-02 19:12:15 +02:00
}
2021-12-04 23:09:20 +01:00
# Set AppArmor for full system policy
# See https://gitlab.com/apparmor/apparmor/-/wikis/FullSystemPolicy
full() {
cp -a apparmor.d/groups/_full/* "$ROOT/apparmor.d/"
}
2021-04-02 19:12:15 +02:00
# Print help message
cmd_help() {
cat <<-_EOF
./configure [options] - Configure the apparmor.d package
Options:
2021-12-04 23:09:20 +01:00
-f, --full Set AppArmor for full system policy
-c, --complain Set complain flag on all profiles
-h, --help Print this help message and exit
2021-04-02 19:12:15 +02:00
_EOF
}
main() {
2021-12-04 23:09:20 +01:00
local opts err
FULL=0
COMPLAIN=0
small_arg="cfh"
long_arg="complain,full,help"
2022-02-16 14:29:53 +01:00
opts="$(getopt -o $small_arg -l $long_arg -n "configure" -- "$@")"
2021-04-02 19:12:15 +02:00
err=$?
eval set -- "$opts"
while true; do case $1 in
2021-12-04 23:09:20 +01:00
-f|--full) FULL=1; shift ;;
-c|--complain) COMPLAIN=1; shift ;;
2021-04-02 19:12:15 +02:00
-h|--help) shift; cmd_help; exit 0 ;;
--) shift; break ;;
esac done
[[ $err -ne 0 ]] && { cmd_help; exit 1; }
2021-12-04 23:09:20 +01:00
_title "Set the configuration for $DISTRIBUTION."
initialize || _die "initializing build directory"
ignore || _die "removing ignored profiles"
synchronise || _die "merging profiles"
2021-12-04 23:09:20 +01:00
configure || _die "configuring distributaion"
flags || _die "settings flags"
[[ "$COMPLAIN" == 1 ]] && complain
[[ "$FULL" == 1 ]] && full
return 0
2021-04-02 19:12:15 +02:00
}
main "$@"