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.
@@ -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
- # XFS has a birth time, called crtime
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, Optional, Union
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) -> Optional[Filesystem]:
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=self.target.fs.path(pwent.get(5)),
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) -> Optional[str]:
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) -> Optional[str]:
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) -> Optional[str]:
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: Optional[list[str]] = None) -> Optional[dict[str, str]]:
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: Optional[list[str]] = None) -> dict[str, str]:
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: Optional[str] = None) -> dict[str, str]:
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") -> Optional[str]:
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[Union[uuid.UUID, str], str, str, str, str]]:
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, Optional
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) -> Optional[Filesystem]:
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) -> Optional[str]:
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) -> Optional[str]:
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) -> Optional[int]:
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) -> Optional[int]:
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) -> Optional[int]:
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) -> Optional[str]:
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) -> Optional[str]:
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
 
@@ -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 or "?",
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.dev21
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=kIyFGKYlyFYC7H3jaEv-lNKtBW4ZkD92H0WpfGcr1ww,4498
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=u7m97qASdm_l90k4i7dzMtu2kcF6fVPKutx4_ISQTSg,14606
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=-x5TD5BvFw-7zEfqT6WG7n04YSeyr7wVLO07y6xkBP8,12476
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=dyAdp2fzydcozaIZ1mFTpdUeVcibYNJCHN8AFw5FoKU,8285
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.dev21.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
372
- dissect.target-3.20.dev21.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
373
- dissect.target-3.20.dev21.dist-info/METADATA,sha256=FdfozSKxhhuFaA4lQezDgcLc3raCghFSQN4owmDjv1w,12897
374
- dissect.target-3.20.dev21.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
375
- dissect.target-3.20.dev21.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
376
- dissect.target-3.20.dev21.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
377
- dissect.target-3.20.dev21.dist-info/RECORD,,
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,,