1
|
|
|
# Copyright 2022, Red Hat, Inc. |
2
|
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later |
3
|
|
|
|
4
|
1 |
|
from ..data_structures import ResultOfScan |
5
|
1 |
|
from ..namespaces import NAMESPACES |
6
|
|
|
|
7
|
|
|
|
8
|
1 |
|
class ScanResultParser: |
9
|
1 |
|
def __init__(self, test_results_el, root): |
10
|
1 |
|
self.root = root |
11
|
1 |
|
self.test_results_el = test_results_el |
12
|
1 |
|
self.benchmark_el = self.root.find(".//xccdf:benchmark", NAMESPACES) |
13
|
|
|
|
14
|
1 |
|
def _get_cpe_platforms(self): |
15
|
1 |
|
return [ |
16
|
|
|
platform.get('idref') |
17
|
|
|
for platform in self.test_results_el.findall('.//xccdf:platform', NAMESPACES) |
18
|
|
|
] |
19
|
|
|
|
20
|
1 |
|
def _get_text_of_element(self, element_path): |
21
|
1 |
|
element = self.test_results_el.find(element_path, NAMESPACES) |
22
|
1 |
|
if element is None: |
23
|
|
|
return "" |
24
|
1 |
|
return element.text |
25
|
|
|
|
26
|
1 |
|
def _get_list_of_addresses(self, type_): |
27
|
1 |
|
out = [] |
28
|
1 |
|
path = ( |
29
|
|
|
".//xccdf:target-facts/xccdf:fact" |
30
|
|
|
f"[@name='urn:xccdf:fact:asset:identifier:{type_.lower()}']" |
31
|
|
|
) |
32
|
1 |
|
for address in self.test_results_el.findall(path, NAMESPACES): |
33
|
1 |
|
out.append(address.text) |
34
|
1 |
|
return out |
35
|
|
|
|
36
|
1 |
|
def get_test_result(self): |
37
|
1 |
|
score_el = self.test_results_el.find(".//xccdf:score", NAMESPACES) |
38
|
|
|
|
39
|
1 |
|
scan_result_dict = { |
40
|
|
|
"title": self._get_text_of_element('.//xccdf:title'), |
41
|
|
|
"identity": self._get_text_of_element('.//xccdf:identity'), |
42
|
|
|
"cpe_platforms": self._get_cpe_platforms(), |
43
|
|
|
"target": self._get_text_of_element('.//xccdf:target'), |
44
|
|
|
"benchmark_version": self.test_results_el.get("version"), |
45
|
|
|
"start_time": self.test_results_el.get("start-time"), |
46
|
|
|
"end_time": self.test_results_el.get("end-time"), |
47
|
|
|
"test_system": self.test_results_el.get("test-system"), |
48
|
|
|
"score_system": score_el.get("system"), |
49
|
|
|
"score": float(score_el.text), |
50
|
|
|
"score_max": float(score_el.get("maximum")), |
51
|
|
|
"benchmark_url": self.benchmark_el.get("href"), |
52
|
|
|
"benchmark_id": self.benchmark_el.get("id"), |
53
|
|
|
"scanner": self._get_text_of_element( |
54
|
|
|
".//xccdf:target-facts/xccdf:fact[@name='urn:xccdf:fact:scanner:name']"), |
55
|
|
|
"scanner_version": self._get_text_of_element( |
56
|
|
|
".//xccdf:target-facts/xccdf:fact[@name='urn:xccdf:fact:scanner:version']"), |
57
|
|
|
} |
58
|
|
|
|
59
|
1 |
|
profile_name = self.test_results_el.find('.//xccdf:profile', NAMESPACES) |
60
|
1 |
|
if profile_name is not None: |
61
|
1 |
|
scan_result_dict["profile_id"] = profile_name.get("idref") |
62
|
|
|
|
63
|
1 |
|
target_addresses = {} |
64
|
1 |
|
for type_ in ["MAC", "IPv4", "IPv6"]: |
65
|
1 |
|
target_addresses[type_] = self._get_list_of_addresses(type_) |
66
|
|
|
|
67
|
1 |
|
scan_result_dict["target_addresses"] = target_addresses |
68
|
|
|
return ResultOfScan(**scan_result_dict) |
69
|
|
|
|