dissect.target 3.20.dev21__py3-none-any.whl → 3.20.dev23__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,,