From d3f3ae14030681c822acda18d035112244eeed33 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Thu, 14 Aug 2025 01:08:56 +0200 Subject: [PATCH 01/13] Unify webserver logfile retrieval --- dissect/target/plugins/apps/webserver/apache.py | 3 +++ dissect/target/plugins/apps/webserver/caddy.py | 3 +++ dissect/target/plugins/apps/webserver/iis.py | 8 ++++++++ dissect/target/plugins/apps/webserver/nginx.py | 3 +++ dissect/target/plugins/apps/webserver/webserver.py | 3 +++ 5 files changed, 20 insertions(+) diff --git a/dissect/target/plugins/apps/webserver/apache.py b/dissect/target/plugins/apps/webserver/apache.py index 9d61b10116..165d40836e 100644 --- a/dissect/target/plugins/apps/webserver/apache.py +++ b/dissect/target/plugins/apps/webserver/apache.py @@ -280,6 +280,9 @@ def find_logs(self) -> None: if path not in seen: self._process_conf_file(path, seen) + def _log_paths(self) -> set: + return self.access_paths | self.error_paths + def _process_conf_file(self, path: Path, seen: set[Path] | None = None) -> None: """Process an Apache ``.conf`` file for ``ServerRoot``, ``CustomLog``, ``Include`` and ``OptionalInclude`` directives. Populates ``self.access_paths`` and ``self.error_paths``. diff --git a/dissect/target/plugins/apps/webserver/caddy.py b/dissect/target/plugins/apps/webserver/caddy.py index acbaa13a55..f556d67e44 100644 --- a/dissect/target/plugins/apps/webserver/caddy.py +++ b/dissect/target/plugins/apps/webserver/caddy.py @@ -95,6 +95,9 @@ def get_log_paths(self) -> list[Path]: return log_paths + def _log_paths(self) -> list[Path]: + return self.log_paths + @export(record=WebserverAccessLogRecord) def access(self) -> Iterator[WebserverAccessLogRecord]: """Parses Caddy V1 CRF and Caddy V2 JSON access logs. diff --git a/dissect/target/plugins/apps/webserver/iis.py b/dissect/target/plugins/apps/webserver/iis.py index afd70f78c1..1a6db2e38b 100644 --- a/dissect/target/plugins/apps/webserver/iis.py +++ b/dissect/target/plugins/apps/webserver/iis.py @@ -125,6 +125,14 @@ def log_dirs(self) -> dict[str, set[Path]]: return dirs + def _log_paths(self) -> set: + complete_set = set() + + for path in self.log_dirs.values(): + complete_set.update(path) + + return complete_set + @export(record=BasicRecordDescriptor) def logs(self) -> Iterator[TargetRecordDescriptor]: """Return contents of IIS (v7 and above) log files. diff --git a/dissect/target/plugins/apps/webserver/nginx.py b/dissect/target/plugins/apps/webserver/nginx.py index a9bf62764e..683e3d5e0e 100644 --- a/dissect/target/plugins/apps/webserver/nginx.py +++ b/dissect/target/plugins/apps/webserver/nginx.py @@ -132,6 +132,9 @@ def find_logs(self) -> None: elif (config_file := self.target.fs.path(config_file)).exists(): self.parse_config(config_file) + def _log_paths(self) -> set: + return self.access_paths | self.error_paths + def parse_config(self, path: Path, seen: set[Path] | None = None) -> None: """Parse the given NGINX ``.conf`` file for ``access_log``, ``error_log`` and ``include`` directives.""" diff --git a/dissect/target/plugins/apps/webserver/webserver.py b/dissect/target/plugins/apps/webserver/webserver.py index b8a5b55559..9c9d6ba5ad 100644 --- a/dissect/target/plugins/apps/webserver/webserver.py +++ b/dissect/target/plugins/apps/webserver/webserver.py @@ -66,3 +66,6 @@ def logs(self) -> Iterator[WebserverAccessLogRecord | WebserverErrorLogRecord]: """Returns log file records from installed webservers.""" yield from self.access() yield from self.error() + + def _iter_log_paths(self) -> Iterator[str]: + yield from self._log_paths() From 5acc01e2d35bad5fff8c4d306f923db00daedfde Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Sat, 16 Aug 2025 03:24:57 +0200 Subject: [PATCH 02/13] Remove function from main class --- dissect/target/plugins/apps/webserver/webserver.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dissect/target/plugins/apps/webserver/webserver.py b/dissect/target/plugins/apps/webserver/webserver.py index 9c9d6ba5ad..24413b7cf8 100644 --- a/dissect/target/plugins/apps/webserver/webserver.py +++ b/dissect/target/plugins/apps/webserver/webserver.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING from dissect.target.helpers.record import TargetRecordDescriptor -from dissect.target.plugin import NamespacePlugin, export +from dissect.target.plugin import NamespacePlugin, export, internal if TYPE_CHECKING: from collections.abc import Iterator @@ -66,6 +66,3 @@ def logs(self) -> Iterator[WebserverAccessLogRecord | WebserverErrorLogRecord]: """Returns log file records from installed webservers.""" yield from self.access() yield from self.error() - - def _iter_log_paths(self) -> Iterator[str]: - yield from self._log_paths() From 42560df433a1be9cfee920a4ecde33ecdcc27960 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Sat, 16 Aug 2025 03:27:16 +0200 Subject: [PATCH 03/13] Remove unused import --- dissect/target/plugins/apps/webserver/webserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dissect/target/plugins/apps/webserver/webserver.py b/dissect/target/plugins/apps/webserver/webserver.py index 24413b7cf8..b8a5b55559 100644 --- a/dissect/target/plugins/apps/webserver/webserver.py +++ b/dissect/target/plugins/apps/webserver/webserver.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING from dissect.target.helpers.record import TargetRecordDescriptor -from dissect.target.plugin import NamespacePlugin, export, internal +from dissect.target.plugin import NamespacePlugin, export if TYPE_CHECKING: from collections.abc import Iterator From 8b63617d518e04cc93a10665e0393de16c9191b2 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Mon, 18 Aug 2025 13:15:12 +0200 Subject: [PATCH 04/13] Use `_get_paths()` --- dissect/target/plugins/apps/webserver/apache.py | 4 ++-- dissect/target/plugins/apps/webserver/caddy.py | 4 ++-- dissect/target/plugins/apps/webserver/iis.py | 8 ++------ dissect/target/plugins/apps/webserver/nginx.py | 4 ++-- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/dissect/target/plugins/apps/webserver/apache.py b/dissect/target/plugins/apps/webserver/apache.py index 165d40836e..f0c99a70d6 100644 --- a/dissect/target/plugins/apps/webserver/apache.py +++ b/dissect/target/plugins/apps/webserver/apache.py @@ -280,8 +280,8 @@ def find_logs(self) -> None: if path not in seen: self._process_conf_file(path, seen) - def _log_paths(self) -> set: - return self.access_paths | self.error_paths + def _get_paths(self) -> Iterator[Path]: + yield from self.access_paths | self.error_paths def _process_conf_file(self, path: Path, seen: set[Path] | None = None) -> None: """Process an Apache ``.conf`` file for ``ServerRoot``, ``CustomLog``, ``Include`` diff --git a/dissect/target/plugins/apps/webserver/caddy.py b/dissect/target/plugins/apps/webserver/caddy.py index f556d67e44..3ee4cc3d22 100644 --- a/dissect/target/plugins/apps/webserver/caddy.py +++ b/dissect/target/plugins/apps/webserver/caddy.py @@ -95,8 +95,8 @@ def get_log_paths(self) -> list[Path]: return log_paths - def _log_paths(self) -> list[Path]: - return self.log_paths + def _get_paths(self) -> Iterator[Path]: + yield from self.log_paths @export(record=WebserverAccessLogRecord) def access(self) -> Iterator[WebserverAccessLogRecord]: diff --git a/dissect/target/plugins/apps/webserver/iis.py b/dissect/target/plugins/apps/webserver/iis.py index 1a6db2e38b..f4af91b092 100644 --- a/dissect/target/plugins/apps/webserver/iis.py +++ b/dissect/target/plugins/apps/webserver/iis.py @@ -125,13 +125,9 @@ def log_dirs(self) -> dict[str, set[Path]]: return dirs - def _log_paths(self) -> set: - complete_set = set() - + def _get_paths(self) -> Iterator[Path]: for path in self.log_dirs.values(): - complete_set.update(path) - - return complete_set + yield path @export(record=BasicRecordDescriptor) def logs(self) -> Iterator[TargetRecordDescriptor]: diff --git a/dissect/target/plugins/apps/webserver/nginx.py b/dissect/target/plugins/apps/webserver/nginx.py index 683e3d5e0e..b708a2e02f 100644 --- a/dissect/target/plugins/apps/webserver/nginx.py +++ b/dissect/target/plugins/apps/webserver/nginx.py @@ -132,8 +132,8 @@ def find_logs(self) -> None: elif (config_file := self.target.fs.path(config_file)).exists(): self.parse_config(config_file) - def _log_paths(self) -> set: - return self.access_paths | self.error_paths + def _get_paths(self) -> set: + yield from self.access_paths | self.error_paths def parse_config(self, path: Path, seen: set[Path] | None = None) -> None: """Parse the given NGINX ``.conf`` file for ``access_log``, ``error_log`` and ``include`` directives.""" From e50d424fef46f38a349e23478a62a6342a9c3a51 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Mon, 18 Aug 2025 13:38:14 +0200 Subject: [PATCH 05/13] Fix IIS plugin --- dissect/target/plugins/apps/webserver/iis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dissect/target/plugins/apps/webserver/iis.py b/dissect/target/plugins/apps/webserver/iis.py index f4af91b092..96473c2a67 100644 --- a/dissect/target/plugins/apps/webserver/iis.py +++ b/dissect/target/plugins/apps/webserver/iis.py @@ -127,7 +127,7 @@ def log_dirs(self) -> dict[str, set[Path]]: def _get_paths(self) -> Iterator[Path]: for path in self.log_dirs.values(): - yield path + yield from path @export(record=BasicRecordDescriptor) def logs(self) -> Iterator[TargetRecordDescriptor]: From d6c2066760269103761076e6b3ffe9b7840c8244 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:16:17 +0200 Subject: [PATCH 06/13] Add get_all_paths function and include config files --- dissect/target/plugin.py | 10 ++++++++++ dissect/target/plugins/apps/webserver/apache.py | 14 +++++++++++--- dissect/target/plugins/apps/webserver/caddy.py | 11 ++++++++--- dissect/target/plugins/apps/webserver/iis.py | 7 ++++++- dissect/target/plugins/apps/webserver/nginx.py | 9 +++++++-- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/dissect/target/plugin.py b/dissect/target/plugin.py index 55a2371e6b..5ff12696a8 100644 --- a/dissect/target/plugin.py +++ b/dissect/target/plugin.py @@ -459,11 +459,21 @@ def __call__(self, *args, **kwargs) -> Iterator[Record | Any]: self.target.log.debug("", exc_info=e) def get_paths(self) -> Iterator[Path]: + """Return all artifact paths.""" if self.target.is_direct: yield from self._get_paths_direct() else: yield from self._get_paths() + def get_all_paths(self) -> Iterator[Path]: + """Return all arrtifact and auxiliary paths. + + The implementation of this function will + probably change in the future, but the interface + should stay the same. + """ + yield from self.get_paths() + def _get_paths_direct(self) -> Iterator[Path]: """Return all paths as given by the user.""" for path in self.target._loader.paths: diff --git a/dissect/target/plugins/apps/webserver/apache.py b/dissect/target/plugins/apps/webserver/apache.py index f0c99a70d6..f55821785c 100644 --- a/dissect/target/plugins/apps/webserver/apache.py +++ b/dissect/target/plugins/apps/webserver/apache.py @@ -4,6 +4,7 @@ import re from datetime import datetime from functools import cached_property +from pathlib import Path from typing import TYPE_CHECKING, NamedTuple from dissect.target.exceptions import FileNotFoundError, UnsupportedPluginError @@ -18,7 +19,6 @@ if TYPE_CHECKING: from collections.abc import Iterator - from pathlib import Path from dissect.target.target import Target @@ -240,6 +240,7 @@ def __init__(self, target: Target): self.access_paths = set() self.error_paths = set() self.virtual_hosts = set() + self.resolved_config_paths = set() self.find_logs() def check_compatible(self) -> None: @@ -251,7 +252,8 @@ def check_compatible(self) -> None: def find_logs(self) -> None: """Discover any present Apache log paths on the target system. - Populates ``self.access_paths``, ``self.error_paths`` and ``self.virtual_hosts``. + Populates ``self.access_paths``, ``self.error_paths``, + ``self.virtual_hosts`` and ``self.resolved_config_paths``. References: - https://httpd.apache.org/docs/2.4/logs.html @@ -281,7 +283,13 @@ def find_logs(self) -> None: self._process_conf_file(path, seen) def _get_paths(self) -> Iterator[Path]: - yield from self.access_paths | self.error_paths + config_paths = set() + for path in self.DEFAULT_CONFIG_PATHS: + config_paths.add(Path(path)) + + config_paths.update(self.resolved_config_paths) + + yield from self.access_paths | self.error_paths | config_paths def _process_conf_file(self, path: Path, seen: set[Path] | None = None) -> None: """Process an Apache ``.conf`` file for ``ServerRoot``, ``CustomLog``, ``Include`` diff --git a/dissect/target/plugins/apps/webserver/caddy.py b/dissect/target/plugins/apps/webserver/caddy.py index 3ee4cc3d22..fc99a64a4b 100644 --- a/dissect/target/plugins/apps/webserver/caddy.py +++ b/dissect/target/plugins/apps/webserver/caddy.py @@ -3,6 +3,7 @@ import json import re from datetime import datetime +from pathlib import Path from typing import TYPE_CHECKING from dissect.util.ts import from_unix @@ -17,7 +18,6 @@ if TYPE_CHECKING: from collections.abc import Iterator - from pathlib import Path from dissect.target.target import Target @@ -32,6 +32,8 @@ class CaddyPlugin(WebserverPlugin): __namespace__ = "caddy" + DEFAULT_CONFIG_PATH = "/etc/caddy/Caddyfile" + def __init__(self, target: Target): super().__init__(target) self.log_paths = self.get_log_paths() @@ -47,7 +49,7 @@ def get_log_paths(self) -> list[Path]: log_paths.extend(self.target.fs.path("/var/log").glob("caddy_access.log*")) # Check for custom paths in Caddy config - if (config_file := self.target.fs.path("/etc/caddy/Caddyfile")).exists(): + if (config_file := self.target.fs.path(self.DEFAULT_CONFIG_PATH)).exists(): found_roots = [] for line in config_file.open("rt"): line = line.strip() @@ -96,7 +98,10 @@ def get_log_paths(self) -> list[Path]: return log_paths def _get_paths(self) -> Iterator[Path]: - yield from self.log_paths + config_paths = {Path(self.DEFAULT_CONFIG_PATH)} + log_paths = set(self.log_paths) + + yield from log_paths | config_paths @export(record=WebserverAccessLogRecord) def access(self) -> Iterator[WebserverAccessLogRecord]: diff --git a/dissect/target/plugins/apps/webserver/iis.py b/dissect/target/plugins/apps/webserver/iis.py index 96473c2a67..eb1fefd101 100644 --- a/dissect/target/plugins/apps/webserver/iis.py +++ b/dissect/target/plugins/apps/webserver/iis.py @@ -126,8 +126,13 @@ def log_dirs(self) -> dict[str, set[Path]]: return dirs def _get_paths(self) -> Iterator[Path]: + log_paths = set() + config_paths = {self.config} + for path in self.log_dirs.values(): - yield from path + log_paths = log_paths | path + + yield from log_paths | config_paths @export(record=BasicRecordDescriptor) def logs(self) -> Iterator[TargetRecordDescriptor]: diff --git a/dissect/target/plugins/apps/webserver/nginx.py b/dissect/target/plugins/apps/webserver/nginx.py index b708a2e02f..8f94c0ab8d 100644 --- a/dissect/target/plugins/apps/webserver/nginx.py +++ b/dissect/target/plugins/apps/webserver/nginx.py @@ -3,6 +3,7 @@ import json import re from datetime import datetime +from pathlib import Path from typing import TYPE_CHECKING from dissect.target.exceptions import UnsupportedPluginError @@ -17,7 +18,6 @@ if TYPE_CHECKING: from collections.abc import Iterator - from pathlib import Path from dissect.target.target import Target @@ -133,7 +133,12 @@ def find_logs(self) -> None: self.parse_config(config_file) def _get_paths(self) -> set: - yield from self.access_paths | self.error_paths + config_paths = set() + + for path in self.DEFAULT_CONFIG_PATHS: + config_paths.add(Path(path)) + + yield from self.access_paths | self.error_paths | config_paths def parse_config(self, path: Path, seen: set[Path] | None = None) -> None: """Parse the given NGINX ``.conf`` file for ``access_log``, ``error_log`` and ``include`` directives.""" From e0ab65ec2b4d9e89685bed25e0e63e82cff5e980 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:17:23 +0200 Subject: [PATCH 07/13] Fix typo --- dissect/target/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dissect/target/plugin.py b/dissect/target/plugin.py index 5ff12696a8..b5ea106e61 100644 --- a/dissect/target/plugin.py +++ b/dissect/target/plugin.py @@ -466,7 +466,7 @@ def get_paths(self) -> Iterator[Path]: yield from self._get_paths() def get_all_paths(self) -> Iterator[Path]: - """Return all arrtifact and auxiliary paths. + """Return all artifact and auxiliary paths. The implementation of this function will probably change in the future, but the interface From fa1682cebc4343f08c9b8a06793e74d2859aba21 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:23:40 +0200 Subject: [PATCH 08/13] Fix path expansion in nginx plugin --- dissect/target/plugins/apps/webserver/nginx.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dissect/target/plugins/apps/webserver/nginx.py b/dissect/target/plugins/apps/webserver/nginx.py index 8f94c0ab8d..fe84071cf0 100644 --- a/dissect/target/plugins/apps/webserver/nginx.py +++ b/dissect/target/plugins/apps/webserver/nginx.py @@ -106,6 +106,7 @@ def __init__(self, target: Target): self.access_paths = set() self.error_paths = set() self.host_paths = set() + self.config_paths = set() self.find_logs() @@ -127,18 +128,15 @@ def find_logs(self) -> None: if "*" in config_file: base, _, glob = config_file.partition("*") for f in self.target.fs.path(base).rglob(f"*{glob}"): + self.config_paths.add(f) self.parse_config(f) elif (config_file := self.target.fs.path(config_file)).exists(): + self.config_paths.add(config_file) self.parse_config(config_file) def _get_paths(self) -> set: - config_paths = set() - - for path in self.DEFAULT_CONFIG_PATHS: - config_paths.add(Path(path)) - - yield from self.access_paths | self.error_paths | config_paths + yield from self.access_paths | self.error_paths | self.config_paths def parse_config(self, path: Path, seen: set[Path] | None = None) -> None: """Parse the given NGINX ``.conf`` file for ``access_log``, ``error_log`` and ``include`` directives.""" From 61a0308686794e25599165a9615068487ecd0717 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:24:48 +0200 Subject: [PATCH 09/13] Restore imports in nginx --- dissect/target/plugins/apps/webserver/nginx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dissect/target/plugins/apps/webserver/nginx.py b/dissect/target/plugins/apps/webserver/nginx.py index fe84071cf0..b1af8bd673 100644 --- a/dissect/target/plugins/apps/webserver/nginx.py +++ b/dissect/target/plugins/apps/webserver/nginx.py @@ -3,7 +3,6 @@ import json import re from datetime import datetime -from pathlib import Path from typing import TYPE_CHECKING from dissect.target.exceptions import UnsupportedPluginError @@ -18,6 +17,7 @@ if TYPE_CHECKING: from collections.abc import Iterator + from pathlib import Path from dissect.target.target import Target From 42c4cc55004dd5b959f60c3cc2471213ed11f5f4 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:39:49 +0200 Subject: [PATCH 10/13] Seperate auxiliary and artifact paths --- dissect/target/plugin.py | 11 ++++++++++- dissect/target/plugins/apps/webserver/apache.py | 5 ++++- dissect/target/plugins/apps/webserver/caddy.py | 6 +++--- dissect/target/plugins/apps/webserver/iis.py | 8 +++----- dissect/target/plugins/apps/webserver/nginx.py | 7 +++++-- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/dissect/target/plugin.py b/dissect/target/plugin.py index b5ea106e61..05d6a07b1e 100644 --- a/dissect/target/plugin.py +++ b/dissect/target/plugin.py @@ -473,6 +473,7 @@ def get_all_paths(self) -> Iterator[Path]: should stay the same. """ yield from self.get_paths() + yield from self._get_auxiliary_paths() def _get_paths_direct(self) -> Iterator[Path]: """Return all paths as given by the user.""" @@ -480,12 +481,20 @@ def _get_paths_direct(self) -> Iterator[Path]: yield self.target.fs.path(str(path)) def _get_paths(self) -> Iterator[Path]: - """Return all files of interest to the plugin. + """Return all artifact files of interest to the plugin. To be implemented by the plugin subclass. """ raise NotImplementedError + def _get_auxiliary_paths(self) -> Iterator[Path]: + """Return all auxiliary files of interest to the plugin. + + To be implemented by the plugin subclass. + """ + raise NotImplementedError + + def register(plugincls: type[Plugin]) -> None: """Register a plugin, and put related data inside :attr:`PLUGINS`. diff --git a/dissect/target/plugins/apps/webserver/apache.py b/dissect/target/plugins/apps/webserver/apache.py index f55821785c..5a3181d3dc 100644 --- a/dissect/target/plugins/apps/webserver/apache.py +++ b/dissect/target/plugins/apps/webserver/apache.py @@ -283,13 +283,16 @@ def find_logs(self) -> None: self._process_conf_file(path, seen) def _get_paths(self) -> Iterator[Path]: + yield from self.access_paths | self.error_paths + + def _get_auxiliary_paths(self) -> Iterator[Path]: config_paths = set() for path in self.DEFAULT_CONFIG_PATHS: config_paths.add(Path(path)) config_paths.update(self.resolved_config_paths) - yield from self.access_paths | self.error_paths | config_paths + yield from config_paths def _process_conf_file(self, path: Path, seen: set[Path] | None = None) -> None: """Process an Apache ``.conf`` file for ``ServerRoot``, ``CustomLog``, ``Include`` diff --git a/dissect/target/plugins/apps/webserver/caddy.py b/dissect/target/plugins/apps/webserver/caddy.py index fc99a64a4b..0171bad427 100644 --- a/dissect/target/plugins/apps/webserver/caddy.py +++ b/dissect/target/plugins/apps/webserver/caddy.py @@ -98,10 +98,10 @@ def get_log_paths(self) -> list[Path]: return log_paths def _get_paths(self) -> Iterator[Path]: - config_paths = {Path(self.DEFAULT_CONFIG_PATH)} - log_paths = set(self.log_paths) + yield from self.log_paths - yield from log_paths | config_paths + def _get_auxiliary_paths(self) -> Iterator[Path]: + yield from {Path(self.DEFAULT_CONFIG_PATH)} @export(record=WebserverAccessLogRecord) def access(self) -> Iterator[WebserverAccessLogRecord]: diff --git a/dissect/target/plugins/apps/webserver/iis.py b/dissect/target/plugins/apps/webserver/iis.py index eb1fefd101..39ccfd8c5b 100644 --- a/dissect/target/plugins/apps/webserver/iis.py +++ b/dissect/target/plugins/apps/webserver/iis.py @@ -126,13 +126,11 @@ def log_dirs(self) -> dict[str, set[Path]]: return dirs def _get_paths(self) -> Iterator[Path]: - log_paths = set() - config_paths = {self.config} - for path in self.log_dirs.values(): - log_paths = log_paths | path + yield from path - yield from log_paths | config_paths + def _get_auxiliary_paths(self) -> Iterator[Path]: + yield from {self.config} @export(record=BasicRecordDescriptor) def logs(self) -> Iterator[TargetRecordDescriptor]: diff --git a/dissect/target/plugins/apps/webserver/nginx.py b/dissect/target/plugins/apps/webserver/nginx.py index b1af8bd673..2eeaa850f2 100644 --- a/dissect/target/plugins/apps/webserver/nginx.py +++ b/dissect/target/plugins/apps/webserver/nginx.py @@ -135,8 +135,11 @@ def find_logs(self) -> None: self.config_paths.add(config_file) self.parse_config(config_file) - def _get_paths(self) -> set: - yield from self.access_paths | self.error_paths | self.config_paths + def _get_paths(self) -> Iterator[Path]: + yield from self.access_paths | self.error_paths + + def _get_auxiliary_paths(self) -> Iterator[Path]: + yield from self.config_paths def parse_config(self, path: Path, seen: set[Path] | None = None) -> None: """Parse the given NGINX ``.conf`` file for ``access_log``, ``error_log`` and ``include`` directives.""" From d7a0a7a5dfe90ac1a9cd0d297fe1e4f2489ede40 Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:42:10 +0200 Subject: [PATCH 11/13] Formatting --- dissect/target/plugin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dissect/target/plugin.py b/dissect/target/plugin.py index 05d6a07b1e..e752956aa3 100644 --- a/dissect/target/plugin.py +++ b/dissect/target/plugin.py @@ -495,7 +495,6 @@ def _get_auxiliary_paths(self) -> Iterator[Path]: raise NotImplementedError - def register(plugincls: type[Plugin]) -> None: """Register a plugin, and put related data inside :attr:`PLUGINS`. From 2902ea7051c5b87dabe01f1edc48fe7703671b3a Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:24:05 +0100 Subject: [PATCH 12/13] Update comment --- dissect/target/plugins/apps/webserver/iis.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dissect/target/plugins/apps/webserver/iis.py b/dissect/target/plugins/apps/webserver/iis.py index 39ccfd8c5b..1cbbb2af8c 100644 --- a/dissect/target/plugins/apps/webserver/iis.py +++ b/dissect/target/plugins/apps/webserver/iis.py @@ -154,8 +154,7 @@ def logs(self) -> Iterator[TargetRecordDescriptor]: self.target.log.info("Processing IIS log file %s in %s format", log_file, format) yield from parsers[format](self.target, log_file) - # We don't implement _get_paths() in the IIS plugin because there's little use for it for the way the plugin - # is currently implemented. So handle direct files here. + # We handle direct files here because _get_paths cannot select (filter) on the type of logfile. if self.target.is_direct: for log_file in self.get_paths(): yield from parse_autodetect_format_log(self.target, log_file) From 99608e4ae857f56e4c615f20cfa57dcaec675d6a Mon Sep 17 00:00:00 2001 From: qmadev <190383216+qmadev@users.noreply.github.com> Date: Mon, 24 Nov 2025 00:34:01 +0100 Subject: [PATCH 13/13] Fix linter --- dissect/target/plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dissect/target/plugin.py b/dissect/target/plugin.py index e752956aa3..74781cb465 100644 --- a/dissect/target/plugin.py +++ b/dissect/target/plugin.py @@ -468,9 +468,9 @@ def get_paths(self) -> Iterator[Path]: def get_all_paths(self) -> Iterator[Path]: """Return all artifact and auxiliary paths. - The implementation of this function will - probably change in the future, but the interface - should stay the same. + The implementation of this function will + probably change in the future, but the interface + should stay the same. """ yield from self.get_paths() yield from self._get_auxiliary_paths()