|
1
|
|
|
#!/usr/bin/env python3 |
|
2
|
|
|
import collections |
|
3
|
|
|
import argparse |
|
4
|
|
|
|
|
5
|
|
|
from ssg import controls |
|
6
|
|
|
|
|
7
|
|
|
|
|
8
|
|
|
def print_options(opts): |
|
9
|
|
|
if len(opts) > 0: |
|
10
|
|
|
print("Available options are:\n - " + "\n - ".join(opts)) |
|
11
|
|
|
else: |
|
12
|
|
|
print("The controls file is not written appropriately.") |
|
13
|
|
|
|
|
14
|
|
|
|
|
15
|
|
|
def validate_args(ctrlmgr, args): |
|
16
|
|
|
""" Validates that the appropriate args were given |
|
17
|
|
|
and that they're valid entries in the control manager.""" |
|
18
|
|
|
|
|
19
|
|
|
policy = None |
|
20
|
|
|
try: |
|
21
|
|
|
policy = ctrlmgr._get_policy(args.id) |
|
22
|
|
|
except ValueError as e: |
|
23
|
|
|
print("Error: ", e) |
|
24
|
|
|
print_options(ctrlmgr.policies.keys()) |
|
25
|
|
|
exit(1) |
|
26
|
|
|
|
|
27
|
|
|
try: |
|
28
|
|
|
policy.get_level_with_ancestors_sequence(args.level) |
|
29
|
|
|
except ValueError as e: |
|
30
|
|
|
print("Error: ", e) |
|
31
|
|
|
print_options(policy.levels_by_id.keys()) |
|
32
|
|
|
exit(1) |
|
33
|
|
|
|
|
34
|
|
|
|
|
35
|
|
|
def calculate_stats(ctrls): |
|
36
|
|
|
total = len(ctrls) |
|
37
|
|
|
ctrlstats = collections.defaultdict(int) |
|
38
|
|
|
|
|
39
|
|
|
for ctrl in ctrls: |
|
40
|
|
|
ctrlstats[str(ctrl.status)] += 1 |
|
|
|
|
|
|
41
|
|
|
|
|
42
|
|
|
applicable = total - ctrlstats[controls.Status.NOT_APPLICABLE] |
|
43
|
|
|
assessed = ctrlstats[controls.Status.AUTOMATED] + ctrlstats[controls.Status.SUPPORTED] + \ |
|
44
|
|
|
ctrlstats[controls.Status.DOCUMENTATION] + ctrlstats[controls.Status.INHERENTLY_MET] + \ |
|
45
|
|
|
ctrlstats[controls.Status.PARTIAL] |
|
46
|
|
|
|
|
47
|
|
|
print("Total controls = {total}".format(total=total)) |
|
48
|
|
|
print_specific_stat("Applicable", applicable, total) |
|
49
|
|
|
print_specific_stat("Assessed", assessed, applicable) |
|
50
|
|
|
print() |
|
51
|
|
|
print_specific_stat("Automated", ctrlstats[controls.Status.AUTOMATED], applicable) |
|
52
|
|
|
print_specific_stat("Supported", ctrlstats[controls.Status.SUPPORTED], applicable) |
|
53
|
|
|
print_specific_stat("Documentation", ctrlstats[controls.Status.DOCUMENTATION], applicable) |
|
54
|
|
|
print_specific_stat("Inherently Met", ctrlstats[controls.Status.INHERENTLY_MET], applicable) |
|
55
|
|
|
print_specific_stat("Partial", ctrlstats[controls.Status.PARTIAL], applicable) |
|
56
|
|
|
|
|
57
|
|
|
|
|
58
|
|
|
def print_specific_stat(stat, current, total): |
|
59
|
|
|
print("{stat} = {percent}% -- {current} / {total}".format( |
|
60
|
|
|
stat=stat, |
|
61
|
|
|
percent=round((current / total) * 100.00, 2), |
|
62
|
|
|
current=current, |
|
63
|
|
|
total=total)) |
|
64
|
|
|
|
|
65
|
|
|
|
|
66
|
|
|
def stats(ctrlmgr, args): |
|
67
|
|
|
validate_args(ctrlmgr, args) |
|
68
|
|
|
ctrls = set(ctrlmgr.get_all_controls_of_level(args.id, args.level)) |
|
69
|
|
|
calculate_stats(ctrls) |
|
70
|
|
|
|
|
71
|
|
|
|
|
72
|
|
|
subcmds = dict( |
|
73
|
|
|
stats=stats |
|
74
|
|
|
) |
|
75
|
|
|
|
|
76
|
|
|
|
|
77
|
|
|
def create_parser(): |
|
78
|
|
|
parser = argparse.ArgumentParser() |
|
79
|
|
|
parser.add_argument( |
|
80
|
|
|
"--controls-dir", |
|
81
|
|
|
help=("Directory that contains control files with policy controls. " |
|
82
|
|
|
"e.g.: ~/scap-security-guide/controls"), |
|
83
|
|
|
default="./controls/", |
|
84
|
|
|
) |
|
85
|
|
|
subparsers = parser.add_subparsers(dest="subcmd", required=True) |
|
86
|
|
|
statsparser = subparsers.add_parser( |
|
87
|
|
|
'stats', |
|
88
|
|
|
help="outputs statistics for the given benchmark and level.") |
|
89
|
|
|
statsparser.add_argument("-i", "--id", dest="id", help="id of the controls file.", |
|
90
|
|
|
required=True) |
|
91
|
|
|
statsparser.add_argument("-l", "--level", dest="level", help="level to display statistics of.", |
|
92
|
|
|
required=True) |
|
93
|
|
|
return parser |
|
94
|
|
|
|
|
95
|
|
|
|
|
96
|
|
|
def main(): |
|
97
|
|
|
parser = create_parser() |
|
98
|
|
|
args = parser.parse_args() |
|
99
|
|
|
controls_manager = controls.ControlsManager(args.controls_dir) |
|
100
|
|
|
controls_manager.load() |
|
101
|
|
|
subcmds[args.subcmd](controls_manager, args) |
|
102
|
|
|
|
|
103
|
|
|
|
|
104
|
|
|
if __name__ == "__main__": |
|
105
|
|
|
main() |
|
106
|
|
|
|