import sys
from ...constants import BOOL_TO_STR, OVAL_NAMESPACES, STR_TO_BOOL
from ...xml import ElementTree
from ..general import OVALBaseObject, OVALComponent, load_notes, required_attribute
[docs]
class GeneralCriteriaNode(OVALBaseObject):
negate = False
comment = ""
applicability_check = False
def __init__(self, tag):
super(GeneralCriteriaNode, self).__init__(tag)
[docs]
def get_xml_element(self):
el = ElementTree.Element("{}{}".format(self.namespace, self.tag))
if self.applicability_check:
el.set("applicability_check", BOOL_TO_STR[self.applicability_check])
if self.negate:
el.set("negate", BOOL_TO_STR[self.negate])
if self.comment != "":
el.set("comment", self.comment)
return el
[docs]
def load_terminate_criteria(xml_el, class_, ref_prefix):
terminate_criteria = class_(
xml_el.tag,
required_attribute(xml_el, "{}_ref".format(ref_prefix)),
)
terminate_criteria.negate = STR_TO_BOOL.get(xml_el.get("negate"), False)
terminate_criteria.comment = xml_el.get("comment", "")
terminate_criteria.applicability_check = STR_TO_BOOL.get(
xml_el.get("applicability_check"), False
)
return terminate_criteria
[docs]
class TerminateCriteriaNode(GeneralCriteriaNode):
prefix_ref = ""
def __init__(self, tag, ref):
super(TerminateCriteriaNode, self).__init__(tag)
self.ref = ref
[docs]
def get_xml_element(self):
el = super(TerminateCriteriaNode, self).get_xml_element()
el.set("{}_ref".format(self.prefix_ref), self.ref)
return el
# -----
[docs]
class Criterion(TerminateCriteriaNode):
prefix_ref = "test"
# -----
[docs]
class ExtendDefinition(TerminateCriteriaNode):
prefix_ref = "definition"
# -----
[docs]
def load_criteria(oval_criteria_xml_el):
criteria = Criteria(oval_criteria_xml_el.tag)
criteria.operator = oval_criteria_xml_el.get("operator", "AND")
criteria.negate = STR_TO_BOOL.get(oval_criteria_xml_el.get("negate"), False)
criteria.comment = oval_criteria_xml_el.get("comment", "")
criteria.applicability_check = STR_TO_BOOL.get(
oval_criteria_xml_el.get("applicability_check"), False
)
for child_node_el in oval_criteria_xml_el:
if child_node_el.tag.endswith("criteria"):
criteria.add_child_criteria_node(load_criteria(child_node_el))
elif child_node_el.tag.endswith("criterion"):
criteria.add_child_criteria_node(
load_terminate_criteria(child_node_el, Criterion, "test")
)
elif child_node_el.tag.endswith("extend_definition"):
criteria.add_child_criteria_node(
load_terminate_criteria(child_node_el, ExtendDefinition, "definition")
)
else:
sys.stderr.write(
"Warning: Unknown element '{}'\n".format(child_node_el.tag)
)
return criteria
[docs]
class Criteria(GeneralCriteriaNode):
operator = "AND"
def __init__(self, tag):
super(Criteria, self).__init__(tag)
self.child_criteria_nodes = []
[docs]
def add_child_criteria_node(self, child):
if not isinstance(child, (Criteria, Criterion, ExtendDefinition)):
raise TypeError("Unexpected child type of Criteria!")
self.child_criteria_nodes.append(child)
[docs]
def get_xml_element(self):
criteria_el = super(Criteria, self).get_xml_element()
criteria_el.set("operator", self.operator)
for child_criteria_node in self.child_criteria_nodes:
criteria_el.append(child_criteria_node.get_xml_element())
return criteria_el
# -----
[docs]
def load_references(all_reference_elements):
out = []
for ref_el in all_reference_elements:
ref = Reference(
ref_el.tag,
required_attribute(ref_el, "source"),
required_attribute(ref_el, "ref_id"),
)
ref.ref_url = ref_el.get("ref_url", "")
out.append(ref)
return out if out else None
[docs]
class Reference(OVALBaseObject):
ref_url = ""
def __init__(self, tag, source, ref_id):
super(Reference, self).__init__(tag)
self.source = source
self.ref_id = ref_id
[docs]
def get_xml_element(self):
reference_el = ElementTree.Element("{}{}".format(self.namespace, self.tag))
reference_el.set("ref_id", self.ref_id)
reference_el.set("source", self.source)
if self.ref_url != "":
reference_el.set("ref_url", self.ref_url)
return reference_el
# -----
def _get_tag(el):
if el is None:
return None
return el.tag
def _get_list_of_affected(affected_el, element_name):
elements = affected_el.findall(
"./{%s}%s" % (OVAL_NAMESPACES.definition, element_name)
)
if len(elements) == 0:
return None
return [el.text for el in elements]
[docs]
def load_affected(all_affected_elements):
out = []
for affected_el in all_affected_elements:
affected = Affected(
affected_el.tag,
required_attribute(affected_el, "family"),
)
affected.platform_tag = _get_tag(
affected_el.find("./{%s}platform" % OVAL_NAMESPACES.definition)
)
affected.product_tag = _get_tag(
affected_el.find("./{%s}product" % OVAL_NAMESPACES.definition)
)
affected.platforms = _get_list_of_affected(affected_el, "platform")
affected.products = _get_list_of_affected(affected_el, "product")
out.append(affected)
return out if out else None
[docs]
class Affected(OVALBaseObject):
platform_tag = "platform"
product_tag = "product"
platforms = None
products = None
def __init__(self, tag, family):
super(Affected, self).__init__(tag)
self.family = family
def _add_to_affected_element(self, affected_el, elements):
for platform in elements if elements is not None else []:
platform_el = ElementTree.Element(self.platform_tag)
platform_el.text = platform
affected_el.append(platform_el)
[docs]
def get_xml_element(self):
affected_el = ElementTree.Element("{}{}".format(self.namespace, self.tag))
affected_el.set("family", self.family)
self._add_to_affected_element(affected_el, self.platforms)
self._add_to_affected_element(affected_el, self.products)
return affected_el
# -----
# -----
[docs]
def load_definition(oval_definition_xml_el):
metadata_el = oval_definition_xml_el.find(
"./{%s}metadata" % OVAL_NAMESPACES.definition
)
notes_el = oval_definition_xml_el.find("./{%s}notes" % OVAL_NAMESPACES.definition)
criteria_el = oval_definition_xml_el.find(
"./{%s}criteria" % OVAL_NAMESPACES.definition
)
definition = Definition(
oval_definition_xml_el.tag,
required_attribute(oval_definition_xml_el, "id"),
required_attribute(oval_definition_xml_el, "class"),
load_metadata(metadata_el),
)
definition.deprecated = STR_TO_BOOL.get(
oval_definition_xml_el.get("deprecated", ""), False
)
definition.notes = load_notes(notes_el)
definition.version = required_attribute(oval_definition_xml_el, "version")
definition.criteria = load_criteria(criteria_el)
return definition
[docs]
class Definition(OVALComponent):
criteria = None
def __init__(self, tag, id_, class_, metadata):
super(Definition, self).__init__(tag, id_)
self.class_ = class_
self.metadata = metadata
[docs]
def get_xml_element(self):
definition_el = super(Definition, self).get_xml_element()
definition_el.set("class", self.class_)
definition_el.append(self.metadata.get_xml_element())
if self.criteria:
definition_el.append(self.criteria.get_xml_element())
return definition_el