mirror of
https://github.com/usnistgov/macos_security.git
synced 2026-03-06 18:01:59 +00:00
1493 lines
79 KiB
Python
Executable File
1493 lines
79 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import glob
|
|
import json
|
|
import os
|
|
import re
|
|
import shutil
|
|
from collections import defaultdict
|
|
|
|
import yaml
|
|
|
|
|
|
class MyDumper(yaml.Dumper):
|
|
def increase_indent(self, flow=False, indentless=False):
|
|
return super(MyDumper, self).increase_indent(flow, False)
|
|
|
|
|
|
def str_presenter(dumper, data):
|
|
"""configures yaml for dumping multiline strings
|
|
Ref: https://stackoverflow.com/questions/8640959/how-can-i-control-what-scalar-form-pyyaml-uses-for-my-data"""
|
|
clean_data = data.replace(" \n", "\n")
|
|
if clean_data.count("\n") > 0: # check for multiline string
|
|
return dumper.represent_scalar("tag:yaml.org,2002:str", clean_data, style="|")
|
|
return dumper.represent_scalar("tag:yaml.org,2002:str", clean_data)
|
|
|
|
|
|
yaml.add_representer(str, str_presenter)
|
|
yaml.representer.SafeRepresenter.add_representer(str, str_presenter)
|
|
|
|
|
|
def replace_na_with_none(data):
|
|
if isinstance(data, dict):
|
|
return {key: replace_na_with_none(value) for key, value in data.items()}
|
|
elif isinstance(data, list):
|
|
return [replace_na_with_none(item) for item in data]
|
|
else:
|
|
return None if data == "N/A" else data
|
|
|
|
|
|
def remove_none_fields(data, parent_key=None):
|
|
if isinstance(data, dict):
|
|
# If the current dictionary has a key named 'platforms', leave it unchanged
|
|
if parent_key == "platforms":
|
|
return data
|
|
|
|
result = {}
|
|
for key, value in data.items():
|
|
processed_value = remove_none_fields(value, key) # Pass the key to track parent
|
|
if processed_value is not None:
|
|
result[key] = processed_value
|
|
return result if result else None
|
|
elif isinstance(data, list):
|
|
# Process each item in the list
|
|
processed_list = [remove_none_fields(item, parent_key) for item in data]
|
|
# Remove None values and keep only valid items
|
|
filtered_list = [item for item in processed_list if item is not None]
|
|
return filtered_list if filtered_list else None
|
|
else:
|
|
# Return the value itself if it's not a dict or list
|
|
return data if data is not None else None
|
|
|
|
|
|
def restructure_mobileconfig(rule_yaml):
|
|
if "mobileconfig_info" in rule_yaml.keys() and rule_yaml["mobileconfig_info"] is not None:
|
|
mobileconfig_info_obj = []
|
|
for obj, data in rule_yaml["mobileconfig_info"].items():
|
|
payload = {}
|
|
payload["PayloadType"] = obj
|
|
|
|
# generate list of keys for payload content
|
|
payload_content = []
|
|
for k, v in data.items():
|
|
payload_content.append({k: v})
|
|
payload["PayloadContent"] = payload_content
|
|
|
|
mobileconfig_info_obj.append(payload)
|
|
return mobileconfig_info_obj
|
|
else:
|
|
return {}
|
|
|
|
|
|
def restructure_benchmarks(benchmarks, severity):
|
|
bmarks = []
|
|
for b in benchmarks:
|
|
if severity == "" or severity is None:
|
|
bmarks.append({"name": b})
|
|
elif "stig" in b or "indigo" in b and not severity == "":
|
|
bmarks.append({"name": b, "severity": severity})
|
|
else:
|
|
bmarks.append({"name": b})
|
|
return bmarks
|
|
|
|
|
|
def restructure_severity(benchmarks, severity):
|
|
severity_list = []
|
|
for b in benchmarks:
|
|
if "stig" in b or "indigo" in b:
|
|
severity_list.append({b: severity})
|
|
return severity_list
|
|
|
|
|
|
def get_introduced(payloadtype, key, os):
|
|
version = "-1"
|
|
for item in payloadtype["payloadkeys"]:
|
|
if item["key"] == key:
|
|
try:
|
|
if os in item["supportedOS"].keys():
|
|
version = item["supportedOS"][os]["introduced"]
|
|
else:
|
|
# try go get introduced from payload parent
|
|
if os in payloadtype["payload"]["supportedOS"].keys():
|
|
version = payloadtype["payload"]["supportedOS"][os]["introduced"]
|
|
except KeyError:
|
|
# try go get introduced from payload parent
|
|
if os in payloadtype["payload"]["supportedOS"].keys():
|
|
version = payloadtype["payload"]["supportedOS"][os]["introduced"]
|
|
return version
|
|
|
|
|
|
def correct_result_key(result_dict):
|
|
if isinstance(result_dict, str):
|
|
return {}
|
|
new_result = result_dict.copy()
|
|
for k, v in result_dict.items():
|
|
if k == "boolean" and isinstance(v, int):
|
|
new_result["integer"] = v
|
|
new_result.pop("boolean")
|
|
return new_result
|
|
|
|
|
|
def remove_lines_containing(text, substring):
|
|
lines = text.splitlines()
|
|
filtered_lines = [line for line in lines if substring not in line]
|
|
return "\n".join(filtered_lines)
|
|
|
|
|
|
def cleanup_fix(fix_text):
|
|
new_result = fix_text.strip().replace(" \n", "\n")
|
|
if "[source,xml]" in fix_text:
|
|
return "", new_result
|
|
new_result = remove_lines_containing(new_result, "----")
|
|
new_result = remove_lines_containing(new_result, "[source,bash]")
|
|
|
|
pattern = r"----\n(.*?)\n----(.*)"
|
|
match = re.search(pattern, fix_text, re.DOTALL)
|
|
|
|
note = ""
|
|
if match:
|
|
code = match.group(1)
|
|
note = match.group(2)
|
|
return code, note.strip()
|
|
else:
|
|
return "", new_result
|
|
|
|
|
|
def main():
|
|
files_created = []
|
|
file_dir = os.path.dirname(os.path.abspath(__file__))
|
|
parent_dir = os.path.dirname(file_dir)
|
|
|
|
original_working_directory = os.getcwd()
|
|
|
|
os.chdir(file_dir)
|
|
build_path = os.path.join(parent_dir, "rules")
|
|
# build_path = os.path.join(parent_dir, 'build', 'rules', 'v2.0')
|
|
if not (os.path.isdir(build_path)):
|
|
try:
|
|
os.makedirs(build_path)
|
|
except OSError:
|
|
print(f"Creation of the directory {build_path} failed")
|
|
|
|
# load apple device-management profile for referencing
|
|
apple_profiles = {}
|
|
for apple_profile_file in glob.glob("../_work/apple/mdm/profiles/*.yaml"):
|
|
with open(apple_profile_file) as p:
|
|
apple_yam = yaml.load(p, Loader=yaml.SafeLoader)
|
|
payloadtype = apple_yam["payload"]["payloadtype"]
|
|
apple_profiles[payloadtype] = apple_yam
|
|
|
|
# load odv.json for reference
|
|
with open("../includes/odv.json") as o:
|
|
odv_json = json.load(o)
|
|
|
|
# load discussions.yaml for reference
|
|
with open("../includes/discussions.yaml") as y:
|
|
discussions_yaml = yaml.load(y, Loader=yaml.SafeLoader)
|
|
|
|
# os_supported = ["sequoia", "sonoma", "ventura", "monterey", "big_sur", "catalina", "ios_18", "ios_17", "ios_16", "visionos_2.0"]
|
|
os_supported = ["sequoia", "sonoma", "ventura", "ios_18", "ios_17", "ios_16", "visionos_2.0"]
|
|
# for os_list in glob.glob("../_work/*"):
|
|
# os_supported.add(os_list.split("/")[2])
|
|
|
|
all_rules = {}
|
|
for os_version in os_supported:
|
|
for os_rule in glob.glob("../_work/{}/rules/*/*".format(os_version)):
|
|
if "supplemental" in os_rule:
|
|
continue
|
|
# Initialize list for the OS version if not already done
|
|
if os_version not in all_rules:
|
|
all_rules[os_version] = []
|
|
|
|
with open(os_rule) as r:
|
|
rule_yam = yaml.load(r, Loader=yaml.SafeLoader)
|
|
rule_yaml = replace_na_with_none(rule_yam)
|
|
# restructure the mobileconfig object
|
|
new_mobileconfig = restructure_mobileconfig(rule_yaml)
|
|
rule_yaml["mobileconfig_info"] = new_mobileconfig
|
|
if "This is implemented by a Configuration Profile" in rule_yaml["fix"]:
|
|
rule_yaml.pop("fix")
|
|
all_rules[os_version].append(rule_yaml)
|
|
|
|
# print(json.dumps(all_rules))
|
|
id_to_os = defaultdict(list)
|
|
for os_version, rules in all_rules.items():
|
|
for rule in rules:
|
|
id_to_os[rule["id"]].append(os_version)
|
|
|
|
new_yaml = {}
|
|
duplicates = {id_: os_versions for id_, os_versions in id_to_os.items() if len(os_versions) > 1}
|
|
non_duplicates = {id_: os_versions[0] for id_, os_versions in id_to_os.items() if len(os_versions) == 1}
|
|
|
|
try:
|
|
if os.path.isfile(build_path) or os.path.islink(build_path):
|
|
os.unlink(build_path)
|
|
elif os.path.isdir(build_path):
|
|
shutil.rmtree(build_path)
|
|
except Exception as e:
|
|
print("Failed to delete %s. Reason: %s" % (build_path, e))
|
|
|
|
if non_duplicates:
|
|
for id_, os_versions in non_duplicates.items():
|
|
os_ = os_versions
|
|
|
|
section = id_.split("_")[0]
|
|
if section == "system":
|
|
section = "system_settings"
|
|
section_build_path = os.path.join(parent_dir, "rules", section)
|
|
|
|
if not (os.path.isdir(section_build_path)):
|
|
try:
|
|
os.makedirs(section_build_path)
|
|
except OSError:
|
|
print(f"Creation of the directory {build_path} failed")
|
|
|
|
with open("../_work/{}/rules/{}/{}.yaml".format(os_, section, id_)) as r:
|
|
rule_yam = yaml.load(r, Loader=yaml.SafeLoader)
|
|
rule_yaml = replace_na_with_none(rule_yam)
|
|
new_mobileconfig = restructure_mobileconfig(rule_yaml)
|
|
rule_yaml["mobileconfig_info"] = new_mobileconfig
|
|
if "This is implemented by a Configuration Profile" in rule_yaml["fix"]:
|
|
rule_yaml.pop("fix")
|
|
yaml_file_name = f"{rule_yaml['id']}.yaml"
|
|
yaml_full_path = os.path.join(build_path, section, yaml_file_name)
|
|
|
|
new_yaml = {
|
|
"id": rule_yaml["id"],
|
|
"title": rule_yaml["title"],
|
|
"discussion": rule_yaml["discussion"],
|
|
"references": {"nist": {"cce": {os_: rule_yaml["references"]["cce"]}}},
|
|
"platforms": {},
|
|
"tags": rule_yaml["tags"],
|
|
}
|
|
if "mobileconfig_info" in rule_yaml:
|
|
new_yaml.update({"mobileconfig_info": rule_yaml["mobileconfig_info"]})
|
|
if "ddm_info" in rule_yaml:
|
|
new_yaml.update({"ddm_info": rule_yaml["ddm_info"]})
|
|
if "odv" in rule_yaml:
|
|
new_yaml.update({"odv": rule_yaml["odv"]})
|
|
if (
|
|
os_ == "sequoia"
|
|
or os_ == "sonoma"
|
|
or os_ == "ventura"
|
|
or os_ == "monterey"
|
|
or os_ == "big_sur"
|
|
or os_ == "catalina"
|
|
):
|
|
new_yaml["platforms"] = {"macOS": {}}
|
|
new_yaml["platforms"]["macOS"].update({os_: {}})
|
|
|
|
new_yaml["platforms"]["macOS"].update({"check": rule_yaml["check"].strip()})
|
|
if "fix" in rule_yaml:
|
|
new_yaml["platforms"]["macOS"].update({"fix": rule_yaml["fix"].strip()})
|
|
if "result" in rule_yaml:
|
|
new_yaml["platforms"]["macOS"].update({"result": rule_yaml["result"]})
|
|
new_yaml["platforms"]["macOS"].update({os_: {}})
|
|
if "severity" in rule_yaml:
|
|
new_yaml["platforms"]["macOS"][os_].update({"severity": rule_yaml["severity"]})
|
|
|
|
if "cis_lvl1" in rule_yaml["tags"]:
|
|
# new_yaml['platforms']['macOS'][os_]['benchmarks'].append("cis_lvl1")
|
|
new_yaml["platforms"]["macOS"][os_].update({"benchmarks": ["cis_lvl1"]})
|
|
new_yaml["tags"].remove("cis_lvl1")
|
|
if "cis_lvl2" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["macOS"][os_]:
|
|
new_yaml["platforms"]["macOS"][os_]["benchmarks"].append("cis_lvl2")
|
|
else:
|
|
new_yaml["platforms"]["macOS"][os_].update({"benchmarks": ["cis_lvl2"]})
|
|
new_yaml["tags"].remove("cis_lvl2")
|
|
if "stig" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["macOS"][os_]:
|
|
new_yaml["platforms"]["macOS"][os_]["benchmarks"].append("disa_stig")
|
|
else:
|
|
new_yaml["platforms"]["macOS"][os_].update({"benchmarks": ["disa_stig"]})
|
|
new_yaml["tags"].remove("stig")
|
|
# print(new_yaml)
|
|
if "ddm_info" in rule_yaml:
|
|
new_yaml.update({"ddm_info": rule_yaml["ddm_info"]})
|
|
|
|
if "vision" in os_:
|
|
new_yaml["tags"].remove("visionos")
|
|
new_yaml["platforms"] = {"visionOS": {}}
|
|
|
|
new_yaml["platforms"]["visionOS"].update({os_: {}})
|
|
if "severity" in rule_yaml:
|
|
new_yaml["platforms"]["visionOS"][os_].update({"severity": rule_yaml["severity"]})
|
|
if "supervised" in rule_yaml:
|
|
new_yaml["platforms"]["visionOS"][os_].update({"supervised": rule_yaml["supervised"]})
|
|
|
|
if os_ == "ios_18" or os_ == "ios_17" or os_ == "ios_16":
|
|
new_yaml["tags"].remove("ios")
|
|
new_yaml["platforms"] = {"iOS": {}}
|
|
|
|
new_yaml["platforms"]["iOS"].update({os_: {}})
|
|
if "severity" in rule_yaml:
|
|
new_yaml["platforms"]["iOS"][os_].update({"severity": rule_yaml["severity"]})
|
|
if "supervised" in rule_yaml:
|
|
new_yaml["platforms"]["iOS"][os_].update({"supervised": rule_yaml["supervised"]})
|
|
|
|
if "cis_lvl1_byod" in rule_yaml["tags"]:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["cis_lvl1_byod"]})
|
|
new_yaml["tags"].remove("cis_lvl1_byod")
|
|
if "cis_lvl2_byod" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("cis_lvl2_byod")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["cis_lvl2_byod"]})
|
|
new_yaml["tags"].remove("cis_lvl2_byod")
|
|
if "cis_lvl1_enterprise" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("cis_lvl1_enterprise")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["cis_lvl1_enterprise"]})
|
|
new_yaml["tags"].remove("cis_lvl1_enterprise")
|
|
if "cis_lvl2_enterprise" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("cis_lvl2_enterprise")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["cis_lvl2_enterprise"]})
|
|
new_yaml["tags"].remove("cis_lvl2_enterprise")
|
|
if "ios_stig" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("ios_stig")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["ios_stig"]})
|
|
new_yaml["tags"].remove("ios_stig")
|
|
if "ios_stig_byoad" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("ios_stig_byoad")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["ios_stig_byoad"]})
|
|
new_yaml["tags"].remove("ios_stig_byoad")
|
|
if "indigo_base" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("indigo_base")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["indigo_base"]})
|
|
new_yaml["tags"].remove("indigo_base")
|
|
if "indigo_high" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("indigo_high")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["indigo_high"]})
|
|
new_yaml["tags"].remove("indigo_high")
|
|
|
|
if "800-53r5" in rule_yaml["references"]:
|
|
new_yaml["references"]["nist"].update({"800-53r5": rule_yaml["references"]["800-53r5"]})
|
|
|
|
if "800-171r3" in rule_yaml["references"]:
|
|
new_yaml["references"]["nist"].update({"800-171r3": rule_yaml["references"]["800-171r3"]})
|
|
if "cci" in rule_yaml["references"]:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"cci": rule_yaml["references"]["cci"]})
|
|
|
|
if "srg" in rule_yaml["references"]:
|
|
if "disa" in new_yaml["references"]:
|
|
new_yaml["references"]["disa"].update({"srg": rule_yaml["references"]["srg"]})
|
|
else:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"srg": rule_yaml["references"]["srg"]})
|
|
if "disa_stig" in rule_yaml["references"]:
|
|
if "disa" in new_yaml["references"]:
|
|
new_yaml["references"]["disa"].update({"disa_stig": {}})
|
|
new_yaml["references"]["disa"]["disa_stig"].update({os_: rule_yaml["references"]["disa_stig"]})
|
|
else:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"disa_stig": {}})
|
|
new_yaml["references"]["disa"]["disa_stig"].update({os_: rule_yaml["references"]["disa_stig"]})
|
|
if "sfr" in rule_yaml["references"]:
|
|
if "disa" in new_yaml["references"]:
|
|
new_yaml["references"]["disa"].update({"sfr": rule_yaml["references"]["sfr"]})
|
|
else:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"sfr": rule_yaml["references"]["sfr"]})
|
|
if "cmmc" in rule_yaml["references"]:
|
|
if "disa" in new_yaml["references"]:
|
|
new_yaml["references"]["disa"].update({"cmmc": rule_yaml["references"]["cmmc"]})
|
|
else:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"cmmc": rule_yaml["references"]["cmmc"]})
|
|
if "indigo" in rule_yaml["references"]:
|
|
if "bsi" in new_yaml["references"]:
|
|
new_yaml["references"]["bsi"].update({"indigo": {os_: rule_yaml["references"]["indigo"]}})
|
|
else:
|
|
new_yaml["references"].update({"bsi": {}})
|
|
new_yaml["references"]["bsi"].update({"indigo": {os_: rule_yaml["references"]["indigo"]}})
|
|
if "cis" in rule_yaml["references"]:
|
|
if "benchmark" in rule_yaml["references"]["cis"]:
|
|
if "cis" in new_yaml["references"]:
|
|
new_yaml["references"]["cis"].update({"benchmark": {}})
|
|
new_yaml["references"]["cis"]["benchmark"].update(
|
|
{os_: rule_yaml["references"]["cis"]["benchmark"]}
|
|
)
|
|
else:
|
|
new_yaml["references"].update({"cis": {}})
|
|
new_yaml["references"]["cis"].update({"benchmark": {}})
|
|
new_yaml["references"]["cis"]["benchmark"].update(
|
|
{os_: rule_yaml["references"]["cis"]["benchmark"]}
|
|
)
|
|
if "controls v8" in rule_yaml["references"]["cis"]:
|
|
if "cis" in new_yaml["references"]:
|
|
new_yaml["references"]["cis"].update(
|
|
{"controls_v8": rule_yaml["references"]["cis"]["controls v8"]}
|
|
)
|
|
else:
|
|
new_yaml["references"].update({"cis": {}})
|
|
new_yaml["references"]["cis"]["controls_v8"].update(
|
|
rule_yaml["references"]["cis"]["controls v8"]
|
|
)
|
|
|
|
with open(yaml_full_path, "w") as wfile:
|
|
# print(replace_na_with_none(new_yaml))
|
|
if yaml_full_path not in files_created:
|
|
files_created.append(yaml_full_path)
|
|
yaml.dump(new_yaml, wfile, Dumper=MyDumper, sort_keys=False, width=float("inf"))
|
|
|
|
if duplicates:
|
|
rules_to_review = []
|
|
|
|
# print("Duplicate IDs and their associated OS versions:")
|
|
for id_, os_versions in duplicates.items():
|
|
# print(f"ID: {id_}, OS Versions: {os_versions}")
|
|
|
|
os_specifics = {}
|
|
for os_ in os_versions:
|
|
section = id_.split("_")[0]
|
|
if section == "system":
|
|
section = "system_settings"
|
|
section_build_path = os.path.join(parent_dir, "rules", section)
|
|
if not (os.path.isdir(section_build_path)):
|
|
try:
|
|
os.makedirs(section_build_path)
|
|
except OSError:
|
|
print(f"Creation of the directory {build_path} failed")
|
|
|
|
with open("../_work/{}/rules/{}/{}.yaml".format(os_, section, id_)) as r:
|
|
rule_yam = yaml.load(r, Loader=yaml.SafeLoader)
|
|
rule_yaml = replace_na_with_none(rule_yam)
|
|
new_mobileconfig = restructure_mobileconfig(rule_yaml)
|
|
rule_yaml["mobileconfig_info"] = new_mobileconfig
|
|
if "This is implemented by a Configuration Profile" in rule_yaml["fix"]:
|
|
rule_yaml.pop("fix")
|
|
os_specifics.update({os_: {}})
|
|
|
|
# if "discussion" in rule_yaml:
|
|
# os_specifics[os_].update({"discussion":rule_yaml['discussion'].strip().replace(" \n","\n")})
|
|
if "check" in rule_yaml:
|
|
os_specifics[os_].update({"check": rule_yaml["check"].strip().replace(" \n", "\n")})
|
|
else:
|
|
os_specifics[os_].update({"check": ""})
|
|
if "result" in rule_yaml:
|
|
rule_yaml["result"] = correct_result_key(rule_yaml["result"])
|
|
os_specifics[os_].update({"result": rule_yaml["result"]})
|
|
else:
|
|
os_specifics[os_].update({"result": ""})
|
|
if "fix" in rule_yaml:
|
|
# fix_code, fix_note = cleanup_fix(rule_yaml['fix'])
|
|
# rule_yaml['fix'] = fix_code
|
|
os_specifics[os_].update({"fix": rule_yaml["fix"]})
|
|
else:
|
|
os_specifics[os_].update({"fix": ""})
|
|
if "mobileconfig" in rule_yaml:
|
|
os_specifics[os_].update({"mobileconfig": rule_yaml["mobileconfig_info"]})
|
|
else:
|
|
os_specifics[os_].update({"mobileconfig": ""})
|
|
|
|
yaml_file_name = f"{rule_yaml['id']}.yaml"
|
|
yaml_full_path = os.path.join(build_path, section, yaml_file_name)
|
|
|
|
if os.path.exists(yaml_full_path):
|
|
with open(yaml_full_path) as ryam:
|
|
update_rule_yam = yaml.load(ryam, Loader=yaml.SafeLoader)
|
|
update_rule_yaml = replace_na_with_none(update_rule_yam)
|
|
|
|
update_rule_yaml["references"]["nist"]["cce"].update({os_: rule_yaml["references"]["cce"]})
|
|
|
|
if "odv" in rule_yaml:
|
|
if "odv" in update_rule_yaml:
|
|
for k, v in rule_yaml["odv"].items():
|
|
update_rule_yaml["odv"].update({k: v})
|
|
else:
|
|
update_rule_yaml.update("odv", rule_yaml["odv"])
|
|
|
|
if "indigo" in rule_yaml["references"]:
|
|
if "bsi" in update_rule_yaml["references"]:
|
|
if "indigo" in update_rule_yaml["references"]["bsi"]:
|
|
update_rule_yaml["references"]["bsi"]["indigo"].update(
|
|
{os_: rule_yaml["references"]["indigo"]}
|
|
)
|
|
else:
|
|
update_rule_yaml["references"]["bsi"].update({"indigo": {}})
|
|
update_rule_yaml["references"]["bsi"]["indigo"].update(
|
|
{os_: rule_yaml["references"]["indigo"]}
|
|
)
|
|
else:
|
|
update_rule_yaml["references"].update({"bsi": {}})
|
|
update_rule_yaml["references"]["bsi"].update({"indigo": {}})
|
|
update_rule_yaml["references"]["bsi"]["indigo"].update(
|
|
{os_: rule_yaml["references"]["indigo"]}
|
|
)
|
|
|
|
if "cis" in rule_yaml["references"]:
|
|
if "benchmark" in rule_yaml["references"]["cis"]:
|
|
if "cis" in update_rule_yaml["references"]:
|
|
if "benchmark" in update_rule_yaml["references"]["cis"]:
|
|
update_rule_yaml["references"]["cis"]["benchmark"].update(
|
|
{os_: rule_yaml["references"]["cis"]["benchmark"]}
|
|
)
|
|
else:
|
|
update_rule_yaml["references"]["cis"].update({"benchmark": {}})
|
|
update_rule_yaml["references"]["cis"]["benchmark"].update(
|
|
{os_: rule_yaml["references"]["cis"]["benchmark"]}
|
|
)
|
|
else:
|
|
update_rule_yaml["references"].update({"cis": {}})
|
|
update_rule_yaml["references"]["cis"].update({"benchmark": {}})
|
|
update_rule_yaml["references"]["cis"]["benchmark"].update(
|
|
{os_: rule_yaml["references"]["cis"]["benchmark"]}
|
|
)
|
|
|
|
if "disa_stig" in rule_yaml["references"]:
|
|
if "disa" in update_rule_yaml["references"]:
|
|
if "disa_stig" in update_rule_yaml["references"]["disa"]:
|
|
update_rule_yaml["references"]["disa"]["disa_stig"].update(
|
|
{os_: rule_yaml["references"]["disa_stig"]}
|
|
)
|
|
else:
|
|
update_rule_yaml["references"]["disa"].update({"disa_stig": {}})
|
|
update_rule_yaml["references"]["disa"]["disa_stig"].update(
|
|
{os_: rule_yaml["references"]["disa_stig"]}
|
|
)
|
|
else:
|
|
update_rule_yaml["references"].update({"disa": {}})
|
|
update_rule_yaml["references"]["disa"].update({"disa_stig": {}})
|
|
update_rule_yaml["references"]["disa"]["disa_stig"].update(
|
|
{os_: rule_yaml["references"]["disa_stig"]}
|
|
)
|
|
|
|
for new_tag in rule_yaml["tags"]:
|
|
if new_tag in update_rule_yaml["tags"]:
|
|
continue
|
|
if (
|
|
"cis_lvl1" in new_tag
|
|
or "cis_lvl2" in new_tag
|
|
or "stig" in new_tag
|
|
or new_tag == "ios"
|
|
or "indigo" in new_tag
|
|
or "none" in new_tag
|
|
):
|
|
continue
|
|
if "ios" in new_tag or "visionos" in new_tag:
|
|
continue
|
|
if (
|
|
"800-53r4_low" in new_tag
|
|
or "800-53r4_moderate" in new_tag
|
|
or "800-53r4_high" in new_tag
|
|
):
|
|
continue
|
|
update_rule_yaml["tags"].append(new_tag)
|
|
|
|
if os_ == "visionos_2.0" or "ios" in os_:
|
|
# print("HELLO")
|
|
# print(os_)
|
|
if os_ == "visionos_2.0":
|
|
# print("hello vision")
|
|
update_rule_yaml["platforms"].update({"visionOS": {}})
|
|
update_rule_yaml["platforms"]["visionOS"].update({os_: {}})
|
|
|
|
if "supervised" in rule_yaml:
|
|
update_rule_yaml["platforms"]["visionOS"][os_].update(
|
|
{"supervised": rule_yaml["supervised"]}
|
|
)
|
|
# print(update_rule_yaml)
|
|
else:
|
|
if "iOS" not in update_rule_yaml["platforms"]:
|
|
update_rule_yaml["platforms"].update({"iOS": {}})
|
|
|
|
update_rule_yaml["platforms"]["iOS"].update({os_: {}})
|
|
|
|
if "severity" in rule_yaml:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"severity": rule_yaml["severity"]}
|
|
)
|
|
|
|
if "supervised" in rule_yaml:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"supervised": rule_yaml["supervised"]}
|
|
)
|
|
|
|
if "cis_lvl1_byod" in rule_yaml["tags"]:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"benchmarks": ["cis_lvl1_byod"]}
|
|
)
|
|
if "cis_lvl1_byod" in update_rule_yaml["tags"]:
|
|
update_rule_yaml["tags"].remove("cis_lvl1_byod")
|
|
|
|
if "cis_lvl2_byod" in rule_yaml["tags"]:
|
|
if "benchmarks" in update_rule_yaml["platforms"]["iOS"][os_]:
|
|
update_rule_yaml["platforms"]["iOS"][os_]["benchmarks"].append(
|
|
"cis_lvl2_byod"
|
|
)
|
|
else:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"benchmarks": ["cis_lvl2_byod"]}
|
|
)
|
|
|
|
if "cis_lvl2_byod" in update_rule_yaml["tags"]:
|
|
update_rule_yaml["tags"].remove("cis_lvl2_byod")
|
|
|
|
if "cis_lvl1_enterprise" in rule_yaml["tags"]:
|
|
if "benchmarks" in update_rule_yaml["platforms"]["iOS"][os_]:
|
|
update_rule_yaml["platforms"]["iOS"][os_]["benchmarks"].append(
|
|
"cis_lvl1_enterprise"
|
|
)
|
|
else:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"benchmarks": ["cis_lvl1_enterprise"]}
|
|
)
|
|
if "cis_lvl1_enterprise" in update_rule_yaml["tags"]:
|
|
update_rule_yaml["tags"].remove("cis_lvl1_enterprise")
|
|
if "cis_lvl2_enterprise" in rule_yaml["tags"]:
|
|
if "benchmarks" in update_rule_yaml["platforms"]["iOS"][os_]:
|
|
update_rule_yaml["platforms"]["iOS"][os_]["benchmarks"].append(
|
|
"cis_lvl2_enterprise"
|
|
)
|
|
else:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"benchmarks": ["cis_lvl2_enterprise"]}
|
|
)
|
|
|
|
if "cis_lvl2_enterprise" in update_rule_yaml["tags"]:
|
|
update_rule_yaml["tags"].remove("cis_lvl2_enterprise")
|
|
if "ios_stig" in rule_yaml["tags"]:
|
|
if "benchmarks" in update_rule_yaml["platforms"]["iOS"][os_]:
|
|
update_rule_yaml["platforms"]["iOS"][os_]["benchmarks"].append("ios_stig")
|
|
else:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"benchmarks": ["ios_stig"]}
|
|
)
|
|
|
|
if "ios_stig" in update_rule_yaml["tags"]:
|
|
update_rule_yaml["tags"].remove("ios_stig")
|
|
if "ios_stig_byoad" in rule_yaml["tags"]:
|
|
if "benchmarks" in update_rule_yaml["platforms"]["iOS"][os_]:
|
|
update_rule_yaml["platforms"]["iOS"][os_]["benchmarks"].append(
|
|
"ios_stig_byoad"
|
|
)
|
|
else:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"benchmarks": ["ios_stig_byoad"]}
|
|
)
|
|
|
|
if "ios_stig_byoad" in update_rule_yaml["tags"]:
|
|
update_rule_yaml["tags"].remove("ios_stig_byoad")
|
|
if "indigo_base" in rule_yaml["tags"]:
|
|
if "benchmarks" in update_rule_yaml["platforms"]["iOS"][os_]:
|
|
update_rule_yaml["platforms"]["iOS"][os_]["benchmarks"].append(
|
|
"indigo_base"
|
|
)
|
|
else:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"benchmarks": ["indigo_base"]}
|
|
)
|
|
|
|
if "indigo_base" in update_rule_yaml["tags"]:
|
|
update_rule_yaml["tags"].remove("indigo_base")
|
|
if "indigo_high" in rule_yaml["tags"]:
|
|
if "benchmarks" in update_rule_yaml["platforms"]["iOS"][os_]:
|
|
update_rule_yaml["platforms"]["iOS"][os_]["benchmarks"].append(
|
|
"indigo_high"
|
|
)
|
|
else:
|
|
update_rule_yaml["platforms"]["iOS"][os_].update(
|
|
{"benchmarks": ["indigo_high"]}
|
|
)
|
|
|
|
if "indigo_high" in update_rule_yaml["tags"]:
|
|
update_rule_yaml["tags"].remove("indigo_high")
|
|
|
|
if (
|
|
os_ == "sequoia"
|
|
or os_ == "sonoma"
|
|
or os_ == "ventura"
|
|
or os_ == "monterey"
|
|
or os_ == "big_sur"
|
|
or os_ == "catalina"
|
|
):
|
|
if "macOS" not in update_rule_yaml["platforms"]:
|
|
update_rule_yaml["platforms"].update({"macOS": {}})
|
|
update_rule_yaml["platforms"]["macOS"].update({os_: {}})
|
|
else:
|
|
if os_ not in update_rule_yaml["platforms"]["macOS"]:
|
|
update_rule_yaml["platforms"]["macOS"].update({os_: {}})
|
|
|
|
if "severity" in rule_yaml:
|
|
update_rule_yaml["platforms"]["macOS"][os_].update(
|
|
{"severity": rule_yaml["severity"]}
|
|
)
|
|
|
|
if "cis_lvl1" in rule_yaml["tags"]:
|
|
update_rule_yaml["platforms"]["macOS"][os_].update({"benchmarks": ["cis_lvl1"]})
|
|
|
|
if "cis_lvl2" in rule_yaml["tags"]:
|
|
if "benchmarks" in update_rule_yaml["platforms"]["macOS"][os_]:
|
|
update_rule_yaml["platforms"]["macOS"][os_]["benchmarks"].append("cis_lvl2")
|
|
else:
|
|
update_rule_yaml["platforms"]["macOS"][os_].update({"benchmarks": ["cis_lvl2"]})
|
|
|
|
if "stig" in rule_yaml["tags"]:
|
|
if "benchmarks" in update_rule_yaml["platforms"]["macOS"][os_]:
|
|
update_rule_yaml["platforms"]["macOS"][os_]["benchmarks"].append("disa_stig")
|
|
else:
|
|
update_rule_yaml["platforms"]["macOS"][os_].update(
|
|
{"benchmarks": ["disa_stig"]}
|
|
)
|
|
|
|
if "check" not in update_rule_yaml["platforms"]["macOS"]:
|
|
if "check" in rule_yaml:
|
|
# update_rule_yaml['platforms']['macOS'].update({"check", rule_yaml['check']})
|
|
update_rule_yaml["platforms"]["macOS"].update(
|
|
{"check": rule_yaml["check"].strip().replace(" \n", "\n")}
|
|
)
|
|
# update_rule_yaml['platforms']['macOS'].update({"result", rule_yaml['result']})
|
|
update_rule_yaml["platforms"]["macOS"].update({"result": rule_yaml["result"]})
|
|
if "fix" not in update_rule_yaml["platforms"]["macOS"]:
|
|
if "fix" in rule_yaml:
|
|
# fix_code, fix_note = cleanup_fix(rule_yaml['fix'])
|
|
# rule_yaml['fix'] = fix_code
|
|
update_rule_yaml["platforms"]["macOS"].update({"fix": rule_yaml["fix"]})
|
|
|
|
if "ddm_info" in rule_yaml:
|
|
update_rule_yaml.update({"ddm_info": rule_yaml["ddm_info"]})
|
|
|
|
with open(yaml_full_path, "w") as wfile:
|
|
yaml.dump(update_rule_yaml, wfile, Dumper=MyDumper, sort_keys=False, width=float("inf"))
|
|
else:
|
|
new_yaml = {
|
|
"id": rule_yaml["id"],
|
|
"title": rule_yaml["title"],
|
|
"discussion": rule_yaml["discussion"],
|
|
"references": {"nist": {"cce": {os_: rule_yaml["references"]["cce"]}}},
|
|
"platforms": {},
|
|
"tags": rule_yaml["tags"],
|
|
}
|
|
|
|
if "none" in new_yaml["tags"]:
|
|
new_yaml["tags"].remove("none")
|
|
|
|
if "800-53r4_low" in new_yaml["tags"]:
|
|
new_yaml["tags"].remove("800-53r4_low")
|
|
if "800-53r4_moderate" in new_yaml["tags"]:
|
|
new_yaml["tags"].remove("800-53r4_moderate")
|
|
if "800-53r4_high" in new_yaml["tags"]:
|
|
new_yaml["tags"].remove("800-53r4_high")
|
|
|
|
if "mobileconfig_info" in rule_yaml:
|
|
new_yaml.update({"mobileconfig_info": rule_yaml["mobileconfig_info"]})
|
|
if "ddm_info" in rule_yaml:
|
|
new_yaml.update({"ddm_info": rule_yaml["ddm_info"]})
|
|
if "odv" in rule_yaml:
|
|
new_yaml.update({"odv": rule_yaml["odv"]})
|
|
if (
|
|
os_ == "sequoia"
|
|
or os_ == "sonoma"
|
|
or os_ == "ventura"
|
|
or os_ == "monterey"
|
|
or os_ == "big_sur"
|
|
or os_ == "catalina"
|
|
):
|
|
new_yaml["platforms"] = {"macOS": {}}
|
|
|
|
new_yaml["platforms"]["macOS"].update({"check": rule_yaml["check"].strip()})
|
|
if "result" in rule_yaml:
|
|
rule_yaml["result"] = correct_result_key(rule_yaml["result"])
|
|
new_yaml["platforms"]["macOS"].update({"result": rule_yaml["result"]})
|
|
new_yaml["platforms"]["macOS"].update({os_: {}})
|
|
if "severity" in rule_yaml:
|
|
new_yaml["platforms"]["macOS"][os_].update({"severity": rule_yaml["severity"]})
|
|
|
|
if "cis_lvl1" in rule_yaml["tags"]:
|
|
# new_yaml['platforms']['macOS'][os_]['benchmarks'].append("cis_lvl1")
|
|
new_yaml["platforms"]["macOS"][os_].update({"benchmarks": ["cis_lvl1"]})
|
|
new_yaml["tags"].remove("cis_lvl1")
|
|
if "cis_lvl2" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["macOS"][os_]:
|
|
new_yaml["platforms"]["macOS"][os_]["benchmarks"].append("cis_lvl2")
|
|
else:
|
|
new_yaml["platforms"]["macOS"][os_].update({"benchmarks": ["cis_lvl2"]})
|
|
new_yaml["tags"].remove("cis_lvl2")
|
|
if "stig" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["macOS"][os_]:
|
|
new_yaml["platforms"]["macOS"][os_]["benchmarks"].append("disa_stig")
|
|
else:
|
|
new_yaml["platforms"]["macOS"][os_].update({"benchmarks": ["disa_stig"]})
|
|
new_yaml["tags"].remove("stig")
|
|
# print(new_yaml)
|
|
if os_ == "ios_18" or os_ == "ios_17" or os_ == "ios_16":
|
|
new_yaml["tags"].remove("ios")
|
|
new_yaml["platforms"].update({"iOS": {}})
|
|
new_yaml["platforms"]["iOS"].update({os_: {}})
|
|
|
|
if "severity" in rule_yaml:
|
|
new_yaml["platforms"]["iOS"][os_].update({"severity": rule_yaml["severity"]})
|
|
if "supervised" in rule_yaml:
|
|
new_yaml["platforms"]["iOS"][os_].update({"supervised": rule_yaml["supervised"]})
|
|
|
|
if "cis_lvl1_byod" in rule_yaml["tags"]:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["cis_lvl1_byod"]})
|
|
new_yaml["tags"].remove("cis_lvl1_byod")
|
|
if "cis_lvl2_byod" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("cis_lvl2_byod")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["cis_lvl2_byod"]})
|
|
new_yaml["tags"].remove("cis_lvl2_byod")
|
|
if "cis_lvl1_enterprise" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("cis_lvl1_enterprise")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["cis_lvl1_enterprise"]})
|
|
new_yaml["tags"].remove("cis_lvl1_enterprise")
|
|
if "cis_lvl2_enterprise" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("cis_lvl2_enterprise")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["cis_lvl2_enterprise"]})
|
|
new_yaml["tags"].remove("cis_lvl2_enterprise")
|
|
if "ios_stig" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("ios_stig")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["ios_stig"]})
|
|
new_yaml["tags"].remove("ios_stig")
|
|
if "ios_stig_byoad" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("ios_stig_byoad")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["ios_stig_byoad"]})
|
|
new_yaml["tags"].remove("ios_stig_byoad")
|
|
if "indigo_base" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("indigo_base")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["indigo_base"]})
|
|
new_yaml["tags"].remove("indigo_base")
|
|
if "indigo_high" in rule_yaml["tags"]:
|
|
if "benchmarks" in new_yaml["platforms"]["iOS"][os_]:
|
|
new_yaml["platforms"]["iOS"][os_]["benchmarks"].append("indigo_high")
|
|
else:
|
|
new_yaml["platforms"]["iOS"][os_].update({"benchmarks": ["indigo_high"]})
|
|
new_yaml["tags"].remove("indigo_high")
|
|
|
|
if os_ == "visionos_2.0":
|
|
new_yaml["tags"].remove("visionos")
|
|
new_yaml["platforms"].update({"visionOS": {}})
|
|
|
|
new_yaml["platforms"]["visionOS"].update({os_: {}})
|
|
|
|
if "supervised" in rule_yaml:
|
|
new_yaml["platforms"]["visionOS"][os_].update({"supervised": rule_yaml["supervised"]})
|
|
|
|
if "800-53r5" in rule_yaml["references"]:
|
|
new_yaml["references"]["nist"].update({"800-53r5": rule_yaml["references"]["800-53r5"]})
|
|
|
|
if "800-171r3" in rule_yaml["references"]:
|
|
new_yaml["references"]["nist"].update({"800-171r3": rule_yaml["references"]["800-171r3"]})
|
|
if "cci" in rule_yaml["references"]:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"cci": rule_yaml["references"]["cci"]})
|
|
|
|
if "srg" in rule_yaml["references"]:
|
|
if "disa" in new_yaml["references"]:
|
|
new_yaml["references"]["disa"].update({"srg": rule_yaml["references"]["srg"]})
|
|
else:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"srg": rule_yaml["references"]["srg"]})
|
|
if "disa_stig" in rule_yaml["references"]:
|
|
if "disa" in new_yaml["references"]:
|
|
new_yaml["references"]["disa"].update({"disa_stig": {}})
|
|
new_yaml["references"]["disa"]["disa_stig"].update(
|
|
{os_: rule_yaml["references"]["disa_stig"]}
|
|
)
|
|
else:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"disa_stig": {}})
|
|
new_yaml["references"]["disa"]["disa_stig"].update(
|
|
{os_: rule_yaml["references"]["disa_stig"]}
|
|
)
|
|
if "sfr" in rule_yaml["references"]:
|
|
if "disa" in new_yaml["references"]:
|
|
new_yaml["references"]["disa"].update({"sfr": rule_yaml["references"]["sfr"]})
|
|
else:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"sfr": rule_yaml["references"]["sfr"]})
|
|
if "cmmc" in rule_yaml["references"]:
|
|
if "disa" in new_yaml["references"]:
|
|
new_yaml["references"]["disa"].update({"cmmc": rule_yaml["references"]["cmmc"]})
|
|
else:
|
|
new_yaml["references"].update({"disa": {}})
|
|
new_yaml["references"]["disa"].update({"cmmc": rule_yaml["references"]["cmmc"]})
|
|
|
|
if "cis" in rule_yaml["references"]:
|
|
if "benchmark" in rule_yaml["references"]["cis"]:
|
|
if "cis" in new_yaml["references"]:
|
|
new_yaml["references"]["cis"].update({"benchmark": {}})
|
|
new_yaml["references"]["cis"]["benchmark"].update(
|
|
{os_: rule_yaml["references"]["cis"]["benchmark"]}
|
|
)
|
|
else:
|
|
new_yaml["references"].update({"cis": {}})
|
|
new_yaml["references"]["cis"].update({"benchmark": {}})
|
|
new_yaml["references"]["cis"]["benchmark"].update(
|
|
{os_: rule_yaml["references"]["cis"]["benchmark"]}
|
|
)
|
|
if "controls v8" in rule_yaml["references"]["cis"]:
|
|
if "cis" in new_yaml["references"]:
|
|
new_yaml["references"]["cis"].update(
|
|
{"controls_v8": rule_yaml["references"]["cis"]["controls v8"]}
|
|
)
|
|
else:
|
|
new_yaml["references"].update({"cis": {}})
|
|
new_yaml["references"]["cis"]["controls_v8"].update(
|
|
rule_yaml["references"]["cis"]["controls v8"]
|
|
)
|
|
|
|
with open(yaml_full_path, "w") as wfile:
|
|
yaml.dump(new_yaml, wfile, Dumper=MyDumper, sort_keys=False, width=float("inf"))
|
|
|
|
# if os_ == "sequoia" or os_ == "sonoma" or os_ == "ventura" or os_ == "monterey" or os_ == "big_sur" or os_ == "catalina":
|
|
platforms = list(os_specifics.keys())
|
|
|
|
# for p in platforms:
|
|
# base_os = platforms[0]
|
|
# if base_os == "ios_16" or base_os == "ios_17" or base_os == "ios_18" or base_os == "visionos_2.0":
|
|
# base_os = p
|
|
# if base_os != "ios_16" or base_os != "ios_17" or base_os != "ios_18" or base_os != "visionos_2.0":
|
|
# break
|
|
base_os = platforms[0]
|
|
base_value = os_specifics[base_os]["mobileconfig"]
|
|
|
|
configprofile_differences = {}
|
|
|
|
for platform in platforms[1:]:
|
|
if os_specifics[platform]["mobileconfig"] != base_value:
|
|
configprofile_differences[platform] = os_specifics[platform]["mobileconfig"]
|
|
# print(rule_yaml['id'])
|
|
# print(configprofile_differences)
|
|
|
|
# discussion_differences = {}
|
|
# base_value = os_specifics[base_os]['discussion']
|
|
# for platform in platforms[1:]:
|
|
# if os_specifics[platform]['discussion'] != base_value:
|
|
# discussion_differences[base_os] = base_value
|
|
# discussion_differences[platform] = os_specifics[platform]['discussion']
|
|
|
|
# if discussion_differences:
|
|
# print("+++++++++++++++++++")
|
|
# print(rule_yaml['id'])
|
|
# print(json.dumps(discussion_differences,indent=4))
|
|
# print()
|
|
|
|
for key in ["check", "fix", "result", "mobileconfig"]:
|
|
base_os = platforms[0]
|
|
for p in platforms:
|
|
base_os = platforms[0]
|
|
if base_os == "ios_16" or base_os == "ios_17" or base_os == "ios_18" or base_os == "visionos_2.0":
|
|
base_os = p
|
|
if base_os != "ios_16" or base_os != "ios_17" or base_os != "ios_18" or base_os != "visionos_2.0":
|
|
break
|
|
base_value = os_specifics[base_os][key]
|
|
differences = {}
|
|
|
|
for platform in platforms[1:]:
|
|
if ("ios" in platform or "vision" in platform and key == "check") or (
|
|
"ios" in platform or "vision" in platform and key == "result"
|
|
):
|
|
continue
|
|
if os_specifics[platform][key] != base_value:
|
|
# print(rule_yaml['id'])
|
|
# print(base_value)
|
|
# print(base_os)
|
|
|
|
differences[platform] = os_specifics[platform][key]
|
|
if key == "result":
|
|
differences[platform] = os_specifics[platform][key]
|
|
with open(yaml_full_path) as ryam:
|
|
differences_yam = yaml.load(ryam, Loader=yaml.SafeLoader)
|
|
differences_yaml = replace_na_with_none(differences_yam)
|
|
|
|
if differences:
|
|
# print(os_specifics)
|
|
for operating_sys, value in os_specifics.items():
|
|
if "vision" in operating_sys or "ios" in operating_sys:
|
|
continue
|
|
|
|
if key == "check":
|
|
if value["check"] == " " or value["check"] == "":
|
|
continue
|
|
# print(base_os)
|
|
|
|
# print(differences)
|
|
# print("++++++++++++")
|
|
differences_yaml["platforms"]["macOS"][operating_sys].update({"check": value["check"]})
|
|
if key == "result":
|
|
if value["result"] == " " or value["result"] == "":
|
|
continue
|
|
# if "result" in differences_yaml['platforms']['macOS']:
|
|
# if operating_sys != "sequoia":
|
|
differences_yaml["platforms"]["macOS"][operating_sys].update({"result": value["result"]})
|
|
|
|
if key == "fix":
|
|
differences_yaml["platforms"]["macOS"][operating_sys].update({"fix": value["fix"]})
|
|
|
|
# if key == "mobileconfig":
|
|
# differences_yaml['platforms']['macOS'][operating_sys].update({"mobileconfig": value})
|
|
if "macOS" in differences_yaml["platforms"]:
|
|
if key == "result":
|
|
if differences_yaml["id"] not in rules_to_review:
|
|
rules_to_review.append(differences_yaml["id"])
|
|
# differences_yaml['platforms']['macOS']['result'] = "$OS_VALUE"
|
|
if key == "check":
|
|
if differences_yaml["id"] not in rules_to_review:
|
|
rules_to_review.append(differences_yaml["id"])
|
|
# differences_yaml['platforms']['macOS']['check'] = "$OS_VALUE"
|
|
if key == "fix":
|
|
if differences_yaml["id"] not in rules_to_review:
|
|
rules_to_review.append(differences_yaml["id"])
|
|
# differences_yaml['platforms']['macOS']['fix'] = "$OS_VALUE"
|
|
# if key == "mobileconfig":
|
|
# differences_yaml['mobileconfig_info'] = "$OS_VALUE"
|
|
|
|
if configprofile_differences and key == "mobileconfig":
|
|
for operating_sys, value in os_specifics.items():
|
|
if operating_sys == "visionos_2.0":
|
|
differences_yaml["platforms"]["visionOS"][operating_sys].update(
|
|
{"mobileconfig_info": value["mobileconfig"]}
|
|
)
|
|
elif "ios" in operating_sys:
|
|
differences_yaml["platforms"]["iOS"][operating_sys].update(
|
|
{"mobileconfig_info": value["mobileconfig"]}
|
|
)
|
|
elif (
|
|
os_ == "sequoia"
|
|
or os_ == "sonoma"
|
|
or os_ == "ventura"
|
|
or os_ == "monterey"
|
|
or os_ == "big_sur"
|
|
or os_ == "catalina"
|
|
):
|
|
differences_yaml["platforms"]["macOS"][operating_sys].update(
|
|
{"mobileconfig_info": value["mobileconfig"]}
|
|
)
|
|
# print(differences_yaml['id'])
|
|
# print(value['mobileconfig'])
|
|
# print(operating_sys)
|
|
# differences_yaml['mobileconfig_info'] = "$OS_VALUE"
|
|
|
|
with open(yaml_full_path, "w") as wfile:
|
|
yaml.dump(differences_yaml, wfile, Dumper=MyDumper, sort_keys=False, width=float("inf"))
|
|
|
|
with open(yaml_full_path, "r") as r_again:
|
|
re_order_ya = yaml.load(r_again, Loader=yaml.SafeLoader)
|
|
re_order_yam = replace_na_with_none(re_order_ya)
|
|
|
|
yaml_key_order = [
|
|
"id",
|
|
"title",
|
|
"discussion",
|
|
"references",
|
|
"platforms",
|
|
"odv",
|
|
"tags",
|
|
"mobileconfig_info",
|
|
"ddm_info",
|
|
]
|
|
ordered_keys = sorted(
|
|
re_order_yam.keys(),
|
|
key=lambda k: (yaml_key_order.index(k) if k in yaml_key_order else len(yaml_key_order), k),
|
|
)
|
|
re_order_yam = {key: re_order_yam[key] for key in ordered_keys}
|
|
|
|
priority_os_order = [
|
|
"sequoia",
|
|
"sonoma",
|
|
"ventura",
|
|
"monterey",
|
|
"big_sur",
|
|
"catalina",
|
|
"ios_18",
|
|
"ios_17",
|
|
"ios_16",
|
|
"visionos_2.0",
|
|
]
|
|
ordered_keys = sorted(
|
|
re_order_yam["references"]["nist"]["cce"].keys(),
|
|
key=lambda k: (priority_os_order.index(k) if k in priority_os_order else len(priority_os_order), k),
|
|
)
|
|
re_order_yam["references"]["nist"]["cce"] = {
|
|
key: re_order_yam["references"]["nist"]["cce"][key] for key in ordered_keys
|
|
}
|
|
if "disa" in re_order_yam["references"]:
|
|
if "disa_stig" in re_order_yam["references"]["disa"]:
|
|
ordered_keys = sorted(
|
|
re_order_yam["references"]["disa"]["disa_stig"].keys(),
|
|
key=lambda k: (
|
|
priority_os_order.index(k) if k in priority_os_order else len(priority_os_order),
|
|
k,
|
|
),
|
|
)
|
|
re_order_yam["references"]["disa"]["disa_stig"] = {
|
|
key: re_order_yam["references"]["disa"]["disa_stig"][key] for key in ordered_keys
|
|
}
|
|
if "cis" in re_order_yam["references"]:
|
|
if "benchmark" in re_order_yam["references"]["cis"]:
|
|
ordered_keys = sorted(
|
|
re_order_yam["references"]["cis"]["benchmark"].keys(),
|
|
key=lambda k: (
|
|
priority_os_order.index(k) if k in priority_os_order else len(priority_os_order),
|
|
k,
|
|
),
|
|
)
|
|
re_order_yam["references"]["cis"]["benchmark"] = {
|
|
key: re_order_yam["references"]["cis"]["benchmark"][key] for key in ordered_keys
|
|
}
|
|
|
|
priority_macos_order = [
|
|
"check",
|
|
"result",
|
|
"fix",
|
|
"sequoia",
|
|
"sonoma",
|
|
"ventura",
|
|
"monterey",
|
|
"big_sur",
|
|
"catalina",
|
|
]
|
|
priority_ios_order = ["ios_18", "ios_17", "ios_16"]
|
|
platform_order = ["macOS", "iOS", "visionOS"]
|
|
# print(re_order_yam)
|
|
ordered_keys = sorted(
|
|
re_order_yam["platforms"].keys(),
|
|
key=lambda k: (platform_order.index(k) if k in platform_order else len(platform_order), k),
|
|
)
|
|
re_order_yam["platforms"] = {key: re_order_yam["platforms"][key] for key in ordered_keys}
|
|
|
|
if "macOS" in re_order_yam["platforms"]:
|
|
ordered_keys = sorted(
|
|
re_order_yam["platforms"]["macOS"].keys(),
|
|
key=lambda k: (
|
|
priority_macos_order.index(k) if k in priority_macos_order else len(priority_macos_order),
|
|
k,
|
|
),
|
|
)
|
|
re_order_yam["platforms"]["macOS"] = {
|
|
key: re_order_yam["platforms"]["macOS"][key] for key in ordered_keys
|
|
}
|
|
if "iOS" in re_order_yam["platforms"]:
|
|
ordered_keys = sorted(
|
|
re_order_yam["platforms"]["iOS"].keys(),
|
|
key=lambda k: (
|
|
priority_ios_order.index(k) if k in priority_ios_order else len(priority_ios_order),
|
|
k,
|
|
),
|
|
)
|
|
re_order_yam["platforms"]["iOS"] = {key: re_order_yam["platforms"]["iOS"][key] for key in ordered_keys}
|
|
|
|
if "mobileconfig_info" in re_order_yam:
|
|
if re_order_yam["mobileconfig_info"] == None:
|
|
re_order_yam.pop("mobileconfig_info")
|
|
|
|
with open(yaml_full_path, "w") as wfile:
|
|
if yaml_full_path not in files_created:
|
|
files_created.append(yaml_full_path)
|
|
yaml.dump(re_order_yam, wfile, Dumper=MyDumper, sort_keys=False, width=float("inf"))
|
|
|
|
print("review the following rules across branches for minor differences")
|
|
for r in rules_to_review:
|
|
print(r)
|
|
|
|
unknown_keys = []
|
|
odv_rules = []
|
|
for file in files_created:
|
|
with open(file) as newyamlfile:
|
|
_yaml = yaml.load(newyamlfile, Loader=yaml.SafeLoader)
|
|
if "srg" in _yaml["tags"]:
|
|
_yaml["tags"].remove("srg")
|
|
if "visionos" in _yaml["tags"]:
|
|
_yaml["tags"].remove("visionos")
|
|
|
|
_yaml = replace_keys_by_path(_yaml)
|
|
|
|
# update discussions
|
|
for d in discussions_yaml:
|
|
if _yaml["id"] == d["id"]:
|
|
_yaml["discussion"] = d["discussion"]
|
|
|
|
# move permanent, inherant check/fix info into discussions
|
|
if "macOS" in _yaml["platforms"] and "check" in _yaml["platforms"]["macOS"]:
|
|
if (
|
|
"requirement is NA" in _yaml["platforms"]["macOS"]["check"]
|
|
or "inherently" in _yaml["platforms"]["macOS"]["check"]
|
|
or "does not meet finding" in _yaml["platforms"]["macOS"]["check"]
|
|
or "technology does support this requirement" in _yaml["platforms"]["macOS"]["check"]
|
|
or "technology partially supports" in _yaml["platforms"]["macOS"]["check"]
|
|
):
|
|
check_text = _yaml["platforms"]["macOS"]["check"]
|
|
fix_text = _yaml["platforms"]["macOS"]["fix"]
|
|
_yaml["platforms"]["macOS"].pop("check")
|
|
# _yaml['platforms']['macOS'].pop('fix')
|
|
_yaml["discussion"] += f"\nNOTE: {check_text}"
|
|
|
|
# clean up any redundent checks
|
|
for _os in _yaml["platforms"]["macOS"].keys():
|
|
if _os == "check" or _os == "fix" or _os == "result":
|
|
continue
|
|
|
|
_yaml["platforms"]["macOS"][_os]["enforcement_info"] = {}
|
|
|
|
if "check" in _yaml["platforms"]["macOS"][_os]:
|
|
if _yaml["platforms"]["macOS"]["check"] == _yaml["platforms"]["macOS"][_os]["check"]:
|
|
print(f"{_yaml['id']} - main check matches check of {_os}")
|
|
_yaml["platforms"]["macOS"][_os].pop("check")
|
|
# if "result" in _yaml['platforms']['macOS'][_os]:
|
|
# _yaml['platforms']['macOS'][_os].pop('result')
|
|
# move it into compliance object
|
|
|
|
if "check" in _yaml["platforms"]["macOS"][_os]:
|
|
_yaml["platforms"]["macOS"][_os]["enforcement_info"]["check"] = {}
|
|
_yaml["platforms"]["macOS"][_os]["enforcement_info"]["check"]["shell"] = _yaml["platforms"][
|
|
"macOS"
|
|
][_os]["check"]
|
|
_yaml["platforms"]["macOS"][_os].pop("check")
|
|
if (
|
|
"result" in _yaml["platforms"]["macOS"][_os]
|
|
and "check" in _yaml["platforms"]["macOS"][_os]["enforcement_info"]
|
|
):
|
|
_yaml["platforms"]["macOS"][_os]["enforcement_info"]["check"]["result"] = _yaml["platforms"][
|
|
"macOS"
|
|
][_os]["result"]
|
|
_yaml["platforms"]["macOS"][_os].pop("result")
|
|
elif "result" in _yaml["platforms"]["macOS"][_os]:
|
|
_yaml["platforms"]["macOS"][_os].pop("result")
|
|
|
|
if "fix" in _yaml["platforms"]["macOS"][_os]:
|
|
if _yaml["platforms"]["macOS"]["fix"] == _yaml["platforms"]["macOS"][_os]["fix"]:
|
|
print(f"{_yaml['id']} - main fix matches fix of {_os}")
|
|
_yaml["platforms"]["macOS"][_os].pop("fix")
|
|
|
|
# move it into compliance object
|
|
if "fix" in _yaml["platforms"]["macOS"][_os]:
|
|
fix_code, fix_note = cleanup_fix(_yaml["platforms"]["macOS"][_os]["fix"])
|
|
_yaml["platforms"]["macOS"][_os]["enforcement_info"]["fix"] = {}
|
|
if fix_code:
|
|
_yaml["platforms"]["macOS"][_os]["enforcement_info"]["fix"]["shell"] = fix_code
|
|
if fix_note:
|
|
_yaml["platforms"]["macOS"][_os]["enforcement_info"]["fix"]["additional_info"] = fix_note
|
|
_yaml["platforms"]["macOS"][_os].pop("fix")
|
|
|
|
if _yaml["platforms"]["macOS"][_os]["enforcement_info"] == {}:
|
|
_yaml["platforms"]["macOS"][_os].pop("enforcement_info")
|
|
|
|
_yaml["platforms"]["macOS"]["enforcement_info"] = {}
|
|
if "check" in _yaml["platforms"]["macOS"]:
|
|
_yaml["platforms"]["macOS"]["enforcement_info"]["check"] = {}
|
|
_yaml["platforms"]["macOS"]["enforcement_info"]["check"]["shell"] = _yaml["platforms"]["macOS"][
|
|
"check"
|
|
]
|
|
_yaml["platforms"]["macOS"].pop("check")
|
|
|
|
if "result" in _yaml["platforms"]["macOS"]:
|
|
_yaml["platforms"]["macOS"]["enforcement_info"]["check"]["result"] = _yaml["platforms"]["macOS"][
|
|
"result"
|
|
]
|
|
_yaml["platforms"]["macOS"].pop("result")
|
|
|
|
if "fix" in _yaml["platforms"]["macOS"]:
|
|
fix_code, fix_note = cleanup_fix(_yaml["platforms"]["macOS"]["fix"])
|
|
if "inherently" not in fix_code and "permanent" not in fix_note:
|
|
_yaml["platforms"]["macOS"]["enforcement_info"]["fix"] = {}
|
|
if fix_code:
|
|
_yaml["platforms"]["macOS"]["enforcement_info"]["fix"]["shell"] = fix_code
|
|
if fix_note:
|
|
_yaml["platforms"]["macOS"]["enforcement_info"]["fix"]["additional_info"] = fix_note
|
|
_yaml["platforms"]["macOS"].pop("fix")
|
|
|
|
if _yaml["platforms"]["macOS"]["enforcement_info"] == {}:
|
|
_yaml["platforms"]["macOS"].pop("enforcement_info")
|
|
|
|
# restructure benchmarks to include severity
|
|
for p in _yaml["platforms"].keys():
|
|
for o in _yaml["platforms"][p]:
|
|
if "benchmarks" in _yaml["platforms"][p][o]:
|
|
if "severity" in _yaml["platforms"][p][o]:
|
|
s = _yaml["platforms"][p][o]["severity"]
|
|
_yaml["platforms"][p][o].pop("severity")
|
|
else:
|
|
s = ""
|
|
|
|
_yaml["platforms"][p][o]["benchmarks"] = restructure_benchmarks(
|
|
_yaml["platforms"][p][o]["benchmarks"], s
|
|
)
|
|
elif "severity" in _yaml["platforms"][p][o]:
|
|
_yaml["platforms"][p][o].pop("severity")
|
|
|
|
# restructure benchmarks to include severity
|
|
# for p in _yaml['platforms'].keys():
|
|
# for o in _yaml['platforms'][p]:
|
|
# if "benchmarks" in _yaml['platforms'][p][o]:
|
|
# if "severity" in _yaml['platforms'][p][o]:
|
|
# s = _yaml['platforms'][p][o]['severity']
|
|
# else:
|
|
# s = ""
|
|
|
|
# _yaml['platforms'][p][o]['severity'] = restructure_severity(_yaml['platforms'][p][o]['benchmarks'], s)
|
|
# elif "severity" in _yaml['platforms'][p][o]:
|
|
# _yaml['platforms'][p][o].pop('severity')
|
|
|
|
# add the introduced data here
|
|
if "mobileconfig_info" in _yaml.keys():
|
|
os_list = list(_yaml["platforms"].keys())
|
|
|
|
for mobileconfig_payload in _yaml["mobileconfig_info"]:
|
|
payloadtype = mobileconfig_payload["PayloadType"]
|
|
payloadkeys = mobileconfig_payload["PayloadContent"]
|
|
# just get first key, since we can't identify multiple introduce versions
|
|
payloadkey = next(iter(payloadkeys[0]))
|
|
|
|
for opsys in os_list:
|
|
if payloadtype in apple_profiles.keys():
|
|
version = get_introduced(apple_profiles[payloadtype], payloadkey, opsys)
|
|
if version == "-1":
|
|
unknown_keys.append(payloadkey)
|
|
_yaml["platforms"][opsys]["introduced"] = version
|
|
else:
|
|
unknown_keys.append(payloadkey)
|
|
_yaml["platforms"][opsys]["introduced"] = "-1"
|
|
|
|
for platform in _yaml["platforms"].keys():
|
|
for _os in _yaml["platforms"][platform].keys():
|
|
if _os == "check" or _os == "fix" or _os == "result" or _os == "introduced":
|
|
continue
|
|
if (
|
|
"mobileconfig_info" in _yaml["platforms"][platform][_os].keys()
|
|
and _yaml["mobileconfig_info"] == _yaml["platforms"][platform][_os]["mobileconfig_info"]
|
|
):
|
|
_yaml["platforms"][platform][_os].pop("mobileconfig_info")
|
|
|
|
if "odv" in _yaml.keys():
|
|
description = _yaml["odv"]["hint"]
|
|
datatype = None
|
|
validation = None
|
|
for r in odv_json:
|
|
if r["ruleId"] == _yaml["id"]:
|
|
datatype = r["type"]
|
|
if "note" in r.keys():
|
|
description = r["note"]
|
|
if "validation" in r.keys():
|
|
validation = r["validation"]
|
|
|
|
_yaml["odv"]["hint"] = {}
|
|
_yaml["odv"]["hint"]["datatype"] = datatype
|
|
_yaml["odv"]["hint"]["description"] = description
|
|
_yaml["odv"]["hint"]["validation"] = validation
|
|
odv_rules.append(_yaml["id"])
|
|
|
|
with open(file, "w") as nf:
|
|
yaml.dump(remove_none_fields(_yaml), nf, Dumper=MyDumper, sort_keys=False, width=float("inf"))
|
|
|
|
print("\n\nthe following keys are not found in apple git")
|
|
for k in unknown_keys:
|
|
print(k)
|
|
|
|
print("\n\nthe following rules have ODVs to update")
|
|
for k in odv_rules:
|
|
print(k)
|
|
|
|
|
|
def replace_keys_by_path(data, path=None):
|
|
if path is None:
|
|
path = []
|
|
|
|
if isinstance(data, dict):
|
|
new_data = {}
|
|
for k, v in data.items():
|
|
current_path = path + [k]
|
|
new_k = k
|
|
if k == "visionos_2.0":
|
|
if path == ["references", "nist", "cce"]:
|
|
new_k = "visionos_2"
|
|
elif path == ["references", "disa", "disa_stig"]:
|
|
new_k = "visionos_2"
|
|
elif path == ["platforms", "visionOS"]:
|
|
new_k = "2.0"
|
|
# else:
|
|
# new_k = k # leave as-is
|
|
if k == "ios_18":
|
|
if path == ["platforms", "iOS"]:
|
|
new_k = "18.0"
|
|
# else:
|
|
# new_k = k # leave as-is
|
|
# Determine the replacement key
|
|
if k == "ios_16":
|
|
if path == ["platforms", "iOS"]:
|
|
new_k = "16.0"
|
|
# else:
|
|
# new_k = k # leave as-is
|
|
if k == "ios_17":
|
|
if path == ["platforms", "iOS"]:
|
|
new_k = "17.0"
|
|
# else:
|
|
# new_k = k # leave as-is
|
|
if k == "ios_18":
|
|
if path == ["platforms", "iOS"]:
|
|
new_k = "18.0"
|
|
# else:
|
|
# new_k = k # leave as-is
|
|
if k == "ventura":
|
|
if path == ["references", "nist", "cce"]:
|
|
new_k = "macos_13"
|
|
elif path == ["references", "disa", "disa_stig"]:
|
|
new_k = "macos_13"
|
|
elif path == ["references", "cis", "benchmark"]:
|
|
new_k = "macos_13"
|
|
elif path == ["platforms", "macOS"]:
|
|
new_k = "13.0"
|
|
# else:
|
|
# new_k = k # leave as-is
|
|
if k == "sonoma":
|
|
if path == ["references", "nist", "cce"]:
|
|
new_k = "macos_14"
|
|
elif path == ["references", "disa", "disa_stig"]:
|
|
new_k = "macos_14"
|
|
elif path == ["references", "cis", "benchmark"]:
|
|
new_k = "macos_14"
|
|
elif path == ["platforms", "macOS"]:
|
|
new_k = "14.0"
|
|
# else:
|
|
# new_k = k # leave as-is
|
|
if k == "sequoia":
|
|
if path == ["references", "nist", "cce"]:
|
|
new_k = "macos_15"
|
|
elif path == ["references", "disa", "disa_stig"]:
|
|
new_k = "macos_15"
|
|
elif path == ["references", "cis", "benchmark"]:
|
|
new_k = "macos_15"
|
|
elif path == ["platforms", "macOS"]:
|
|
new_k = "15.0"
|
|
# else:
|
|
# new_k = k # leave as-is
|
|
# else:
|
|
# new_k = k
|
|
|
|
new_data[new_k] = replace_keys_by_path(v, current_path)
|
|
return new_data
|
|
|
|
elif isinstance(data, list):
|
|
return [replace_keys_by_path(item, path) for item in data]
|
|
else:
|
|
return data
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|