From 4fbb940e765d9647cf6fab61d4bd3f22c90a5641 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Fri, 19 Sep 2025 13:28:36 +0000 Subject: [PATCH 1/4] Fix an issue where the ESXiPlugin shows a confusing warning when constructing the local fs The following warning was logged every time that the local_tgz tar file was successfully decrypted > "local.tgz is encrypted but static decryption failed and no dynamic decryption available!" Now this warning is moved so it only shows when it isn't run on a local target. --- dissect/target/plugins/os/unix/esxi/_os.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/dissect/target/plugins/os/unix/esxi/_os.py b/dissect/target/plugins/os/unix/esxi/_os.py index cc15ce679a..e0d5db641c 100644 --- a/dissect/target/plugins/os/unix/esxi/_os.py +++ b/dissect/target/plugins/os/unix/esxi/_os.py @@ -354,7 +354,13 @@ def _create_local_fs(target: Target, local_tgz_ve: TargetPath, encryption_info: else: target.log.debug("Skipping static decryption because of missing crypto module") - if not local_tgz and target.name == "local": + if local_tgz is None: + if target.name != "local": + target.log.warning( + "local.tgz is encrypted but static decryption failed and no dynamic decryption available!" + ) + return None + target.log.info( "local.tgz is encrypted but static decryption failed, attempting dynamic decryption using crypto-util" ) @@ -362,12 +368,8 @@ def _create_local_fs(target: Target, local_tgz_ve: TargetPath, encryption_info: if local_tgz is None: target.log.warning("Dynamic decryption of %s failed", local_tgz_ve) - else: - target.log.warning("local.tgz is encrypted but static decryption failed and no dynamic decryption available!") - if local_tgz: - return tar.TarFilesystem(local_tgz) - return None + return tar.TarFilesystem(local_tgz) if local_tgz else None def _mount_filesystems(target: Target, sysvol: Filesystem, cfg: dict[str, str]) -> None: From 76fa1d61d49b43ae92df08cf7c380de277e5c389 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Tue, 17 Mar 2026 09:37:04 +0000 Subject: [PATCH 2/4] Adjust the existing tests to see whether the log entry is there or not --- tests/plugins/os/unix/esxi/test__os.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tests/plugins/os/unix/esxi/test__os.py b/tests/plugins/os/unix/esxi/test__os.py index 9f819459ca..a31a2ef1a8 100644 --- a/tests/plugins/os/unix/esxi/test__os.py +++ b/tests/plugins/os/unix/esxi/test__os.py @@ -1,5 +1,6 @@ from __future__ import annotations +import logging from io import BytesIO from typing import TYPE_CHECKING from unittest.mock import patch @@ -10,6 +11,8 @@ from tests._utils import absolute_path if TYPE_CHECKING: + import pytest + from dissect.target.target import Target @@ -26,14 +29,21 @@ def test__create_tar_fs_no_envelope(target_linux: Target, fs_unix: VirtualFilesy mocked_tar.TarFilesystem.assert_called() -def test__create_tar_fs_envelope(target_linux: Target, fs_unix: VirtualFilesystem) -> None: +def test__create_tar_fs_envelope( + target_linux: Target, fs_unix: VirtualFilesystem, caplog: pytest.LogCaptureFixture +) -> None: with ( patch("dissect.target.plugins.os.unix.esxi._os.HAS_ENVELOPE", True), patch("dissect.target.plugins.os.unix.esxi._os.tar") as mocked_tar, patch("dissect.target.plugins.os.unix.esxi._os._decrypt_envelope") as decrypt_func, + caplog.at_level(logging.WARNING, target_linux.log.name), ): _create_local_fs(target_linux, fs_unix.path("local.tgz.ve"), fs_unix.path("encryption.info")) + assert ( + "local.tgz is encrypted but static decryption failed and no dynamic decryption available!" + not in caplog.text + ) decrypt_func.assert_called() mocked_tar.TarFilesystem.assert_called() @@ -52,10 +62,16 @@ def test__create_tar_fs_failed_envelope(target_linux: Target, fs_unix: VirtualFi mocked_tar.TarFilesystem.assert_called() -def test__decrypt_crypto_not_local(target_linux: Target, fs_unix: VirtualFilesystem) -> None: +def test__decrypt_crypto_not_local( + target_linux: Target, fs_unix: VirtualFilesystem, caplog: pytest.LogCaptureFixture +) -> None: target_linux._name = "not_local" - with patch("dissect.target.plugins.os.unix.esxi._os.HAS_ENVELOPE", False): + with ( + patch("dissect.target.plugins.os.unix.esxi._os.HAS_ENVELOPE", False), + caplog.at_level(logging.WARNING, target_linux.log.name), + ): assert _create_local_fs(target_linux, fs_unix.path(""), fs_unix.path("")) is None + assert "local.tgz is encrypted but static decryption failed and no dynamic decryption available!" in caplog.text def test__decrypt_crypto_local(fs_unix: VirtualFilesystem) -> None: From 1105f4893cb1ef513e820b2af3c8064a2919ceec Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Tue, 17 Mar 2026 13:17:37 +0000 Subject: [PATCH 3/4] Rename tests to reflect the tested function And add assertions for Log messages that occurred --- tests/plugins/os/unix/esxi/test__os.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tests/plugins/os/unix/esxi/test__os.py b/tests/plugins/os/unix/esxi/test__os.py index a31a2ef1a8..8cb3fe91a9 100644 --- a/tests/plugins/os/unix/esxi/test__os.py +++ b/tests/plugins/os/unix/esxi/test__os.py @@ -16,20 +16,30 @@ from dissect.target.target import Target -def test__create_tar_fs_no_envelope(target_linux: Target, fs_unix: VirtualFilesystem) -> None: +def test__create_local_fs_local_no_envelope( + target_linux: Target, fs_unix: VirtualFilesystem, caplog: pytest.LogCaptureFixture +) -> None: with ( patch("dissect.target.plugins.os.unix.esxi._os.HAS_ENVELOPE", False), patch("dissect.target.plugins.os.unix.esxi._os.tar") as mocked_tar, patch("dissect.target.plugins.os.unix.esxi._os._decrypt_crypto_util") as decrypt_func, + caplog.at_level(logging.DEBUG), ): target_linux._name = "local" _create_local_fs(target_linux, fs_unix.path("local.tgz.ve"), fs_unix.path("encryption.info")) + assert len(caplog.messages) == 2 + assert "Skipping static decryption because of missing crypto module" in caplog.messages[0] + assert ( + "local.tgz is encrypted but static decryption failed, attempting dynamic decryption using crypto-util" + in caplog.messages[1] + ) + decrypt_func.assert_called() mocked_tar.TarFilesystem.assert_called() -def test__create_tar_fs_envelope( +def test__create_local_fs_envelope( target_linux: Target, fs_unix: VirtualFilesystem, caplog: pytest.LogCaptureFixture ) -> None: with ( @@ -48,7 +58,7 @@ def test__create_tar_fs_envelope( mocked_tar.TarFilesystem.assert_called() -def test__create_tar_fs_failed_envelope(target_linux: Target, fs_unix: VirtualFilesystem) -> None: +def test__create_local_fs_failed_envelope(target_linux: Target, fs_unix: VirtualFilesystem) -> None: with ( patch("dissect.target.plugins.os.unix.esxi._os.HAS_ENVELOPE", True), patch("dissect.target.plugins.os.unix.esxi._os.tar") as mocked_tar, @@ -62,7 +72,7 @@ def test__create_tar_fs_failed_envelope(target_linux: Target, fs_unix: VirtualFi mocked_tar.TarFilesystem.assert_called() -def test__decrypt_crypto_not_local( +def test__create_local_fs_non_local_target( target_linux: Target, fs_unix: VirtualFilesystem, caplog: pytest.LogCaptureFixture ) -> None: target_linux._name = "not_local" @@ -74,7 +84,7 @@ def test__decrypt_crypto_not_local( assert "local.tgz is encrypted but static decryption failed and no dynamic decryption available!" in caplog.text -def test__decrypt_crypto_local(fs_unix: VirtualFilesystem) -> None: +def test__decrypt_crypto_util(fs_unix: VirtualFilesystem) -> None: with patch("dissect.target.plugins.os.unix.esxi._os.subprocess.run") as mocked_run: mocked_run.return_value.stdout = b"data" From 90a5197c46d24b227e5e31bc13aac13710740bc1 Mon Sep 17 00:00:00 2001 From: Miauwkeru Date: Wed, 18 Mar 2026 10:32:30 +0000 Subject: [PATCH 4/4] Disable configure_logging for test_ips_dhcp_arg configure_logging gets called during the execution of the main of our target tooling. This causes some issues with capturing logging messages with caplog This patch basically does the same as tests/tools/conftest.py::prevent_logging_setup for this specific test --- tests/plugins/os/unix/test_ips.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/plugins/os/unix/test_ips.py b/tests/plugins/os/unix/test_ips.py index b0d0b56faf..b80dac1ae4 100644 --- a/tests/plugins/os/unix/test_ips.py +++ b/tests/plugins/os/unix/test_ips.py @@ -10,6 +10,7 @@ from dissect.target.plugins.os.unix.linux._os import LinuxPlugin from dissect.target.plugins.os.unix.linux.network_managers import NetworkManager from dissect.target.tools.query import main as target_query +from dissect.target.tools.utils.logging import configure_logging from tests._utils import absolute_path if TYPE_CHECKING: @@ -94,8 +95,12 @@ def test_ips_dhcp_arg( if flag: argv.append(flag) + def noop(*args, **kwargs) -> None: + pass + with patch("dissect.target.Target.open_all", return_value=[target_unix]), monkeypatch.context() as m: m.setattr("sys.argv", argv) + m.setattr(configure_logging, "__code__", noop.__code__) target_query() out, _ = capsys.readouterr() assert expected_out in out