From f7a66a0ec2204a9c00a749d32d70b476c256357e Mon Sep 17 00:00:00 2001 From: Evgeny Kolesnikov Date: Mon, 18 Dec 2023 04:57:27 +0100 Subject: [PATCH] Filter out OVALs from XCCDF (WIP) --- ssg/build_renumber.py | 25 +++++++++++-------- ssg/oval_object_model/oval_container.py | 13 +--------- .../oval_definition_references.py | 8 ++++++ ssg/oval_object_model/oval_document.py | 4 ++- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/ssg/build_renumber.py b/ssg/build_renumber.py index 01857e9b87d6..6a8592c468fb 100644 --- a/ssg/build_renumber.py +++ b/ssg/build_renumber.py @@ -10,8 +10,7 @@ ) from . import utils from .xml import parse_file, map_elements_to_their_ids -from .oval_object_model import load_oval_document - +from .oval_object_model import load_oval_document, OVALDefinitionReference from .checks import get_content_ref_if_exists_and_not_remote from .cce import is_cce_value_valid, is_cce_format_valid @@ -275,19 +274,23 @@ def _ensure_by_xccdf_referenced_oval_no_extra_def_in_oval_file(self): # or internally via extend-definition xccdf_oval_check_refs = [name for name in self._get_list_of_names_of_oval_checks()] - def_keys = list(self.oval_document.definitions.keys()) + document_def_keys = list(self.oval_document.definitions.keys()) - internal_refs = set() - for def_id in def_keys: + references_from_xccdf_to_keep = OVALDefinitionReference() + for def_id in document_def_keys: if def_id in xccdf_oval_check_refs: oval_def_refs = self.oval_document.get_all_references_of_definition(def_id) - for ref_def_id in oval_def_refs.definitions: - if ref_def_id != def_id: - internal_refs.add(ref_def_id) + references_from_xccdf_to_keep += oval_def_refs + + references_to_remove = OVALDefinitionReference() + for def_id in document_def_keys: + if def_id not in xccdf_oval_check_refs: + if def_id in self.oval_document.definitions: + def_refs = self.oval_document.get_all_references_of_definition(def_id) + def_refs -= references_from_xccdf_to_keep + references_to_remove += def_refs - for def_id in def_keys: - if def_id not in xccdf_oval_check_refs and def_id not in internal_refs: - self.oval_document.remove_definition_and_all_references(def_id) + self.oval_document.remove_referenced_components(references_to_remove) class OCILFileLinker(FileLinker): diff --git a/ssg/oval_object_model/oval_container.py b/ssg/oval_object_model/oval_container.py index 0bb35186b430..ef1ff48cb1f5 100644 --- a/ssg/oval_object_model/oval_container.py +++ b/ssg/oval_object_model/oval_container.py @@ -73,7 +73,7 @@ def _copy_component(destination, source_of_components): def _remove_keys_from_dict(dict_, to_remove): for k in to_remove: - del dict_[k] + dict_.pop(k, None) def _keep_keys_in_dict(dict_, to_keep): @@ -220,17 +220,6 @@ def get_all_references_of_definition(self, definition_id): self._process_objects_states_variables_references(ref) return ref - def remove_definition_and_all_references(self, definition_id): - if definition_id not in self.definitions: - raise ValueError( - "ERROR: OVAL definition '{}' doesn't exist.".format(definition_id) - ) - org_fun = self._skip_if_is_none - self._skip_if_is_none = lambda *_: True - ref = self.get_all_references_of_definition(definition_id) - self._skip_if_is_none = org_fun - self.remove_referenced_components(ref) - def keep_referenced_components(self, ref): self._call_function_for_every_component(_keep_keys_in_dict, ref) diff --git a/ssg/oval_object_model/oval_definition_references.py b/ssg/oval_object_model/oval_definition_references.py index fe2be3e72eae..09a4c7a91518 100644 --- a/ssg/oval_object_model/oval_definition_references.py +++ b/ssg/oval_object_model/oval_definition_references.py @@ -51,6 +51,14 @@ def __iadd__(self, other): self.variables.extend(other.variables) return self + def __isub__(self, other): + self.definitions = list(filter(lambda i: i not in other.definitions, self.definitions)) + self.tests = list(filter(lambda i: i not in other.tests, self.tests)) + self.objects = list(filter(lambda i: i not in other.objects, self.objects)) + self.states = list(filter(lambda i: i not in other.states, self.states)) + self.variables = list(filter(lambda i: i not in other.variables, self.variables)) + return self + def __repr__(self): return str(self.__dict__) diff --git a/ssg/oval_object_model/oval_document.py b/ssg/oval_object_model/oval_document.py index 4eef50d04d18..19598a4a0dee 100644 --- a/ssg/oval_object_model/oval_document.py +++ b/ssg/oval_object_model/oval_document.py @@ -107,7 +107,9 @@ def product_name(self, __value): @staticmethod def _skip_if_is_none(value, component_id): if value is None: - raise MissingOVALComponent(component_id) + #raise MissingOVALComponent(component_id) + logging.warning("Component {} is None".format(component_id)) + return True return False def load_shorthand(self, xml_string, product=None, rule_id=None):