update/sw-patch/bin/rpm-audit

184 lines
4.0 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright (c) 2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
if [[ $EUID -ne 0 ]]; then
echo "This utility must be run as root." >&2
exit 1
fi
function show_usage()
{
cat <<EOF
Usage: [ --include-pyc ] [ --include-cfg ] --skip-multi [ pkg ... ]
This utility scans the installed RPMs to compare checksums of files.
By default, files flagged as config are skipped, as are python pyc files.
Optional arguments:
--include-pyc : Include pyc files in check
--include-cfg : Include config files in check
--skip-links : Skip symlink check
--skip-multi : Skip the search for files with multiple owners
pkg : Specify one or more packages to limit the scan
(implies --skip-multi)
EOF
exit 1
}
declare INCLUDE_PYTHON_FILES="no"
declare INCLUDE_CFG_FILES="no"
declare CHECK_FOR_MULTI="yes"
declare CHECK_LINKS="yes"
declare TIS_ONLY="yes"
declare CHECK_RPM=
for arg in "$@"
do
case $arg in
-h|--help)
show_usage
;;
--include-pyc)
INCLUDE_PYTHON_FILES="yes"
;;
--include-cfg)
INCLUDE_CFG_FILES="yes"
;;
--skip-links)
CHECK_LINKS="no"
;;
--skip-multi)
CHECK_FOR_MULTI="no"
;;
--all-rpms)
TIS_ONLY="no"
;;
*)
CHECK_RPM="$CHECK_RPM $arg"
CHECK_FOR_MULTI="no"
;;
esac
done
function rpm_list()
{
if [ -n "$CHECK_RPM" ]
then
for pkg in $CHECK_RPM
do
echo $pkg
done
elif [ "$TIS_ONLY" = "yes" ]
then
rpm -qa | grep '\.tis\.' | sort
else
rpm -qa | sort
fi
}
rpm_list | while read pkg
do
# Get the --dump from the pkg
rpm -q --queryformat "[%{FILENAMES}|%{FILEMD5S}|%{FILEFLAGS:fflags}|%{FILELINKTOS}\n]" $pkg | \
while IFS='|' read pname psum pflags plinkto
do
if [[ $pname == "(contains" ]]
then
# (contains no files)
continue
fi
if [[ $INCLUDE_CFG_FILES == "no" && $pflags =~ c ]]
then
# Skip file already flagged as config
continue
fi
if [[ $INCLUDE_PYTHON_FILES == "no" && $pname =~ \.py[co]$ ]]
then
# Skip python .pyo or .pyc file
continue
fi
# Directories and symlinks will have no checksum
if [[ -z $psum ]]
then
if [[ -n $plinkto && $CHECK_LINKS == "yes" ]]
then
# Check the symlink pointer
flinkto=$(readlink $pname)
if [[ "$flinkto" != "$plinkto" ]]
then
echo "Link Mismatch: $pname ($pkg)"
fi
fi
continue
fi
# Does the file exist?
if [ ! -e "$pname" ]
then
echo "Missing: $pname ($pkg)"
continue
fi
# Has the file been replaced by a symlink? ie. update-alternatives
if [ -L "$pname" ]
then
continue
fi
let -i sumlen=$(echo -n $psum | wc -c)
if [ $sumlen = 64 ]
then
sumcmd=sha256sum
else
sumcmd=md5sum
fi
echo $psum $pname | $sumcmd --check --status
if [ $? -ne 0 ]
then
echo "Mismatch: $pname ($pkg)"
fi
done
done
function check_for_multi_master()
{
# Search for files owned by multiple packages
prev=
rpm_list | xargs rpm -q --queryformat "[%{FILENAMES}|%{=NAME}\n]" | sort | while IFS='|' read f p
do
if [ "$f" = "$prev" ]
then
echo $f
fi
prev=$f
done | sort -u | while read f
do
if [ ! -d "$f" ]
then
echo $f
fi
done
}
if [ $CHECK_FOR_MULTI = "yes" ]
then
echo
echo
echo "The following files belong to multiple packages:"
echo
check_for_multi_master
fi