From c4d7c6087d963feaa2ec9a0864be6d268dc391c0 Mon Sep 17 00:00:00 2001 From: cecinestpasunepipe <110607403+cecinestpasunepipe@users.noreply.github.com> Date: Mon, 7 Oct 2024 12:53:32 +0200 Subject: [PATCH 1/2] Misc/Custom Parsers (DIS-2162) --- dissect/target/filesystems/config.py | 4 ++++ dissect/target/helpers/configutil.py | 26 +++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/dissect/target/filesystems/config.py b/dissect/target/filesystems/config.py index 66f07af36..524dc2a8c 100644 --- a/dissect/target/filesystems/config.py +++ b/dissect/target/filesystems/config.py @@ -247,10 +247,14 @@ def open(self) -> BinaryIO: Returns: A file-like object holding a byte representation of :attr:`parser_items`. """ + if isinstance(self.parser_items, ConfigurationParser): # Currently trying to open the underlying entry return self.entry.open() + if isinstance(self.parser_items, bytes): + return io.BytesIO(self.parser_items) + output_data = self._write_value_mapping(self.parser_items) return io.BytesIO(bytes(output_data, "utf-8")) diff --git a/dissect/target/helpers/configutil.py b/dissect/target/helpers/configutil.py index aae967c2e..288535688 100644 --- a/dissect/target/helpers/configutil.py +++ b/dissect/target/helpers/configutil.py @@ -161,7 +161,7 @@ def parse_file(self, fh: TextIO) -> None: def get(self, item: str, default: Optional[Any] = None) -> Any: return self.parsed_data.get(item, default) - def read_file(self, fh: TextIO) -> None: + def read_file(self, fh: TextIO | io.BytesIO) -> None: """Parse a configuration file. Raises: @@ -303,6 +303,14 @@ def parse_file(self, fh: TextIO) -> None: self.parsed_data = {"content": fh.read(), "size": str(fh.tell())} +class Bin(ConfigurationParser): + + """Read the file into ``binary`` and show the number of bytes read""" + + def parse_file(self, fh: io.BytesIO) -> None: + self.parsed_data = {"binary": fh.read(), "size": str(fh.tell())} + + class Xml(ConfigurationParser): """Parses an XML file. Ignores any constructor parameters passed from ``ConfigurationParser`.""" @@ -733,6 +741,8 @@ def create_parser(self, options: Optional[ParserOptions] = None) -> Configuratio "*/sysconfig/network-scripts/ifcfg-*": ParserConfig(Default), "*/sysctl.d/*.conf": ParserConfig(Default), "*/xml/*": ParserConfig(Xml), + "*.bashrc": ParserConfig(Txt), + "*/vim/vimrc*": ParserConfig(Txt), } CONFIG_MAP: dict[tuple[str, ...], ParserConfig] = { @@ -744,6 +754,13 @@ def create_parser(self, options: Optional[ParserOptions] = None) -> Configuratio "cnf": ParserConfig(Default), "conf": ParserConfig(Default, separator=(r"\s",)), "sample": ParserConfig(Txt), + "sh": ParserConfig(Txt), + "key": ParserConfig(Txt), + "crt": ParserConfig(Txt), + "pem": ParserConfig(Txt), + "pl": ParserConfig(Txt), # various admin panels + "lua": ParserConfig(Txt), # wireshark etc. + "txt": ParserConfig(Txt), "systemd": ParserConfig(SystemD), "template": ParserConfig(Txt), "toml": ParserConfig(Toml), @@ -759,6 +776,7 @@ def create_parser(self, options: Optional[ParserOptions] = None) -> Configuratio "nsswitch.conf": ParserConfig(Default, separator=(":",)), "lsb-release": ParserConfig(Default), "catalog": ParserConfig(Xml), + "ld.so.cache": ParserConfig(Bin), "fstab": ParserConfig( CSVish, separator=(r"\s",), @@ -832,9 +850,11 @@ def parse_config( parser_type = _select_parser(entry, hint) parser = parser_type.create_parser(options) - with entry.open() as fh: - open_file = io.TextIOWrapper(fh, encoding="utf-8") + if not isinstance(parser, Bin): + open_file = io.TextIOWrapper(fh, encoding="utf-8") + else: + open_file = io.BytesIO(fh.read()) parser.read_file(open_file) return parser From 15f8db6664116ee16a76cec0db38860e29810f73 Mon Sep 17 00:00:00 2001 From: cecinestpasunepipe <110607403+cecinestpasunepipe@users.noreply.github.com> Date: Mon, 14 Oct 2024 11:58:26 +0200 Subject: [PATCH 2/2] Misc/Custom Parsers (DIS-2162) --- tests/helpers/test_configutil.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/helpers/test_configutil.py b/tests/helpers/test_configutil.py index c72520a4b..1b9644a94 100644 --- a/tests/helpers/test_configutil.py +++ b/tests/helpers/test_configutil.py @@ -1,7 +1,7 @@ from __future__ import annotations import textwrap -from io import StringIO +from io import BytesIO, StringIO from pathlib import Path from typing import TYPE_CHECKING, Union @@ -9,6 +9,7 @@ from dissect.target.exceptions import FileNotFoundError from dissect.target.helpers.configutil import ( + Bin, ConfigurationParser, CSVish, Default, @@ -269,6 +270,18 @@ def test_json_syntax(data_string: str, expected_data: Union[dict, list]) -> None assert parser.parsed_data == expected_data +@pytest.mark.parametrize( + "data, expected_data", + [ + (b"\x00\x01\x02", {"binary": b"\x00\x01\x02", "size": "3"}), + ], +) +def test_bin_parser(data: bytes, expected_data: dict) -> None: + parser = Bin() + parser.parse_file(BytesIO(data)) + assert parser.parsed_data == expected_data + + @pytest.mark.parametrize( "fields, separator, comment, data_string, expected_data", [