Issues (70)

utils/refchecker.py (1 issue)

1
#!/usr/bin/python3
2
3
import sys
4
import os
5
import argparse
6
import json
7
8
from ssg.build_cpe import ProductCPEs
9
import ssg.build_profile
10
import ssg.build_yaml
11
import ssg.controls
12
import ssg.environment
13
import ssg.products
14
import ssg.rules
15
import ssg.rule_yaml
16
import ssg.yaml
17
import ssg.utils
18
19
SSG_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
20
RULES_JSON = os.path.join(SSG_ROOT, "build", "rule_dirs.json")
21
BUILD_CONFIG = os.path.join(SSG_ROOT, "build", "build_config.yml")
22
CONTROLS_DIR = os.path.join(SSG_ROOT, "controls")
23
24
25 View Code Duplication
def parse_args():
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
26
    parser = argparse.ArgumentParser(description="Check all rule.yml referenced in a given"
27
                                     "profile for a required reference identifier")
28
    parser.add_argument("-j", "--json", type=str, action="store",
29
                        default=RULES_JSON, help="File to read "
30
                        "json output of rule_dir_json from (defaults to "
31
                        "build/rule_dirs.json")
32
    parser.add_argument("-c", "--build-config-yaml", default=BUILD_CONFIG,
33
                        help="YAML file with information about the build configuration. "
34
                        "Defaults to build/build_config.yml")
35
    parser.add_argument("--controls", default=CONTROLS_DIR,
36
                        help="Directory that contains control files with policy controls.")
37
    parser.add_argument("-p", "--profiles-root",
38
                        help="Override where to look for profile files.")
39
    parser.add_argument("product", type=str, help="Product to check has required references")
40
    parser.add_argument("profile", type=str, help="Profile to iterate over")
41
    parser.add_argument("reference", type=str, help="Required reference system to check for")
42
43
    return parser.parse_args()
44
45
46
def load(rule_obj, env_yaml=None):
47
    """
48
    From the given rule_dir object, load the build_yaml.Rule associated with
49
    it.
50
    """
51
52
    yaml_file = ssg.rules.get_rule_dir_yaml(rule_obj['dir'])
53
    return ssg.build_yaml.Rule.from_yaml(yaml_file, env_yaml=env_yaml)
54
55
56
def load_for_product(rule_obj, product, env_yaml=None):
57
    """
58
    From the given rule_dir object, load the build_yaml.Rule associated with
59
    it, normalizing for the given product.
60
    """
61
62
    rule = load(rule_obj, env_yaml=env_yaml)
63
    rule.normalize(product)
64
    return rule
65
66
67
def reference_check(env_yaml, rule_dirs, profile_path, product, product_yaml, reference,
68
                    profiles_root, controls_manager=None):
69
    profile = ssg.build_yaml.ProfileWithInlinePolicies.from_yaml(profile_path, env_yaml)
70
    product_cpes = ProductCPEs()
71
    product_cpes.load_product_cpes(env_yaml)
72
    product_cpes.load_content_cpes(env_yaml)
73
74
    if controls_manager:
75
        profile_files = ssg.products.get_profile_files_from_root(env_yaml, product_yaml)
76
        all_profiles = ssg.build_profile.make_name_to_profile_mapping(profile_files, env_yaml,
77
                                                                      product_cpes)
78
        profile.resolve(all_profiles, rule_dirs, controls_manager)
79
80
    ok = True
81
    for rule_id in profile.selected + profile.unselected:
82
        if rule_id not in rule_dirs:
83
            msg = "Unable to find rule in rule_dirs.json: {0}"
84
            msg = msg.format(rule_id)
85
            raise ValueError(msg)
86
87
        rule = load_for_product(rule_dirs[rule_id], product, env_yaml=env_yaml)
88
89
        if reference not in rule.references:
90
            ok = False
91
            msg = "Rule {0} lacks required reference {1} or {1}@{2}"
92
            msg = msg.format(rule_id, reference, product)
93
            print(msg, file=sys.stderr)
94
95
    return ok
96
97
98
def main():
99
    args = parse_args()
100
101
    json_file = open(args.json, 'r')
102
    all_rules = json.load(json_file)
103
104
    linux_products, other_products = ssg.products.get_all(SSG_ROOT)
105
    all_products = linux_products.union(other_products)
106
    if args.product not in all_products:
107
        msg = "Unknown product {0}: check SSG_ROOT and try again"
108
        msg = msg.format(args.product)
109
        raise ValueError(msg)
110
111
    product_base = os.path.join(SSG_ROOT, "products", args.product)
112
    product_yaml_path = os.path.join(product_base, "product.yml")
113
    product_yaml = ssg.products.Product(product_yaml_path)
114
    env_yaml = ssg.environment.open_environment(
115
        args.build_config_yaml, product_yaml_path, os.path.join(SSG_ROOT, "product_properties"))
116
117
    controls_manager = None
118
    if os.path.exists(args.controls):
119
        controls_manager = ssg.controls.ControlsManager(args.controls, env_yaml)
120
        controls_manager.load()
121
122
    profiles_root = os.path.join(product_base, "profiles")
123
    if args.profiles_root:
124
        profiles_root = args.profiles_root
125
126
    profile_filename = args.profile + ".profile"
127
    profile_path = os.path.join(profiles_root, profile_filename)
128
    if not os.path.exists(profile_path):
129
        msg = "Unknown profile {0}: check profile, --profiles-root, and try again. "
130
        msg += "Note that the '.profile' suffix shouldn't be included."
131
        msg = msg.format(args.profile)
132
        raise ValueError(msg)
133
134
    ok = reference_check(env_yaml, all_rules, profile_path, args.product, product_yaml,
135
                         args.reference, profiles_root, controls_manager)
136
    if not ok:
137
        sys.exit(1)
138
139
140
if __name__ == "__main__":
141
    main()
142