From 8997205ee32c8905157c2a466678507563644cf3 Mon Sep 17 00:00:00 2001 From: jiazhang Date: Fri, 13 Sep 2024 18:37:40 +0800 Subject: [PATCH 1/6] Enhance datasource httpd ignore include expanded inner Signed-off-by: jiazhang --- insights/specs/datasources/httpd.py | 14 +++++++++++++ insights/tests/datasources/test_httpd.py | 25 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/insights/specs/datasources/httpd.py b/insights/specs/datasources/httpd.py index 1c8adde76d..fb4da72821 100644 --- a/insights/specs/datasources/httpd.py +++ b/insights/specs/datasources/httpd.py @@ -71,7 +71,14 @@ def _get_all_include_conf(root, glob_path): _paths.add(conf) with open(conf) as cfp: _includes = None + section_number = 0 for line in cfp.readlines(): + if line.startswith("<") and not line.startswith(" 0: + continue if line.strip().startswith("Include"): _includes = line.split()[-1].strip('"\'') _paths.update(_get_all_include_conf(root, _includes)) @@ -92,7 +99,14 @@ def get_httpd_configuration_files(httpd_root): server_root = httpd_root # Add it only when it exists all_paths.add(main_httpd_conf) + section_number = 0 for line in cfp.readlines(): + if line.startswith("<") and not line.startswith(" 0: + continue if line.strip().startswith("ServerRoot"): server_root = line.strip().split()[-1].strip().strip('"\'') elif line.strip().startswith("Include"): diff --git a/insights/tests/datasources/test_httpd.py b/insights/tests/datasources/test_httpd.py index 274db2df80..6e6719c46a 100644 --- a/insights/tests/datasources/test_httpd.py +++ b/insights/tests/datasources/test_httpd.py @@ -90,6 +90,19 @@ def test_httpd_on_nfs(run_cmds): Listen 443 https """.strip() +data_lines_httpd_conf_section_test = """ +ServerRoot "/etc/httpd" + + # ModSecurity Core Rules Set and Local configuration + IncludeOptional modsecurity.d/*.conf + +""".strip() + +data_lines_crs_setup_conf = """ +SecAction \ + "id:900990,\ +""".strip() + @patch("os.path.isfile", return_value=True) @patch("os.path.isdir", return_value=True) @@ -103,6 +116,18 @@ def test_httpd_conf_files(m_open, m_glob, m_isdir, m_isfile): assert result == set(['/etc/httpd/conf.d/ssl.conf', '/etc/httpd/conf/httpd.conf']) +@patch("os.path.isfile", return_value=True) +@patch("os.path.isdir", return_value=True) +@patch("glob.glob", return_value=["/etc/httpd/modsecurity.d/crs-setup.conf"]) +@patch(builtin_open, new_callable=mock_open, read_data=data_lines_httpd_conf_section_test) +def test_httpd_conf_files_section(m_open, m_glob, m_isdir, m_isfile): + handlers = (m_open.return_value, mock_open(read_data=data_lines_crs_setup_conf).return_value) + m_open.side_effect = handlers + broker = {HostContext: None} + result = httpd_configuration_files(broker) + assert result == set(['/etc/httpd/conf/httpd.conf']) + + @patch("os.path.isfile", return_value=True) @patch("os.path.isdir", return_value=True) @patch("glob.glob", return_value=["/opt/rh/httpd24/root/etc/httpd/conf.d/ssl.conf"]) From 599bed91ce6f3564569663665b4c2c02f3606bd7 Mon Sep 17 00:00:00 2001 From: jiazhang Date: Sat, 14 Sep 2024 10:35:11 +0800 Subject: [PATCH 2/6] Update test coverage Signed-off-by: jiazhang --- insights/tests/datasources/test_httpd.py | 53 ++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/insights/tests/datasources/test_httpd.py b/insights/tests/datasources/test_httpd.py index 6e6719c46a..60f80dfc00 100644 --- a/insights/tests/datasources/test_httpd.py +++ b/insights/tests/datasources/test_httpd.py @@ -22,6 +22,11 @@ /dev/mapper/httpd1 /httpd1 nfs4 rw,relatime,vers=4,barrier=1,data=ordered 0 0 /dev/mapper/httpd2 /httpd2 nfs4 rw,relatime,vers=4,barrier=1,data=ordered 0 0 """.strip() + +MOUNT_DATA_NO_NFS = """ +/dev/mapper/root / ext4 rw,relatime,barrier=1,data=ordered 0 0 +""".strip() + NFS_LSOF_666 = """ zsh 3520 httpd 3r REG 253,0 6940392 648646 /httpd1 zsh 3520 httpd 11r REG 253,0 9253600 648644 /httpd1 @@ -46,6 +51,14 @@ def shell_out(self, cmd, split=True, timeout=None, keep_rc=False, env=None, sign raise Exception +class FakeContext_NO_httpd(HostContext): + def shell_out(self, cmd, split=True, timeout=None, keep_rc=False, env=None, signum=None): + if 'pgrep' in cmd: + return '' + + raise Exception + + # The ``get_running_commands()`` is tested in: # - insights/tests/datasources/test_get_running_commands.py # Here, we do not test it @@ -71,6 +84,20 @@ def test_httpd_on_nfs(run_cmds): assert '"nfs_mounts": ["/httpd1", "/httpd2"]' in result.content[0] +@patch('insights.specs.datasources.httpd.get_running_commands') +def test_httpd_on_nfs_no_httpd(run_cmds): + broker = {ProcMounts: ProcMounts(context_wrap(MOUNT_DATA)), HostContext: FakeContext_NO_httpd()} + with pytest.raises(SkipComponent): + httpd_on_nfs(broker) + + +@patch('insights.specs.datasources.httpd.get_running_commands') +def test_httpd_on_nfs_no_mount(run_cmds): + broker = {ProcMounts: ProcMounts(context_wrap(MOUNT_DATA_NO_NFS)), HostContext: FakeContext()} + with pytest.raises(SkipComponent): + httpd_on_nfs(broker) + + data_lines_httpd_conf = """ ServerRoot "/etc/httpd" Include conf.d/*.conf @@ -88,6 +115,11 @@ def test_httpd_on_nfs(run_cmds): data_lines_ssl_conf = """ Listen 443 https +IncludeOptional modsecurity.d/*.conf + + # ModSecurity Core Rules Set and Local configuration + IncludeOptional modsecurity.d/*.conf + """.strip() data_lines_httpd_conf_section_test = """ @@ -128,6 +160,27 @@ def test_httpd_conf_files_section(m_open, m_glob, m_isdir, m_isfile): assert result == set(['/etc/httpd/conf/httpd.conf']) +@patch("os.path.isfile", return_value=False) +@patch("os.path.isdir", return_value=False) +@patch("glob.glob", return_value=["/etc/httpd/conf.d/ssl.conf"]) +@patch(builtin_open, new_callable=mock_open, read_data=data_lines_httpd_conf) +def test_httpd_conf_files_ssl_miss(m_open, m_glob, m_isdir, m_isfile): + handlers = (m_open.return_value, mock_open(read_data=data_lines_ssl_conf).return_value) + m_open.side_effect = handlers + broker = {HostContext: None} + result = httpd_configuration_files(broker) + assert result == set(['/etc/httpd/conf/httpd.conf']) + + +@patch("os.path.isfile", return_value=True) +@patch("os.path.isdir", return_value=True) +@patch("glob.glob", return_value=["/etc/httpd/conf.d/ssl.conf"]) +def test_httpd_conf_files_main_miss(m_glob, m_isdir, m_isfile): + broker = {HostContext: None} + with pytest.raises(SkipComponent): + httpd_configuration_files(broker) + + @patch("os.path.isfile", return_value=True) @patch("os.path.isdir", return_value=True) @patch("glob.glob", return_value=["/opt/rh/httpd24/root/etc/httpd/conf.d/ssl.conf"]) From 466fd0f0c2dd3d2a338b9f24f36438c5ca838f60 Mon Sep 17 00:00:00 2001 From: jiazhang Date: Sat, 14 Sep 2024 11:43:44 +0800 Subject: [PATCH 3/6] Update coverage Signed-off-by: jiazhang --- insights/specs/datasources/httpd.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/insights/specs/datasources/httpd.py b/insights/specs/datasources/httpd.py index fb4da72821..39be02e788 100644 --- a/insights/specs/datasources/httpd.py +++ b/insights/specs/datasources/httpd.py @@ -131,10 +131,7 @@ def httpd_configuration_files(broker): SkipComponent: there is no httpd configuration file """ httpd_root = '/etc/httpd' - all_paths = get_httpd_configuration_files(httpd_root) - if all_paths: - return all_paths - raise SkipComponent + return get_httpd_configuration_files(httpd_root) @datasource(HostContext) @@ -149,10 +146,7 @@ def httpd24_scl_configuration_files(broker): SkipComponent: there is no httpd24 slc configuration file """ httpd_root = '/opt/rh/httpd24/root/etc/httpd' - all_paths = get_httpd_configuration_files(httpd_root) - if all_paths: - return all_paths - raise SkipComponent + return get_httpd_configuration_files(httpd_root) @datasource(HostContext) @@ -167,7 +161,4 @@ def httpd24_scl_jbcs_configuration_files(broker): SkipComponent: there is no httpd24 slc jbcs configuration file """ httpd_root = '/opt/rh/jbcs-httpd24/root/etc/httpd' - all_paths = get_httpd_configuration_files(httpd_root) - if all_paths: - return all_paths - raise SkipComponent + return get_httpd_configuration_files(httpd_root) From 317bc88c7ea173d2f0713fec8a307d61e1b93835 Mon Sep 17 00:00:00 2001 From: jiazhang Date: Sun, 15 Sep 2024 08:38:52 +0800 Subject: [PATCH 4/6] Update section_number usage Signed-off-by: jiazhang --- insights/specs/datasources/httpd.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/insights/specs/datasources/httpd.py b/insights/specs/datasources/httpd.py index 39be02e788..81ee34327e 100644 --- a/insights/specs/datasources/httpd.py +++ b/insights/specs/datasources/httpd.py @@ -73,13 +73,12 @@ def _get_all_include_conf(root, glob_path): _includes = None section_number = 0 for line in cfp.readlines(): + line = line.strip() if line.startswith("<") and not line.startswith(" 0: - continue - if line.strip().startswith("Include"): + if section_number == 0 and line.startswith("Include"): _includes = line.split()[-1].strip('"\'') _paths.update(_get_all_include_conf(root, _includes)) if os.path.isdir(conf): @@ -101,16 +100,15 @@ def get_httpd_configuration_files(httpd_root): all_paths.add(main_httpd_conf) section_number = 0 for line in cfp.readlines(): + line = line.strip() if line.startswith("<") and not line.startswith(" 0: - continue - if line.strip().startswith("ServerRoot"): + if line.startswith("ServerRoot"): server_root = line.strip().split()[-1].strip().strip('"\'') - elif line.strip().startswith("Include"): - includes = line.strip().split()[-1].strip('"\'') + elif section_number == 0 and line.startswith("Include"): + includes = line.split()[-1].strip('"\'') # For multiple "Include" directives, all of them will be included all_paths.update(_get_all_include_conf(server_root, includes)) except Exception: From 4a9dce3fb007c603d8646d8e1aeaa09b7c0c0cff Mon Sep 17 00:00:00 2001 From: jiazhang Date: Wed, 18 Sep 2024 16:29:26 +0800 Subject: [PATCH 5/6] Add elif, and update startswith pattern Signed-off-by: jiazhang --- insights/specs/datasources/httpd.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/insights/specs/datasources/httpd.py b/insights/specs/datasources/httpd.py index 81ee34327e..f5388d14c9 100644 --- a/insights/specs/datasources/httpd.py +++ b/insights/specs/datasources/httpd.py @@ -76,9 +76,9 @@ def _get_all_include_conf(root, glob_path): line = line.strip() if line.startswith("<") and not line.startswith(" Date: Thu, 19 Sep 2024 13:55:31 +0800 Subject: [PATCH 6/6] Update section check logic Signed-off-by: jiazhang --- insights/specs/datasources/httpd.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/insights/specs/datasources/httpd.py b/insights/specs/datasources/httpd.py index f5388d14c9..7192cad9e5 100644 --- a/insights/specs/datasources/httpd.py +++ b/insights/specs/datasources/httpd.py @@ -74,10 +74,10 @@ def _get_all_include_conf(root, glob_path): section_number = 0 for line in cfp.readlines(): line = line.strip() - if line.startswith("<") and not line.startswith("