Passed
Push — master ( 42467a...9d011f )
by Matěj
03:19 queued 11s
created

perform_combined_check()   A

Complexity

Conditions 2

Size

Total Lines 28
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 20
nop 1
dl 0
loc 28
ccs 0
cts 17
cp 0
crap 6
rs 9.4
c 0
b 0
f 0
1
#!/usr/bin/env python2
2
from __future__ import print_function
3
4
import logging
5
import re
6
7
from ssg.constants import OSCAP_PROFILE
8
from ssg_test_suite import common
9
from ssg_test_suite import rule
10
from ssg_test_suite import xml_operations
11
from ssg_test_suite import test_env
12
13
14
class CombinedChecker(rule.RuleChecker):
15
    """
16
    Combined mode works like pretty much like the Rule mode -
17
    for every rule selected in a profile:
18
19
    - Alter the system.
20
    - Run the scan, check that the result meets expectations.
21
      If the test scenario passed as requested, return True,
22
      if it failed or passed unexpectedly, return False.
23
24
    The following sequence applies if the initial scan
25
    has failed as expected:
26
27
    - If there are no remediations, return True.
28
    - Run remediation, return False if it failed.
29
    - Return result of the final scan of remediated system.
30
31
    If a rule doesn't have any test scenario, it is skipped.
32
    Skipped rules are reported at the end.
33
    """
34
    def __init__(self, test_env):
35
        super(CombinedChecker, self).__init__(test_env)
36
        self._matching_rule_found = False
37
38
        self.rules_not_tested_yet = set()
39
        self.results = list()
40
        self._current_result = None
41
42
    def _rule_should_be_tested(self, rule, rules_to_be_tested):
43
        if rule.short_id not in rules_to_be_tested:
44
            return False
45
        return True
46
47
    def _modify_parameters(self, script, params):
48
        # If there is no profiles metadata in a script we will use
49
        # the ALL profile - this will prevent failures which might
50
        # be caused by the tested profile selecting different values
51
        # in tested variables compared to defaults. The ALL profile
52
        # is always selecting default values.
53
        # If there is profiles metadata we check the metadata and set
54
        # it to self.profile (the tested profile) only if the metadata
55
        # contains self.profile - otherwise scenario is not supposed to
56
        # be tested using the self.profile and we return empty profiles
57
        # metadata.
58
        if not params["profiles"]:
59
            params["profiles"].append(rule.OSCAP_PROFILE_ALL_ID)
60
            logging.debug(
61
                "Added the {0} profile to the list of available profiles for {1}"
62
                .format(rule.OSCAP_PROFILE_ALL_ID, script))
63
        else:
64
            params['profiles'] = [item for item in params['profiles'] if re.search(self.profile, item)]
65
        return params
66
67
    def _test_target(self, target):
68
        self.rules_not_tested_yet = set(target)
69
70
        super(CombinedChecker, self)._test_target(target)
71
72
        if len(self.rules_not_tested_yet) != 0:
73
            not_tested = sorted(list(self.rules_not_tested_yet))
74
            logging.info("The following rule(s) were not tested:")
75
            for rule in not_tested:
76
                logging.info("{0}".format(rule))
77
78
    def test_rule(self, state, rule, scenarios):
79
        super(CombinedChecker, self).test_rule(state, rule, scenarios)
80
        # In combined mode there is no expectations of matching substrings,
81
        # every entry in the target is expected to be unique.
82
        # Let's remove matched targets, so we can track rules not tested
83
        self.rules_not_tested_yet.discard(rule.short_id)
84
85
def perform_combined_check(options):
86
    checker = CombinedChecker(options.test_env)
87
88
    checker.datastream = options.datastream
89
    checker.benchmark_id = options.benchmark_id
90
    checker.remediate_using = options.remediate_using
91
    checker.dont_clean = options.dont_clean
92
    # No debug option is provided for combined mode
93
    checker.manual_debug = False
94
    checker.benchmark_cpes = options.benchmark_cpes
95
    checker.scenarios_regex = options.scenarios_regex
96
    # Let's keep track of originaly targeted profile
97
    checker.profile = options.target
98
99
    profile = options.target
100
    # check if target is a complete profile ID, if not prepend profile prefix
101
    if not profile.startswith(OSCAP_PROFILE):
102
        profile = OSCAP_PROFILE+profile
103
    logging.info("Performing combined test using profile: {0}".format(profile))
104
105
    # Fetch target list from rules selected in profile
106
    target_rules = xml_operations.get_all_rule_ids_in_profile(
107
            options.datastream, options.benchmark_id,
108
            profile, logging)
109
    logging.debug("Profile {0} expanded to following list of "
110
                  "rules: {1}".format(profile, target_rules))
111
112
    checker.test_target(target_rules)
113