Completed
Pull Request — master (#6005)
by
unknown
01:54
created

run_scapval.workaround_datastream()   B

Complexity

Conditions 8

Size

Total Lines 22
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 18
nop 1
dl 0
loc 22
rs 7.3333
c 0
b 0
f 0
1
#!/usr/bin/python
2
3
from __future__ import print_function
4
5
import argparse
6
import subprocess
7
import os
8
import xml.etree.ElementTree as ET
9
import sys
10
11
scapval_results_ns = "http://csrc.nist.gov/ns/decima/results/1.0"
12
oval_unix_ns = "http://oval.mitre.org/XMLSchema/oval-definitions-5#unix"
13
xccdf_ns = "http://checklists.nist.gov/xccdf/1.2"
14
15
16
def parse_args():
17
    parser = argparse.ArgumentParser(
18
        description="Runs SCAP Validation of our data streams using SCAP"
19
        "Validation Tool (SCAPVal)")
20
    parser.add_argument(
21
        "--scap-version",
22
        help="SCAP Version (Only 1.2 and 1.3 supported)",
23
        choices=["1.2", "1.3"], required=True)
24
    parser.add_argument(
25
        "--scapval-path",
26
        help="Full path to the SCAPVal JAR archive", required=True)
27
    parser.add_argument(
28
        "--build-dir",
29
        help="Full path to the ComplianceAsCode build directory",
30
        required=True)
31
    return parser.parse_args()
32
33
34
def process_results(result_path):
35
    ret_val = True
36
    tree = ET.parse(result_path)
37
    root = tree.getroot()
38
    results = root.find("./{%s}results" % scapval_results_ns)
39
    for base_req in results.findall(
40
            "./{%s}base-requirement" % scapval_results_ns):
41
        id_ = base_req.get("id")
42
        status = base_req.find("./{%s}status" % scapval_results_ns).text
43
        if status == "FAIL":
44
            print("    %s: %s" % (id_, status))
45
            ret_val = False
46
    return ret_val
47
48
49
def test_datastream(datastream_path,  scapval_path, scap_version):
50
    result_path = datastream_path + ".result.xml"
51
    report_path = datastream_path + ".report.html"
52
    scapval_command = [
53
            "java",
54
            "-Xmx1024m",
55
            "-jar", scapval_path,
56
            "-scapversion", scap_version,
57
            "-file", datastream_path,
58
            "-valresultfile", result_path,
59
            "-valreportfile", report_path
60
            ]
61
    try:
62
        subprocess.check_output(scapval_command, stderr=subprocess.STDOUT)
63
    except subprocess.CalledProcessError as e:
64
        scapval_output = e.output.decode("utf-8")
65
        # Workaround: SCAPVal 1.3.2 can't generate HTML report because
66
        # it throws a NullPointerException, but we don't need the HTML
67
        # report for this test, so we can ignore this error.
68
        # TODO: Remove this when this is fixed in SCAPVal
69
        last_line = scapval_output.splitlines()[-1]
70
        if not last_line.endswith(
71
                "ERROR SCAPVal has encountered a problem and cannot continue "
72
                "with this validation. - java.lang.NullPointerException: "
73
                "XSLTemplateExtension cannot be null"):
74
            sys.stderr.write("Command '{0}' returned {1}:\n{2}\n".format(
75
                " ".join(e.cmd), e.returncode, scapval_output))
76
            sys.exit(1)
77
    return process_results(result_path)
78
79
80
def main():
81
    overall_result = True
82
    args = parse_args()
83
    if args.scap_version == "1.2":
84
        ds_suffix = "-ds-1.2.xml"
85
    elif args.scap_version == "1.3":
86
        ds_suffix = "-ds.xml"
87
    for filename in os.listdir(args.build_dir):
88
        if filename.endswith(ds_suffix):
0 ignored issues
show
introduced by
The variable ds_suffix does not seem to be defined for all execution paths.
Loading history...
89
            print("Testing %s ..." % filename)
90
            datastream_path = os.path.join(args.build_dir, filename)
91
            datastream_result = test_datastream(
92
                    datastream_path, args.scapval_path, args.scap_version)
93
            if datastream_result:
94
                print("%s: PASS" % filename)
95
            else:
96
                print("%s: FAIL" % filename)
97
                overall_result = False
98
    if overall_result:
99
        sys.exit(0)
100
    else:
101
        sys.exit(1)
102
103
104
if __name__ == "__main__":
105
    main()
106