dissect.target 3.19.dev29__py3-none-any.whl → 3.19.dev31__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dissect/target/filesystems/config.py +32 -21
- dissect/target/helpers/configutil.py +1 -1
- dissect/target/plugins/os/unix/esxi/_os.py +17 -17
- dissect/target/plugins/os/unix/etc/etc.py +4 -4
- {dissect.target-3.19.dev29.dist-info → dissect.target-3.19.dev31.dist-info}/METADATA +1 -1
- {dissect.target-3.19.dev29.dist-info → dissect.target-3.19.dev31.dist-info}/RECORD +11 -11
- {dissect.target-3.19.dev29.dist-info → dissect.target-3.19.dev31.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.19.dev29.dist-info → dissect.target-3.19.dev31.dist-info}/LICENSE +0 -0
- {dissect.target-3.19.dev29.dist-info → dissect.target-3.19.dev31.dist-info}/WHEEL +0 -0
- {dissect.target-3.19.dev29.dist-info → dissect.target-3.19.dev31.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.19.dev29.dist-info → dissect.target-3.19.dev31.dist-info}/top_level.txt +0 -0
@@ -3,11 +3,11 @@ from __future__ import annotations
|
|
3
3
|
import io
|
4
4
|
import textwrap
|
5
5
|
from logging import getLogger
|
6
|
-
from typing import Any, BinaryIO, Iterator, Optional
|
6
|
+
from typing import Any, BinaryIO, Iterator, Optional
|
7
7
|
|
8
8
|
from dissect.target import Target
|
9
9
|
from dissect.target.exceptions import ConfigurationParsingError, FileNotFoundError
|
10
|
-
from dissect.target.filesystem import
|
10
|
+
from dissect.target.filesystem import FilesystemEntry, VirtualFilesystem
|
11
11
|
from dissect.target.helpers import fsutil
|
12
12
|
from dissect.target.helpers.configutil import ConfigurationParser, parse
|
13
13
|
|
@@ -46,7 +46,7 @@ class ConfigurationFilesystem(VirtualFilesystem):
|
|
46
46
|
super().__init__(**kwargs)
|
47
47
|
self.root.top = target.fs.get(path)
|
48
48
|
|
49
|
-
def _get_till_file(self, path: str, relentry: FilesystemEntry) -> tuple[list[str], FilesystemEntry]:
|
49
|
+
def _get_till_file(self, path: str, relentry: FilesystemEntry | None) -> tuple[list[str], FilesystemEntry]:
|
50
50
|
"""Searches for the file entry that is pointed to by ``path``.
|
51
51
|
|
52
52
|
The ``path`` could contain ``key`` entries too, so it searches for the entry from
|
@@ -56,9 +56,13 @@ class ConfigurationFilesystem(VirtualFilesystem):
|
|
56
56
|
A list of ``parts`` containing keys: [keys, into, the, file].
|
57
57
|
And the resolved entry: Entry(filename)
|
58
58
|
"""
|
59
|
+
|
59
60
|
entry = relentry or self.root
|
61
|
+
root_path = relentry.path if relentry else self.root.top.path
|
60
62
|
|
61
|
-
|
63
|
+
# Calculate the relative path
|
64
|
+
relpath = fsutil.relpath(path, root_path, alt_separator=self.alt_separator)
|
65
|
+
path = fsutil.normalize(relpath, alt_separator=self.alt_separator).strip("/")
|
62
66
|
|
63
67
|
if not path:
|
64
68
|
return [], entry
|
@@ -85,10 +89,8 @@ class ConfigurationFilesystem(VirtualFilesystem):
|
|
85
89
|
|
86
90
|
return parts[idx:], entry
|
87
91
|
|
88
|
-
def get(
|
89
|
-
|
90
|
-
) -> Union[FilesystemEntry, ConfigurationEntry]:
|
91
|
-
"""Retrieve a :class:`ConfigurationEntry` or :class:`.FilesystemEntry` relative to the root or ``relentry``.
|
92
|
+
def get(self, path: str, relentry: Optional[FilesystemEntry] = None, *args, **kwargs) -> ConfigurationEntry:
|
93
|
+
"""Retrieve a :class:`ConfigurationEntry` relative to the root or ``relentry``.
|
92
94
|
|
93
95
|
Raises:
|
94
96
|
FileNotFoundError: if it could not find the entry.
|
@@ -96,7 +98,7 @@ class ConfigurationFilesystem(VirtualFilesystem):
|
|
96
98
|
parts, entry = self._get_till_file(path, relentry)
|
97
99
|
|
98
100
|
if entry.is_dir():
|
99
|
-
return entry
|
101
|
+
return ConfigurationEntry(self, entry.path, entry, None)
|
100
102
|
|
101
103
|
entry = self._convert_entry(entry, *args, **kwargs)
|
102
104
|
|
@@ -108,23 +110,21 @@ class ConfigurationFilesystem(VirtualFilesystem):
|
|
108
110
|
|
109
111
|
return entry
|
110
112
|
|
111
|
-
def _convert_entry(
|
112
|
-
self, file_entry: FilesystemEntry, *args, **kwargs
|
113
|
-
) -> Union[ConfigurationEntry, FilesystemEntry]:
|
113
|
+
def _convert_entry(self, file_entry: FilesystemEntry, *args, **kwargs) -> ConfigurationEntry:
|
114
114
|
"""Creates a :class:`ConfigurationEntry` from a ``file_entry``.
|
115
115
|
|
116
116
|
If an error occurs during the parsing of the file contents,
|
117
117
|
the original ``file_entry`` is returned.
|
118
118
|
"""
|
119
119
|
entry = file_entry
|
120
|
+
config_parser = None
|
120
121
|
try:
|
121
122
|
config_parser = parse(entry, *args, **kwargs)
|
122
|
-
entry = ConfigurationEntry(self, entry.path, entry, config_parser)
|
123
123
|
except ConfigurationParsingError as e:
|
124
124
|
# If a parsing error gets created, it should return the `entry`
|
125
125
|
log.debug("Error when parsing %s with message '%s'", entry.path, e)
|
126
126
|
|
127
|
-
return entry
|
127
|
+
return ConfigurationEntry(self, entry.path, entry, config_parser)
|
128
128
|
|
129
129
|
|
130
130
|
class ConfigurationEntry(FilesystemEntry):
|
@@ -163,10 +163,10 @@ class ConfigurationEntry(FilesystemEntry):
|
|
163
163
|
|
164
164
|
def __init__(
|
165
165
|
self,
|
166
|
-
fs:
|
166
|
+
fs: ConfigurationFilesystem,
|
167
167
|
path: str,
|
168
168
|
entry: FilesystemEntry,
|
169
|
-
parser_items:
|
169
|
+
parser_items: dict | ConfigurationParser | str | list | None = None,
|
170
170
|
) -> None:
|
171
171
|
super().__init__(fs, path, entry)
|
172
172
|
self.parser_items = parser_items
|
@@ -182,7 +182,7 @@ class ConfigurationEntry(FilesystemEntry):
|
|
182
182
|
|
183
183
|
return f"<{self.__class__.__name__} {output}"
|
184
184
|
|
185
|
-
def get(self, key, default:
|
185
|
+
def get(self, key, default: Any | None = None) -> ConfigurationEntry | Any | None:
|
186
186
|
"""Gets the dictionary key that belongs to this entry using ``key``.
|
187
187
|
Behaves like ``dictionary.get()``.
|
188
188
|
|
@@ -197,13 +197,19 @@ class ConfigurationEntry(FilesystemEntry):
|
|
197
197
|
if not key:
|
198
198
|
raise TypeError("key should be defined")
|
199
199
|
|
200
|
-
|
200
|
+
path = fsutil.join(self.path, key, alt_separator=self.fs.alt_separator)
|
201
|
+
|
202
|
+
if self.parser_items and key in self.parser_items:
|
201
203
|
return ConfigurationEntry(
|
202
204
|
self.fs,
|
203
|
-
|
205
|
+
path,
|
204
206
|
self.entry,
|
205
207
|
self.parser_items[key],
|
206
208
|
)
|
209
|
+
|
210
|
+
if self.entry.is_dir():
|
211
|
+
return self.fs.get(path, self.entry)
|
212
|
+
|
207
213
|
return default
|
208
214
|
|
209
215
|
def _write_value_mapping(self, values: dict[str, Any], indentation_nr: int = 0) -> str:
|
@@ -257,6 +263,11 @@ class ConfigurationEntry(FilesystemEntry):
|
|
257
263
|
if self.is_file():
|
258
264
|
raise NotADirectoryError()
|
259
265
|
|
266
|
+
if self.parser_items is None and self.entry.is_dir():
|
267
|
+
for entry in self.entry.scandir():
|
268
|
+
yield ConfigurationEntry(self.fs, entry.name, entry, None)
|
269
|
+
return
|
270
|
+
|
260
271
|
for key, values in self.parser_items.items():
|
261
272
|
yield ConfigurationEntry(self.fs, key, self.entry, values)
|
262
273
|
|
@@ -266,7 +277,7 @@ class ConfigurationEntry(FilesystemEntry):
|
|
266
277
|
def is_dir(self, follow_symlinks: bool = True) -> bool:
|
267
278
|
"""Returns whether this :class:`ConfigurationEntry` can be considered a directory."""
|
268
279
|
# if self.parser_items has keys (thus sub-values), we can consider it a directory.
|
269
|
-
return hasattr(self.parser_items, "keys")
|
280
|
+
return (self.parser_items is None and self.entry.is_dir()) or hasattr(self.parser_items, "keys")
|
270
281
|
|
271
282
|
def is_symlink(self) -> bool:
|
272
283
|
"""Return whether this :class:`ConfigurationEntry` is a symlink or not.
|
@@ -284,7 +295,7 @@ class ConfigurationEntry(FilesystemEntry):
|
|
284
295
|
Returns:
|
285
296
|
Whether the ``entry`` and ``key`` exists
|
286
297
|
"""
|
287
|
-
return self.entry.exists() and key in self.parser_items
|
298
|
+
return self.parser_items and self.entry.exists() and key in self.parser_items
|
288
299
|
|
289
300
|
def stat(self, follow_symlinks: bool = True) -> fsutil.stat_result:
|
290
301
|
"""Returns the stat from the underlying :class:`.FilesystemEntry` :attr:`entry`."""
|
@@ -171,7 +171,7 @@ class ConfigurationParser:
|
|
171
171
|
try:
|
172
172
|
self.parse_file(fh)
|
173
173
|
except Exception as e:
|
174
|
-
raise ConfigurationParsingError(
|
174
|
+
raise ConfigurationParsingError(e.args) from e
|
175
175
|
|
176
176
|
if self.collapse_all or self.collapse:
|
177
177
|
self.parsed_data = self._collapse_dict(self.parsed_data)
|
@@ -8,7 +8,7 @@ import subprocess
|
|
8
8
|
from configparser import ConfigParser
|
9
9
|
from configparser import Error as ConfigParserError
|
10
10
|
from io import BytesIO
|
11
|
-
from typing import Any, BinaryIO, Iterator,
|
11
|
+
from typing import Any, BinaryIO, Iterator, TextIO
|
12
12
|
|
13
13
|
from defusedxml import ElementTree
|
14
14
|
from dissect.hypervisor.util import vmtar
|
@@ -73,7 +73,7 @@ class ESXiPlugin(UnixPlugin):
|
|
73
73
|
if configstore.exists():
|
74
74
|
self._configstore = parse_config_store(configstore.open())
|
75
75
|
|
76
|
-
def _cfg(self, path: str) ->
|
76
|
+
def _cfg(self, path: str) -> str | None:
|
77
77
|
if not self._config:
|
78
78
|
self.target.log.warning("No ESXi config!")
|
79
79
|
return None
|
@@ -87,7 +87,7 @@ class ESXiPlugin(UnixPlugin):
|
|
87
87
|
return obj.get(value_name) if obj else None
|
88
88
|
|
89
89
|
@classmethod
|
90
|
-
def detect(cls, target: Target) ->
|
90
|
+
def detect(cls, target: Target) -> Filesystem | None:
|
91
91
|
bootbanks = [
|
92
92
|
fs for fs in target.filesystems if fs.path("boot.cfg").exists() and list(fs.path("/").glob("*.v00"))
|
93
93
|
]
|
@@ -128,7 +128,7 @@ class ESXiPlugin(UnixPlugin):
|
|
128
128
|
return "localhost"
|
129
129
|
|
130
130
|
@export(property=True)
|
131
|
-
def domain(self) ->
|
131
|
+
def domain(self) -> str | None:
|
132
132
|
if hostname := self._cfg("/adv/Misc/HostName"):
|
133
133
|
return hostname.partition(".")[2]
|
134
134
|
|
@@ -146,7 +146,7 @@ class ESXiPlugin(UnixPlugin):
|
|
146
146
|
return list(result)
|
147
147
|
|
148
148
|
@export(property=True)
|
149
|
-
def version(self) ->
|
149
|
+
def version(self) -> str | None:
|
150
150
|
boot_cfg = self.target.fs.path("/bootbank/boot.cfg")
|
151
151
|
if not boot_cfg.exists():
|
152
152
|
return None
|
@@ -187,11 +187,11 @@ class ESXiPlugin(UnixPlugin):
|
|
187
187
|
return self._configstore
|
188
188
|
|
189
189
|
@export(property=True)
|
190
|
-
def os(self):
|
190
|
+
def os(self) -> str:
|
191
191
|
return OperatingSystem.ESXI.value
|
192
192
|
|
193
193
|
|
194
|
-
def _mount_modules(target: Target, sysvol: Filesystem, cfg: dict[str, str]):
|
194
|
+
def _mount_modules(target: Target, sysvol: Filesystem, cfg: dict[str, str]) -> None:
|
195
195
|
modules = [m.strip() for m in cfg["modules"].split("---")]
|
196
196
|
|
197
197
|
for module in modules:
|
@@ -218,20 +218,22 @@ def _mount_modules(target: Target, sysvol: Filesystem, cfg: dict[str, str]):
|
|
218
218
|
target.fs.append_layer().mount("/", tfs)
|
219
219
|
|
220
220
|
|
221
|
-
def _mount_local(target: Target, local_layer: VirtualFilesystem):
|
221
|
+
def _mount_local(target: Target, local_layer: VirtualFilesystem) -> None:
|
222
222
|
local_tgz = target.fs.path("local.tgz")
|
223
|
+
local_tgz_ve = target.fs.path("local.tgz.ve")
|
223
224
|
local_fs = None
|
224
225
|
|
225
226
|
if local_tgz.exists():
|
226
227
|
local_fs = tar.TarFilesystem(local_tgz.open())
|
227
|
-
|
228
|
-
local_tgz_ve = target.fs.path("local.tgz.ve")
|
228
|
+
elif local_tgz_ve.exists():
|
229
229
|
# In the case "encryption.info" does not exist, but ".#encryption.info" does
|
230
230
|
encryption_info = next(target.fs.path("/").glob("*encryption.info"), None)
|
231
231
|
if not local_tgz_ve.exists() or not encryption_info.exists():
|
232
232
|
raise ValueError("Unable to find valid configuration archive")
|
233
233
|
|
234
234
|
local_fs = _create_local_fs(target, local_tgz_ve, encryption_info)
|
235
|
+
else:
|
236
|
+
target.log.warning("No local.tgz or local.tgz.ve found, skipping local state")
|
235
237
|
|
236
238
|
if local_fs:
|
237
239
|
local_layer.mount("/", local_fs)
|
@@ -245,7 +247,7 @@ def _decrypt_envelope(local_tgz_ve: TargetPath, encryption_info: TargetPath) ->
|
|
245
247
|
return local_tgz
|
246
248
|
|
247
249
|
|
248
|
-
def _decrypt_crypto_util(local_tgz_ve: TargetPath) ->
|
250
|
+
def _decrypt_crypto_util(local_tgz_ve: TargetPath) -> BytesIO | None:
|
249
251
|
"""Decrypt ``local.tgz.ve`` using ESXi ``crypto-util``.
|
250
252
|
|
251
253
|
We write to stdout, but this results in ``crypto-util`` exiting with a non-zero return code
|
@@ -264,9 +266,7 @@ def _decrypt_crypto_util(local_tgz_ve: TargetPath) -> Optional[BytesIO]:
|
|
264
266
|
return BytesIO(result.stdout)
|
265
267
|
|
266
268
|
|
267
|
-
def _create_local_fs(
|
268
|
-
target: Target, local_tgz_ve: TargetPath, encryption_info: TargetPath
|
269
|
-
) -> Optional[tar.TarFilesystem]:
|
269
|
+
def _create_local_fs(target: Target, local_tgz_ve: TargetPath, encryption_info: TargetPath) -> tar.TarFilesystem | None:
|
270
270
|
local_tgz = None
|
271
271
|
|
272
272
|
if HAS_ENVELOPE:
|
@@ -292,7 +292,7 @@ def _create_local_fs(
|
|
292
292
|
return tar.TarFilesystem(local_tgz)
|
293
293
|
|
294
294
|
|
295
|
-
def _mount_filesystems(target: Target, sysvol: Filesystem, cfg: dict[str, str]):
|
295
|
+
def _mount_filesystems(target: Target, sysvol: Filesystem, cfg: dict[str, str]) -> None:
|
296
296
|
version = cfg["build"]
|
297
297
|
|
298
298
|
osdata_fs = None
|
@@ -371,7 +371,7 @@ def _mount_filesystems(target: Target, sysvol: Filesystem, cfg: dict[str, str]):
|
|
371
371
|
target.fs.symlink(f"/vmfs/volumes/LOCKER-{locker_fs.vmfs.uuid}", "/locker")
|
372
372
|
|
373
373
|
|
374
|
-
def _link_log_dir(target: Target, cfg: dict[str, str], plugin_obj: ESXiPlugin):
|
374
|
+
def _link_log_dir(target: Target, cfg: dict[str, str], plugin_obj: ESXiPlugin) -> None:
|
375
375
|
version = cfg["build"]
|
376
376
|
|
377
377
|
# Don't really know how ESXi does this, but let's just take a shortcut for now
|
@@ -441,7 +441,7 @@ def parse_esx_conf(fh: TextIO) -> dict[str, Any]:
|
|
441
441
|
return config
|
442
442
|
|
443
443
|
|
444
|
-
def _traverse(path: str, obj: dict[str, Any], create: bool = False):
|
444
|
+
def _traverse(path: str, obj: dict[str, Any], create: bool = False) -> dict[str, Any] | None:
|
445
445
|
parts = path.strip("/").split("/")
|
446
446
|
path_parts = parts[:-1]
|
447
447
|
for part in path_parts:
|
@@ -62,13 +62,13 @@ class EtcTree(ConfigurationTreePlugin):
|
|
62
62
|
|
63
63
|
@export(record=UnixConfigTreeRecord)
|
64
64
|
@arg("--glob", dest="pattern", required=False, default="*", type=str, help="Glob-style pattern to search for")
|
65
|
-
|
66
|
-
|
65
|
+
@arg("--root", dest="root", required=False, default="/", type=str, help="Path to use as root for search")
|
66
|
+
def etc(self, pattern: str, root: str) -> Iterator[UnixConfigTreeRecord]:
|
67
|
+
for entry, subs, items in self.config_fs.walk(root):
|
67
68
|
for item in items:
|
68
69
|
try:
|
69
70
|
config_object = self.get(str(Path(entry) / Path(item)))
|
70
|
-
|
71
|
-
yield from self._sub(config_object, Path(entry) / Path(item), pattern)
|
71
|
+
yield from self._sub(config_object, Path(entry) / Path(item), pattern)
|
72
72
|
except Exception:
|
73
73
|
self.target.log.warning("Could not open configuration item: %s", item)
|
74
74
|
pass
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.19.
|
3
|
+
Version: 3.19.dev31
|
4
4
|
Summary: This module ties all other Dissect modules together, it provides a programming API and command line tools which allow easy access to various data sources inside disk images or file collections (a.k.a. targets)
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
6
6
|
License: Affero General Public License v3
|
@@ -25,7 +25,7 @@ dissect/target/filesystems/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
25
25
|
dissect/target/filesystems/ad1.py,sha256=nEPzaaRsb6bL4ItFo0uLdmdLvrmK9BjqHeD3FOp3WQI,2413
|
26
26
|
dissect/target/filesystems/btrfs.py,sha256=5MBi193ZvclkEQcxDr_sDHfj_FYU_hyYNRL4YqpDu4M,6243
|
27
27
|
dissect/target/filesystems/cb.py,sha256=6LcoJiwsYu1Han31IUzVpZVDTifhTLTx_gLfNpB_p6k,5329
|
28
|
-
dissect/target/filesystems/config.py,sha256=
|
28
|
+
dissect/target/filesystems/config.py,sha256=GQOtixIIt-Jjtpl3IVqUTujcBFfWaAZeAtvxgNUNetU,11963
|
29
29
|
dissect/target/filesystems/cpio.py,sha256=ssVCjkAtLn2FqmNxeo6U5boyUdSYFxLWfXpytHYGPqs,641
|
30
30
|
dissect/target/filesystems/dir.py,sha256=rKEreX3A7CI6a3pMssrO9F-9i5pkxCn_Ucs_dMtHxxA,4574
|
31
31
|
dissect/target/filesystems/exfat.py,sha256=PRkZPUVN5NlgB1VetFtywdNgF6Yj5OBtF5a25t-fFvw,5917
|
@@ -46,7 +46,7 @@ dissect/target/filesystems/zip.py,sha256=WT1bQhzX_1MXXVZTKrJniae4xqRqMZ8FsfbvhgG
|
|
46
46
|
dissect/target/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
47
|
dissect/target/helpers/cache.py,sha256=TXlJBdFRz6V9zKs903am4Yawr0maYw5kZY0RqklDQJM,8568
|
48
48
|
dissect/target/helpers/config.py,sha256=6917CZ6eDHaK_tOoiVEIndyhRXO6r6eCBIleq6f47PQ,2346
|
49
|
-
dissect/target/helpers/configutil.py,sha256=
|
49
|
+
dissect/target/helpers/configutil.py,sha256=AEnkMQ0e6PncvCqGa-ACzBQWQBhMGBCzO5qzGJtRu60,27644
|
50
50
|
dissect/target/helpers/cyber.py,sha256=WnJlk-HqAETmDAgLq92JPxyDLxvzSoFV_WrO-odVKBI,16805
|
51
51
|
dissect/target/helpers/descriptor_extensions.py,sha256=uT8GwznfDAiIgMM7JKKOY0PXKMv2c0GCqJTCkWFgops,2605
|
52
52
|
dissect/target/helpers/docs.py,sha256=J5U65Y3yOTqxDEZRCdrEmO63XQCeDzOJea1PwPM6Cyc,5146
|
@@ -208,9 +208,9 @@ dissect/target/plugins/os/unix/bsd/osx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
|
|
208
208
|
dissect/target/plugins/os/unix/bsd/osx/_os.py,sha256=KvP7YJ7apVwoIop7MR-8q5QbVGoB6MdR42l6ssEe6es,4081
|
209
209
|
dissect/target/plugins/os/unix/bsd/osx/user.py,sha256=qopB0s3n7e6Q7NjWzn8Z-dKtDtU7e6In4Vm7hIvvedo,2322
|
210
210
|
dissect/target/plugins/os/unix/esxi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
211
|
-
dissect/target/plugins/os/unix/esxi/_os.py,sha256=
|
211
|
+
dissect/target/plugins/os/unix/esxi/_os.py,sha256=s6pAgUyfHh3QcY6sgvk5uVMmLvqK1tIHWR7MSbrFn8w,17789
|
212
212
|
dissect/target/plugins/os/unix/etc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
213
|
-
dissect/target/plugins/os/unix/etc/etc.py,sha256=
|
213
|
+
dissect/target/plugins/os/unix/etc/etc.py,sha256=px_UwtPuk_scD-3nKJQZ0ao5lus9-BrSU4lPZWelYzI,2541
|
214
214
|
dissect/target/plugins/os/unix/linux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
215
215
|
dissect/target/plugins/os/unix/linux/_os.py,sha256=n6VkfGYIdZUxcK2C1aPDUY_ZZQEIl0GkrpvIKeguv5o,2812
|
216
216
|
dissect/target/plugins/os/unix/linux/cmdline.py,sha256=AyMfndt3UsmJtoOyZYC8nWq2GZg9oPvn8SiI3M4NxnE,1622
|
@@ -346,10 +346,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
346
346
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
347
347
|
dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
|
348
348
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
349
|
-
dissect.target-3.19.
|
350
|
-
dissect.target-3.19.
|
351
|
-
dissect.target-3.19.
|
352
|
-
dissect.target-3.19.
|
353
|
-
dissect.target-3.19.
|
354
|
-
dissect.target-3.19.
|
355
|
-
dissect.target-3.19.
|
349
|
+
dissect.target-3.19.dev31.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
350
|
+
dissect.target-3.19.dev31.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
351
|
+
dissect.target-3.19.dev31.dist-info/METADATA,sha256=GZuNZDNA6Y6mINzf5sqR_gX4uyq0i5TLvFhCse-bxPc,12719
|
352
|
+
dissect.target-3.19.dev31.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
353
|
+
dissect.target-3.19.dev31.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
|
354
|
+
dissect.target-3.19.dev31.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
355
|
+
dissect.target-3.19.dev31.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.19.dev29.dist-info → dissect.target-3.19.dev31.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|