From df5dd5e58f0a8deb63cb0a11b49e7f2adcfcee6f Mon Sep 17 00:00:00 2001 From: Milan Lysonek Date: Wed, 31 Jan 2024 12:25:01 +0100 Subject: [PATCH 1/3] Add helper functions for work with controls --- ctf/DiffStruct.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/ctf/DiffStruct.py b/ctf/DiffStruct.py index 4ab6d60..0a5cd8e 100644 --- a/ctf/DiffStruct.py +++ b/ctf/DiffStruct.py @@ -61,6 +61,42 @@ def find_rule_profiles(self, rule): if find_rule.search(line): yield profile_file + def find_rule_controls(self, rule): + controls = [] + find_rule = re.compile(r"^\s*-\s*" + rule + r"\s*$", re.MULTILINE) + control_folder = git_wrapper.repo_path + "/" + "controls/" + # Check all yaml files in controls/ + for control in os.listdir(control_folder): + if not control.endswith(".yml"): + continue + control_path = control_folder + control + with open(control_path) as f: + control_content = f.read() + # If controls in separate directory, merge them to one string + controls_dir = re.search(r"controls_dir:\s*(\w+)", control_content) + if controls_dir: + controls_dir = controls_dir.group(1) + for c in os.listdir(control_folder + controls_dir): + with open(control_folder + controls_dir + "/" + c) as cf: + control_content += cf.read() + # Search for rule in control content + if find_rule.search(control_content): + yield control.rstrip(".yml") + + def find_control_products(self, control): + products_folder = git_wrapper.repo_path + "/" + "products" + find_control = re.compile(r"^\s*-\s*" + control + r":", re.MULTILINE) + # Find dirs with profile files + for dir_path, _, files in os.walk(products_folder): + for file in files: + if not file.endswith(".profile"): + continue + # Search if desired control is used and if so, return product + with open(dir_path + "/" + file) as f: + for line in f: + if find_control.search(line): + yield re.match(r".*/products/([^/]+)", dir_path).group(1) + def get_rule_ruleyml(self, rule): # Find a directory with a rule name and check if it has rule.yml file for root, dirs, files in os.walk(git_wrapper.repo_path): From a78fd0d81fa5ea5307a493ccbbc77570c17b50d2 Mon Sep 17 00:00:00 2001 From: Milan Lysonek Date: Wed, 31 Jan 2024 12:40:43 +0100 Subject: [PATCH 2/3] Rework searching for rule product. No prodtype, now rule must be a part of some profile. --- ctf/DiffStruct.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/ctf/DiffStruct.py b/ctf/DiffStruct.py index 0a5cd8e..5bb4af1 100644 --- a/ctf/DiffStruct.py +++ b/ctf/DiffStruct.py @@ -119,20 +119,17 @@ def get_rule_profiles(self, rule): return profiles def get_rule_products(self, rule): + products = [] # Parse from matched profiles product names - ruleyml_path = self.get_rule_ruleyml(rule) - prodtype_line = None - with open(ruleyml_path) as f: - for line in f.readlines(): - if "prodtype:" in line: - prodtype_line = line - break - # rule.yml does not have prodtype - if not prodtype_line: - return None - - prodtypes = re.match(r"\s*prodtype:\s*([\w|,]+)\s*", prodtype_line).group(1) - products = prodtypes.split(",") + for profile_path in self.find_rule_profiles(rule): + parse_file = re.match(r".+/((?:\w|-)+)/profiles/(?:\w|-)+\.profile", + profile_path) + products.append(parse_file.group(1)) + # Find in controls and from controls get product + for control in self.find_rule_controls(rule): + for product in self.find_control_products(control): + products.append(product) + products = sorted(products, key=lambda k: (k!="rhel8", k!="rhel7", k!="ocp4", k)) return products From 696df04a145978c425dfa74bb4f0bfe017fee08b Mon Sep 17 00:00:00 2001 From: Milan Lysonek Date: Wed, 31 Jan 2024 13:16:44 +0100 Subject: [PATCH 3/3] Adjust test scenarios to use more generic approach. Use rpm_verify_* rule changes as they are not expected to be templated because of their specificity. --- tests/ansible.bats | 16 ++++++++-------- tests/bash.bats | 10 +++++----- tests/jinja.bats | 5 ++--- tests/json_ansible.bats | 16 ++++++++-------- tests/json_bash.bats | 10 +++++----- tests/json_jinja.bats | 6 ++---- 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/tests/ansible.bats b/tests/ansible.bats index ca07207..8f6e727 100644 --- a/tests/ansible.bats +++ b/tests/ansible.bats @@ -5,7 +5,7 @@ prepare_repository @test "Add comment line" { - file="./linux_os/guide/system/software/integrity/disable_prelink/ansible/shared.yml" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" sed -i "\$a# comment" "$file" git add "$file" && git commit -m "test commit" &>/dev/null @@ -21,7 +21,7 @@ prepare_repository } @test "Change metadata" { - file="./linux_os/guide/system/software/integrity/disable_prelink/ansible/shared.yml" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" sed -i 's/# reboot = false/# reboot = true/' "$file" regex_check="build_product " @@ -38,8 +38,8 @@ prepare_repository } @test "Change name" { - file="./linux_os/guide/system/software/integrity/disable_prelink/ansible/shared.yml" - sed -i 's/- name: Disable.*/- name: some name/' "$file" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" + sed -i 's/- name: .*/- name: some name/' "$file" git add "$file" && git commit -m "test commit" &>/dev/null @@ -54,10 +54,10 @@ prepare_repository } @test "Change remediation part" { - file="./linux_os/guide/system/software/integrity/disable_prelink/ansible/shared.yml" - sed -i 's;path: .*;path: /some/path/;' "$file" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" + sed -i 's/command: .*/command: ls/' "$file" regex_check_1="build_product " - regex_check_2=".*test_suite\.py rule.*disable_prelink" + regex_check_2=".*test_suite\.py rule.*rpm_verify_permissions" git add "$file" && git commit -m "test commit" &>/dev/null @@ -98,7 +98,7 @@ prepare_repository } @test "Remove ansible remediation" { - file="./linux_os/guide/services/ssh/ssh_server/sshd_use_approved_macs/ansible/shared.yml" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" rm -f "$file" git add "$file" && git commit -m "test commit" &>/dev/null diff --git a/tests/bash.bats b/tests/bash.bats index 00d4d92..c565a24 100644 --- a/tests/bash.bats +++ b/tests/bash.bats @@ -5,7 +5,7 @@ prepare_repository @test "Add comment line" { - file="./linux_os/guide/services/sssd/sssd_run_as_sssd_user/bash/shared.sh" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/bash/shared.sh" sed -i "\$a# comment" "$file" git add "$file" && git commit -m "test commit" &>/dev/null @@ -38,10 +38,10 @@ prepare_repository } @test "Change remediation" { - file="./linux_os/guide/services/sssd/sssd_run_as_sssd_user/bash/shared.sh" - sed -i "s/chmod 600/chmod 744/" "$file" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/bash/shared.sh" + sed -i "s/rpm//" "$file" regex_check_1="build_product " - regex_check_2="test_suite\.py rule.*sssd_run_as_sssd_user" + regex_check_2="test_suite\.py rule.*rpm_verify_permissions" git add "$file" && git commit -m "test commit" &>/dev/null @@ -83,7 +83,7 @@ prepare_repository @test "Remove bash remediation" { - file="./linux_os/guide/services/ssh/ssh_server/sshd_use_approved_macs/bash/shared.sh" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/bash/shared.sh" rm -f "$file" git add "$file" && git commit -m "test commit" &>/dev/null diff --git a/tests/jinja.bats b/tests/jinja.bats index 0166a66..1e06118 100644 --- a/tests/jinja.bats +++ b/tests/jinja.bats @@ -8,9 +8,8 @@ prepare_repository file="./shared/macros/10-bash.jinja" sed -i "/macro bash_sshd_config_set/a echo 1" "$file" regex_check_1="build_product" - regex_check_2="test_suite.py rule.*sshd_use_strong_macs" - regex_check_3="test_suite.py rule.*sshd_set_idle_timeout" - regex_check_4="test_suite.py rule.*sshd_use_priv_separation" + regex_check_2="test_suite.py rule.*sshd_set_" + regex_check_3="test_suite.py rule.*sshd_use_" git add "$file" && git commit -m "test commit" &>/dev/null diff --git a/tests/json_ansible.bats b/tests/json_ansible.bats index 437c45f..7f81d7c 100644 --- a/tests/json_ansible.bats +++ b/tests/json_ansible.bats @@ -5,7 +5,7 @@ prepare_repository @test "Add comment line" { - file="./linux_os/guide/system/software/integrity/disable_prelink/ansible/shared.yml" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" sed -i "\$a# comment" "$file" git add "$file" && git commit -m "test commit" &>/dev/null @@ -21,7 +21,7 @@ prepare_repository } @test "Change metadata" { - file="./linux_os/guide/system/software/integrity/disable_prelink/ansible/shared.yml" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" sed -i 's/# reboot = false/# reboot = true/' "$file" regex_check="build_product " @@ -38,8 +38,8 @@ prepare_repository } @test "Change name" { - file="./linux_os/guide/system/software/integrity/disable_prelink/ansible/shared.yml" - sed -i 's/- name: Disable.*/- name: some name/' "$file" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" + sed -i 's/- name: .*/- name: some name/' "$file" git add "$file" && git commit -m "test commit" &>/dev/null @@ -54,9 +54,9 @@ prepare_repository } @test "Change remediation part" { - file="./linux_os/guide/system/software/integrity/disable_prelink/ansible/shared.yml" - sed -i 's;path: .*;path: /some/path/;' "$file" - regex_check='{.*"rules": \["disable_prelink"\].*"bash": "False".*"ansible": "True"}' + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" + sed -i 's/command: .*/command: ls/' "$file" + regex_check='{.*"rules": \["rpm_verify_permissions"\].*"bash": "False".*"ansible": "True"}' git add "$file" && git commit -m "test commit" &>/dev/null @@ -88,7 +88,7 @@ prepare_repository } @test "Remove ansible remediation" { - file="./linux_os/guide/services/ssh/ssh_server/sshd_use_approved_macs/ansible/shared.yml" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/ansible/shared.yml" rm -f "$file" git add "$file" && git commit -m "test commit" &>/dev/null diff --git a/tests/json_bash.bats b/tests/json_bash.bats index 4edcc6e..43bb5ae 100644 --- a/tests/json_bash.bats +++ b/tests/json_bash.bats @@ -5,7 +5,7 @@ prepare_repository @test "Add comment line" { - file="./linux_os/guide/services/sssd/sssd_run_as_sssd_user/bash/shared.sh" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/bash/shared.sh" sed -i "\$a# comment" "$file" git add "$file" && git commit -m "test commit" &>/dev/null @@ -38,9 +38,9 @@ prepare_repository } @test "Change remediation" { - file="./linux_os/guide/services/sssd/sssd_run_as_sssd_user/bash/shared.sh" - sed -i "s/chmod 600/chmod 744/" "$file" - regex_check='{.*"rules": \["sssd_run_as_sssd_user"\].*"bash": "True".*"ansible": "False"}' + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/bash/shared.sh" + sed -i "s/rpm//" "$file" + regex_check='{.*"rules": \["rpm_verify_permissions"\].*"bash": "True".*"ansible": "False"}' git add "$file" && git commit -m "test commit" &>/dev/null @@ -73,7 +73,7 @@ prepare_repository @test "Remove bash remediation" { - file="./linux_os/guide/services/ssh/ssh_server/sshd_use_approved_macs/bash/shared.sh" + file="./linux_os/guide/system/software/integrity/software-integrity/rpm_verification/rpm_verify_permissions/bash/shared.sh" rm -f "$file" git add "$file" && git commit -m "test commit" &>/dev/null diff --git a/tests/json_jinja.bats b/tests/json_jinja.bats index 20a4421..18000af 100644 --- a/tests/json_jinja.bats +++ b/tests/json_jinja.bats @@ -7,10 +7,8 @@ prepare_repository @test "Change sshd macro" { file="./shared/macros/10-bash.jinja" sed -i "/macro bash_sshd_config_set/a echo 1" "$file" - regex_check_1='{.*"rules": \[.*"sshd_use_strong_ciphers".*\].*"bash": "True".*"ansible": "False".*}' - regex_check_2='{.*"rules": \[.*"sshd_use_strong_macs".*\].*"bash": "True".*"ansible": "False".*}' - regex_check_3='{.*"rules": \[.*"sshd_set_keepalive".*\].*"bash": "True".*"ansible": "False".*}' - regex_check_4='{.*"rules": \[.*"sshd_set_idle_timeout".*\].*"bash": "True".*"ansible": "False".*}' + regex_check_1='{.*"rules": \[.*"sshd_use_.*".*\].*"bash": "True".*"ansible": "False".*}' + regex_check_2='{.*"rules": \[.*"sshd_set_.*".*\].*"bash": "True".*"ansible": "False".*}' git add "$file" && git commit -m "test commit" &>/dev/null