dissect.target 3.20.dev21__py3-none-any.whl → 3.20.dev23__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/xfs.py +8 -1
- dissect/target/plugins/os/unix/_os.py +14 -12
- dissect/target/plugins/os/windows/_os.py +12 -10
- dissect/target/tools/fsutils.py +1 -1
- {dissect.target-3.20.dev21.dist-info → dissect.target-3.20.dev23.dist-info}/METADATA +1 -1
- {dissect.target-3.20.dev21.dist-info → dissect.target-3.20.dev23.dist-info}/RECORD +11 -11
- {dissect.target-3.20.dev21.dist-info → dissect.target-3.20.dev23.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.20.dev21.dist-info → dissect.target-3.20.dev23.dist-info}/LICENSE +0 -0
- {dissect.target-3.20.dev21.dist-info → dissect.target-3.20.dev23.dist-info}/WHEEL +0 -0
- {dissect.target-3.20.dev21.dist-info → dissect.target-3.20.dev23.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.20.dev21.dist-info → dissect.target-3.20.dev23.dist-info}/top_level.txt +0 -0
@@ -130,8 +130,15 @@ class XfsFilesystemEntry(FilesystemEntry):
|
|
130
130
|
st_info.st_mtime_ns = self.entry.mtime_ns
|
131
131
|
st_info.st_ctime_ns = self.entry.ctime_ns
|
132
132
|
|
133
|
-
|
133
|
+
st_info.st_blksize = self.fs.xfs.block_size
|
134
|
+
# Convert number of filesystem blocks to basic blocks
|
135
|
+
# Reference: https://github.com/torvalds/linux/blob/e32cde8d2bd7d251a8f9b434143977ddf13dcec6/fs/xfs/xfs_iops.c#L602 # noqa: E501
|
136
|
+
# Note that block size in XFS is always a multiple of 512, so the division below is safe
|
137
|
+
st_info.st_blocks = self.entry.nblocks * (self.fs.xfs.block_size // 512)
|
138
|
+
|
139
|
+
# XFS has a birth time, since inode version 3 (version 5 of filesystem)
|
134
140
|
st_info.st_birthtime = self.entry.crtime.timestamp()
|
141
|
+
st_info.st_birthtime_ns = self.entry.crtime_ns
|
135
142
|
|
136
143
|
return st_info
|
137
144
|
|
@@ -4,7 +4,9 @@ import logging
|
|
4
4
|
import re
|
5
5
|
import uuid
|
6
6
|
from struct import unpack
|
7
|
-
from typing import Iterator
|
7
|
+
from typing import Iterator
|
8
|
+
|
9
|
+
from flow.record.fieldtypes import posix_path
|
8
10
|
|
9
11
|
from dissect.target.filesystem import Filesystem
|
10
12
|
from dissect.target.helpers.fsutil import TargetPath
|
@@ -25,7 +27,7 @@ class UnixPlugin(OSPlugin):
|
|
25
27
|
self._os_release = self._parse_os_release()
|
26
28
|
|
27
29
|
@classmethod
|
28
|
-
def detect(cls, target: Target) ->
|
30
|
+
def detect(cls, target: Target) -> Filesystem | None:
|
29
31
|
for fs in target.filesystems:
|
30
32
|
if fs.exists("/var") and fs.exists("/etc"):
|
31
33
|
return fs
|
@@ -71,7 +73,7 @@ class UnixPlugin(OSPlugin):
|
|
71
73
|
uid=pwent.get(2),
|
72
74
|
gid=pwent.get(3),
|
73
75
|
gecos=pwent.get(4),
|
74
|
-
home=
|
76
|
+
home=posix_path(pwent.get(5)),
|
75
77
|
shell=pwent.get(6),
|
76
78
|
source=passwd_file,
|
77
79
|
_target=self.target,
|
@@ -115,23 +117,23 @@ class UnixPlugin(OSPlugin):
|
|
115
117
|
|
116
118
|
yield UnixUserRecord(
|
117
119
|
name=user["name"],
|
118
|
-
home=user["home"],
|
120
|
+
home=posix_path(user["home"]),
|
119
121
|
shell=user["shell"],
|
120
122
|
source="/var/log/syslog",
|
121
123
|
_target=self.target,
|
122
124
|
)
|
123
125
|
|
124
126
|
@export(property=True)
|
125
|
-
def architecture(self) ->
|
127
|
+
def architecture(self) -> str | None:
|
126
128
|
return self._get_architecture(self.os)
|
127
129
|
|
128
130
|
@export(property=True)
|
129
|
-
def hostname(self) ->
|
131
|
+
def hostname(self) -> str | None:
|
130
132
|
hosts_string = self._hosts_dict.get("hostname", "localhost")
|
131
133
|
return self._hostname_dict.get("hostname", hosts_string)
|
132
134
|
|
133
135
|
@export(property=True)
|
134
|
-
def domain(self) ->
|
136
|
+
def domain(self) -> str | None:
|
135
137
|
domain = self._hostname_dict.get("domain", "localhost")
|
136
138
|
if domain == "localhost":
|
137
139
|
domain = self._hosts_dict["hostname", "localhost"]
|
@@ -152,7 +154,7 @@ class UnixPlugin(OSPlugin):
|
|
152
154
|
_, _, hostname = line.rstrip().partition("=")
|
153
155
|
return hostname
|
154
156
|
|
155
|
-
def _parse_hostname_string(self, paths:
|
157
|
+
def _parse_hostname_string(self, paths: list[str] | None = None) -> dict[str, str] | None:
|
156
158
|
"""
|
157
159
|
Returns a dict containing the hostname and domain name portion of the path(s) specified
|
158
160
|
|
@@ -184,7 +186,7 @@ class UnixPlugin(OSPlugin):
|
|
184
186
|
break # break whenever a valid hostname is found
|
185
187
|
return hostname_dict
|
186
188
|
|
187
|
-
def _parse_hosts_string(self, paths:
|
189
|
+
def _parse_hosts_string(self, paths: list[str] | None = None) -> dict[str, str]:
|
188
190
|
paths = paths or ["/etc/hosts"]
|
189
191
|
hosts_string = {"ip": None, "hostname": None}
|
190
192
|
|
@@ -244,7 +246,7 @@ class UnixPlugin(OSPlugin):
|
|
244
246
|
self.target.log.debug("Mounting %s (%s) at %s", fs, fs.volume, mount_point)
|
245
247
|
self.target.fs.mount(mount_point, fs)
|
246
248
|
|
247
|
-
def _parse_os_release(self, glob:
|
249
|
+
def _parse_os_release(self, glob: str | None = None) -> dict[str, str]:
|
248
250
|
"""Parse files containing Unix version information.
|
249
251
|
|
250
252
|
Not all these files are equal. Generally speaking these files are
|
@@ -286,7 +288,7 @@ class UnixPlugin(OSPlugin):
|
|
286
288
|
continue
|
287
289
|
return os_release
|
288
290
|
|
289
|
-
def _get_architecture(self, os: str = "unix", path: str = "/bin/ls") ->
|
291
|
+
def _get_architecture(self, os: str = "unix", path: str = "/bin/ls") -> str | None:
|
290
292
|
arch_strings = {
|
291
293
|
0x00: "Unknown",
|
292
294
|
0x02: "SPARC",
|
@@ -322,7 +324,7 @@ class UnixPlugin(OSPlugin):
|
|
322
324
|
def parse_fstab(
|
323
325
|
fstab: TargetPath,
|
324
326
|
log: logging.Logger = log,
|
325
|
-
) -> Iterator[tuple[
|
327
|
+
) -> Iterator[tuple[uuid.UUID | str, str, str, str, str]]:
|
326
328
|
"""Parse fstab file and return a generator that streams the details of entries,
|
327
329
|
with unsupported FS types and block devices filtered away.
|
328
330
|
"""
|
@@ -2,7 +2,9 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import operator
|
4
4
|
import struct
|
5
|
-
from typing import Any, Iterator
|
5
|
+
from typing import Any, Iterator
|
6
|
+
|
7
|
+
from flow.record.fieldtypes import windows_path
|
6
8
|
|
7
9
|
from dissect.target.exceptions import RegistryError, RegistryValueNotFoundError
|
8
10
|
from dissect.target.filesystem import Filesystem
|
@@ -26,7 +28,7 @@ class WindowsPlugin(OSPlugin):
|
|
26
28
|
)
|
27
29
|
|
28
30
|
@classmethod
|
29
|
-
def detect(cls, target: Target) ->
|
31
|
+
def detect(cls, target: Target) -> Filesystem | None:
|
30
32
|
for fs in target.filesystems:
|
31
33
|
if fs.exists("/windows/system32") or fs.exists("/winnt"):
|
32
34
|
return fs
|
@@ -90,7 +92,7 @@ class WindowsPlugin(OSPlugin):
|
|
90
92
|
self.target.log.warning("Unknown drive letter for sysvol")
|
91
93
|
|
92
94
|
@export(property=True)
|
93
|
-
def hostname(self) ->
|
95
|
+
def hostname(self) -> str | None:
|
94
96
|
key = "HKLM\\SYSTEM\\ControlSet001\\Control\\Computername\\Computername"
|
95
97
|
try:
|
96
98
|
return self.target.registry.value(key, "Computername").value
|
@@ -109,7 +111,7 @@ class WindowsPlugin(OSPlugin):
|
|
109
111
|
|
110
112
|
return value
|
111
113
|
|
112
|
-
def _legacy_current_version(self) ->
|
114
|
+
def _legacy_current_version(self) -> str | None:
|
113
115
|
"""Returns the NT version as used up to and including NT 6.3.
|
114
116
|
|
115
117
|
This corresponds with Windows 8 / Windows 2012 Server.
|
@@ -121,7 +123,7 @@ class WindowsPlugin(OSPlugin):
|
|
121
123
|
"""
|
122
124
|
return self._get_version_reg_value("CurrentVersion")
|
123
125
|
|
124
|
-
def _major_version(self) ->
|
126
|
+
def _major_version(self) -> int | None:
|
125
127
|
"""Return the NT major version number (starting from NT 10.0 / Windows 10).
|
126
128
|
|
127
129
|
Returns:
|
@@ -131,7 +133,7 @@ class WindowsPlugin(OSPlugin):
|
|
131
133
|
"""
|
132
134
|
return self._get_version_reg_value("CurrentMajorVersionNumber")
|
133
135
|
|
134
|
-
def _minor_version(self) ->
|
136
|
+
def _minor_version(self) -> int | None:
|
135
137
|
"""Return the NT minor version number (starting from NT 10.0 / Windows 10).
|
136
138
|
|
137
139
|
Returns:
|
@@ -141,7 +143,7 @@ class WindowsPlugin(OSPlugin):
|
|
141
143
|
"""
|
142
144
|
return self._get_version_reg_value("CurrentMinorVersionNumber")
|
143
145
|
|
144
|
-
def _nt_version(self) ->
|
146
|
+
def _nt_version(self) -> int | None:
|
145
147
|
"""Return the Windows NT version in x.y format.
|
146
148
|
|
147
149
|
For systems up to and including NT 6.3 (Win 8 / Win 2012 Server) this
|
@@ -169,7 +171,7 @@ class WindowsPlugin(OSPlugin):
|
|
169
171
|
return version
|
170
172
|
|
171
173
|
@export(property=True)
|
172
|
-
def version(self) ->
|
174
|
+
def version(self) -> str | None:
|
173
175
|
"""Return a string representation of the Windows version of the target.
|
174
176
|
|
175
177
|
For Windows versions before Windows 10 this looks like::
|
@@ -255,7 +257,7 @@ class WindowsPlugin(OSPlugin):
|
|
255
257
|
return version_string
|
256
258
|
|
257
259
|
@export(property=True)
|
258
|
-
def architecture(self) ->
|
260
|
+
def architecture(self) -> str | None:
|
259
261
|
"""
|
260
262
|
Returns a dict containing the architecture and bitness of the system
|
261
263
|
|
@@ -312,7 +314,7 @@ class WindowsPlugin(OSPlugin):
|
|
312
314
|
yield WindowsUserRecord(
|
313
315
|
sid=subkey.name,
|
314
316
|
name=name,
|
315
|
-
home=home,
|
317
|
+
home=windows_path(home),
|
316
318
|
_target=self.target,
|
317
319
|
)
|
318
320
|
|
dissect/target/tools/fsutils.py
CHANGED
@@ -207,7 +207,7 @@ def print_stat(path: fsutil.TargetPath, stdout: TextIO, dereference: bool = Fals
|
|
207
207
|
filetype=filetype(path),
|
208
208
|
device="?",
|
209
209
|
inode=s.st_ino,
|
210
|
-
blocks=s.st_blocks
|
210
|
+
blocks=s.st_blocks if s.st_blocks is not None else "?",
|
211
211
|
blksize=s.st_blksize or "?",
|
212
212
|
nlink=s.st_nlink,
|
213
213
|
modeord=oct(stat.S_IMODE(s.st_mode)),
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.20.
|
3
|
+
Version: 3.20.dev23
|
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
|
@@ -41,7 +41,7 @@ dissect/target/filesystems/squashfs.py,sha256=ehzlThXB7n96XUvQnsK5tWLsA9HIxYN-Zx
|
|
41
41
|
dissect/target/filesystems/tar.py,sha256=EJyvRCU6H7eu0exC0tQggyAZKZ3JFFaihYyx9SIQNqk,5742
|
42
42
|
dissect/target/filesystems/vmfs.py,sha256=sRtYBUAKTKcHrjCXqpFJ8GIVU-ERjqxhB2zXBndtcXU,4955
|
43
43
|
dissect/target/filesystems/vmtar.py,sha256=LlKWkTIuLemQmG9yGqL7980uC_AOL77_GWhbJc_grSk,804
|
44
|
-
dissect/target/filesystems/xfs.py,sha256=
|
44
|
+
dissect/target/filesystems/xfs.py,sha256=bNYyiAqqTnzKf-Cd-XTbr-3EPWjSlOpjlcyCzO2Toq4,5017
|
45
45
|
dissect/target/filesystems/zip.py,sha256=BeNj23DOYfWuTm5V1V419ViJiMfBrO1VA5gP6rljwXs,5467
|
46
46
|
dissect/target/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
47
|
dissect/target/helpers/cache.py,sha256=TXlJBdFRz6V9zKs903am4Yawr0maYw5kZY0RqklDQJM,8568
|
@@ -191,7 +191,7 @@ dissect/target/plugins/general/scrape.py,sha256=Fz7BNXflvuxlnVulyyDhLpyU8D_hJdH6
|
|
191
191
|
dissect/target/plugins/general/users.py,sha256=yy9gvRXfN9BT71v4Xqo5hpwfgN9he9Otu8TBPZ_Tegs,3009
|
192
192
|
dissect/target/plugins/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
193
193
|
dissect/target/plugins/os/unix/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
194
|
-
dissect/target/plugins/os/unix/_os.py,sha256=
|
194
|
+
dissect/target/plugins/os/unix/_os.py,sha256=74qY8zoyP1e3sPzIdwsPsYr7P2mJCXUN0CPF6CRsbMI,14606
|
195
195
|
dissect/target/plugins/os/unix/cronjobs.py,sha256=2ssj97UVJueyATVl7NMJmqd9uHflQ2tXUqdOCFIEje8,3182
|
196
196
|
dissect/target/plugins/os/unix/datetime.py,sha256=gKfBdPyUirt3qmVYfOJ1oZXRPn8wRzssbZxR_ARrtk8,1518
|
197
197
|
dissect/target/plugins/os/unix/etc.py,sha256=HoPEC1hxqurSnAXQAK-jf_HxdBIDe-1z_qSw_n-ViI4,258
|
@@ -265,7 +265,7 @@ dissect/target/plugins/os/unix/log/lastlog.py,sha256=Wq89wRSFZSBsoKVCxjDofnC4yw9
|
|
265
265
|
dissect/target/plugins/os/unix/log/messages.py,sha256=O10Uw3PGTanfGpphUWYqOwOIR7XiiM-clfboVCoiP0U,4501
|
266
266
|
dissect/target/plugins/os/unix/log/utmp.py,sha256=1nPHIaBUHt_9z6PDrvyqg4huKLihUaWLrMmgMsbaeIo,7755
|
267
267
|
dissect/target/plugins/os/windows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
268
|
-
dissect/target/plugins/os/windows/_os.py,sha256=-
|
268
|
+
dissect/target/plugins/os/windows/_os.py,sha256=-Bsp9696JqU7luh_AbqojzG9BxVdYIFl5Ma-LiFBQBo,12505
|
269
269
|
dissect/target/plugins/os/windows/activitiescache.py,sha256=Q2aILnhJ2rp2AwEbWwyBuSLjMbGqaYJTsavSbfkcFKE,6741
|
270
270
|
dissect/target/plugins/os/windows/adpolicy.py,sha256=qjv0s-gAIGKCznWdVOARJbLXnCKYgvzoFNWoXnq3m1M,7102
|
271
271
|
dissect/target/plugins/os/windows/amcache.py,sha256=ZZNOs3bILTf0AGkDkhoatndl0j39DXkstN7oOyxJECU,27188
|
@@ -347,7 +347,7 @@ dissect/target/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
347
347
|
dissect/target/tools/build_pluginlist.py,sha256=5fomcuMwsVzcnYx5Htf5f9lSwsLeUUvomLUXNA4t7m4,849
|
348
348
|
dissect/target/tools/dd.py,sha256=rTM-lgXxrYBpVAtJqFqAatDz45bLoD8-mFt_59Q3Lio,1928
|
349
349
|
dissect/target/tools/fs.py,sha256=3Ny8zoooVeeF7OUkQ0nxZVdEaQeU7vPRjDOYhz6XfRA,5385
|
350
|
-
dissect/target/tools/fsutils.py,sha256=
|
350
|
+
dissect/target/tools/fsutils.py,sha256=q0t9gFwKHaPr2Ya-MN2o4LsYledde7kp2DZZTd8roIc,8314
|
351
351
|
dissect/target/tools/info.py,sha256=8nnbqFUYeo4NLPE7ORcTBcDL-TioGB2Nqc1TKcu5qdY,5715
|
352
352
|
dissect/target/tools/logging.py,sha256=5ZnumtMWLyslxfrUGZ4ntRyf3obOOhmn8SBjKfdLcEg,4174
|
353
353
|
dissect/target/tools/mount.py,sha256=8GRYnu4xEmFBHxuIZAYhOMyyTGX8fat1Ou07DNiUnW4,3945
|
@@ -368,10 +368,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
368
368
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
369
369
|
dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
|
370
370
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
371
|
-
dissect.target-3.20.
|
372
|
-
dissect.target-3.20.
|
373
|
-
dissect.target-3.20.
|
374
|
-
dissect.target-3.20.
|
375
|
-
dissect.target-3.20.
|
376
|
-
dissect.target-3.20.
|
377
|
-
dissect.target-3.20.
|
371
|
+
dissect.target-3.20.dev23.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
372
|
+
dissect.target-3.20.dev23.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
373
|
+
dissect.target-3.20.dev23.dist-info/METADATA,sha256=dGuBoIpEp_hKqGr5hAlD6pnyc70LxqqzpOG40g_EeLE,12897
|
374
|
+
dissect.target-3.20.dev23.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
375
|
+
dissect.target-3.20.dev23.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
|
376
|
+
dissect.target-3.20.dev23.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
377
|
+
dissect.target-3.20.dev23.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.20.dev21.dist-info → dissect.target-3.20.dev23.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|