#!/usr/bin/env bash # Copyright 2009 Red Hat Inc., Durham, North Carolina. # All Rights Reserved. # # OpenScap Testing Helpers. # # Authors: # Ondrej Moris # Normalized path. PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin PREFERRED_PYTHON=@PREFERRED_PYTHON_PATH@ # Some of the tests rely on the "C" locale and would fail with some locales. LC_ALL=C export LC_ALL OSCAP_FULL_VALIDATION=1 export OSCAP_FULL_VALIDATION if [ -z ${CUSTOM_OSCAP+x} ] ; then enable_valgrind="@ENABLE_VALGRIND@" if [ $enable_valgrind != "OFF" ] ; then actualdir=@CMAKE_BINARY_DIR@ export actualdir [ -z "@CMAKE_BINARY_DIR@" ] || export OSCAP="@CMAKE_SOURCE_DIR@/tests/valgrind_test.sh" else [ -z "@CMAKE_BINARY_DIR@" ] || export OSCAP="bash @CMAKE_BINARY_DIR@/run @CMAKE_BINARY_DIR@/utils/oscap" fi [ -z "@CMAKE_BINARY_DIR@" ] || export OSCAP_CHROOTABLE_EXEC="@CMAKE_BINARY_DIR@/utils/oscap-chrootable" [ -z "@CMAKE_BINARY_DIR@" ] || export OSCAP_CHROOTABLE="bash @CMAKE_BINARY_DIR@/run $OSCAP_CHROOTABLE_EXEC" else export OSCAP=${CUSTOM_OSCAP} fi export XMLDIFF="@CMAKE_SOURCE_DIR@/tests/xmldiff.pl" if ! XPATH_ORIG=`command -v xpath 2>&1`; then echo "I require xpath tool but it's not installed. Aborting." >&2 exit 1 fi xpath_variant=$(perl -MXML::XPath -e 'print $XML::XPath::VERSION >= 1.34 ? "need_wrapper" : "standard"') if [ "$xpath_variant" == "need_wrapper" ]; then export XPATH_ORIG xpath_wrapper() { if [ "$#" == "1" ]; then # read file from stdin xpath_expr="$1" "$XPATH_ORIG" -e "$xpath_expr" elif [ "$#" == "2" ]; then file="$1" xpath_expr="$2" "$XPATH_ORIG" -e "$xpath_expr" "$file" else echo "Parameters are not supported by xpath wrapper" >&2 exit 1 fi } export -f xpath_wrapper export XPATH=xpath_wrapper else export XPATH="$XPATH_ORIG" fi # Overall test result. result=0 # Set-up testing environment. function test_init { : } # Execute test and report its results. function test_run { printf "+ %-60s\n" "$1"; echo -e "TEST: $1" >&2; shift ( exec 1>&2 ; eval "$@" ) ret_val=$? if [ $ret_val -eq 0 ]; then echo -e "RESULT: PASSED\n" >&2 return 0; elif [ $ret_val -eq 1 ]; then result=$(($result + $ret_val)) echo -e "RESULT: FAILED\n" >&2 return 1; elif [ $ret_val -eq 255 ]; then echo -e "RESULT: SKIPPED\n" >&2 return 0; else result=$(($result + $ret_val)) echo -e "RESULT: WARNING (unknown exist status $ret_val)\n" >&2 return 1; fi } # Clean-up testing environment. function test_exit { if [ $# -eq 1 ] then ( exec 1>&2 ; eval "$@" ) fi [ $result -eq 0 ] && exit 0 exit 1 } # Check if requirements are in a path, use it as follows: # require 'program' || return 255 function require { eval "which $1 > /dev/null 2>&1" if [ ! $? -eq 0 ]; then echo -e "No '$1' found in $PATH!\n" return 1; # Test is not applicable. fi return 0 } # Check if probe exists, use it as follows: # probecheck 'probe' || return 255 function probecheck { if ! $OSCAP --version | grep "\<"$1"\>" >/dev/null ; then echo -e "Probe $1 does not exist!\n" return 255 # Test is not applicable. fi return 0 } # Check for package names and return a version number function package_version { # loop through multiple potential package names # return first version number found for package in $@; do ver="" # check rpm for package version first if [ -f "/usr/bin/rpm" ]; then ver=$(rpm -q $package --qf="%{version}" 2> /dev/null) # rpm returns error messages on stdout, check return code if [ ! "$?" -eq "0" ]; then ver="" fi fi # fall back to dpkg for debian systems if [ "${ver}" == "" ] && [ -f "/usr/bin/dpkg-query" ]; then # for Debian-based systems, return the upstream version ver="$(dpkg-query -f '${source:Upstream-Version}' -W $package 2> /dev/null)" fi # return the first match found if [ "${ver}" != "" ]; then echo "${ver}" return 0 fi done # package not found if [ "${ver}" == "" ]; then return 255 fi } function verify_results { require "grep" || return 255 local ret_val=0; local TYPE="$1" local CONTENT="$2" local RESULTS="$3" local COUNT="$4" local FULLTYPE="definition" [ $TYPE == "tst" ] && FULLTYPE="test" ID=1 while [ $ID -le $COUNT ]; do CON_ITEM=`grep "id=\"oval:[[:digit:]]\+:${TYPE}:${ID}\"" $CONTENT` RES_ITEM=`grep "${FULLTYPE}_id=\"oval:[[:digit:]]\+:${TYPE}:${ID}\"" $RESULTS` OVAL_ID=`echo ${CON_ITEM} | grep -o "oval:[[:digit:]]\+:${TYPE}:${ID}"` if (echo $RES_ITEM | grep "result=\"true\"") >/dev/null; then RES="TRUE" elif (echo $RES_ITEM | grep "result=\"false\"" >/dev/null); then RES="FALSE" else RES="ERROR" fi if (echo $CON_ITEM | grep "comment=\"true\"" >/dev/null); then CMT="TRUE" elif (echo $CON_ITEM | grep "comment=\"false\"" >/dev/null); then CMT="FALSE" else CMT="ERROR" fi if [ ! $RES = $CMT ]; then echo "Result of ${OVAL_ID} should be ${CMT} and is ${RES}" ret_val=$(($ret_val + 1)) fi ID=$(($ID+1)) done return $([ $ret_val -eq 0 ]) } assert_exists() { real_cnt="$($XPATH $result 'count('"$2"')' 2>/dev/null)" if [ "$real_cnt" != "$1" ]; then echo "Failed: expected count: $1, real count: $real_cnt, xpath: '$2'" return 1 fi } # $1: The chroot directory set_chroot_offline_test_mode() { if test -n "$_OSCAP_BEFORE"; then echo "Already in offline test mode!" >&2 return fi if test -x "$OSCAP_CHROOTABLE_EXEC"; then if ! getcap "$OSCAP_CHROOTABLE_EXEC" | grep -q 'cap_sys_chroot+ep'; then echo "Skipping test '${FUNCNAME[1]}' as '$OSCAP_CHROOTABLE_EXEC' doesn't have the chroot capability." >&2 return 255 fi _OSCAP_BEFORE="$OSCAP" OSCAP="$OSCAP_CHROOTABLE" elif test $(id -u) -eq 0; then : # Running offline tests as root is acceptable too else echo "Skipping test '${FUNCNAME[1]}' as '$OSCAP_CHROOTABLE_EXEC' oscap which is supposed to have chroot capability doesn't exist." >&2 return 255 fi set_offline_chroot_dir "$1" return 0 } # $1: The chroot directory. If empty, unset the OSCAP_PROBE_ROOT variable set_offline_chroot_dir() { if test -n "$1"; then export OSCAP_PROBE_ROOT="$1" else unset OSCAP_PROBE_ROOT fi } unset_chroot_offline_test_mode() { if test -n "$_OSCAP_BEFORE"; then OSCAP="$_OSCAP_BEFORE" _OSCAP_BEFORE= fi set_offline_chroot_dir "" } export -f assert_exists