Skip to content

Commit 07c765c

Browse files
authored
Merge pull request #11252 from Mab879/new_rules_need_prodtype
New Rules Must Have a `prodtype`
2 parents 639639b + de666d5 commit 07c765c

5 files changed

Lines changed: 104 additions & 0 deletions

File tree

docs/manual/developer/04_style_guide.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ Rules sections must be in the following order, if they are present.
229229
* Comma separated list
230230
* No spaces between items
231231
* Items must be in alphabetical order
232+
* Required on all new rules
232233
* `title`
233234
* Must be one line
234235
* Must be in [Title case](https://en.wikipedia.org/wiki/Title_case)

docs/manual/developer/05_tools_and_utilities.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,3 +672,15 @@ $ python3 utils/compare_versions.py compare_tags v0.1.67 v0.1.68 rhel9
672672
```
673673
674674
It will internally clone the upstream project, checkout these tags, generate ComplianceAsCode JSON manifests, compare them and print the output.
675+
676+
`utils/no_new_global_applicable_rules.py` - Ensure That New Rules Have a `prodtype` Key
677+
678+
This script checks the rules in `utils/rule_dir_json.py` (created by `utils/rule_dir_json.py`) and checks if rules not on the allow list have prodtypes.
679+
Rules that have no `prodtype` and are not on the allow list in `tests/data/utils/no_new_global_applicable_rules.json` will cause the script to return an error.
680+
This script is ran as part of the `ctest` run.
681+
682+
To run the test (assuming that the content is built)
683+
```
684+
$ cd build
685+
$ ctest --output-on-failure -R test-no-new-global-applicable-rules
686+
```

tests/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ endmacro()
9696

9797
mypy_test("utils/import_srg_spreadsheet.py")
9898
mypy_test("utils/check_eof.py")
99+
mypy_test("utils/no_new_global_applicable_rules.py")
100+
99101

100102
if(PYTHON_VERSION_MAJOR GREATER 2 AND PY_OPENPYXL AND PY_PANDAS AND SSG_PRODUCT_RHEL9)
101103
add_test(
@@ -313,3 +315,12 @@ add_test(
313315
COMMAND env "PYTHONPATH=$ENV{PYTHONPATH}" "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/test_components.py" --build-dir "${CMAKE_BINARY_DIR}" --source-dir "${CMAKE_SOURCE_DIR}" --product "rhel9"
314316
)
315317
endif()
318+
319+
if(PYTHON_VERSION_MAJOR GREATER 2)
320+
add_test(
321+
NAME "test-no-new-global-applicable-rules"
322+
COMMAND env "PYTHONPATH=$ENV{PYTHONPATH}" "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/utils/no_new_global_applicable_rules.py" --root "${CMAKE_SOURCE_DIR}" --json "${CMAKE_SOURCE_DIR}/build/rule_dirs.json"
323+
)
324+
set_tests_properties("test-no-new-global-applicable-rules" PROPERTIES FIXTURES_REQUIRED "rule-dir-json")
325+
set_tests_properties("test-no-new-global-applicable-rules" PROPERTIES DEPENDS "test-rule-dir-json")
326+
endif()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
["avahi_disable_publishing", "package_cron_installed", "service_cron_enabled", "package_inetutils-telnetd_removed", "package_nis_removed", "package_ntpdate_removed", "package_telnetd-ssl_removed", "package_telnetd_removed", "dhcp_client_restrict_options", "dhcp_server_minimize_served_info", "fapolicyd_prevent_home_folder_access", "ftp_configure_firewall", "ftp_limit_users", "package_postfix_installed", "postfix_client_configure_mail_alias", "postfix_client_configure_mail_alias_postmaster", "postfix_client_configure_relayhost", "service_netfs_disabled", "no_all_squash_exports", "chronyd_server_directive", "chronyd_specify_remote_server", "ntpd_specify_multiple_servers", "ntpd_specify_remote_server", "package_chrony_installed", "package_ntp_installed", "service_chronyd_enabled", "service_ntp_enabled", "service_ntpd_enabled", "no_rsh_trust_files", "file_groupownership_sshd_private_key", "file_groupownership_sshd_pub_key", "file_ownership_sshd_private_key", "file_ownership_sshd_pub_key", "file_permissions_sshd_private_key", "file_permissions_sshd_pub_key", "iptables_sshd_disabled", "package_openssh-server_installed", "package_openssh-server_removed", "service_sshd_disabled", "disable_host_auth", "sshd_allow_only_protocol2", "sshd_disable_compression", "sshd_disable_empty_passwords", "sshd_disable_gssapi_auth", "sshd_disable_kerb_auth", "sshd_disable_pubkey_auth", "sshd_disable_rhosts", "sshd_disable_rhosts_rsa", "sshd_disable_root_login", "sshd_disable_root_password_login", "sshd_disable_tcp_forwarding", "sshd_disable_user_known_hosts", "sshd_disable_x11_forwarding", "sshd_do_not_permit_user_env", "sshd_enable_gssapi_auth", "sshd_enable_pam", "sshd_enable_pubkey_auth", "sshd_enable_strictmodes", "sshd_enable_warning_banner", "sshd_enable_warning_banner_net", "sshd_enable_x11_forwarding", "sshd_limit_user_access", "sshd_print_last_log", "sshd_rekey_limit", "sshd_set_idle_timeout", "sshd_set_keepalive", "sshd_set_keepalive_0", "sshd_set_login_grace_time", "sshd_set_loglevel_info", "sshd_set_loglevel_verbose", "sshd_set_max_auth_tries", "sshd_set_max_sessions", "sshd_set_maxstartups", "sshd_use_priv_separation", "disallow_bypass_password_sudo", "display_login_attempts", "account_passwords_pam_faillock_audit", "account_passwords_pam_faillock_dir", "accounts_passwords_pam_faillock_audit", "account_unique_name", "account_use_centralized_automated_auth", "accounts_maximum_age_login_defs", "accounts_minimum_age_login_defs", "accounts_password_minlen_login_defs", "accounts_password_warn_age_login_defs", "accounts_password_all_shadowed", "accounts_password_last_change_is_in_past", "gid_passwd_group_same", "no_empty_passwords", "no_empty_passwords_etc_shadow", "no_netrc_files", "accounts_no_uid_except_zero", "accounts_root_gid_zero", "no_direct_root_logins", "no_password_auth_for_systemaccounts", "restrict_serial_port_logins", "securetty_root_login_console_only", "accounts_logon_fail_delay", "accounts_max_concurrent_login_sessions", "accounts_polyinstantiated_tmp", "accounts_polyinstantiated_var_tmp", "file_permissions_home_dirs", "accounts_root_path_dirs_no_write", "root_path_no_dot", "accounts_umask_etc_login_defs", "accounts_umask_etc_profile", "audit_rules_dac_modification_chmod", "audit_rules_dac_modification_chown", "audit_rules_dac_modification_fchmod", "audit_rules_dac_modification_fchmodat", "audit_rules_dac_modification_fchown", "audit_rules_dac_modification_fchownat", "audit_rules_dac_modification_fremovexattr", "audit_rules_dac_modification_fsetxattr", "audit_rules_dac_modification_lchown", "audit_rules_dac_modification_lremovexattr", "audit_rules_dac_modification_lsetxattr", "audit_rules_dac_modification_removexattr", "audit_rules_dac_modification_setxattr", "audit_rules_dac_modification_umount", "audit_rules_dac_modification_umount2", "audit_rules_file_deletion_events_rename", "audit_rules_file_deletion_events_renameat", "audit_rules_file_deletion_events_rmdir", "audit_rules_file_deletion_events_unlink", "audit_rules_file_deletion_events_unlinkat", "audit_privileged_commands_init", "audit_privileged_commands_poweroff", "audit_privileged_commands_reboot", "audit_privileged_commands_shutdown", "audit_rules_privileged_commands", "audit_rules_immutable", "audit_rules_mac_modification", "audit_rules_mac_modification_usr_share", "audit_rules_media_export", "audit_rules_networkconfig_modification", "audit_rules_session_events", "audit_rules_sysadmin_actions", "audit_rules_usergroup_modification", "audit_rules_time_adjtimex", "audit_rules_time_clock_settime", "audit_rules_time_settimeofday", "audit_rules_time_stime", "audit_rules_time_watch_localtime", "directory_access_var_log_audit", "directory_permissions_var_log_audit", "file_groupownership_audit_configuration", "file_ownership_audit_configuration", "file_ownership_var_log_audit", "file_permissions_audit_configuration", "auditd_audispd_syslog_plugin_activated", "auditd_data_disk_error_action", "auditd_data_disk_error_action_stig", "auditd_data_disk_full_action", "auditd_data_disk_full_action_stig", "auditd_data_retention_action_mail_acct", "auditd_data_retention_admin_space_left_action", "auditd_data_retention_max_log_file", "auditd_data_retention_max_log_file_action", "auditd_data_retention_max_log_file_action_stig", "auditd_data_retention_num_logs", "auditd_data_retention_space_left_action", "auditd_freq", "auditd_local_events", "auditd_log_format", "auditd_name_format", "auditd_overflow_action", "auditd_write_logs", "package_audit-audispd-plugins_installed", "package_audit_installed", "service_auditd_enabled", "grub2_disable_recovery", "grub2_enable_iommu_force", "grub2_l1tf_argument", "grub2_mce_argument", "grub2_nosmap_argument_absent", "grub2_nosmep_argument_absent", "grub2_rng_core_default_quality_argument", "grub2_slab_nomerge_argument", "grub2_spec_store_bypass_disable_argument", "grub2_spectre_v2_argument", "grub2_systemd_debug-shell_argument_absent", "kernel_disable_entropy_contribution_for_solid_state_drives", "kernel_config_acpi_custom_method", "kernel_config_binfmt_misc", "kernel_config_bug", "kernel_config_compat_brk", "kernel_config_compat_vdso", "kernel_config_debug_credentials", "kernel_config_debug_fs", "kernel_config_debug_list", "kernel_config_debug_notifiers", "kernel_config_debug_sg", "kernel_config_default_mmap_min_addr", "kernel_config_devkmem", "kernel_config_hibernation", "kernel_config_ia32_emulation", "kernel_config_ipv6", "kernel_config_kexec", "kernel_config_legacy_ptys", "kernel_config_module_sig", "kernel_config_module_sig_all", "kernel_config_module_sig_force", "kernel_config_module_sig_hash", "kernel_config_module_sig_key", "kernel_config_module_sig_sha512", "kernel_config_page_poisoning_no_sanity", "kernel_config_page_poisoning_zero", "kernel_config_page_table_isolation", "kernel_config_panic_on_oops", "kernel_config_panic_timeout", "kernel_config_proc_kcore", "kernel_config_randomize_base", "kernel_config_randomize_memory", "kernel_config_retpoline", "kernel_config_seccomp", "kernel_config_seccomp_filter", "kernel_config_security", "kernel_config_security_dmesg_restrict", "kernel_config_security_writable_hooks", "kernel_config_security_yama", "kernel_config_slub_debug", "kernel_config_syn_cookies", "kernel_config_unmap_kernel_at_el0", "kernel_config_x86_vsyscall_emulation", "rsyslog_encrypt_offload_actionsendstreamdriverauthmode", "rsyslog_encrypt_offload_actionsendstreamdrivermode", "rsyslog_encrypt_offload_defaultnetstreamdriver", "rsyslog_files_groupownership", "rsyslog_files_ownership", "rsyslog_files_permissions", "service_systemd-journald_enabled", "ensure_logrotate_activated", "package_logrotate_installed", "package_rsyslog_installed", "package_syslogng_installed", "rsyslog_accept_remote_messages_tcp", "rsyslog_accept_remote_messages_udp", "service_syslogng_enabled", "rsyslog_remote_loghost", "service_rsyslog_enabled", "service_ip6tables_enabled", "service_iptables_enabled", "set_ip6tables_default_rule", "set_ipv6_loopback_traffic", "set_loopback_traffic", "set_iptables_default_rule", "set_iptables_default_rule_forward", "kernel_module_ipv6_option_disabled", "sysctl_net_ipv6_conf_all_disable_ipv6", "sysctl_net_ipv6_conf_default_disable_ipv6", "sysctl_net_ipv4_conf_all_accept_local", "sysctl_net_ipv4_conf_all_arp_filter", "sysctl_net_ipv4_conf_all_arp_ignore", "sysctl_net_ipv4_conf_all_route_localnet", "sysctl_net_ipv4_conf_all_shared_media", "sysctl_net_ipv4_conf_default_shared_media", "service_ufw_enabled", "kernel_module_rds_disabled", "kernel_module_tipc_disabled", "dir_perms_world_writable_sticky_bits", "file_permissions_systemmap", "file_permissions_unauthorized_world_writable", "file_groupowner_backup_etc_group", "file_groupowner_backup_etc_gshadow", "file_groupowner_backup_etc_passwd", "file_groupowner_backup_etc_shadow", "file_groupowner_etc_group", "file_groupowner_etc_gshadow", "file_groupowner_etc_passwd", "file_groupowner_etc_shadow", "file_owner_backup_etc_group", "file_owner_backup_etc_gshadow", "file_owner_backup_etc_passwd", "file_owner_backup_etc_shadow", "file_owner_etc_group", "file_owner_etc_gshadow", "file_owner_etc_passwd", "file_owner_etc_shadow", "file_permissions_backup_etc_group", "file_permissions_backup_etc_gshadow", "file_permissions_backup_etc_passwd", "file_permissions_backup_etc_shadow", "file_permissions_etc_group", "file_permissions_etc_gshadow", "file_permissions_etc_passwd", "file_permissions_etc_shadow", "file_groupowner_var_log", "file_groupowner_var_log_messages", "file_groupowner_var_log_syslog", "file_owner_var_log", "file_owner_var_log_messages", "file_owner_var_log_syslog", "file_permissions_var_log", "file_permissions_var_log_messages", "file_permissions_var_log_syslog", "dir_ownership_binary_dirs", "dir_ownership_library_dirs", "dir_permissions_binary_dirs", "dir_permissions_library_dirs", "file_ownership_binary_dirs", "file_ownership_library_dirs", "file_permissions_binary_dirs", "file_permissions_library_dirs", "sysctl_fs_protected_hardlinks", "sysctl_fs_protected_symlinks", "mount_option_dev_shm_nodev", "mount_option_dev_shm_nosuid", "coredump_disable_backtraces", "coredump_disable_storage", "sysctl_fs_suid_dumpable", "sysctl_kernel_kptr_restrict", "sysctl_kernel_randomize_va_space", "kernel_module_uvcvideo_disabled", "sysctl_kernel_panic_on_oops", "selinux_not_disabled", "selinux_state", "partition_for_dev_shm", "partition_for_home", "partition_for_srv", "partition_for_tmp", "partition_for_var", "partition_for_var_log", "partition_for_var_log_audit", "gnome_gdm_disable_xdmcp", "harden_ssh_client_crypto_policy", "configure_user_data_backups", "package_MFEhiplsm_installed", "prefer_64bit_os", "sudo_add_noexec", "sudo_add_requiretty", "sudo_add_use_pty", "sudo_custom_logfile", "sudo_remove_no_authenticate", "sudo_remove_nopasswd", "sudo_require_authentication", "sudo_vdsm_nopasswd", "sudoers_explicit_command_args", "sudoers_no_command_negation", "package_gnutls-utils_installed", "package_nss-tools_installed", "chromium_blacklist_extension_installation", "chromium_block_desktop_notifications", "chromium_check_cert_revocation", "chromium_default_block_plugins", "chromium_default_search_provider", "chromium_default_search_provider_name", "chromium_disable_3d_graphics_api", "chromium_disable_autocomplete", "chromium_disable_automatic_installation", "chromium_disable_background_processing", "chromium_disable_cleartext_passwords", "chromium_disable_cloud_print_sharing", "chromium_disable_firewall_traversal", "chromium_disable_google_sync", "chromium_disable_incognito_mode", "chromium_disable_metrics_reporting", "chromium_disable_network_prediction", "chromium_disable_outdated_plugins", "chromium_disable_password_manager", "chromium_disable_plugin_blacklist", "chromium_disable_popups", "chromium_disable_protocol_schemas", "chromium_disable_saved_passwords", "chromium_disable_search_suggestions", "chromium_disable_session_cookies", "chromium_disable_thirdparty_cookies", "chromium_disallow_location_tracking", "chromium_enable_approved_plugins", "chromium_enable_browser_history", "chromium_enable_encrypted_searching", "chromium_enable_safe_browsing", "chromium_extension_whitelist", "chromium_http_authentication", "chromium_plugins_require_authorization", "chromium_policy_file", "chromium_trusted_home_page", "chromium_whitelist_plugin_urls", "firefox_preferences-enable_ca_trust", "audit_failure_halt", "service_com_apple_auditd_enabled"]
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/python3
2+
3+
import argparse
4+
import json
5+
import os
6+
import sys
7+
from typing import Set
8+
9+
import ssg.rule_yaml
10+
11+
SSG_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
12+
RULES_JSON = os.path.join(SSG_ROOT, "build", "rule_dirs.json")
13+
14+
15+
def _parse_args() -> argparse.Namespace:
16+
parser = argparse.ArgumentParser()
17+
parser.add_argument("-r", "--root",
18+
help=f"Path to the root of the project. Defaults to {SSG_ROOT}",
19+
default=SSG_ROOT)
20+
parser.add_argument("-j", "--json",
21+
help=f"Path to rule_dirs.json. Defaults to {RULES_JSON}",
22+
default=RULES_JSON)
23+
return parser.parse_args()
24+
25+
26+
def _get_expected_set() -> set:
27+
expected_path = os.path.join(SSG_ROOT, 'tests', 'data', 'utils',
28+
'no_new_global_applicable_rules.json')
29+
with open(expected_path, 'r') as f:
30+
expected_list = json.load(f)
31+
expected_set = {rule_id for rule_id in expected_list}
32+
return expected_set
33+
34+
35+
def _process_current_rule(current_no_prodtypes: set, rule: dict, rule_id: str):
36+
rule_yaml = ssg.rule_yaml.get_yaml_contents(rule)
37+
has_prodtype = False
38+
for line in rule_yaml.contents:
39+
if 'prodtype:' in line:
40+
has_prodtype = True
41+
break
42+
if not has_prodtype:
43+
current_no_prodtypes.add(rule_id)
44+
45+
46+
def _get_current_noprodtypes(rule_dirs: dict) -> set:
47+
current_no_prodtypes: Set[str] = set()
48+
for rule_id, rule in rule_dirs.items():
49+
_process_current_rule(current_no_prodtypes, rule, rule_id)
50+
return current_no_prodtypes
51+
52+
53+
def _get_rule_dir(json_path: str) -> dict:
54+
if not os.path.exists(json_path):
55+
print(f"Cannot find rule_dirs.json file at {json_path}.", file=sys.stderr)
56+
print(f"Hint: run {SSG_ROOT}/utils/rule_dir_json.py", file=sys.stderr)
57+
exit(1)
58+
with open(json_path, 'r') as f:
59+
rule_dirs = json.load(f)
60+
return rule_dirs
61+
62+
63+
def main():
64+
args = _parse_args()
65+
json_path = args.json
66+
rule_dirs = _get_rule_dir(json_path)
67+
current_no_prodtypes = _get_current_noprodtypes(rule_dirs)
68+
expected_set = _get_expected_set()
69+
70+
delta = current_no_prodtypes - expected_set
71+
if len(delta) != 0:
72+
for bad_rule in delta:
73+
print(f"Rule {bad_rule} doesn't have a prodtype and it is expected to. "
74+
f"You must add one.", file=sys.stderr)
75+
exit(1)
76+
77+
78+
if __name__ == "__main__":
79+
main()

0 commit comments

Comments
 (0)