Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Put plugins in the proper unix or linux namespace #447

Merged
merged 1 commit into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 4 additions & 16 deletions dissect/target/plugins/os/unix/cronjobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
from dissect.target.plugin import Plugin, export

CronjobRecord = TargetRecordDescriptor(
"linux/cronjob",
"unix/cronjob",
[
("string", "minute"),
("string", "hour"),
("string", "day"),
("string", "month"),
("string", "weekday"),
("string", "user"),
("wstring", "command"),
("string", "command"),
("path", "source"),
],
)

EnvironmentVariableRecord = TargetRecordDescriptor(
"linux/environmentvariable",
"unix/environmentvariable",
[
("string", "key"),
("string", "value"),
Expand All @@ -31,19 +31,6 @@ class CronjobPlugin(Plugin):
def check_compatible(self) -> None:
pass

def get_record(self, minute, hour, day, month, weekday, usr, cmd, path):
return CronjobRecord(
minute=minute,
hour=hour,
day=day,
month=month,
weekday=weekday,
user=usr,
command=cmd,
source=self.resolver.resolve(path),
_target=self.target,
)

def parse_crontab(self, file_path):
for line in file_path.open("rt"):
line = line.strip()
Expand Down Expand Up @@ -93,6 +80,7 @@ def cronjobs(self):
"/var/spool/cron",
"/var/spool/cron/crontabs",
"/etc/cron.d",
"/usr/local/etc/cron.d", # FreeBSD
]
for path in crontab_dirs:
fspath = self.target.fs.path(path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from dissect.target.filesystems import tar
from dissect.target.helpers.record import TargetRecordDescriptor
from dissect.target.plugin import OperatingSystem, arg, export, internal
from dissect.target.plugins.os.unix.linux._os import LinuxPlugin
from dissect.target.plugins.os.unix._os import UnixPlugin
from dissect.target.target import Target

VirtualMachineRecord = TargetRecordDescriptor(
Expand All @@ -36,7 +36,7 @@
)


class ESXiPlugin(LinuxPlugin):
class ESXiPlugin(UnixPlugin):
"""ESXi OS plugin

ESXi partitioning varies between versions. Generally, specific partition numbers have special meaning.
Expand Down
4 changes: 3 additions & 1 deletion dissect/target/plugins/os/unix/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,18 @@ def activity(self) -> Optional[datetime]:
def install_date(self) -> Optional[datetime]:
"""Return the likely install date of the operating system."""

# Although this purports to be a generic function for Unix targets,
# these paths are Linux specific.
files = [
# Debian
"/var/log/installer/install-journal.txt",
"/var/log/installer/syslog",
"/var/lib/dpkg/arch",
# RedHat
"/root/anaconda-ks.cfg",
# Generic
"/etc/hostname",
"/etc/machine-id",
"/var/lib/dpkg/arch",
]
dates = []

Expand Down
2 changes: 1 addition & 1 deletion dissect/target/plugins/os/unix/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from dissect.target.plugin import Plugin, export, internal

CommandHistoryRecord = create_extended_descriptor([UserRecordDescriptorExtension])(
"linux/history",
"unix/history",
[
("datetime", "ts"),
("string", "command"),
Expand Down
8 changes: 4 additions & 4 deletions dissect/target/plugins/os/unix/linux/suse/zypper.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ def logs(self) -> Iterator[PackageManagerLogRecord]:
Example log format::

2022-12-16 12:56:23|command|root@ec9fa6d67dda|'zypper' 'install' 'unzip'|
2022-12-16 12:56:23|install|update-alternatives|1.21.8-1.4|x86_64||repo-oss|b4d6389437e306d6104559c82d09fce15c4486fbc7fd215cc33d265ff729aaf1| # noqa
2022-12-16 12:56:23|install|update-alternatives|1.21.8-1.4|x86_64||repo-oss|b4d6389437e306d6104559c82d09fce15c4486fbc7fd215cc33d265ff729aaf1|
# 2022-12-16 12:56:23 unzip-6.00-41.1.x86_64.rpm installed ok
# Additional rpm output:
# update-alternatives: using /usr/bin/unzip-plain to provide /usr/bin/unzip (unzip) in auto mode
#
2022-12-16 12:56:23|install|unzip|6.00-41.1|x86_64|root@ec9fa6d67dda|repo-oss|d7e42c9d83f97cf3b7eceb4d3fa64e445a33a7a33f387366734c444d5571cb3a| # noqa
2022-12-16 12:56:23|install|unzip|6.00-41.1|x86_64|root@ec9fa6d67dda|repo-oss|d7e42c9d83f97cf3b7eceb4d3fa64e445a33a7a33f387366734c444d5571cb3a|
2022-12-16 12:57:50|command|root@ec9fa6d67dda|'zypper' 'remove' 'unzip'|
# 2022-12-16 12:57:50 unzip-6.00-41.1.x86_64 removed ok
# Additional rpm output:
# update-alternatives: warning: alternative /usr/bin/unzipsfx-plain (part of link group unzipsfx) doesn't exist; removing from list of alternatives # noqa
# update-alternatives: warning: alternative /usr/bin/zipgrep-plain (part of link group zipgrep) doesn't exist; removing from list of alternatives # noqa
# update-alternatives: warning: alternative /usr/bin/unzipsfx-plain (part of link group unzipsfx) doesn't exist; removing from list of alternatives
# update-alternatives: warning: alternative /usr/bin/zipgrep-plain (part of link group zipgrep) doesn't exist; removing from list of alternatives
#
2022-12-16 12:57:50|remove |unzip|6.00-41.1|x86_64|root@ec9fa6d67dda|
2022-12-16 12:58:49|command|root@ec9fa6d67dda|'zypper' 'install' 'unzip'|
Expand Down
4 changes: 3 additions & 1 deletion dissect/target/plugins/os/unix/locale.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dissect.target.plugin import Plugin, export

UnixKeyboardRecord = TargetRecordDescriptor(
"linux/keyboard",
"unix/keyboard",
[
("string", "layout"),
("string", "model"),
Expand Down Expand Up @@ -64,6 +64,8 @@ def timezone(self):
@export(property=True)
def language(self):
"""Get the configured locale(s) of the system."""
# Although this purports to be a generic function for Unix targets,
# these paths are Linux specific.
locale_paths = ["/etc/default/locale", "/etc/locale.conf"]

found_languages = []
Expand Down
6 changes: 3 additions & 3 deletions dissect/target/plugins/os/unix/packagemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from dissect.target.plugin import Plugin, export

PackageManagerLogRecord = TargetRecordDescriptor(
"linux/log/packagemanager",
"unix/log/packagemanager",
[
("datetime", "ts"),
("string", "package_manager"),
Expand Down Expand Up @@ -61,7 +61,7 @@ def __init__(self, target: Target):
for entry in self.TOOLS:
try:
self._plugins.append(getattr(self.target, entry))
except Exception: # noqa
except Exception:
target.log.exception(f"Failed to load tool plugin: {entry}")

def check_compatible(self) -> None:
Expand All @@ -77,5 +77,5 @@ def _func(self, f: str) -> Iterator[PackageManagerLogRecord]:

@export(record=PackageManagerLogRecord)
def logs(self) -> Iterator[PackageManagerLogRecord]:
"""Returns logs from apt, yum and zypper package managers."""
"""Returns logs from all available Unix package managers."""
yield from self._func("logs")
2 changes: 1 addition & 1 deletion dissect/target/plugins/os/unix/shadow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dissect.target.plugin import Plugin, export

UnixShadowRecord = TargetRecordDescriptor(
"linux/shadow",
"unix/shadow",
[
("string", "name"),
("string", "crypt"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

import pytest

from dissect.target.plugins.os.unix.services import ServicesPlugin, parse_systemd_config
from dissect.target.plugins.os.unix.linux.services import (
ServicesPlugin,
parse_systemd_config,
)
from tests._utils import absolute_path


def test_unix_services(target_unix_users, fs_unix):
def test_services(target_unix_users, fs_unix):
systemd_service_1 = absolute_path("_data/plugins/os/unix/services/systemd.service")
systemd_service_2 = absolute_path("_data/plugins/os/unix/services/systemd2.service")
initd_service_1 = absolute_path("_data/plugins/os/unix/services/initd.sh")
Expand Down Expand Up @@ -57,13 +60,13 @@ def test_unix_services(target_unix_users, fs_unix):
("[Unit]\ntest=hello\tme", 'Unit_test="hello\tme"'),
],
)
def test_unix_systemd_parser(assignment, expected_value):
def test_systemd(assignment, expected_value):
data = parse_systemd_config(StringIO(assignment))
assert data == expected_value


@pytest.mark.xfail
def test_unix_systemd_known_fails():
def test_systemd_known_fails():
# While this should return `Hello world test help`,
# the configparser attempts to append `help` as a value to the list of options
# belonging to the key before it `test\\`.
Expand Down
4 changes: 2 additions & 2 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def test_find_plugin_function_unix(target_unix: Target) -> None:

assert len(found) == 1
assert found[0].name == "services"
assert found[0].path == "os.unix.services.services"
assert found[0].path == "os.unix.linux.services.services"


TestRecord = create_extended_descriptor([UserRecordDescriptorExtension])(
Expand Down Expand Up @@ -184,7 +184,7 @@ def test_find_plugin_function_default(target_default: Target) -> None:
assert "services" in names
assert "services" in names
paths = [item.path for item in found]
assert "os.unix.services.services" in paths
assert "os.unix.linux.services.services" in paths
assert "os.windows.services.services" in paths

found, _ = find_plugin_functions(target_default, "mcafee.msc")
Expand Down