dissect.hypervisor 3.17.dev2__py3-none-any.whl → 3.18.dev1__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.
@@ -0,0 +1,20 @@
1
+ import tarfile
2
+
3
+ from dissect.hypervisor.util import vmtar
4
+
5
+
6
+ def main() -> None:
7
+ # We just want to run the main function of the tarfile module, but with our VisorTarFile and is_tarfile functions
8
+ type(tarfile.main)(
9
+ tarfile.main.__code__,
10
+ tarfile.main.__globals__
11
+ | {
12
+ "TarFile": vmtar.VisorTarFile,
13
+ "is_tarfile": vmtar.is_tarfile,
14
+ "open": vmtar.open,
15
+ },
16
+ )()
17
+
18
+
19
+ if __name__ == "__main__":
20
+ main()
@@ -5,6 +5,8 @@ from __future__ import annotations
5
5
 
6
6
  import struct
7
7
  import tarfile
8
+ from io import BytesIO
9
+ from typing import BinaryIO, Final
8
10
 
9
11
 
10
12
  class VisorTarInfo(tarfile.TarInfo):
@@ -49,9 +51,72 @@ class VisorTarInfo(tarfile.TarInfo):
49
51
  return super()._proc_member(tarfile)
50
52
 
51
53
 
52
- def VisorTarFile(*args, **kwargs) -> tarfile.TarFile:
53
- return tarfile.TarFile(*args, **kwargs, tarinfo=VisorTarInfo)
54
+ class VisorTarFile(tarfile.TarFile):
55
+ def __init__(self, *args, **kwargs) -> None:
56
+ super().__init__(*args, **kwargs, tarinfo=VisorTarInfo)
54
57
 
55
-
56
- def open(*args, **kwargs) -> tarfile.TarFile:
57
- return tarfile.open(*args, **kwargs, tarinfo=VisorTarInfo)
58
+ @classmethod
59
+ def visoropen(cls, name: str, mode: str = "r", fileobj: BinaryIO | None = None, **kwargs) -> VisorTarFile:
60
+ """Open a visor tar file for reading. Supports gzip and lzma compression."""
61
+ if mode not in ("r",):
62
+ raise tarfile.TarError("visor currently only supports read mode")
63
+
64
+ try:
65
+ from gzip import GzipFile
66
+ except ImportError:
67
+ raise tarfile.CompressionError("gzip module is not available") from None
68
+
69
+ try:
70
+ from lzma import LZMAError, LZMAFile
71
+ except ImportError:
72
+ raise tarfile.CompressionError("lzma module is not available") from None
73
+
74
+ compressed = False
75
+
76
+ try:
77
+ t = cls.taropen(name, mode, fileobj, **kwargs)
78
+ except Exception:
79
+ try:
80
+ fileobj = GzipFile(name, mode + "b", fileobj=fileobj)
81
+ except OSError as e:
82
+ if fileobj is not None and mode == "r":
83
+ raise tarfile.ReadError("not a visor file") from e
84
+ raise
85
+
86
+ try:
87
+ t = cls.taropen(name, mode, fileobj, **kwargs)
88
+ except Exception:
89
+ fileobj.seek(0)
90
+ fileobj = LZMAFile(fileobj or name, mode) # noqa: SIM115
91
+
92
+ try:
93
+ t = cls.taropen(name, mode, fileobj, **kwargs)
94
+ except (LZMAError, EOFError, OSError) as e:
95
+ fileobj.close()
96
+ if mode == "r":
97
+ raise tarfile.ReadError("not a visor file") from e
98
+ raise
99
+ except:
100
+ fileobj.close()
101
+ raise
102
+
103
+ compressed = True
104
+
105
+ # If we get here, we have a valid visor tar file
106
+ if fileobj is not None and compressed:
107
+ # Just read the entire file into memory, it's probably small
108
+ fileobj.seek(0)
109
+ fileobj = BytesIO(fileobj.read())
110
+
111
+ t = cls.taropen(name, mode, fileobj, **kwargs)
112
+
113
+ t._extfileobj = False
114
+ return t
115
+
116
+ # Only allow opening visor tar files
117
+ OPEN_METH: Final[dict[str, str]] = {"visor": "visoropen"}
118
+
119
+
120
+ open = VisorTarFile.open
121
+
122
+ is_tarfile = type(tarfile.is_tarfile)(tarfile.is_tarfile.__code__, tarfile.is_tarfile.__globals__ | {"open": open})
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: dissect.hypervisor
3
- Version: 3.17.dev2
3
+ Version: 3.18.dev1
4
4
  Summary: A Dissect module implementing parsers for various hypervisor disk, backup and configuration files
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License: Affero General Public License v3
@@ -31,6 +31,7 @@ Provides-Extra: dev
31
31
  Requires-Dist: dissect.hypervisor[full]; extra == "dev"
32
32
  Requires-Dist: dissect.cstruct<5.0.dev,>=4.0.dev; extra == "dev"
33
33
  Requires-Dist: dissect.util<4.0.dev,>=3.0.dev; extra == "dev"
34
+ Dynamic: license-file
34
35
 
35
36
  # dissect.hypervisor
36
37
 
@@ -22,13 +22,14 @@ dissect/hypervisor/disk/vhdx.py,sha256=Yidz57PsH6IGRiN8cpfAnyZiOGt1qApd8ohVdHGF2
22
22
  dissect/hypervisor/disk/vmdk.py,sha256=s23a8Gs_kemy4ZKYuJYXYCFckZtYgeZ7Rmrgxpj5W7s,19565
23
23
  dissect/hypervisor/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  dissect/hypervisor/tools/envelope.py,sha256=BvaBSoXq3VrZ2GJVrfnL8NB6OLbdp8qD05jedxSAKwQ,1024
25
+ dissect/hypervisor/tools/vmtar.py,sha256=bAf_rEhqUmeI8my22p7L9uV3SgB5C_61YQKfD3tNo60,476
25
26
  dissect/hypervisor/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
27
  dissect/hypervisor/util/envelope.py,sha256=EhZjZh3EezqxkJ84OgqpptHIhpVWPcUkFMjdYU-iAnU,10442
27
- dissect/hypervisor/util/vmtar.py,sha256=kMYhmL6cUBnhPqKfoVE_jn9OZOTM7iW-mm9Dxhl2lD4,1707
28
- dissect.hypervisor-3.17.dev2.dist-info/COPYRIGHT,sha256=EOOoIwk_inOMUD4c1ylpzMtYLjGzmc-MLEVAEdLLr20,305
29
- dissect.hypervisor-3.17.dev2.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
30
- dissect.hypervisor-3.17.dev2.dist-info/METADATA,sha256=QKvUKzT3FgMrCqycy4_luvc180C1UdbyG9WLuO840FA,3412
31
- dissect.hypervisor-3.17.dev2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
32
- dissect.hypervisor-3.17.dev2.dist-info/entry_points.txt,sha256=oM21bFD0YBHKjgCBk-DQ2398PUZdKV2VNR_IWzd1yog,76
33
- dissect.hypervisor-3.17.dev2.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
34
- dissect.hypervisor-3.17.dev2.dist-info/RECORD,,
28
+ dissect/hypervisor/util/vmtar.py,sha256=xzc4bd5RnBgP9_dCU9i-ZwXI_0S3N7gCfMzElwwnd5s,4004
29
+ dissect_hypervisor-3.18.dev1.dist-info/licenses/COPYRIGHT,sha256=EOOoIwk_inOMUD4c1ylpzMtYLjGzmc-MLEVAEdLLr20,305
30
+ dissect_hypervisor-3.18.dev1.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
31
+ dissect_hypervisor-3.18.dev1.dist-info/METADATA,sha256=I1eM8mXEJRNMCt4RfSLZQ1-FU730qvKO5xV6pqcw1WI,3434
32
+ dissect_hypervisor-3.18.dev1.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
33
+ dissect_hypervisor-3.18.dev1.dist-info/entry_points.txt,sha256=kW36GnJ3G1dSRYFL4r8Bj32Al_CkGqST3bdHvo3pyiY,120
34
+ dissect_hypervisor-3.18.dev1.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
35
+ dissect_hypervisor-3.18.dev1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (80.7.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  envelope-decrypt = dissect.hypervisor.tools.envelope:main
3
+ vmtar = dissect.hypervisor.tools.vmtar:main