From 12fb20126bcdd88a82633f86c0ad2ab9c7947221 Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Sun, 9 Apr 2023 22:24:03 +0200 Subject: [PATCH] Add support for Parallels PVS --- dissect/hypervisor/__init__.py | 3 ++- dissect/hypervisor/descriptor/pvs.py | 25 +++++++++++++++++++++++++ dissect/hypervisor/descriptor/vbox.py | 14 ++++++++++---- tests/test_pvs.py | 20 ++++++++++++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 dissect/hypervisor/descriptor/pvs.py create mode 100644 tests/test_pvs.py diff --git a/dissect/hypervisor/__init__.py b/dissect/hypervisor/__init__.py index 1ad7286..0da1051 100644 --- a/dissect/hypervisor/__init__.py +++ b/dissect/hypervisor/__init__.py @@ -1,5 +1,5 @@ from dissect.hypervisor.backup import vma, wim, xva -from dissect.hypervisor.descriptor import hyperv, ovf, vbox, vmx +from dissect.hypervisor.descriptor import hyperv, ovf, pvs, vbox, vmx from dissect.hypervisor.disk import hdd, qcow2, vdi, vhd, vhdx, vmdk from dissect.hypervisor.util import envelope, vmtar @@ -8,6 +8,7 @@ "hdd", "hyperv", "ovf", + "pvs", "qcow2", "vbox", "vdi", diff --git a/dissect/hypervisor/descriptor/pvs.py b/dissect/hypervisor/descriptor/pvs.py new file mode 100644 index 0000000..23c4a40 --- /dev/null +++ b/dissect/hypervisor/descriptor/pvs.py @@ -0,0 +1,25 @@ +from typing import IO, Iterator +from xml.etree.ElementTree import Element + +try: + from defusedxml import ElementTree +except ImportError: + from xml.etree import ElementTree + + +class PVS: + """Parallels VM settings file. + + Args: + fh: The file-like object to a PVS file. + """ + + def __init__(self, fh: IO): + self._xml: Element = ElementTree.fromstring(fh.read()) + + def disks(self) -> Iterator[str]: + """Yield the disk file names.""" + for hdd_elem in self._xml.iterfind(".//Hdd"): + system_name = hdd_elem.find("SystemName") + if system_name is not None: + yield system_name.text diff --git a/dissect/hypervisor/descriptor/vbox.py b/dissect/hypervisor/descriptor/vbox.py index 16b3a93..1dc1779 100644 --- a/dissect/hypervisor/descriptor/vbox.py +++ b/dissect/hypervisor/descriptor/vbox.py @@ -1,13 +1,19 @@ -from xml.etree import ElementTree +from typing import IO, Iterator +from xml.etree.ElementTree import Element + +try: + from defusedxml import ElementTree +except ImportError: + from xml.etree import ElementTree class VBox: VBOX_XML_NAMESPACE = "{http://www.virtualbox.org/}" - def __init__(self, fh): - self._xml = ElementTree.fromstring(fh.read()) + def __init__(self, fh: IO): + self._xml: Element = ElementTree.fromstring(fh.read()) - def disks(self): + def disks(self) -> Iterator[str]: for hdd_elem in self._xml.findall( f".//{self.VBOX_XML_NAMESPACE}HardDisk[@location][@format='VDI'][@type='Normal']" ): diff --git a/tests/test_pvs.py b/tests/test_pvs.py new file mode 100644 index 0000000..2bec592 --- /dev/null +++ b/tests/test_pvs.py @@ -0,0 +1,20 @@ +from io import StringIO + +from dissect.hypervisor.descriptor.pvs import PVS + + +def test_pvs(): + xml = """ + + + + + Fedora-0.hdd + + + + """ # noqa: E501 + + with StringIO(xml.strip()) as fh: + pvs = PVS(fh) + assert next(pvs.disks()) == "Fedora-0.hdd"