summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/include/ApplianceImplPrivate.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Main/include/ApplianceImplPrivate.h
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Main/include/ApplianceImplPrivate.h')
-rw-r--r--src/VBox/Main/include/ApplianceImplPrivate.h571
1 files changed, 571 insertions, 0 deletions
diff --git a/src/VBox/Main/include/ApplianceImplPrivate.h b/src/VBox/Main/include/ApplianceImplPrivate.h
new file mode 100644
index 00000000..87712811
--- /dev/null
+++ b/src/VBox/Main/include/ApplianceImplPrivate.h
@@ -0,0 +1,571 @@
+/* $Id: ApplianceImplPrivate.h $ */
+/** @file
+ * VirtualBox Appliance private data definitions
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ApplianceImplPrivate_h
+#define MAIN_INCLUDED_ApplianceImplPrivate_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+
+class VirtualSystemDescription;
+
+#include "ovfreader.h"
+#include "SecretKeyStore.h"
+#include "ThreadTask.h"
+#include "CertificateImpl.h"
+#include <map>
+#include <vector>
+#include <iprt/manifest.h>
+#include <iprt/vfs.h>
+#include <iprt/crypto/x509.h>
+#include <iprt/crypto/pkcs7.h>
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Appliance data definition
+//
+////////////////////////////////////////////////////////////////////////////////
+
+namespace settings
+{
+ struct AttachedDevice;
+}
+
+typedef std::pair<Utf8Str, Utf8Str> STRPAIR;
+
+typedef std::vector<com::Guid> GUIDVEC;
+
+/* Describe a location for the import/export. The location could be a file on a
+ * local hard disk or a remote target based on the supported inet protocols. */
+struct LocationInfo
+{
+ LocationInfo()
+ : storageType(VFSType_File) {}
+ VFSType_T storageType; /* Which type of storage should be handled */
+ Utf8Str strProvider; /* cloud provider name in case of export/import to Cloud */
+ Utf8Str strPath; /* File path for the import/export */
+ Utf8Str strHostname; /* Hostname on remote storage locations (could be empty) */
+ Utf8Str strUsername; /* Username on remote storage locations (could be empty) */
+ Utf8Str strPassword; /* Password on remote storage locations (could be empty) */
+};
+
+/**
+ * opaque private instance data of Appliance class
+ */
+struct Appliance::Data
+{
+ enum digest_T {SHA1, SHA256};
+
+ Data()
+ : state(Appliance::ApplianceIdle)
+ , fDigestTypes(0)
+ , hOurManifest(NIL_RTMANIFEST)
+ , fManifest(true)
+ , fDeterminedDigestTypes(false)
+ , hTheirManifest(NIL_RTMANIFEST)
+ , hMemFileTheirManifest(NIL_RTVFSFILE)
+ , fSignerCertLoaded(false)
+ , fCertificateIsSelfSigned(false)
+ , fSignatureValid(false)
+ , fCertificateValid(false)
+ , fCertificateMissingPath(true)
+ , fCertificateValidTime(false)
+ , pbSignedDigest(NULL)
+ , cbSignedDigest(0)
+ , enmSignedDigestType(RTDIGESTTYPE_INVALID)
+ , fContentInfoLoaded(false)
+ , fContentInfoOkay(false)
+ , fContentInfoSameCert(false)
+ , fContentInfoValidSignature(false)
+ , fExportISOImages(false)
+ , pReader(NULL)
+ , ulWeightForXmlOperation(0)
+ , ulWeightForManifestOperation(0)
+ , ulTotalDisksMB(0)
+ , cDisks(0)
+ , m_cPwProvided(0)
+ {
+ RT_ZERO(SignerCert);
+ RT_ZERO(ContentInfo);
+ }
+
+ ~Data()
+ {
+ if (pReader)
+ {
+ delete pReader;
+ pReader = NULL;
+ }
+ resetReadData();
+ }
+
+ /**
+ * Resets data used by read.
+ */
+ void resetReadData(void)
+ {
+ strOvfManifestEntry.setNull();
+ if (hOurManifest != NIL_RTMANIFEST)
+ {
+ RTManifestRelease(hOurManifest);
+ hOurManifest = NIL_RTMANIFEST;
+ }
+ if (hTheirManifest != NIL_RTMANIFEST)
+ {
+ RTManifestRelease(hTheirManifest);
+ hTheirManifest = NIL_RTMANIFEST;
+ }
+ if (hMemFileTheirManifest)
+ {
+ RTVfsFileRelease(hMemFileTheirManifest);
+ hMemFileTheirManifest = NIL_RTVFSFILE;
+ }
+ if (pbSignedDigest)
+ {
+ RTMemFree(pbSignedDigest);
+ pbSignedDigest = NULL;
+ cbSignedDigest = 0;
+ }
+ if (fSignerCertLoaded)
+ {
+ RTCrX509Certificate_Delete(&SignerCert);
+ fSignerCertLoaded = false;
+ }
+ RT_ZERO(SignerCert);
+ enmSignedDigestType = RTDIGESTTYPE_INVALID;
+ fCertificateIsSelfSigned = false;
+ fSignatureValid = false;
+ fCertificateValid = false;
+ fCertificateMissingPath = true;
+ fCertificateValidTime = false;
+ fDeterminedDigestTypes = false;
+ fDigestTypes = RTMANIFEST_ATTR_SHA1 | RTMANIFEST_ATTR_SHA256 | RTMANIFEST_ATTR_SHA512;
+ ptrCertificateInfo.setNull();
+ strCertError.setNull();
+ if (fContentInfoLoaded)
+ {
+ RTCrPkcs7ContentInfo_Delete(&ContentInfo);
+ fContentInfoLoaded = false;
+ }
+ RT_ZERO(ContentInfo);
+ }
+
+ Appliance::ApplianceState state;
+
+ LocationInfo locInfo; // location info for the currently processed OVF
+ /** The digests types to calculate (RTMANIFEST_ATTR_XXX) for the manifest.
+ * This will be a single value when exporting. Zero, one or two. */
+ uint32_t fDigestTypes;
+ /** Manifest created while importing or exporting. */
+ RTMANIFEST hOurManifest;
+
+ /** @name Write data
+ * @{ */
+ bool fManifest; // Create a manifest file on export
+ /** @} */
+
+ /** @name Read data
+ * @{ */
+ /** The manifest entry name of the OVF-file. */
+ Utf8Str strOvfManifestEntry;
+
+ /** Set if we've parsed the manifest and determined the digest types. */
+ bool fDeterminedDigestTypes;
+
+ /** Manifest read in during read() and kept around for later verification. */
+ RTMANIFEST hTheirManifest;
+ /** Memorized copy of the manifest file for signature checking purposes. */
+ RTVFSFILE hMemFileTheirManifest;
+
+ /** The signer certificate from the signature file (.cert).
+ * This will be used in the future provide information about the signer via
+ * the API. */
+ RTCRX509CERTIFICATE SignerCert;
+ /** Set if the SignerCert member contains usable data. */
+ bool fSignerCertLoaded;
+ /** Cached RTCrX509Validity_IsValidAtTimeSpec result set by read(). */
+ bool fCertificateIsSelfSigned;
+ /** Set by read() if pbSignedDigest verified correctly against SignerCert. */
+ bool fSignatureValid;
+ /** Set by read() when the SignerCert checked out fine. */
+ bool fCertificateValid;
+ /** Set by read() when the SignerCert certificate path couldn't be built. */
+ bool fCertificateMissingPath;
+ /** Set by read() when the SignerCert (+path) is valid in the temporal sense. */
+ bool fCertificateValidTime;
+ /** For keeping certificate error messages we delay from read() to import(). */
+ Utf8Str strCertError;
+ /** The signed digest of the manifest. */
+ uint8_t *pbSignedDigest;
+ /** The size of the signed digest. */
+ size_t cbSignedDigest;
+ /** The digest type used to sign the manifest. */
+ RTDIGESTTYPE enmSignedDigestType;
+ /** The certificate info object. This is NULL if no signature and
+ * successfully loaded certificate. */
+ ComObjPtr<Certificate> ptrCertificateInfo;
+
+ /** The PKCS\#7/CMS signed data signing manifest, optional VBox extension.
+ * This contains at least one signature using the same certificate as above
+ * (SignerCert), but should preferrably use a different digest. The PKCS\#7/CMS
+ * format is a lot more versatile, allow multiple signatures using different
+ * digests and certificates, optionally with counter signed timestamps.
+ * Additional intermediate certificates can also be shipped, helping to bridge
+ * the gap to a trusted root certificate installed on the recieving system. */
+ RTCRPKCS7CONTENTINFO ContentInfo;
+ /** Set if the ContentInfo member contains usable data. */
+ bool fContentInfoLoaded;
+ /** Set by read() if the ContentInfo member checked out okay (says nothing about
+ * the signature or certificates within it). */
+ bool fContentInfoOkay;
+ /** Set by read() if the ContentInfo member is using the SignerCert too. */
+ bool fContentInfoSameCert;
+ /** Set by read() if the ContentInfo member contains valid signatures (not
+ * saying anything about valid signing certificates). */
+ bool fContentInfoValidSignature;
+ /** Set by read() if we've already verified the signed data signature(s). */
+ bool fContentInfoDoneVerification;
+
+ bool fContentInfoVerifiedOkay;
+ /** @} */
+
+ bool fExportISOImages;// when 1 the ISO images are exported
+
+ RTCList<ImportOptions_T> optListImport;
+ RTCList<ExportOptions_T> optListExport;
+
+ ovf::OVFReader *pReader;
+
+ std::list< ComObjPtr<VirtualSystemDescription> >
+ virtualSystemDescriptions;
+
+ std::list<Utf8Str> llWarnings;
+
+ ULONG ulWeightForXmlOperation;
+ ULONG ulWeightForManifestOperation;
+ ULONG ulTotalDisksMB;
+ ULONG cDisks;
+
+ std::list<Guid> llGuidsMachinesCreated;
+
+ /** Sequence of password identifiers to encrypt disk images during export. */
+ std::vector<com::Utf8Str> m_vecPasswordIdentifiers;
+ /** Map to get all medium identifiers assoicated with a given password identifier. */
+ std::map<com::Utf8Str, GUIDVEC> m_mapPwIdToMediumIds;
+ /** Secret key store used to hold the passwords during export. */
+ SecretKeyStore *m_pSecretKeyStore;
+ /** Number of passwords provided. */
+ uint32_t m_cPwProvided;
+};
+
+struct Appliance::XMLStack
+{
+ std::map<Utf8Str, const VirtualSystemDescriptionEntry*> mapDisks;
+ std::list<Utf8Str> mapDiskSequence;
+ std::list<Utf8Str> mapDiskSequenceForOneVM;//temporary keeps all disks attached to one exported VM
+ std::map<Utf8Str, bool> mapNetworks;
+};
+
+class Appliance::TaskOVF : public ThreadTask
+{
+public:
+ enum TaskType
+ {
+ Read,
+ Import,
+ Write
+ };
+
+ TaskOVF(Appliance *aThat,
+ TaskType aType,
+ LocationInfo aLocInfo,
+ ComObjPtr<Progress> &aProgress)
+ : ThreadTask("TaskOVF")
+ , pAppliance(aThat)
+ , taskType(aType)
+ , locInfo(aLocInfo)
+ , pProgress(aProgress)
+ , enFormat(ovf::OVFVersion_unknown)
+ , hrc(S_OK)
+ {
+ switch (taskType)
+ {
+ case TaskOVF::Read: m_strTaskName = "ApplRead"; break;
+ case TaskOVF::Import: m_strTaskName = "ApplImp"; break;
+ case TaskOVF::Write: m_strTaskName = "ApplWrit"; break;
+ default: m_strTaskName = "ApplTask"; break;
+ }
+ }
+
+ static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
+
+ Appliance *pAppliance;
+ TaskType taskType;
+ const LocationInfo locInfo;
+ ComObjPtr<Progress> pProgress;
+
+ ovf::OVFVersion_T enFormat;
+
+ HRESULT hrc;
+
+ void handler()
+ {
+ Appliance::i_importOrExportThreadTask(this);
+ }
+};
+
+class Appliance::TaskOPC : public ThreadTask
+{
+public:
+ enum TaskType
+ {
+ Export
+ };
+
+ TaskOPC(Appliance *aThat,
+ TaskType aType,
+ LocationInfo aLocInfo,
+ ComObjPtr<Progress> &aProgress)
+ : ThreadTask("TaskOPC")
+ , pAppliance(aThat)
+ , taskType(aType)
+ , locInfo(aLocInfo)
+ , pProgress(aProgress)
+ , hrc(S_OK)
+ {
+ m_strTaskName = "OPCExpt";
+ }
+
+ ~TaskOPC()
+ {
+ }
+
+ static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
+
+ Appliance *pAppliance;
+ TaskType taskType;
+ const LocationInfo locInfo;
+ ComObjPtr<Progress> pProgress;
+
+ HRESULT hrc;
+
+ void handler()
+ {
+ Appliance::i_exportOPCThreadTask(this);
+ }
+};
+
+
+class Appliance::TaskCloud : public ThreadTask
+{
+public:
+ enum TaskType
+ {
+ Export,
+ Import,
+ ReadData
+ };
+
+ TaskCloud(Appliance *aThat,
+ TaskType aType,
+ LocationInfo aLocInfo,
+ ComObjPtr<Progress> &aProgress)
+ : ThreadTask("TaskCloud")
+ , pAppliance(aThat)
+ , taskType(aType)
+ , locInfo(aLocInfo)
+ , pProgress(aProgress)
+ , hrc(S_OK)
+ {
+ switch (taskType)
+ {
+ case TaskCloud::Export: m_strTaskName = "CloudExpt"; break;
+ case TaskCloud::Import: m_strTaskName = "CloudImpt"; break;
+ case TaskCloud::ReadData: m_strTaskName = "CloudRead"; break;
+ default: m_strTaskName = "CloudTask"; break;
+ }
+ }
+
+ ~TaskCloud()
+ {
+ }
+
+ static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
+
+ Appliance *pAppliance;
+ TaskType taskType;
+ const LocationInfo locInfo;
+ ComObjPtr<Progress> pProgress;
+
+ HRESULT hrc;
+
+ void handler()
+ {
+ Appliance::i_importOrExportCloudThreadTask(this);
+ }
+};
+
+struct MyHardDiskAttachment
+{
+ ComPtr<IMachine> pMachine;
+ Utf8Str controllerName;
+ int32_t lControllerPort; // 0-29 for SATA
+ int32_t lDevice; // IDE: 0 or 1, otherwise 0 always
+};
+
+/**
+ * Used by Appliance::importMachineGeneric() to store
+ * input parameters and rollback information.
+ */
+struct Appliance::ImportStack
+{
+ // input pointers
+ const LocationInfo &locInfo; // ptr to location info from Appliance::importFS()
+ Utf8Str strSourceDir; // directory where source files reside
+ const ovf::DiskImagesMap &mapDisks; // ptr to disks map in OVF
+ ComObjPtr<Progress> &pProgress; // progress object passed into Appliance::importFS()
+
+ // input parameters from VirtualSystemDescriptions
+ Utf8Str strNameVBox; // VM name
+ Utf8Str strSettingsFilename; // Absolute path to VM config file
+ Utf8Str strMachineFolder; // Absolute path to VM folder (derived from strSettingsFilename)
+ Utf8Str strOsTypeVBox; // VirtualBox guest OS type as string
+ Utf8Str strPrimaryGroup; // VM primary group as string
+ Utf8Str strDescription;
+ uint32_t cCPUs; // CPU count
+ bool fForceHWVirt; // if true, we force enabling hardware virtualization
+ bool fForceIOAPIC; // if true, we force enabling the IOAPIC
+ uint32_t ulMemorySizeMB; // virtual machine RAM in megabytes
+ Utf8Str strFirmwareType; //Firmware - BIOS or EFI
+#ifdef VBOX_WITH_USB
+ bool fUSBEnabled;
+#endif
+ Utf8Str strAudioAdapter; // if not empty, then the guest has audio enabled, and this is the decimal
+ // representation of the audio adapter (should always be "0" for AC97 presently)
+
+ // session (not initially created)
+ ComPtr<ISession> pSession; // session opened in Appliance::importFS() for machine manipulation
+ bool fSessionOpen; // true if the pSession is currently open and needs closing
+
+ /** @name File access related stuff (TAR stream)
+ * @{ */
+ /** OVA file system stream handle. NIL if not OVA. */
+ RTVFSFSSTREAM hVfsFssOva;
+ /** OVA lookahead I/O stream object. */
+ RTVFSIOSTREAM hVfsIosOvaLookAhead;
+ /** OVA lookahead I/O stream object name. */
+ char *pszOvaLookAheadName;
+ /** @} */
+
+ // a list of images that we created/imported; this is initially empty
+ // and will be cleaned up on errors
+ std::list<MyHardDiskAttachment> llHardDiskAttachments; // disks that were attached
+ std::map<Utf8Str, Utf8Str> mapNewUUIDsToOriginalUUIDs;
+
+ ImportStack(const LocationInfo &aLocInfo,
+ const ovf::DiskImagesMap &aMapDisks,
+ ComObjPtr<Progress> &aProgress,
+ RTVFSFSSTREAM aVfsFssOva)
+ : locInfo(aLocInfo),
+ mapDisks(aMapDisks),
+ pProgress(aProgress),
+ cCPUs(1),
+ fForceHWVirt(false),
+ fForceIOAPIC(false),
+ ulMemorySizeMB(0),
+ fSessionOpen(false),
+ hVfsFssOva(aVfsFssOva),
+ hVfsIosOvaLookAhead(NIL_RTVFSIOSTREAM),
+ pszOvaLookAheadName(NULL)
+ {
+ if (hVfsFssOva != NIL_RTVFSFSSTREAM)
+ RTVfsFsStrmRetain(hVfsFssOva);
+
+ // disk images have to be on the same place as the OVF file. So
+ // strip the filename out of the full file path
+ strSourceDir = aLocInfo.strPath;
+ strSourceDir.stripFilename();
+ }
+
+ ~ImportStack()
+ {
+ if (hVfsFssOva != NIL_RTVFSFSSTREAM)
+ {
+ RTVfsFsStrmRelease(hVfsFssOva);
+ hVfsFssOva = NIL_RTVFSFSSTREAM;
+ }
+ if (hVfsIosOvaLookAhead != NIL_RTVFSIOSTREAM)
+ {
+ RTVfsIoStrmRelease(hVfsIosOvaLookAhead);
+ hVfsIosOvaLookAhead = NIL_RTVFSIOSTREAM;
+ }
+ if (pszOvaLookAheadName)
+ {
+ RTStrFree(pszOvaLookAheadName);
+ pszOvaLookAheadName = NULL;
+ }
+ }
+
+ HRESULT restoreOriginalUUIDOfAttachedDevice(settings::MachineConfigFile *config);
+ HRESULT saveOriginalUUIDOfAttachedDevice(settings::AttachedDevice &device, const Utf8Str &newlyUuid);
+ RTVFSIOSTREAM claimOvaLookAHead(void);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// VirtualSystemDescription data definition
+//
+////////////////////////////////////////////////////////////////////////////////
+
+struct VirtualSystemDescription::Data
+{
+ /** item descriptions */
+ std::vector<VirtualSystemDescriptionEntry> maDescriptions;
+
+ /** VirtualBox machine this description was exported from (export only) */
+ ComPtr<Machine> pMachine;
+
+ /** machine config created from <vbox:Machine> element if found (import only) */
+ settings::MachineConfigFile *pConfig;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Internal helpers
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void convertCIMOSType2VBoxOSType(Utf8Str &strType, ovf::CIMOSType_T c, const Utf8Str &cStr);
+
+ovf::CIMOSType_T convertVBoxOSType2CIMOSType(const char *pcszVBox, BOOL fLongMode);
+
+Utf8Str convertNetworkAttachmentTypeToString(NetworkAttachmentType_T type);
+
+
+#endif /* !MAIN_INCLUDED_ApplianceImplPrivate_h */
+