Skip to content

Commit dbe5869

Browse files
cecinestpasunepipeotnxSl
authored andcommitted
Add glob/dump function for config tree (fox-it#728)
(DIS-2163)
1 parent 6358c46 commit dbe5869

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

dissect/target/plugins/os/unix/etc/__init__.py

Whitespace-only changes.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import fnmatch
2+
import logging
3+
import re
4+
from pathlib import Path
5+
from typing import Iterator
6+
7+
from dissect.target import Target
8+
from dissect.target.helpers.record import TargetRecordDescriptor
9+
from dissect.target.plugin import arg, export
10+
from dissect.target.plugins.general.config import (
11+
ConfigurationEntry,
12+
ConfigurationTreePlugin,
13+
)
14+
15+
UnixConfigTreeRecord = TargetRecordDescriptor(
16+
"unix/config",
17+
[
18+
("path", "source"),
19+
("path", "path"),
20+
("string", "key"),
21+
("string[]", "value"),
22+
],
23+
)
24+
25+
log = logging.getLogger(__name__)
26+
27+
28+
class EtcTree(ConfigurationTreePlugin):
29+
__namespace__ = "etc"
30+
31+
def __init__(self, target: Target):
32+
super().__init__(target, "/etc")
33+
34+
def _sub(self, items: ConfigurationEntry, entry: Path, pattern: str) -> Iterator[UnixConfigTreeRecord]:
35+
index = 0
36+
config_entry = items
37+
if not isinstance(items, dict):
38+
items = items.as_dict()
39+
40+
for raw_key, value in items.items():
41+
key = re.sub(r"[\n\r\t]", "", raw_key)
42+
path = Path(entry) / Path(key)
43+
44+
if isinstance(value, dict):
45+
yield from self._sub(value, path, pattern)
46+
continue
47+
48+
if not isinstance(value, list):
49+
value = [str(value)]
50+
51+
if fnmatch.fnmatch(path, pattern):
52+
data = {
53+
"_target": self.target,
54+
"source": self.target.fs.path(config_entry.entry.path),
55+
"path": path,
56+
"key": key,
57+
"value": value,
58+
}
59+
if value == [""]:
60+
data["key"] = index
61+
data["value"] = [key]
62+
index += 1
63+
64+
yield UnixConfigTreeRecord(**data)
65+
66+
@export(record=UnixConfigTreeRecord)
67+
@arg("--glob", dest="pattern", required=False, default="*", type=str, help="Glob-style pattern to search for")
68+
def etc(self, pattern: str) -> Iterator[UnixConfigTreeRecord]:
69+
for entry, subs, items in self.config_fs.walk("/"):
70+
for item in items:
71+
try:
72+
config_object = self.get(str(Path(entry) / Path(item)))
73+
if isinstance(config_object, ConfigurationEntry):
74+
yield from self._sub(config_object, Path(entry) / Path(item), pattern)
75+
except Exception:
76+
log.warning("Could not open configuration item: %s", item)
77+
pass

0 commit comments

Comments
 (0)