From 924ac0a482b374bcfed2f2519c5ab9fd542bc5b1 Mon Sep 17 00:00:00 2001 From: Matus Marhefka Date: Dec 02 2022 09:51:41 +0000 Subject: [PATCH 1/3] Sanity/cpe-applicability: new test to verify CPE AL extension --- diff --git a/Sanity/cpe-applicability/main.fmf b/Sanity/cpe-applicability/main.fmf new file mode 100644 index 0000000..6620935 --- /dev/null +++ b/Sanity/cpe-applicability/main.fmf @@ -0,0 +1,34 @@ +summary: Verify CPE applicability language. +description: | + Verify that CPEs are correctly built into a data stream and that they are + properly evaluated on a tested system with specific OS and RPM versions. + Source tree is built from the scap-security-guide source RPM by running + %prep stage and applying patches from the spec file. +contact: Matus Marhefka +component: +- scap-security-guide +test: ./runtest.sh +framework: beakerlib +require: +- library(distribution/Cleanup) +- library(distribution/RpmSnapshot) +recommend: +- scap-security-guide +- openscap-scanner +- yum-utils +- rpm-build +- dnf-plugins-core +- findutils +- openssh-server +- libxml2 +duration: 1h +enabled: true +tag: +- CI-Tier-1 +- Tier1 +- rhel8-buildroot +- rhel9-buildroot +- MidWeekProductization +tier: '1' +extra-summary: /CoreOS/scap-security-guide/Sanity/cpe-applicability +extra-task: /CoreOS/scap-security-guide/Sanity/cpe-applicability diff --git a/Sanity/cpe-applicability/runtest.sh b/Sanity/cpe-applicability/runtest.sh new file mode 100755 index 0000000..2bf6abf --- /dev/null +++ b/Sanity/cpe-applicability/runtest.sh @@ -0,0 +1,229 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="scap-security-guide" + +RULE_PREFIX="xccdf_org.ssgproject.content_rule" +declare -A RULE_RESULTS=( + ["test_cpe_applicable"]="pass" + ["test_cpe_applicable_no_platforms"]="pass" + ["test_cpe_applicable_legacy_platform"]="pass" + ["test_cpe_applicable_complex"]="pass" + ["test_cpe_applicable_more_platforms"]="pass" + ["test_cpe_applicable_os_interval"]="pass" + ["test_cpe_not_applicable"]="notapplicable" + ["test_cpe_not_applicable_os"]="notapplicable" + ["test_cpe_not_applicable_arch"]="notapplicable" + ["test_cpe_not_applicable_package"]="notapplicable" +) + +PKG_NAME="openssh-server" +# We only accept X.Y format in package version as our CPE AL +# implementation currently cannot properly process letters which +# are used as delimeters in the openssh-server RPM version. +PKG_VERSION="$(rpm -q "$PKG_NAME" | sed "s/${PKG_NAME}-//" | sed "s/\(\.fc\|\.el\).*$//" | grep -o "[0-9]\+\.[0-9]\+")" + +# TEST_ARCH must be different than architecture of the host running the test. +if [ "$(rlGetArch)" == "aarch64" ]; then + TEST_ARCH="s390x" +else + TEST_ARCH="aarch64" +fi + +if rlIsRHEL || rlIsCentOS; then + DISTRO_NAME="rhel" + PRODUCT="${DISTRO_NAME}$(rlGetDistroRelease)" + if rlIsCentOS "<9"; then + DS_NAME="ssg-centos$(rlGetDistroRelease)-ds.xml" + elif rlIsCentOS ">=9"; then + DS_NAME="ssg-cs$(rlGetDistroRelease)-ds.xml" + else + DS_NAME="ssg-${DISTRO_NAME}$(rlGetDistroRelease)-ds.xml" + fi + DISTRO_VERSION=$(grep "^VERSION_ID" /etc/os-release | sed 's|VERSION_ID=["]*\([^"]\+\)["]*|\1|') + if rlIsCentOS; then + # CentOS Stream does not have minor version. + DISTRO_VERSION_FUTURE="$(( DISTRO_VERSION + 1 ))" + # Only RHEL and Fedora are supported in os_linux platform atm. + RULE_RESULTS["test_cpe_applicable"]="notapplicable" + RULE_RESULTS["test_cpe_applicable_os_interval"]="notapplicable" + else + DISTRO_VERSION_MAJOR=$(cut -f 1 -d '.' <<< "$DISTRO_VERSION") + DISTRO_VERSION_MINOR=$(cut -f 2 -d '.' <<< "$DISTRO_VERSION") + DISTRO_VERSION_FUTURE="${DISTRO_VERSION_MAJOR}.$(( DISTRO_VERSION_MINOR + 1 ))" + fi +else + DISTRO_NAME="fedora" + PRODUCT="${DISTRO_NAME}" + DS_NAME="ssg-${DISTRO_NAME}-ds.xml" + DISTRO_VERSION="$(rlGetDistroRelease)" + DISTRO_VERSION_FUTURE=$(( DISTRO_VERSION + 1 )) +fi + + +function assertStringNotEmpty() { + local string="$1" + local assert_msg="$2" + + if [ -z "$string" ]; then + rlFail "$assert_msg" + else + rlPass "$assert_msg" + fi +} + + +# Function verifies that CPE platforms from rule with ID are correctly +# built into a data stream . +# +# Usage: +# verifyCpePlatformInDS +# +# Description of a data stream with a rule which has applicability limited by a CPE platform: +# element has a subelement . +# Then there is a element under +# which contains elements (referenced from the elements). +# Each platform contains logical tests () and fact-refs +# (). Fact-refs are, for example, defined like this: +# +# so they are pointing to a CPE name in component. The CPE item is defined like this +# +# Bare-metal or Virtual Machine +# oval:ssg-installed_env_is_a_machine:def:1 +# +# and it is pointing to an actual OVAL inventory check which is defined in the OVAL +# component of the data stream. +function verifyCpePlatformInDS() { + local rule="$1" + local ds="$2" + + local platform_idref=$(xmllint --xpath "string(//*[local-name()=\"Rule\"][@id=\"$rule\"]/*[local-name()=\"platform\"]/@idref)" "$ds" | tr -d '#') + assertStringNotEmpty "$platform_idref" "Rule '$rule' contains platform with idref '$platform_idref'" + + rlRun "xmllint --xpath '//*[local-name()=\"platform-specification\"]/*[local-name()=\"platform\"][@id=\"$platform_idref\"]/*[local-name()=\"logical-test\"]' $ds" \ + 0 "Platform '$platform_idref' contains logical-test element" + + local fact_refs=$(xmllint --xpath "//*[local-name()=\"platform-specification\"]/*[local-name()=\"platform\"][@id=\"$platform_idref\"]/*[local-name()=\"logical-test\"]//*[local-name()=\"fact-ref\"]/@name" "$ds" \ + | sed 's|name="\([^"]\+\)"|\1|g') + assertStringNotEmpty "$fact_refs" "Platform '$platform_idref' contains fact-ref elements '$fact_refs'" + + for fact_ref in $fact_refs; do + oval_def=$(xmllint --xpath "string(//*[local-name()=\"cpe-list\"]/*[local-name()=\"cpe-item\"][@name=\"$fact_ref\"]/*[local-name()=\"check\"])" "$ds") + assertStringNotEmpty "$fact_ref" "cpe-item '$fact_ref' contains check element '$oval_def'" + + rlRun "xmllint --xpath '//*[local-name()=\"oval_definitions\"]/*[local-name()=\"definitions\"]/*[local-name()=\"definition\"][@id=\"$oval_def\"]' $ds" \ + 0 "OVAL definition referenced by check element '$oval_def' exists in data stream" + done +} + + +rlJournalStart + + rlPhaseStartSetup + rlImport --all || rlDie "Failed to import libraries" + rlAssertRpm "$PACKAGE" + rlAssertRpm "openscap-scanner" + + RpmSnapshotCreate + CleanupRegister "RpmSnapshotRevert" + rlRun "TmpDir=\$(mktemp -d)" + CleanupRegister "rlRun 'rm -r $TmpDir' 0 'Removing tmp directory'" + rlRun "cp -r test_rules/ $TmpDir" + rlRun "pushd $TmpDir" + CleanupRegister "rlRun 'popd'" + + rlFetchSrcForInstalled "$PACKAGE" + if rlIsFedora || rlIsRHEL ">=8" || rlIsCentOS ">=8"; then + rlRun "dnf builddep -y $PACKAGE*" + else + rlRun "yum-builddep -y $PACKAGE*" + fi + TOP_DIR=$(rpm --eval %_topdir) + rlRun "rm -rf $TOP_DIR" 0-255 + CleanupRegister "rlRun 'rm -rf $TOP_DIR'" + rlRun "rpm -ihv `ls *.rpm`" 0 "Install $PACKAGE source RPM" + rlPhaseEnd + + rlPhaseStartSetup "Prepare source tree (%prep stage and patches from the spec file)" + #rlRun "rpmbuild -v -bp ${TOP_DIR}/SPECS/${PACKAGE}.spec" + #TODO + rlRun "git clone https://github.com/ComplianceAsCode/content -b cpe_versioning" + TOP_DIR="content" + #TODO + + #SRC_DIR=$(readlink -f ${TOP_DIR}/BUILD/${PACKAGE}* | tail -n1) + #TODO + SRC_DIR=$(readlink -f ${TOP_DIR} | tail -n1) + #TODO + RULES_DIR="${SRC_DIR}/linux_os/guide/system" + PKG_APPLICABILITY_CONF="${SRC_DIR}/shared/applicability/package.yml" + BUILD_DIR="${SRC_DIR}/build" + DS="${BUILD_DIR}/${DS_NAME}" + + rlLog "ENV:" + rlLog " SRC_DIR : $SRC_DIR" + rlLog " BUILD_DIR : $BUILD_DIR" + rlLog " DS : $DS" + rlLog " OS : $DISTRO_NAME" + rlLog " OS VERSION : $DISTRO_VERSION" + rlLog " OS VERSION (FUTURE) : $DISTRO_VERSION_FUTURE" + rlLog " TEST PKG : $PKG_NAME" + rlLog " TEST PKG VERSION : $PKG_VERSION" + rlPhaseEnd + + rlPhaseStartSetup "Insert test content into the source tree" + # Extend source tree with our prepared content updated with + # versions of RHEL and test RPM. + if ! grep -q "${PKG_NAME}:" "$PKG_APPLICABILITY_CONF"; then + rlRun "echo ' $PKG_NAME: + title: \"SSH Server Test\" + pkgname: $PKG_NAME' >> $PKG_APPLICABILITY_CONF" \ + 0 "Define $PKG_NAME package applicability" + fi + for f in $(find test_rules/ -iname "*rule.yml"); do + rlRun "sed -i \"s/{PRODTYPE}/$PRODUCT/g\" $f" + rlRun "sed -i \"s/{DISTRO_NAME}/$DISTRO_NAME/g\" $f" + rlRun "sed -i \"s/{DISTRO_VERSION}/$DISTRO_VERSION/g\" $f" + rlRun "sed -i \"s/{DISTRO_VERSION_FUTURE}/$DISTRO_VERSION_FUTURE/g\" $f" + rlRun "sed -i \"s/{TEST_ARCH}/$TEST_ARCH/g\" $f" + rlRun "sed -i \"s/{PKG_NAME}/$PKG_NAME/g\" $f" + rlRun "sed -i \"s/{PKG_VERSION}/$PKG_VERSION/g\" $f" + done + rlRun "cp -r test_rules/ $RULES_DIR" + rlRun "cd $SRC_DIR" + rlRun "mkdir -p build" + rlRun "./build_product $PRODUCT --derivatives" \ + 0 "Building $PRODUCT data stream" \ + || { CleanupDo; rlDie "Failed to build $PRODUCT data stream"; } + rlRun "cd -" + rlPhaseEnd + + for rule in ${!RULE_RESULTS[@]}; do + rule_id="${RULE_PREFIX}_${rule}" + rlPhaseStartTest "$rule - verify CPE is properly built into a data stream" + rlRun "cat ${RULES_DIR}/test_rules/${rule}/rule.yml" 0 "Print full rule.yml" + if [ "$rule" == "test_cpe_applicable_no_platforms" ]; then + rlLogInfo "$rule has no platforms, skiping." + else + verifyCpePlatformInDS "$rule_id" "$DS" + fi + rlPhaseEnd + rlPhaseStartTest "$rule - scan result corresponds with its CPE applicability" + rule_exp_result="${RULE_RESULTS[$rule]}" + rlRun "oscap xccdf eval --verbose INFO --progress --profile '(all)' --rule $rule_id $DS >stdout 2>stderr" + rlAssertNotGrep "(^E:|^openscap error:)" stderr -iE + rlAssertGrep "${rule_id}:${rule_exp_result}" stdout -i + if [ $? -ne 0 ]; then + rlRun "cat stdout" + rlRun "cat stderr" + fi + rlPhaseEnd + done + + rlPhaseStartCleanup + CleanupDo + rlPhaseEnd + +rlJournalPrintText +rlJournalEnd diff --git a/Sanity/cpe-applicability/test_rules/group.yml b/Sanity/cpe-applicability/test_rules/group.yml new file mode 100644 index 0000000..5dca323 --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/group.yml @@ -0,0 +1,6 @@ +documentation_complete: true + +title: 'Test group' + +description: |- + Test group diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_applicable/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_applicable/rule.yml new file mode 100644 index 0000000..86746d3 --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_applicable/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Applicable rule, platform requires: + greater or equal OS version than installed [true] + and + greater or equal package version than installed [true] + +rationale: |- + Test rationale. + +severity: medium + +platforms: + - "os_linux[{DISTRO_NAME}]>={DISTRO_VERSION} and package[{PKG_NAME}]>={PKG_VERSION}" + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_applicable_complex/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_complex/rule.yml new file mode 100644 index 0000000..2701077 --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_complex/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Applicable rule, platform requires: + lower OS version than installed and greater or equal package version than installed [false] + or + negated (CPU architecture different than architecture of the installed system) [true] + +rationale: |- + Test rationale. + +severity: medium + +platforms: + - "(os_linux[{DISTRO_NAME}]<{DISTRO_VERSION} and package[{PKG_NAME}]>={PKG_VERSION}) or not arch[{TEST_ARCH}]" + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_applicable_legacy_platform/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_legacy_platform/rule.yml new file mode 100644 index 0000000..14824f3 --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_legacy_platform/rule.yml @@ -0,0 +1,22 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Applicable rule, platform requires: + greater or equal package version than installed [true] + +rationale: |- + Test rationale. + +severity: medium + +platform: "package[{PKG_NAME}]>={PKG_VERSION}" + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_applicable_more_platforms/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_more_platforms/rule.yml new file mode 100644 index 0000000..1522150 --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_more_platforms/rule.yml @@ -0,0 +1,26 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Applicable rule, platform requires: + greater or equal OS version than installed [true] + and + negated (CPU architecture different than architecture of the installed system) [true] + +rationale: |- + Test rationale. + +severity: medium + +platforms: + - "package[{PKG_NAME}]>={PKG_VERSION}" + - "not arch[{TEST_ARCH}]" + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_applicable_no_platforms/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_no_platforms/rule.yml new file mode 100644 index 0000000..3c9f1bc --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_no_platforms/rule.yml @@ -0,0 +1,19 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Applicable rule, it has no platform which would be restricting its applicability. + +rationale: |- + Test rationale. + +severity: medium + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_applicable_os_interval/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_os_interval/rule.yml new file mode 100644 index 0000000..f710be9 --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_applicable_os_interval/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Applicable rule, platform requires: + greater or equal OS version than installed [true] + and + lower OS version than installed OS + 1 (note: for RHEL, minor version is incremented by 1 and major is left the same) [true] + +rationale: |- + Test rationale. + +severity: medium + +platforms: + - "os_linux[{DISTRO_NAME}]>={DISTRO_VERSION},<{DISTRO_VERSION_FUTURE}" + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable/rule.yml new file mode 100644 index 0000000..81f21b1 --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Not applicable rule, platform requires: + lower OS version than installed [false] + and + greater or equal package version than installed [true] + +rationale: |- + Test rationale. + +severity: medium + +platforms: + - "os_linux[{DISTRO_NAME}]<{DISTRO_VERSION} and package[{PKG_NAME}]>={PKG_VERSION}" + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable_arch/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable_arch/rule.yml new file mode 100644 index 0000000..91dadf2 --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable_arch/rule.yml @@ -0,0 +1,23 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Not applicable rule, platform requires: + CPU architecture different than architecture of the installed system [false] + +rationale: |- + Test rationale. + +severity: medium + +platforms: + - "arch[{TEST_ARCH}]" + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable_os/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable_os/rule.yml new file mode 100644 index 0000000..4e58917 --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable_os/rule.yml @@ -0,0 +1,23 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Not applicable rule, platform requires: + greater or equal OS version than installed OS + 1 (note: for RHEL, minor version is incremented by 1 and major is left the same) [false] + +rationale: |- + Test rationale. + +severity: medium + +platforms: + - "os_linux[{DISTRO_NAME}]>={DISTRO_VERSION_FUTURE}" + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true diff --git a/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable_package/rule.yml b/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable_package/rule.yml new file mode 100644 index 0000000..6cbc3ab --- /dev/null +++ b/Sanity/cpe-applicability/test_rules/test_cpe_not_applicable_package/rule.yml @@ -0,0 +1,23 @@ +documentation_complete: true + +prodtype: {PRODTYPE} + +title: 'Test rule' + +description: |- + Not applicable rule, platform requires: + lower package version than installed [false] + +rationale: |- + Test rationale. + +severity: medium + +platforms: + - "package[{PKG_NAME}]<{PKG_VERSION}" + +template: + name: file_existence + vars: + filepath: /etc/ssh/sshd_config + exists: true From dc9d2ab7d1c5fc05b8b728e267affbd2e9b3bb80 Mon Sep 17 00:00:00 2001 From: Matus Marhefka Date: Dec 02 2022 10:37:23 +0000 Subject: [PATCH 2/3] Sanity/cpe-applicability: add a check for Ansible remediations applicability --- diff --git a/Sanity/cpe-applicability/main.fmf b/Sanity/cpe-applicability/main.fmf index 6620935..9e895bd 100644 --- a/Sanity/cpe-applicability/main.fmf +++ b/Sanity/cpe-applicability/main.fmf @@ -12,6 +12,9 @@ framework: beakerlib require: - library(distribution/Cleanup) - library(distribution/RpmSnapshot) +- url: https://src.fedoraproject.org/tests/scap-security-guide.git + name: /Library/scap-common + nick: scap-common-lib recommend: - scap-security-guide - openscap-scanner diff --git a/Sanity/cpe-applicability/runtest.sh b/Sanity/cpe-applicability/runtest.sh index 2bf6abf..ecab9d0 100755 --- a/Sanity/cpe-applicability/runtest.sh +++ b/Sanity/cpe-applicability/runtest.sh @@ -18,49 +18,6 @@ declare -A RULE_RESULTS=( ["test_cpe_not_applicable_package"]="notapplicable" ) -PKG_NAME="openssh-server" -# We only accept X.Y format in package version as our CPE AL -# implementation currently cannot properly process letters which -# are used as delimeters in the openssh-server RPM version. -PKG_VERSION="$(rpm -q "$PKG_NAME" | sed "s/${PKG_NAME}-//" | sed "s/\(\.fc\|\.el\).*$//" | grep -o "[0-9]\+\.[0-9]\+")" - -# TEST_ARCH must be different than architecture of the host running the test. -if [ "$(rlGetArch)" == "aarch64" ]; then - TEST_ARCH="s390x" -else - TEST_ARCH="aarch64" -fi - -if rlIsRHEL || rlIsCentOS; then - DISTRO_NAME="rhel" - PRODUCT="${DISTRO_NAME}$(rlGetDistroRelease)" - if rlIsCentOS "<9"; then - DS_NAME="ssg-centos$(rlGetDistroRelease)-ds.xml" - elif rlIsCentOS ">=9"; then - DS_NAME="ssg-cs$(rlGetDistroRelease)-ds.xml" - else - DS_NAME="ssg-${DISTRO_NAME}$(rlGetDistroRelease)-ds.xml" - fi - DISTRO_VERSION=$(grep "^VERSION_ID" /etc/os-release | sed 's|VERSION_ID=["]*\([^"]\+\)["]*|\1|') - if rlIsCentOS; then - # CentOS Stream does not have minor version. - DISTRO_VERSION_FUTURE="$(( DISTRO_VERSION + 1 ))" - # Only RHEL and Fedora are supported in os_linux platform atm. - RULE_RESULTS["test_cpe_applicable"]="notapplicable" - RULE_RESULTS["test_cpe_applicable_os_interval"]="notapplicable" - else - DISTRO_VERSION_MAJOR=$(cut -f 1 -d '.' <<< "$DISTRO_VERSION") - DISTRO_VERSION_MINOR=$(cut -f 2 -d '.' <<< "$DISTRO_VERSION") - DISTRO_VERSION_FUTURE="${DISTRO_VERSION_MAJOR}.$(( DISTRO_VERSION_MINOR + 1 ))" - fi -else - DISTRO_NAME="fedora" - PRODUCT="${DISTRO_NAME}" - DS_NAME="ssg-${DISTRO_NAME}-ds.xml" - DISTRO_VERSION="$(rlGetDistroRelease)" - DISTRO_VERSION_FUTURE=$(( DISTRO_VERSION + 1 )) -fi - function assertStringNotEmpty() { local string="$1" @@ -121,10 +78,49 @@ function verifyCpePlatformInDS() { rlJournalStart rlPhaseStartSetup - rlImport --all || rlDie "Failed to import libraries" + rlImport "distribution/Cleanup" || rlDie "Failed to import Cleanup library" + rlImport "distribution/RpmSnapshot" || rlDie "Failed to import RpmSnapshot library" + rlImport "scap-common-lib/scap-common" || rlDie "Failed to import scap-common library" rlAssertRpm "$PACKAGE" rlAssertRpm "openscap-scanner" + PKG_NAME="openssh-server" + # We only accept X.Y format in package version as our CPE AL + # implementation currently cannot properly process letters which + # are used as delimeters in the openssh-server RPM version. + PKG_VERSION="$(rpm -q "$PKG_NAME" | sed "s/${PKG_NAME}-//" | sed "s/\(\.fc\|\.el\).*$//" | grep -o "[0-9]\+\.[0-9]\+")" + + # TEST_ARCH must be different than architecture of the host running the test. + if [ "$(rlGetArch)" == "aarch64" ]; then + TEST_ARCH="s390x" + else + TEST_ARCH="aarch64" + fi + + if rlIsRHEL || rlIsCentOS; then + # DISTRO_NAME must be rhel also for centos as it is built as a derivative of rhel. + DISTRO_NAME="rhel" + PRODUCT="${DISTRO_NAME}$(rlGetDistroRelease)" + DISTRO_VERSION=$(grep "^VERSION_ID" /etc/os-release | sed 's|VERSION_ID=["]*\([^"]\+\)["]*|\1|') + if rlIsCentOS; then + # CentOS Stream does not have minor version. + DISTRO_VERSION_FUTURE="$(( DISTRO_VERSION + 1 ))" + # Only RHEL and Fedora are supported in os_linux platform atm. + RULE_RESULTS["test_cpe_applicable"]="notapplicable" + RULE_RESULTS["test_cpe_applicable_os_interval"]="notapplicable" + else + DISTRO_VERSION_MAJOR=$(cut -f 1 -d '.' <<< "$DISTRO_VERSION") + DISTRO_VERSION_MINOR=$(cut -f 2 -d '.' <<< "$DISTRO_VERSION") + DISTRO_VERSION_FUTURE="${DISTRO_VERSION_MAJOR}.$(( DISTRO_VERSION_MINOR + 1 ))" + fi + else + DISTRO_NAME="fedora" + PRODUCT="${DISTRO_NAME}" + DISTRO_VERSION="$(rlGetDistroRelease)" + DISTRO_VERSION_FUTURE=$(( DISTRO_VERSION + 1 )) + fi + DS_NAME="ssg-$(scapCommonGetDistroName)-ds.xml" + RpmSnapshotCreate CleanupRegister "RpmSnapshotRevert" rlRun "TmpDir=\$(mktemp -d)" @@ -133,6 +129,8 @@ rlJournalStart rlRun "pushd $TmpDir" CleanupRegister "rlRun 'popd'" + scapCommonInstallAnsible || rlDie "Failed to install required Ansible packages" + rlFetchSrcForInstalled "$PACKAGE" if rlIsFedora || rlIsRHEL ">=8" || rlIsCentOS ">=8"; then rlRun "dnf builddep -y $PACKAGE*" @@ -219,6 +217,27 @@ rlJournalStart rlRun "cat stderr" fi rlPhaseEnd + rlPhaseStartTest "$rule - verify Ansible remediation CPE applicability" + ruleDS="$(basename $DS).${rule}" + rlRun "cp $DS $ruleDS" 0 "Create a copy of data stream to generate Ansible remediation" + rlRun "sed -i '/<.*Rule.*id=\"${rule_id}\"/s/selected=\"false\"/selected=\"true\"/g' $ruleDS" \ + 0 "Select only single rule in the data stream copy - $rule" + rlRun "oscap xccdf generate fix --fix-type ansible --output ${rule}.yml $ruleDS" \ + 0 "Generate Ansible remediation for the rule $rule" + cat "${rule}.yml" + rlRun "ansible-playbook --syntax-check ${rule}.yml" \ + 0 "Verify generated Ansible remediation has correct syntax" + rlRun -s "ansible-playbook -i \"localhost,\" -c local ${rule}.yml" \ + 0 "Run generated Ansible remediation for rule $rule" + rlAssertGrep "failed=0" "$rlRun_LOG" + rlAssertGrep "ok=[1-9]\+" "$rlRun_LOG" + if [ "$rule_exp_result" == "pass" ]; then + rlAssertGrep "skipped=0" "$rlRun_LOG" + else + rlAssertGrep "skipped=1" "$rlRun_LOG" + fi + rlRun "rm -f $rlRun_LOG $ruleDS" + rlPhaseEnd done rlPhaseStartCleanup From ad4bfd08847432cb483040862f5a9ec7d8914a30 Mon Sep 17 00:00:00 2001 From: Matus Marhefka Date: Dec 05 2022 14:39:34 +0000 Subject: [PATCH 3/3] Sanity/cpe-applicability: change tested package Current CPE AL implementation cannot properly process letters which are used as delimeters in the openssh-server RPM version. Therefore, we will use different package for testing (kernel). --- diff --git a/Sanity/cpe-applicability/runtest.sh b/Sanity/cpe-applicability/runtest.sh index ecab9d0..dc7f203 100755 --- a/Sanity/cpe-applicability/runtest.sh +++ b/Sanity/cpe-applicability/runtest.sh @@ -84,11 +84,8 @@ rlJournalStart rlAssertRpm "$PACKAGE" rlAssertRpm "openscap-scanner" - PKG_NAME="openssh-server" - # We only accept X.Y format in package version as our CPE AL - # implementation currently cannot properly process letters which - # are used as delimeters in the openssh-server RPM version. - PKG_VERSION="$(rpm -q "$PKG_NAME" | sed "s/${PKG_NAME}-//" | sed "s/\(\.fc\|\.el\).*$//" | grep -o "[0-9]\+\.[0-9]\+")" + PKG_NAME="kernel" + PKG_VERSION="$(rpm -q "$PKG_NAME" --queryformat "%{VERSION}-%{RELEASE}\n" | tail -n1 | sed "s/\(\.fc\|\.el\).*$//")" # TEST_ARCH must be different than architecture of the host running the test. if [ "$(rlGetArch)" == "aarch64" ]; then