This commit is contained in:
Bob Gendler
2025-09-24 10:55:17 -04:00
parent 0ce0adffdd
commit ca618f9363

View File

@@ -402,7 +402,7 @@ def concatenate_payload_settings(settings):
def generate_profiles( def generate_profiles(
baseline_name, build_path, parent_dir, baseline_yaml, signing, hash="" baseline_name, build_path, parent_dir, baseline_yaml, signing, hash="", generate_domain=True, generate_consolidated=True
): ):
"""Generate the configuration profiles for the rules in the provided baseline YAML file""" """Generate the configuration profiles for the rules in the provided baseline YAML file"""
@@ -525,6 +525,15 @@ def generate_profiles(
) )
for error in profile_errors: for error in profile_errors:
print(error) print(error)
consolidated_profile = PayloadDict(
identifier="consolidated." + baseline_name,
uuid=False,
organization="macOS Security Compliance Project",
displayname=f"{baseline_name} settings",
description=f"Consolidated configuration settings for {baseline_name}."
)
# process the payloads from the yaml file and generate new config profile for each type # process the payloads from the yaml file and generate new config profile for each type
for payload, settings in profile_types.items(): for payload, settings in profile_types.items():
if payload.startswith("."): if payload.startswith("."):
@@ -572,35 +581,35 @@ def generate_profiles(
if payload == "com.apple.ManagedClient.preferences": if payload == "com.apple.ManagedClient.preferences":
for item in settings: for item in settings:
newProfile.addMCXPayload(item, baseline_name) newProfile.addMCXPayload(item, baseline_name)
consolidated_profile.addMCXPayload(item, baseline_name)
# handle these payloads for array settings # handle these payloads for array settings
elif ( elif (
(payload == "com.apple.applicationaccess.new") (payload == "com.apple.applicationaccess.new")
or (payload == "com.apple.systempreferences") or (payload == "com.apple.systempreferences")
or (payload == "com.apple.SetupAssistant.managed") or (payload == "com.apple.SetupAssistant.managed")
): ):
newProfile.addNewPayload( newProfile.addNewPayload(payload, concatenate_payload_settings(settings), baseline_name)
payload, concatenate_payload_settings(settings), baseline_name consolidated_profile.addNewPayload(payload, concatenate_payload_settings(settings), baseline_name)
)
else: else:
newProfile.addNewPayload(payload, settings, baseline_name) newProfile.addNewPayload(payload, settings, baseline_name)
consolidated_profile.addNewPayload(payload, settings, baseline_name)
if generate_domain:
with open(settings_plist_file_path, "wb") as settings_plist_file:
newProfile.finalizeAndSavePlist(settings_plist_file)
with open(unsigned_mobileconfig_file_path, "wb") as unsigned_mobileconfig_file:
newProfile.finalizeAndSave(unsigned_mobileconfig_file)
if signing:
sign_config_profile(unsigned_mobileconfig_file_path, signed_mobileconfig_file_path, hash)
if generate_consolidated:
consolidated_mobileconfig_file_path = os.path.join(unsigned_mobileconfig_output_path, f"{baseline_name}.mobileconfig")
with open(consolidated_mobileconfig_file_path, "wb") as consolidated_mobileconfig_file:
consolidated_profile.finalizeAndSave(consolidated_mobileconfig_file)
if signing: if signing:
unsigned_file_path = os.path.join(unsigned_mobileconfig_file_path) signed_consolidated_mobileconfig_path = os.path.join(signed_mobileconfig_output_path, f"{baseline_name}.mobileconfig")
unsigned_config_file = open(unsigned_file_path, "wb") sign_config_profile(consolidated_mobileconfig_file_path, signed_consolidated_mobileconfig_path, hash)
newProfile.finalizeAndSave(unsigned_config_file)
settings_config_file = open(settings_plist_file_path, "wb")
newProfile.finalizeAndSavePlist(settings_config_file)
unsigned_config_file.close()
# sign the profiles
sign_config_profile(unsigned_file_path, signed_mobileconfig_file_path, hash)
# delete the unsigned
else:
config_file = open(unsigned_mobileconfig_file_path, "wb")
settings_config_file = open(settings_plist_file_path, "wb")
newProfile.finalizeAndSave(config_file)
newProfile.finalizeAndSavePlist(settings_config_file)
config_file.close()
print( print(
f""" f"""
@@ -889,17 +898,16 @@ def default_audit_plist(baseline_name, build_path, baseline_yaml):
plist_output_path, "org." + baseline_name + ".audit.plist" plist_output_path, "org." + baseline_name + ".audit.plist"
) )
plist_file = open(plist_file_path, "wb") with open(plist_file_path, "wb") as plist_file:
plist_dict = {}
plist_dict = {} for sections in baseline_yaml["profile"]:
for profile_rule in sections["rules"]:
if profile_rule.startswith("supplemental"):
continue
plist_dict[profile_rule] = {"exempt": False}
for sections in baseline_yaml["profile"]: plistlib.dump(plist_dict, plist_file)
for profile_rule in sections["rules"]:
if profile_rule.startswith("supplemental"):
continue
plist_dict[profile_rule] = {"exempt": False}
plistlib.dump(plist_dict, plist_file)
def generate_script(baseline_name, audit_name, build_path, baseline_yaml, reference): def generate_script(baseline_name, audit_name, build_path, baseline_yaml, reference):
@@ -2051,7 +2059,14 @@ def create_args():
"-p", "-p",
"--profiles", "--profiles",
default=None, default=None,
help="Generate configuration profiles for the rules.", help="Generate domain-specific configuration profiles for the rules.",
action="store_true",
)
parser.add_argument(
"-P",
"--consolidated-profile",
default=None,
help="Generate consolidated configuration profile for all rules.",
action="store_true", action="store_true",
) )
parser.add_argument( parser.add_argument(
@@ -2716,10 +2731,20 @@ def main():
else: else:
audit_name = baseline_name audit_name = baseline_name
if args.profiles: if args.profiles or args.consolidated_profile:
print("Generating configuration profiles...") # Build message based on what's being generated
messages = []
if args.profiles:
messages.append("domain-specific")
if args.consolidated_profile:
messages.append("consolidated")
print(f"Generating {' and '.join(messages)} configuration profiles...")
# Single call to generate_profiles with both parameters
generate_profiles( generate_profiles(
baseline_name, build_path, parent_dir, baseline_yaml, signing, args.hash baseline_name, build_path, parent_dir, baseline_yaml, signing, args.hash,
generate_domain=args.profiles, generate_consolidated=args.consolidated_profile
) )
if args.ddm: if args.ddm: