VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/TrustedPlatformModuleImpl.cpp@ 91581

Last change on this file since 91581 was 91213, checked in by vboxsync, 3 years ago

Main,FE/VBoxManage: Add the necessary Main API bits to control the trusted platform module settings as well as implementing support in VBoxManage, bugref:10075

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1/* $Id: TrustedPlatformModuleImpl.cpp 91213 2021-09-10 17:58:08Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - Machine Trusted Platform Module settings.
4 */
5
6/*
7 * Copyright (C) 2021 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#define LOG_GROUP LOG_GROUP_MAIN_TRUSTEDPLATFORMMODULE
19#include "TrustedPlatformModuleImpl.h"
20#include "MachineImpl.h"
21
22#include <iprt/cpp/utils.h>
23#include <VBox/settings.h>
24
25#include "AutoStateDep.h"
26#include "AutoCaller.h"
27#include "LoggingNew.h"
28
29
30////////////////////////////////////////////////////////////////////////////////
31//
32// TrustedPlatformModule private data definition
33//
34////////////////////////////////////////////////////////////////////////////////
35
36struct TrustedPlatformModule::Data
37{
38 Data()
39 : pMachine(NULL)
40 { }
41
42 Machine * const pMachine;
43 ComObjPtr<TrustedPlatformModule> pPeer;
44
45 // use the XML settings structure in the members for simplicity
46 Backupable<settings::TpmSettings> bd;
47};
48
49// constructor / destructor
50/////////////////////////////////////////////////////////////////////////////
51
52DEFINE_EMPTY_CTOR_DTOR(TrustedPlatformModule)
53
54HRESULT TrustedPlatformModule::FinalConstruct()
55{
56 return BaseFinalConstruct();
57}
58
59void TrustedPlatformModule::FinalRelease()
60{
61 uninit();
62 BaseFinalRelease();
63}
64
65// public initializer/uninitializer for internal purposes only
66/////////////////////////////////////////////////////////////////////////////
67
68/**
69 * Initializes the BIOS settings object.
70 *
71 * @returns COM result indicator
72 */
73HRESULT TrustedPlatformModule::init(Machine *aParent)
74{
75 LogFlowThisFuncEnter();
76 LogFlowThisFunc(("aParent: %p\n", aParent));
77
78 ComAssertRet(aParent, E_INVALIDARG);
79
80 /* Enclose the state transition NotReady->InInit->Ready */
81 AutoInitSpan autoInitSpan(this);
82 AssertReturn(autoInitSpan.isOk(), E_FAIL);
83
84 m = new Data();
85
86 /* share the parent weakly */
87 unconst(m->pMachine) = aParent;
88
89 m->bd.allocate();
90
91 autoInitSpan.setSucceeded();
92
93 LogFlowThisFuncLeave();
94 return S_OK;
95}
96
97/**
98 * Initializes the Trusted Platform Module settings object given another Trusted Platform Module settings object
99 * (a kind of copy constructor). This object shares data with
100 * the object passed as an argument.
101 *
102 * @note This object must be destroyed before the original object
103 * it shares data with is destroyed.
104 */
105HRESULT TrustedPlatformModule::init(Machine *aParent, TrustedPlatformModule *that)
106{
107 LogFlowThisFuncEnter();
108 LogFlowThisFunc(("aParent: %p, that: %p\n", aParent, that));
109
110 ComAssertRet(aParent && that, E_INVALIDARG);
111
112 /* Enclose the state transition NotReady->InInit->Ready */
113 AutoInitSpan autoInitSpan(this);
114 AssertReturn(autoInitSpan.isOk(), E_FAIL);
115
116 m = new Data();
117
118 unconst(m->pMachine) = aParent;
119 m->pPeer = that;
120
121 AutoWriteLock thatlock(that COMMA_LOCKVAL_SRC_POS);
122 m->bd.share(that->m->bd);
123
124 autoInitSpan.setSucceeded();
125
126 LogFlowThisFuncLeave();
127 return S_OK;
128}
129
130/**
131 * Initializes the guest object given another guest object
132 * (a kind of copy constructor). This object makes a private copy of data
133 * of the original object passed as an argument.
134 */
135HRESULT TrustedPlatformModule::initCopy(Machine *aParent, TrustedPlatformModule *that)
136{
137 LogFlowThisFuncEnter();
138 LogFlowThisFunc(("aParent: %p, that: %p\n", aParent, that));
139
140 ComAssertRet(aParent && that, E_INVALIDARG);
141
142 /* Enclose the state transition NotReady->InInit->Ready */
143 AutoInitSpan autoInitSpan(this);
144 AssertReturn(autoInitSpan.isOk(), E_FAIL);
145
146 m = new Data();
147
148 unconst(m->pMachine) = aParent;
149 // mPeer is left null
150
151 AutoWriteLock thatlock(that COMMA_LOCKVAL_SRC_POS);
152 m->bd.attachCopy(that->m->bd);
153
154 autoInitSpan.setSucceeded();
155
156 LogFlowThisFuncLeave();
157 return S_OK;
158}
159
160/**
161 * Uninitializes the instance and sets the ready flag to FALSE.
162 * Called either from FinalRelease() or by the parent when it gets destroyed.
163 */
164void TrustedPlatformModule::uninit()
165{
166 LogFlowThisFuncEnter();
167
168 /* Enclose the state transition Ready->InUninit->NotReady */
169 AutoUninitSpan autoUninitSpan(this);
170 if (autoUninitSpan.uninitDone())
171 return;
172
173 m->bd.free();
174
175 unconst(m->pPeer) = NULL;
176 unconst(m->pMachine) = NULL;
177
178 delete m;
179 m = NULL;
180
181 LogFlowThisFuncLeave();
182}
183
184// ITrustedPlatformModule properties
185/////////////////////////////////////////////////////////////////////////////
186
187
188HRESULT TrustedPlatformModule::getType(TpmType_T *aType)
189{
190 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
191
192 *aType = m->bd->tpmType;
193
194 return S_OK;
195}
196
197HRESULT TrustedPlatformModule::setType(TpmType_T aType)
198{
199 /* the machine needs to be mutable */
200 AutoMutableStateDependency adep(m->pMachine);
201 if (FAILED(adep.rc())) return adep.rc();
202
203 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
204
205 m->bd.backup();
206 m->bd->tpmType = aType;
207
208 alock.release();
209 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
210 m->pMachine->i_setModified(Machine::IsModified_TrustedPlatformModule);
211
212 return S_OK;
213}
214
215HRESULT TrustedPlatformModule::getLocation(com::Utf8Str &location)
216{
217 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
218
219 location = m->bd->strLocation;
220 return S_OK;
221}
222
223HRESULT TrustedPlatformModule::setLocation(const com::Utf8Str &location)
224{
225 /* the machine needs to be mutable */
226 AutoMutableStateDependency adep(m->pMachine);
227 if (FAILED(adep.rc())) return adep.rc();
228
229 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
230
231 m->bd.backup();
232 m->bd->strLocation = location;
233
234 alock.release();
235 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
236 m->pMachine->i_setModified(Machine::IsModified_TrustedPlatformModule);
237
238 return S_OK;
239}
240
241
242// ITrustedPlatformModule methods
243/////////////////////////////////////////////////////////////////////////////
244
245// public methods only for internal purposes
246/////////////////////////////////////////////////////////////////////////////
247
248/**
249 * Loads settings from the given machine node.
250 * May be called once right after this object creation.
251 *
252 * @param data Configuration settings.
253 *
254 * @note Locks this object for writing.
255 */
256HRESULT TrustedPlatformModule::i_loadSettings(const settings::TpmSettings &data)
257{
258 AutoCaller autoCaller(this);
259 AssertComRCReturnRC(autoCaller.rc());
260
261 AutoReadLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
262 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
263
264 // simply copy
265 m->bd.assignCopy(&data);
266 return S_OK;
267}
268
269/**
270 * Saves settings to the given machine node.
271 *
272 * @param data Configuration settings.
273 *
274 * @note Locks this object for reading.
275 */
276HRESULT TrustedPlatformModule::i_saveSettings(settings::TpmSettings &data)
277{
278 AutoCaller autoCaller(this);
279 AssertComRCReturnRC(autoCaller.rc());
280
281 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
282
283 data = *m->bd.data();
284
285 return S_OK;
286}
287
288void TrustedPlatformModule::i_rollback()
289{
290 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
291 m->bd.rollback();
292}
293
294void TrustedPlatformModule::i_commit()
295{
296 /* sanity */
297 AutoCaller autoCaller(this);
298 AssertComRCReturnVoid(autoCaller.rc());
299
300 /* sanity too */
301 AutoCaller peerCaller(m->pPeer);
302 AssertComRCReturnVoid(peerCaller.rc());
303
304 /* lock both for writing since we modify both (mPeer is "master" so locked
305 * first) */
306 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
307
308 if (m->bd.isBackedUp())
309 {
310 m->bd.commit();
311 if (m->pPeer)
312 {
313 /* attach new data to the peer and reshare it */
314 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS);
315 m->pPeer->m->bd.attach(m->bd);
316 }
317 }
318}
319
320void TrustedPlatformModule::i_copyFrom(TrustedPlatformModule *aThat)
321{
322 AssertReturnVoid(aThat != NULL);
323
324 /* sanity */
325 AutoCaller autoCaller(this);
326 AssertComRCReturnVoid(autoCaller.rc());
327
328 /* sanity too */
329 AutoCaller thatCaller(aThat);
330 AssertComRCReturnVoid(thatCaller.rc());
331
332 /* peer is not modified, lock it for reading (aThat is "master" so locked
333 * first) */
334 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
335 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
336
337 /* this will back up current data */
338 m->bd.assignCopy(aThat->m->bd);
339}
340
341/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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