Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dissect/hypervisor/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from dissect.hypervisor.descriptor import hyperv, ovf, pvs, vbox, vmx
from dissect.hypervisor.disk import asif, hdd, qcow2, vdi, vhd, vhdx, vmdk
from dissect.hypervisor.util import envelope, vmtar
Expand Down
8 changes: 1 addition & 7 deletions dissect/hypervisor/descriptor/vmx.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def unlock_with_phrase(self, passphrase: str) -> None:
self.attr.update(**_parse_dictionary(decrypted.decode()))

def disks(self) -> list[str]:
"""Return a list of paths to disk files"""
"""Return a list of paths to disk files."""
dev_classes = ("scsi", "sata", "ide", "nvme")
devices = {}

Expand Down Expand Up @@ -179,7 +179,6 @@ def unseal_with_phrase(self, passphrase: str) -> bytes:
@classmethod
def from_text(cls, text: str) -> KeySafe:
"""Parse a ``KeySafe`` from a string."""

# Key safes are a list of key locators. It's a key locator string with a specific prefix
identifier, _, remainder = text.partition("/")
if identifier != "vmware:key":
Expand Down Expand Up @@ -262,7 +261,6 @@ def _parse_key_locator(locator_string: str) -> Pair | Phrase | list[Pair | Phras

Interally called ``KeyLocator``.
"""

identifier, _, remainder = locator_string.partition("/")

if identifier == "list":
Expand Down Expand Up @@ -303,7 +301,6 @@ def _split_list(value: str) -> list[str]:
Lists are wrapped by braces and separated by comma. They can contain nested lists/pairs,
so we need to separate at the correct nest level.
"""

if not (match := re.match(r"\((.+)\)", value)):
raise ValueError("Invalid list string")

Expand Down Expand Up @@ -337,7 +334,6 @@ def _parse_crypto_dict(dict_string: str) -> dict[str, str]:

Internally called ``CryptoDict``.
"""

crypto_dict = {}
for part in dict_string.split(":"):
key, _, value = part.partition("=")
Expand All @@ -351,7 +347,6 @@ def _decrypt_hmac(key: bytes, data: bytes, digest: str) -> bytes:
First 16 bytes of the ciphertext are the IV and the last N bytes are the HMAC digest.
The cleartext is padded using PKCS#7.
"""

digest, digest_size = HMAC_MAP[digest]

iv, encrypted, mac = data[:16], data[16:-digest_size], data[-digest_size:]
Expand All @@ -374,7 +369,6 @@ def _create_cipher(key: bytes, iv: bytes) -> AES.CbcMode:

Dynamic based on the available crypto module.
"""

if HAS_PYSTANDALONE:
if len(key) == 32:
cipher = "aes-256-cbc"
Expand Down
5 changes: 1 addition & 4 deletions dissect/hypervisor/disk/vmdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@

class VMDK(AlignedStream):
def __init__(self, fh: BinaryIO | Path | str | list[BinaryIO | Path | str]):
"""
Input can be a file handle to a Disk Descriptor file or a list of file handles to multiple VMDK files.
"""
"""Input can be a file handle to a Disk Descriptor file or a list of file handles to multiple VMDK files."""
fhs = [fh] if not isinstance(fh, list) else fh

self.disks = []
Expand Down Expand Up @@ -462,7 +460,6 @@ def parse(cls, vmdk_config: str) -> DiskDescriptor:
Resources:
- https://github.com/libyal/libvmdk/blob/main/documentation/VMWare%20Virtual%20Disk%20Format%20(VMDK).asciidoc
"""

descriptor_settings = {}
extents: list[ExtentDescriptor] = []
disk_db = {}
Expand Down
3 changes: 3 additions & 0 deletions dissect/hypervisor/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from __future__ import annotations


class Error(Exception):
pass

Expand Down
2 changes: 2 additions & 0 deletions dissect/hypervisor/tools/vmtar.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import tarfile

from dissect.hypervisor.util import vmtar
Expand Down
4 changes: 2 additions & 2 deletions dissect/hypervisor/util/vmtar.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ def visoropen(cls, name: str, mode: str = "r", fileobj: BinaryIO | None = None,
raise tarfile.TarError("visor currently only supports read mode")

try:
from gzip import GzipFile # noqa: PLC0415
from gzip import GzipFile
except ImportError:
raise tarfile.CompressionError("gzip module is not available") from None

try:
from lzma import LZMAError, LZMAFile # noqa: PLC0415
from lzma import LZMAError, LZMAFile
except ImportError:
raise tarfile.CompressionError("lzma module is not available") from None

Expand Down
22 changes: 20 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,33 @@ select = [
"SLOT",
"SIM",
"TID",
"TCH",
"TC",
"PTH",
"PLC",
"TRY",
"FLY",
"PERF",
"FURB",
"RUF",
"D"
]
ignore = ["E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM105", "TRY003"]
ignore = [
"E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM105", "TRY003", "PLC0415",
# Ignore some pydocstyle rules for now as they require a larger cleanup
"D1",
"D205",
"D301",
"D417",
# Seems bugged: https://github.com/astral-sh/ruff/issues/16824
"D402",
]
future-annotations = true

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.ruff.lint.flake8-type-checking]
strict = true

[tool.ruff.lint.per-file-ignores]
"tests/_docs/**" = ["INP001"]
Expand All @@ -123,6 +140,7 @@ ignore = ["E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM1
[tool.ruff.lint.isort]
known-first-party = ["dissect.hypervisor"]
known-third-party = ["dissect"]
required-imports = ["from __future__ import annotations"]

[tool.setuptools.packages.find]
include = ["dissect.*"]
Expand Down
2 changes: 2 additions & 0 deletions tests/_docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

project = "dissect.hypervisor"

extensions = [
Expand Down
3 changes: 1 addition & 2 deletions tests/disk/test_vmdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,11 @@ def test_vmdk_sesparse() -> None:
),
)
def test_vmdk_extent_description(extent_description: str, expected_extents: list[ExtentDescriptor]) -> None:
"""test if we correctly parse VMDK sparse and flat extent descriptions.
"""Test if we correctly parse VMDK sparse and flat extent descriptions.

Resources:
- https://github.com/libyal/libvmdk/blob/main/documentation/VMWare%20Virtual%20Disk%20Format%20(VMDK).asciidoc#22-extent-descriptions
"""

descriptor = DiskDescriptor.parse(extent_description)
assert descriptor.extents == expected_extents

Expand Down
Loading