Mini Shell

Direktori : /usr/bin/
Upload File :
Current File : //usr/bin/ima-add-sigs

#!/usr/bin/bash
#
# This script add IMA signatures to installed RPM package files
# Usage: add_ima_sigs.sh [--package=PACKAGE_NAME|ALL] [--ima-cert=IMA_CERT_PATH] [--reinstall_threshold=NUM]
#
# By default, it will add IMA sigantures to all installed package files. Or you
# can provide a package name to only add IMA signature for files of specicifed
# package.  If it detects >=20 packages (or 1 package if you specify a package
# name) missing signatures in the RPM database, it will reinstall the packages
# in order to get the IMA signatures.
#
# With the signing IMA cert path specified, it will also try to verify
# the added IMA signature.

for _opt in "$@"; do
	case "$_opt" in
	--reinstall_threshold=*)
		reinstall_threshold=${_opt#*=}
		;;
	--package=*)
		package=${_opt#*=}
		;;
	--ima_cert=*)
		ima_cert=${_opt#*=}
		;;
	*)
		usage
		;;
	esac
done

if [[ -z $package ]] || [[ $package == ALL ]]; then
	package="--all"
fi

abort() {
	echo "$1"
	exit 1
}

# Add IMA signatures from RPM database
add_from_rpm_db() {
	if ! command -v setfattr &>/dev/null; then
			abort "Please install attr"
	fi

	# use "|" as deliminator since it won't be used in a filename or signature
	while IFS="|" read -r path sig; do
		# [[ -z "$sig" ]] somehow doesn't work for some files that don't have IMA
		# signatures. This may be a issue of rpm
		if [[ "$sig" != "0"* ]]; then
			continue
		fi

		# Skip directory, soft links, non-existent files and vfat fs
		if [[ -d "$path" || -L "$path" || ! -f "$path" || "$path" == "/boot/efi/EFI/"* ]]; then
			continue
		fi

		if ! setfattr -n security.ima "$path" -v "0x$sig"; then
			echo "Failed to add IMA sig for $path"
		fi

		[[ -e "$ima_cert" ]] || continue
		# TODO
		# don't verify the modified files like /etc?
		if ! evmctl ima_verify -k "$ima_cert" "$path" &>/dev/null; then
			echo "Failed to verify $path"
		fi
	done < <(rpm -q --queryformat "[%{FILENAMES}|%{FILESIGNATURES}\n]" "$package")
}

# Add IMA signatures by reinstalling all packages
add_by_reinstall() {
	[[ $package == "--all" ]] && package='*'
	dnf reinstall "$package" -yq >/dev/null
}

if [[ -z $reinstall_threshold ]]; then
	if [[ $package == "--all" ]]; then
		reinstall_threshold=20
	else
		if ! rpm -q --quiet $package; then
			dnf install "$package" -yq >/dev/null
			exit 0
		fi
		reinstall_threshold=1
	fi
fi

unsigned_packages_in_rpm_db=$(rpm -q --queryformat "%{SIGPGP:pgpsig}\n" $package | grep "^(none)$" | wc -l)

if [[ $unsigned_packages_in_rpm_db -ge $reinstall_threshold ]]; then
	add_by_reinstall
else
	add_from_rpm_db
fi

Zerion Mini Shell 1.0