1 | #!/usr/bin/python3 |
||
2 | |||
3 | from __future__ import print_function |
||
4 | |||
5 | """ |
||
6 | Takes given XCCDF or DataStream and adds RHEL derivative operating system(s) CPE name next |
||
7 | to RHEL CPE names. Can automatically recognize RHEL CPEs and adds the derivitive OS ones |
||
8 | next to those accordingly. |
||
9 | |||
10 | Apart from adding the CPEs it adds a notice informing the user that the content |
||
11 | has been enabled for the derivative operating systems and what are the implications. |
||
12 | |||
13 | Author: Martin Preisler <[email protected]> |
||
14 | """ |
||
15 | |||
16 | import sys |
||
17 | from optparse import OptionParser |
||
18 | |||
19 | import ssg.constants |
||
20 | import ssg.build_derivatives |
||
21 | import ssg.xccdf |
||
22 | import ssg.xml |
||
23 | |||
24 | XCCDF12_NS = ssg.constants.XCCDF12_NS |
||
25 | oval_ns = ssg.constants.oval_namespace |
||
26 | |||
27 | CENTOS_NOTICE_ELEMENT = ssg.xml.ElementTree.fromstring(ssg.constants.CENTOS_NOTICE) |
||
28 | SL_NOTICE_ELEMENT = ssg.xml.ElementTree.fromstring(ssg.constants.SL_NOTICE) |
||
29 | |||
30 | CENTOS_WARNING = 'centos_warning' |
||
31 | SL_WARNING = 'sl_warning' |
||
32 | |||
33 | |||
34 | def parse_args(): |
||
35 | usage = "usage: %prog [options]" |
||
36 | parser = OptionParser(usage=usage) |
||
37 | parser.add_option("--enable-centos", dest="centos", default=False, |
||
38 | action="store_true", help="Enable CentOS") |
||
39 | parser.add_option("--enable-sl", dest="sl", default=False, |
||
40 | action="store_true", help="Enable Scientific Linux") |
||
41 | parser.add_option("-i", "--input", dest="input_content", default=False, |
||
42 | action="store", |
||
43 | help="INPUT can be XCCDF or Source DataStream") |
||
44 | parser.add_option("-o", "--output", dest="output", default=False, |
||
45 | action="store", help="XML Tree content") |
||
46 | parser.add_option("--id-name", dest="id_name", default="ssg", |
||
47 | action="store", help="ID naming scheme") |
||
48 | parser.add_option( |
||
49 | "--cpe-items-dir", |
||
50 | dest="cpe_items_dir", help="path to the directory where compiled cpe items are stored") |
||
51 | (options, args) = parser.parse_args() |
||
52 | |||
53 | if options.centos and options.sl: |
||
54 | sys.stderr.write( |
||
55 | "Cannot enable two derivative OS(s) at the same time\n" |
||
56 | ) |
||
57 | parser.print_help() |
||
58 | sys.exit(1) |
||
59 | |||
60 | if not options.output and not options.input_content: |
||
61 | parser.print_help() |
||
62 | sys.exit(1) |
||
63 | return options, args |
||
64 | |||
65 | |||
66 | def main(): |
||
67 | options, args = parse_args() |
||
68 | |||
69 | if options.centos: |
||
70 | mapping = ssg.constants.RHEL_CENTOS_CPE_MAPPING |
||
71 | notice = CENTOS_NOTICE_ELEMENT |
||
72 | warning = CENTOS_WARNING |
||
73 | derivative = "CentOS" |
||
74 | |||
75 | if options.sl: |
||
76 | mapping = ssg.constants.RHEL_SL_CPE_MAPPING |
||
77 | notice = SL_NOTICE_ELEMENT |
||
78 | warning = SL_WARNING |
||
79 | derivative = "Scientific Linux" |
||
80 | |||
81 | tree = ssg.xml.open_xml(options.input_content) |
||
82 | root = tree.getroot() |
||
83 | |||
84 | benchmarks = [] |
||
85 | |||
86 | ssg.xccdf.scrape_benchmarks(root, XCCDF12_NS, benchmarks) |
||
87 | |||
88 | # Remove CCEs and DISA STIG IDs from derivatives as these are specific to |
||
89 | # the vendor/OS. |
||
90 | ssg.build_derivatives.remove_idents(root, XCCDF12_NS) |
||
91 | ssg.build_derivatives.remove_cce_reference(root, oval_ns) |
||
92 | |||
93 | if len(benchmarks) == 0: |
||
94 | raise RuntimeError("No Benchmark found!") |
||
95 | |||
96 | for namespace, benchmark in benchmarks: |
||
97 | if args[1] != "cs9" and not args[1].startswith("centos"): |
||
98 | # In all CentOS and CentOS Streams, profiles are kept because they are systems |
||
99 | # intended to test content that will get into RHEL |
||
100 | ssg.build_derivatives.profile_handling(benchmark, namespace) |
||
101 | if not ssg.build_derivatives.add_cpes(benchmark, namespace, mapping): |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
102 | raise RuntimeError( |
||
103 | "Could not add derivative OS CPEs to Benchmark '%s'." |
||
104 | % (benchmark) |
||
105 | ) |
||
106 | |||
107 | if not ssg.build_derivatives.add_notice(benchmark, namespace, notice, |
||
0 ignored issues
–
show
|
|||
108 | warning): |
||
0 ignored issues
–
show
|
|||
109 | raise RuntimeError( |
||
110 | "Managed to add derivative OS CPEs but failed to add the " |
||
111 | "notice to affected XCCDF Benchmark '%s'." % (benchmark) |
||
112 | ) |
||
113 | |||
114 | ssg.build_derivatives.replace_platform(root, oval_ns, derivative) |
||
0 ignored issues
–
show
|
|||
115 | ssg.build_derivatives.add_cpe_item_to_dictionary( |
||
116 | root, args[0], args[1], options.id_name, options.cpe_items_dir) |
||
117 | |||
118 | tree.write(options.output) |
||
119 | |||
120 | |||
121 | if __name__ == "__main__": |
||
122 | main() |
||
123 |