utils/profile_tool/profile.py
import os
from ..controleval import get_parameter_from_yaml
def _get_extends_profile_path(profiles_files, profile_name):
for profile_path in profiles_files:
if f"{profile_name}.profile" in profile_path:
return profile_path
return None
def _process_extends(profiles_files, file, policies, profile):
extends = get_parameter_from_yaml(file, "extends")
if isinstance(extends, str):
profile_path = _get_extends_profile_path(profiles_files, extends)
if profile_path is None:
raise Exception("There is no Extension '{}' Profile.".format(extends))
profile = get_profile(profiles_files, profile_path, policies, profile)
def _process_selections(file, profile, policies):
selections = get_parameter_from_yaml(file, "selections")
for selected in selections:
if ":" in selected and "=" not in selected:
profile.add_from_policy(policies, selected)
else:
profile.add_rule(selected)
profile.clean_rules()
def get_profile(profiles_files, file, policies, profile=None):
if profile is None:
title = get_parameter_from_yaml(file, "title")
profile = Profile(file, title)
_process_extends(profiles_files, file, policies, profile)
_process_selections(file, profile, policies)
return profile
class Profile:
def __init__(self, path, title):
normalized_path = os.path.normpath(path)
profile_file = os.path.basename(normalized_path)
self.path = normalized_path
self.title = title
self.id = profile_file.split('.profile')[0]
self.product = normalized_path.split('/')[-3]
self.rules = []
self.variables = {}
self.unselected_rules = []
def add_rule(self, rule_id):
if rule_id.startswith("!"):
self.unselected_rules.append(rule_id)
return
if "=" not in rule_id:
self.rules.append(rule_id)
else:
variable_name, variable_value = rule_id.split('=', 1)
self.variables[variable_name] = variable_value
def add_rules(self, rules):
for rule in rules:
self.add_rule(rule)
def clean_rules(self):
for rule in self.unselected_rules:
rule_ = rule.replace("!", "")
if rule_ in self.rules:
self.rules.remove(rule_)
@staticmethod
def _get_sel(selected):
policy = None
control = None
level = None
if selected.count(":") == 2:
policy, control, level = selected.split(":")
else:
policy, control = selected.split(":")
return policy, control, level
@staticmethod
def _get_levels(policy, level, levels=None):
if levels is None:
levels = set()
levels.add(level)
if policy.levels_by_id.get(level).inherits_from is not None:
for parent_level in policy.levels_by_id.get(level).inherits_from:
levels.update(Profile._get_levels(policy, parent_level, levels))
return levels
def add_from_policy(self, policies, selected):
policy_id, control, level = self._get_sel(selected)
policy = policies[policy_id]
if control != "all":
self.add_rules(policy.controls_by_id[control].rules)
return
if level is None:
for control in policy.controls:
self.add_rules(control.rules)
return
levels = self._get_levels(policy, level)
for control in policy.controls:
intersection = set(control.levels) & set(levels)
if len(intersection) >= 1:
self.add_rules(control.rules)