VirtualBox

source: vbox/trunk/src/VBox/Main/include/ApplianceImplPrivate.h@ 107519

Last change on this file since 107519 was 107519, checked in by vboxsync, 3 weeks ago

src/VBox/Main/include/ApplianceImplPrivate.h: Fixed warning found by Parfait (uninitialized attributes). jiraref:VBP-1424

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.2 KB
Line 
1/* $Id: ApplianceImplPrivate.h 107519 2025-01-08 14:44:40Z vboxsync $ */
2/** @file
3 * VirtualBox Appliance private data definitions
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef MAIN_INCLUDED_ApplianceImplPrivate_h
29#define MAIN_INCLUDED_ApplianceImplPrivate_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34
35class VirtualSystemDescription;
36
37#include "ovfreader.h"
38#include "SecretKeyStore.h"
39#include "ThreadTask.h"
40#include "CertificateImpl.h"
41#include <map>
42#include <vector>
43#include <iprt/manifest.h>
44#include <iprt/vfs.h>
45#include <iprt/crypto/x509.h>
46#include <iprt/crypto/pkcs7.h>
47
48////////////////////////////////////////////////////////////////////////////////
49//
50// Appliance data definition
51//
52////////////////////////////////////////////////////////////////////////////////
53
54namespace settings
55{
56 struct AttachedDevice;
57}
58
59typedef std::pair<Utf8Str, Utf8Str> STRPAIR;
60
61typedef std::vector<com::Guid> GUIDVEC;
62
63/* Describe a location for the import/export. The location could be a file on a
64 * local hard disk or a remote target based on the supported inet protocols. */
65struct LocationInfo
66{
67 LocationInfo()
68 : storageType(VFSType_File) {}
69 VFSType_T storageType; /* Which type of storage should be handled */
70 Utf8Str strProvider; /* cloud provider name in case of export/import to Cloud */
71 Utf8Str strPath; /* File path for the import/export */
72 Utf8Str strHostname; /* Hostname on remote storage locations (could be empty) */
73 Utf8Str strUsername; /* Username on remote storage locations (could be empty) */
74 Utf8Str strPassword; /* Password on remote storage locations (could be empty) */
75};
76
77/**
78 * opaque private instance data of Appliance class
79 */
80struct Appliance::Data
81{
82 enum digest_T {SHA1, SHA256};
83
84 /** @todo r=andy Make up your mind if naming attributes with a m_ prefix or not. */
85 Data()
86 : state(Appliance::ApplianceIdle)
87 , fDigestTypes(0)
88 , hOurManifest(NIL_RTMANIFEST)
89 , fManifest(true)
90 , fDeterminedDigestTypes(false)
91 , hTheirManifest(NIL_RTMANIFEST)
92 , hMemFileTheirManifest(NIL_RTVFSFILE)
93 , fSignerCertLoaded(false)
94 , fCertificateIsSelfSigned(false)
95 , fSignatureValid(false)
96 , fCertificateValid(false)
97 , fCertificateMissingPath(true)
98 , fCertificateValidTime(false)
99 , pbSignedDigest(NULL)
100 , cbSignedDigest(0)
101 , enmSignedDigestType(RTDIGESTTYPE_INVALID)
102 , fContentInfoLoaded(false)
103 , fContentInfoOkay(false)
104 , fContentInfoSameCert(false)
105 , fContentInfoValidSignature(false)
106 , fContentInfoDoneVerification(false)
107 , fContentInfoVerifiedOkay(false)
108 , fExportISOImages(false)
109 , pReader(NULL)
110 , ulWeightForXmlOperation(0)
111 , ulWeightForManifestOperation(0)
112 , ulTotalDisksMB(0)
113 , cDisks(0)
114 , m_pSecretKeyStore(NULL)
115 , m_cPwProvided(0)
116 {
117 RT_ZERO(SignerCert);
118 RT_ZERO(ContentInfo);
119 }
120
121 ~Data()
122 {
123 if (pReader)
124 {
125 delete pReader;
126 pReader = NULL;
127 }
128 resetReadData();
129 }
130
131 /**
132 * Resets data used by read.
133 */
134 void resetReadData(void)
135 {
136 strOvfManifestEntry.setNull();
137 if (hOurManifest != NIL_RTMANIFEST)
138 {
139 RTManifestRelease(hOurManifest);
140 hOurManifest = NIL_RTMANIFEST;
141 }
142 if (hTheirManifest != NIL_RTMANIFEST)
143 {
144 RTManifestRelease(hTheirManifest);
145 hTheirManifest = NIL_RTMANIFEST;
146 }
147 if (hMemFileTheirManifest)
148 {
149 RTVfsFileRelease(hMemFileTheirManifest);
150 hMemFileTheirManifest = NIL_RTVFSFILE;
151 }
152 if (pbSignedDigest)
153 {
154 RTMemFree(pbSignedDigest);
155 pbSignedDigest = NULL;
156 cbSignedDigest = 0;
157 }
158 if (fSignerCertLoaded)
159 {
160 RTCrX509Certificate_Delete(&SignerCert);
161 fSignerCertLoaded = false;
162 }
163 RT_ZERO(SignerCert);
164 enmSignedDigestType = RTDIGESTTYPE_INVALID;
165 fCertificateIsSelfSigned = false;
166 fSignatureValid = false;
167 fCertificateValid = false;
168 fCertificateMissingPath = true;
169 fCertificateValidTime = false;
170 fDeterminedDigestTypes = false;
171 fDigestTypes = RTMANIFEST_ATTR_SHA1 | RTMANIFEST_ATTR_SHA256 | RTMANIFEST_ATTR_SHA512;
172 ptrCertificateInfo.setNull();
173 strCertError.setNull();
174 if (fContentInfoLoaded)
175 {
176 RTCrPkcs7ContentInfo_Delete(&ContentInfo);
177 fContentInfoLoaded = false;
178 }
179 RT_ZERO(ContentInfo);
180 }
181
182 Appliance::ApplianceState state;
183
184 LocationInfo locInfo; // location info for the currently processed OVF
185 /** The digests types to calculate (RTMANIFEST_ATTR_XXX) for the manifest.
186 * This will be a single value when exporting. Zero, one or two. */
187 uint32_t fDigestTypes;
188 /** Manifest created while importing or exporting. */
189 RTMANIFEST hOurManifest;
190
191 /** @name Write data
192 * @{ */
193 bool fManifest; // Create a manifest file on export
194 /** @} */
195
196 /** @name Read data
197 * @{ */
198 /** The manifest entry name of the OVF-file. */
199 Utf8Str strOvfManifestEntry;
200
201 /** Set if we've parsed the manifest and determined the digest types. */
202 bool fDeterminedDigestTypes;
203
204 /** Manifest read in during read() and kept around for later verification. */
205 RTMANIFEST hTheirManifest;
206 /** Memorized copy of the manifest file for signature checking purposes. */
207 RTVFSFILE hMemFileTheirManifest;
208
209 /** The signer certificate from the signature file (.cert).
210 * This will be used in the future provide information about the signer via
211 * the API. */
212 RTCRX509CERTIFICATE SignerCert;
213 /** Set if the SignerCert member contains usable data. */
214 bool fSignerCertLoaded;
215 /** Cached RTCrX509Validity_IsValidAtTimeSpec result set by read(). */
216 bool fCertificateIsSelfSigned;
217 /** Set by read() if pbSignedDigest verified correctly against SignerCert. */
218 bool fSignatureValid;
219 /** Set by read() when the SignerCert checked out fine. */
220 bool fCertificateValid;
221 /** Set by read() when the SignerCert certificate path couldn't be built. */
222 bool fCertificateMissingPath;
223 /** Set by read() when the SignerCert (+path) is valid in the temporal sense. */
224 bool fCertificateValidTime;
225 /** For keeping certificate error messages we delay from read() to import(). */
226 Utf8Str strCertError;
227 /** The signed digest of the manifest. */
228 uint8_t *pbSignedDigest;
229 /** The size of the signed digest. */
230 size_t cbSignedDigest;
231 /** The digest type used to sign the manifest. */
232 RTDIGESTTYPE enmSignedDigestType;
233 /** The certificate info object. This is NULL if no signature and
234 * successfully loaded certificate. */
235 ComObjPtr<Certificate> ptrCertificateInfo;
236
237 /** The PKCS\#7/CMS signed data signing manifest, optional VBox extension.
238 * This contains at least one signature using the same certificate as above
239 * (SignerCert), but should preferrably use a different digest. The PKCS\#7/CMS
240 * format is a lot more versatile, allow multiple signatures using different
241 * digests and certificates, optionally with counter signed timestamps.
242 * Additional intermediate certificates can also be shipped, helping to bridge
243 * the gap to a trusted root certificate installed on the recieving system. */
244 RTCRPKCS7CONTENTINFO ContentInfo;
245 /** Set if the ContentInfo member contains usable data. */
246 bool fContentInfoLoaded;
247 /** Set by read() if the ContentInfo member checked out okay (says nothing about
248 * the signature or certificates within it). */
249 bool fContentInfoOkay;
250 /** Set by read() if the ContentInfo member is using the SignerCert too. */
251 bool fContentInfoSameCert;
252 /** Set by read() if the ContentInfo member contains valid signatures (not
253 * saying anything about valid signing certificates). */
254 bool fContentInfoValidSignature;
255 /** Set by read() if we've already verified the signed data signature(s). */
256 bool fContentInfoDoneVerification;
257
258 bool fContentInfoVerifiedOkay;
259 /** @} */
260
261 bool fExportISOImages;// when 1 the ISO images are exported
262
263 RTCList<ImportOptions_T> optListImport;
264 RTCList<ExportOptions_T> optListExport;
265
266 ovf::OVFReader *pReader;
267
268 std::list< ComObjPtr<VirtualSystemDescription> >
269 virtualSystemDescriptions;
270
271 std::list<Utf8Str> llWarnings;
272
273 ULONG ulWeightForXmlOperation;
274 ULONG ulWeightForManifestOperation;
275 ULONG ulTotalDisksMB;
276 ULONG cDisks;
277
278 std::list<Guid> llGuidsMachinesCreated;
279
280 /** Sequence of password identifiers to encrypt disk images during export. */
281 std::vector<com::Utf8Str> m_vecPasswordIdentifiers;
282 /** Map to get all medium identifiers assoicated with a given password identifier. */
283 std::map<com::Utf8Str, GUIDVEC> m_mapPwIdToMediumIds;
284 /** Secret key store used to hold the passwords during export. */
285 SecretKeyStore *m_pSecretKeyStore;
286 /** Number of passwords provided. */
287 uint32_t m_cPwProvided;
288};
289
290struct Appliance::XMLStack
291{
292 std::map<Utf8Str, const VirtualSystemDescriptionEntry*> mapDisks;
293 std::list<Utf8Str> mapDiskSequence;
294 std::list<Utf8Str> mapDiskSequenceForOneVM;//temporary keeps all disks attached to one exported VM
295 std::map<Utf8Str, bool> mapNetworks;
296};
297
298class Appliance::TaskOVF : public ThreadTask
299{
300public:
301 enum TaskType
302 {
303 Read,
304 Import,
305 Write
306 };
307
308 TaskOVF(Appliance *aThat,
309 TaskType aType,
310 LocationInfo aLocInfo,
311 ComObjPtr<Progress> &aProgress)
312 : ThreadTask("TaskOVF")
313 , pAppliance(aThat)
314 , taskType(aType)
315 , locInfo(aLocInfo)
316 , pProgress(aProgress)
317 , enFormat(ovf::OVFVersion_unknown)
318 , hrc(S_OK)
319 {
320 switch (taskType)
321 {
322 case TaskOVF::Read: m_strTaskName = "ApplRead"; break;
323 case TaskOVF::Import: m_strTaskName = "ApplImp"; break;
324 case TaskOVF::Write: m_strTaskName = "ApplWrit"; break;
325 default: m_strTaskName = "ApplTask"; break;
326 }
327 }
328
329 static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
330
331 Appliance *pAppliance;
332 TaskType taskType;
333 const LocationInfo locInfo;
334 ComObjPtr<Progress> pProgress;
335
336 ovf::OVFVersion_T enFormat;
337
338 HRESULT hrc;
339
340 void handler()
341 {
342 Appliance::i_importOrExportThreadTask(this);
343 }
344};
345
346class Appliance::TaskOPC : public ThreadTask
347{
348public:
349 enum TaskType
350 {
351 Export
352 };
353
354 TaskOPC(Appliance *aThat,
355 TaskType aType,
356 LocationInfo aLocInfo,
357 ComObjPtr<Progress> &aProgress)
358 : ThreadTask("TaskOPC")
359 , pAppliance(aThat)
360 , taskType(aType)
361 , locInfo(aLocInfo)
362 , pProgress(aProgress)
363 , hrc(S_OK)
364 {
365 m_strTaskName = "OPCExpt";
366 }
367
368 ~TaskOPC()
369 {
370 }
371
372 static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
373
374 Appliance *pAppliance;
375 TaskType taskType;
376 const LocationInfo locInfo;
377 ComObjPtr<Progress> pProgress;
378
379 HRESULT hrc;
380
381 void handler()
382 {
383 Appliance::i_exportOPCThreadTask(this);
384 }
385};
386
387
388class Appliance::TaskCloud : public ThreadTask
389{
390public:
391 enum TaskType
392 {
393 Export,
394 Import,
395 ReadData
396 };
397
398 TaskCloud(Appliance *aThat,
399 TaskType aType,
400 LocationInfo aLocInfo,
401 ComObjPtr<Progress> &aProgress)
402 : ThreadTask("TaskCloud")
403 , pAppliance(aThat)
404 , taskType(aType)
405 , locInfo(aLocInfo)
406 , pProgress(aProgress)
407 , hrc(S_OK)
408 {
409 switch (taskType)
410 {
411 case TaskCloud::Export: m_strTaskName = "CloudExpt"; break;
412 case TaskCloud::Import: m_strTaskName = "CloudImpt"; break;
413 case TaskCloud::ReadData: m_strTaskName = "CloudRead"; break;
414 default: m_strTaskName = "CloudTask"; break;
415 }
416 }
417
418 ~TaskCloud()
419 {
420 }
421
422 static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
423
424 Appliance *pAppliance;
425 TaskType taskType;
426 const LocationInfo locInfo;
427 ComObjPtr<Progress> pProgress;
428
429 HRESULT hrc;
430
431 void handler()
432 {
433 Appliance::i_importOrExportCloudThreadTask(this);
434 }
435};
436
437struct MyHardDiskAttachment
438{
439 ComPtr<IMachine> pMachine;
440 Utf8Str controllerName;
441 int32_t lControllerPort; // 0-29 for SATA
442 int32_t lDevice; // IDE: 0 or 1, otherwise 0 always
443};
444
445/**
446 * Used by Appliance::importMachineGeneric() to store
447 * input parameters and rollback information.
448 */
449struct Appliance::ImportStack
450{
451 // input pointers
452 const LocationInfo &locInfo; // ptr to location info from Appliance::importFS()
453 Utf8Str strSourceDir; // directory where source files reside
454 const ovf::DiskImagesMap &mapDisks; // ptr to disks map in OVF
455 ComObjPtr<Progress> &pProgress; // progress object passed into Appliance::importFS()
456
457 // input parameters from VirtualSystemDescriptions
458 Utf8Str strNameVBox; // VM name
459 Utf8Str strSettingsFilename; // Absolute path to VM config file
460 Utf8Str strMachineFolder; // Absolute path to VM folder (derived from strSettingsFilename)
461 Utf8Str strOsTypeVBox; // VirtualBox guest OS type as string
462 Utf8Str strPrimaryGroup; // VM primary group as string
463 Utf8Str strDescription;
464 uint32_t cCPUs; // CPU count
465 bool fForceHWVirt; // if true, we force enabling hardware virtualization
466 bool fForceIOAPIC; // if true, we force enabling the IOAPIC
467 uint32_t ulMemorySizeMB; // virtual machine RAM in megabytes
468 Utf8Str strFirmwareType; //Firmware - BIOS or EFI
469#ifdef VBOX_WITH_USB
470 bool fUSBEnabled;
471#endif
472 Utf8Str strAudioAdapter; // if not empty, then the guest has audio enabled, and this is the decimal
473 // representation of the audio adapter (should always be "0" for AC97 presently)
474
475 // session (not initially created)
476 ComPtr<ISession> pSession; // session opened in Appliance::importFS() for machine manipulation
477 bool fSessionOpen; // true if the pSession is currently open and needs closing
478
479 /** @name File access related stuff (TAR stream)
480 * @{ */
481 /** OVA file system stream handle. NIL if not OVA. */
482 RTVFSFSSTREAM hVfsFssOva;
483 /** OVA lookahead I/O stream object. */
484 RTVFSIOSTREAM hVfsIosOvaLookAhead;
485 /** OVA lookahead I/O stream object name. */
486 char *pszOvaLookAheadName;
487 /** @} */
488
489 // a list of images that we created/imported; this is initially empty
490 // and will be cleaned up on errors
491 std::list<MyHardDiskAttachment> llHardDiskAttachments; // disks that were attached
492 std::map<Utf8Str, Utf8Str> mapNewUUIDsToOriginalUUIDs;
493
494 ImportStack(const LocationInfo &aLocInfo,
495 const ovf::DiskImagesMap &aMapDisks,
496 ComObjPtr<Progress> &aProgress,
497 RTVFSFSSTREAM aVfsFssOva)
498 : locInfo(aLocInfo),
499 mapDisks(aMapDisks),
500 pProgress(aProgress),
501 cCPUs(1),
502 fForceHWVirt(false),
503 fForceIOAPIC(false),
504 ulMemorySizeMB(0),
505#ifdef VBOX_WITH_USB
506 fUSBEnabled(false),
507#endif
508 fSessionOpen(false),
509 hVfsFssOva(aVfsFssOva),
510 hVfsIosOvaLookAhead(NIL_RTVFSIOSTREAM),
511 pszOvaLookAheadName(NULL)
512 {
513 if (hVfsFssOva != NIL_RTVFSFSSTREAM)
514 RTVfsFsStrmRetain(hVfsFssOva);
515
516 // disk images have to be on the same place as the OVF file. So
517 // strip the filename out of the full file path
518 strSourceDir = aLocInfo.strPath;
519 strSourceDir.stripFilename();
520 }
521
522 ~ImportStack()
523 {
524 if (hVfsFssOva != NIL_RTVFSFSSTREAM)
525 {
526 RTVfsFsStrmRelease(hVfsFssOva);
527 hVfsFssOva = NIL_RTVFSFSSTREAM;
528 }
529 if (hVfsIosOvaLookAhead != NIL_RTVFSIOSTREAM)
530 {
531 RTVfsIoStrmRelease(hVfsIosOvaLookAhead);
532 hVfsIosOvaLookAhead = NIL_RTVFSIOSTREAM;
533 }
534 if (pszOvaLookAheadName)
535 {
536 RTStrFree(pszOvaLookAheadName);
537 pszOvaLookAheadName = NULL;
538 }
539 }
540
541 HRESULT restoreOriginalUUIDOfAttachedDevice(settings::MachineConfigFile *config);
542 HRESULT saveOriginalUUIDOfAttachedDevice(settings::AttachedDevice &device, const Utf8Str &newlyUuid);
543 RTVFSIOSTREAM claimOvaLookAHead(void);
544};
545
546////////////////////////////////////////////////////////////////////////////////
547//
548// VirtualSystemDescription data definition
549//
550////////////////////////////////////////////////////////////////////////////////
551
552struct VirtualSystemDescription::Data
553{
554 /** item descriptions */
555 std::vector<VirtualSystemDescriptionEntry> maDescriptions;
556
557 /** VirtualBox machine this description was exported from (export only) */
558 ComPtr<Machine> pMachine;
559
560 /** machine config created from <vbox:Machine> element if found (import only) */
561 settings::MachineConfigFile *pConfig;
562};
563
564////////////////////////////////////////////////////////////////////////////////
565//
566// Internal helpers
567//
568////////////////////////////////////////////////////////////////////////////////
569
570void convertCIMOSType2VBoxOSType(Utf8Str &strType, ovf::CIMOSType_T c, const Utf8Str &cStr);
571
572ovf::CIMOSType_T convertVBoxOSType2CIMOSType(const char *pcszVBox, BOOL fLongMode);
573
574Utf8Str convertNetworkAttachmentTypeToString(NetworkAttachmentType_T type);
575
576
577#endif /* !MAIN_INCLUDED_ApplianceImplPrivate_h */
578
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette