Changeset 67237 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jun 2, 2017 12:21:06 PM (8 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/MediumImpl.h
r67231 r67237 368 368 const uint8_t *pbDek, size_t cbDek); 369 369 370 struct CryptoFilterSettings; 371 HRESULT i_openHddForReading(SecretKeyStore *pKeyStore, PVDISK *ppHdd, MediumLockList *pMediumLockList, 372 struct CryptoFilterSettings *pCryptoSettingsRead); 373 370 374 class Task; 371 375 class CreateBaseTask; … … 408 412 HRESULT i_taskEncryptHandler(Medium::EncryptTask &task); 409 413 410 struct CryptoFilterSettings;411 414 void i_taskEncryptSettingsSetup(CryptoFilterSettings *pSettings, const char *pszCipher, 412 415 const char *pszKeyStore, const char *pszPassword, -
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r67234 r67237 6112 6112 AutoCaller autoCaller(this); 6113 6113 HRESULT hrc = autoCaller.rc(); 6114 if (FAILED(hrc))6115 return hrc;6116 6117 /*6118 * Build the source lock list and lock the images.6119 */6120 MediumLockList SourceMediumLockList;6121 hrc = i_createMediumLockList(true /* fFailIfInaccessible */,6122 NULL /* pToLockWrite */,6123 false /* fMediumLockWriteAll */,6124 NULL,6125 SourceMediumLockList);6126 6114 if (SUCCEEDED(hrc)) 6127 hrc = SourceMediumLockList.Lock();6128 if (FAILED(hrc))6129 return hrc;6130 6131 try6132 6115 { 6133 6116 /* 6134 * Lock all in {parent,child} order.6117 * Get a readonly hdd for this medium. 6135 6118 */ 6136 ComObjPtr<Medium> pBase = i_getBase(); 6137 AutoWriteLock thisLock(this COMMA_LOCKVAL_SRC_POS); 6138 6139 PVDISK hdd; 6140 int vrc = VDCreate(m->vdDiskIfaces, i_convertDeviceType(), &hdd); 6141 ComAssertRCThrow(vrc, E_FAIL); 6142 6143 try 6144 { 6145 settings::StringsMap::iterator itKeyStore = pBase->m->mapProperties.find("CRYPT/KeyStore"); 6146 if (itKeyStore != pBase->m->mapProperties.end()) 6147 { 6148 settings::StringsMap::iterator itKeyId = pBase->m->mapProperties.find("CRYPT/KeyId"); 6149 6150 #ifdef VBOX_WITH_EXTPACK 6151 ExtPackManager *pExtPackManager = m->pVirtualBox->i_getExtPackManager(); 6152 if (pExtPackManager->i_isExtPackUsable(ORACLE_PUEL_EXTPACK_NAME)) 6153 { 6154 /* Load the plugin */ 6155 Utf8Str strPlugin; 6156 hrc = pExtPackManager->i_getLibraryPathForExtPack(g_szVDPlugin, ORACLE_PUEL_EXTPACK_NAME, &strPlugin); 6157 if (SUCCEEDED(hrc)) 6158 { 6159 vrc = VDPluginLoadFromFilename(strPlugin.c_str()); 6160 if (RT_FAILURE(vrc)) 6161 throw setError(VBOX_E_NOT_SUPPORTED, 6162 tr("Retrieving encryption settings of the image failed because the encryption plugin could not be loaded (%s)"), 6163 i_vdError(vrc).c_str()); 6164 } 6165 else 6166 throw setError(VBOX_E_NOT_SUPPORTED, 6167 tr("Encryption is not supported because the extension pack '%s' is missing the encryption plugin (old extension pack installed?)"), 6168 ORACLE_PUEL_EXTPACK_NAME); 6169 } 6170 else 6171 throw setError(VBOX_E_NOT_SUPPORTED, 6172 tr("Encryption is not supported because the extension pack '%s' is missing"), 6173 ORACLE_PUEL_EXTPACK_NAME); 6174 #else 6175 throw setError(VBOX_E_NOT_SUPPORTED, 6176 tr("Encryption is not supported because extension pack support is not built in")); 6177 #endif 6178 6179 if (itKeyId == pBase->m->mapProperties.end()) 6180 throw setError(VBOX_E_INVALID_OBJECT_STATE, 6181 tr("Image '%s' is configured for encryption but doesn't has a key identifier set"), 6182 pBase->m->strLocationFull.c_str()); 6183 6184 /* Find the proper secret key in the key store. */ 6185 if (!pKeyStore) 6186 throw setError(VBOX_E_INVALID_OBJECT_STATE, 6187 tr("Image '%s' is configured for encryption but there is no key store to retrieve the password from"), 6188 pBase->m->strLocationFull.c_str()); 6189 6190 SecretKey *pKey = NULL; 6191 vrc = pKeyStore->retainSecretKey(itKeyId->second, &pKey); 6192 if (RT_FAILURE(vrc)) 6193 throw setError(VBOX_E_INVALID_OBJECT_STATE, 6194 tr("Failed to retrieve the secret key with ID \"%s\" from the store (%Rrc)"), 6195 itKeyId->second.c_str(), vrc); 6196 6197 Medium::CryptoFilterSettings CryptoSettingsRead; 6198 i_taskEncryptSettingsSetup(&CryptoSettingsRead, NULL, itKeyStore->second.c_str(), (const char *)pKey->getKeyBuffer(), 6199 false /* fCreateKeyStore */); 6200 vrc = VDFilterAdd(hdd, "CRYPT", VD_FILTER_FLAGS_READ, CryptoSettingsRead.vdFilterIfaces); 6201 pKeyStore->releaseSecretKey(itKeyId->second); 6202 if (vrc == VERR_VD_PASSWORD_INCORRECT) 6203 throw setError(VBOX_E_PASSWORD_INCORRECT, tr("The password to decrypt the image is incorrect")); 6204 if (RT_FAILURE(vrc)) 6205 throw setError(VBOX_E_INVALID_OBJECT_STATE, tr("Failed to load the decryption filter: %s"), 6206 i_vdError(vrc).c_str()); 6207 } 6208 6209 /* Open all media in the source chain. */ 6210 MediumLockList::Base::const_iterator sourceListBegin = SourceMediumLockList.GetBegin(); 6211 MediumLockList::Base::const_iterator sourceListEnd = SourceMediumLockList.GetEnd(); 6212 for (MediumLockList::Base::const_iterator it = sourceListBegin; it != sourceListEnd; ++it) 6213 { 6214 const MediumLock &mediumLock = *it; 6215 const ComObjPtr<Medium> &pMedium = mediumLock.GetMedium(); 6216 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 6217 6218 /* sanity check */ 6219 Assert(pMedium->m->state == MediumState_LockedRead); 6220 6221 /* Open all media in read-only mode. */ 6222 vrc = VDOpen(hdd, 6223 pMedium->m->strFormat.c_str(), 6224 pMedium->m->strLocationFull.c_str(), 6225 VD_OPEN_FLAGS_READONLY | m->uOpenFlagsDef, 6226 pMedium->m->vdImageIfaces); 6227 if (RT_FAILURE(vrc)) 6228 throw setError(VBOX_E_FILE_ERROR, 6229 tr("Could not open the medium storage unit '%s'%s"), 6230 pMedium->m->strLocationFull.c_str(), 6231 i_vdError(vrc).c_str()); 6232 } 6233 6234 Assert(m->state == MediumState_LockedRead); 6235 6236 /* unlock before the potentially lengthy operation */ 6237 thisLock.release(); 6238 6119 Medium::CryptoFilterSettings CryptoSettingsRead; 6120 MediumLockList SourceMediumLockList; 6121 PVDISK pHdd; 6122 hrc = i_openHddForReading(pKeyStore, &pHdd, &SourceMediumLockList, &CryptoSettingsRead); 6123 if (SUCCEEDED(hrc)) 6124 { 6239 6125 /* 6240 6126 * Create a VFS file interface to the HDD and attach a progress wrapper … … 6243 6129 */ 6244 6130 RTVFSFILE hVfsFileDisk = NIL_RTVFSFILE; 6245 vrc = VDCreateVfsFileFromDisk(hdd, 0 /*fFlags*/, &hVfsFileDisk);6131 int vrc = VDCreateVfsFileFromDisk(pHdd, 0 /*fFlags*/, &hVfsFileDisk); 6246 6132 if (RT_SUCCESS(vrc)) 6247 6133 { … … 6249 6135 vrc = RTVfsCreateProgressForFile(hVfsFileDisk, aProgress->i_iprtProgressCallback, &*aProgress, 6250 6136 RTVFSPROGRESS_F_CANCELABLE | RTVFSPROGRESS_F_FORWARD_SEEK_AS_READ, 6251 VDGetSize( hdd, VD_LAST_IMAGE) * (fSparse ? 2 : 1) /*cbExpectedRead*/,6137 VDGetSize(pHdd, VD_LAST_IMAGE) * (fSparse ? 2 : 1) /*cbExpectedRead*/, 6252 6138 0 /*cbExpectedWritten*/, &hVfsFileProgress); 6253 6139 RTVfsFileRelease(hVfsFileDisk); … … 6268 6154 else 6269 6155 hrc = setErrorBoth(VBOX_E_FILE_ERROR, vrc, tr("VDCreateVfsFileFromDisk failed for '%s' (%Rrc)"), aFilename, vrc); 6270 } 6271 catch (HRESULT hrc3) { hrc = hrc3; } 6272 6273 VDDestroy(hdd); 6274 } 6275 catch (HRESULT hrc2) { hrc = hrc2; } 6276 6156 VDDestroy(pHdd); 6157 } 6158 } 6277 6159 return hrc; 6278 6160 } … … 6310 6192 { 6311 6193 AssertPtrReturn(aFilename, E_INVALIDARG); 6312 AssertReturn( !aFormat.isNull(), E_INVALIDARG);6313 AssertReturn( !aProgress.isNull(), E_INVALIDARG);6194 AssertReturn(aFormat.isNotNull(), E_INVALIDARG); 6195 AssertReturn(aProgress.isNotNull(), E_INVALIDARG); 6314 6196 6315 6197 AutoCaller autoCaller(this); … … 8068 7950 8069 7951 return pSettings->pszCipherReturned ? VINF_SUCCESS : VERR_NO_MEMORY; 7952 } 7953 7954 /** 7955 * Creates a read-only VDISK instance for this medium. 7956 * 7957 * @note Caller should not hold any medium related locks as this method will 7958 * acquire the medium lock for writing and others (VirtualBox). 7959 * 7960 * @returns COM status code. 7961 * @param pKeyStore The key store. 7962 * @param ppHdd Where to return the pointer to the VDISK on 7963 * success. 7964 * @param pMediumLockList The lock list to populate and lock. Caller 7965 * is responsible for calling the destructor or 7966 * MediumLockList::Clear() after destroying 7967 * @a *ppHdd 7968 * @param pCryptoSettingsRead The crypto read settings to use for setting 7969 * up decryption of the VDISK. This object 7970 * must be alive until the VDISK is destroyed! 7971 */ 7972 HRESULT Medium::i_openHddForReading(SecretKeyStore *pKeyStore, PVDISK *ppHdd, MediumLockList *pMediumLockList, 7973 Medium::CryptoFilterSettings *pCryptoSettingsRead) 7974 { 7975 /* 7976 * Create the media lock list and lock the media. 7977 */ 7978 HRESULT hrc = i_createMediumLockList(true /* fFailIfInaccessible */, 7979 NULL /* pToLockWrite */, 7980 false /* fMediumLockWriteAll */, 7981 NULL, 7982 *pMediumLockList); 7983 if (SUCCEEDED(hrc)) 7984 hrc = pMediumLockList->Lock(); 7985 if (FAILED(hrc)) 7986 return hrc; 7987 7988 /* 7989 * Get the base medium before write locking this medium. 7990 */ 7991 ComObjPtr<Medium> pBase = i_getBase(); 7992 AutoWriteLock thisLock(this COMMA_LOCKVAL_SRC_POS); 7993 7994 /* 7995 * Create the VDISK instance. 7996 */ 7997 PVDISK pHdd; 7998 int vrc = VDCreate(m->vdDiskIfaces, i_convertDeviceType(), &pHdd); 7999 AssertRCReturn(vrc, E_FAIL); 8000 8001 /* 8002 * Goto avoidance using try/catch/throw(HRESULT). 8003 */ 8004 try 8005 { 8006 settings::StringsMap::iterator itKeyStore = pBase->m->mapProperties.find("CRYPT/KeyStore"); 8007 if (itKeyStore != pBase->m->mapProperties.end()) 8008 { 8009 settings::StringsMap::iterator itKeyId = pBase->m->mapProperties.find("CRYPT/KeyId"); 8010 8011 #ifdef VBOX_WITH_EXTPACK 8012 ExtPackManager *pExtPackManager = m->pVirtualBox->i_getExtPackManager(); 8013 if (pExtPackManager->i_isExtPackUsable(ORACLE_PUEL_EXTPACK_NAME)) 8014 { 8015 /* Load the plugin */ 8016 Utf8Str strPlugin; 8017 hrc = pExtPackManager->i_getLibraryPathForExtPack(g_szVDPlugin, ORACLE_PUEL_EXTPACK_NAME, &strPlugin); 8018 if (SUCCEEDED(hrc)) 8019 { 8020 vrc = VDPluginLoadFromFilename(strPlugin.c_str()); 8021 if (RT_FAILURE(vrc)) 8022 throw setError(VBOX_E_NOT_SUPPORTED, 8023 tr("Retrieving encryption settings of the image failed because the encryption plugin could not be loaded (%s)"), 8024 i_vdError(vrc).c_str()); 8025 } 8026 else 8027 throw setError(VBOX_E_NOT_SUPPORTED, 8028 tr("Encryption is not supported because the extension pack '%s' is missing the encryption plugin (old extension pack installed?)"), 8029 ORACLE_PUEL_EXTPACK_NAME); 8030 } 8031 else 8032 throw setError(VBOX_E_NOT_SUPPORTED, 8033 tr("Encryption is not supported because the extension pack '%s' is missing"), 8034 ORACLE_PUEL_EXTPACK_NAME); 8035 #else 8036 throw setError(VBOX_E_NOT_SUPPORTED, 8037 tr("Encryption is not supported because extension pack support is not built in")); 8038 #endif 8039 8040 if (itKeyId == pBase->m->mapProperties.end()) 8041 throw setError(VBOX_E_INVALID_OBJECT_STATE, 8042 tr("Image '%s' is configured for encryption but doesn't has a key identifier set"), 8043 pBase->m->strLocationFull.c_str()); 8044 8045 /* Find the proper secret key in the key store. */ 8046 if (!pKeyStore) 8047 throw setError(VBOX_E_INVALID_OBJECT_STATE, 8048 tr("Image '%s' is configured for encryption but there is no key store to retrieve the password from"), 8049 pBase->m->strLocationFull.c_str()); 8050 8051 SecretKey *pKey = NULL; 8052 vrc = pKeyStore->retainSecretKey(itKeyId->second, &pKey); 8053 if (RT_FAILURE(vrc)) 8054 throw setError(VBOX_E_INVALID_OBJECT_STATE, 8055 tr("Failed to retrieve the secret key with ID \"%s\" from the store (%Rrc)"), 8056 itKeyId->second.c_str(), vrc); 8057 8058 i_taskEncryptSettingsSetup(pCryptoSettingsRead, NULL, itKeyStore->second.c_str(), (const char *)pKey->getKeyBuffer(), 8059 false /* fCreateKeyStore */); 8060 vrc = VDFilterAdd(pHdd, "CRYPT", VD_FILTER_FLAGS_READ, pCryptoSettingsRead->vdFilterIfaces); 8061 pKeyStore->releaseSecretKey(itKeyId->second); 8062 if (vrc == VERR_VD_PASSWORD_INCORRECT) 8063 throw setError(VBOX_E_PASSWORD_INCORRECT, tr("The password to decrypt the image is incorrect")); 8064 if (RT_FAILURE(vrc)) 8065 throw setError(VBOX_E_INVALID_OBJECT_STATE, tr("Failed to load the decryption filter: %s"), 8066 i_vdError(vrc).c_str()); 8067 } 8068 8069 /* 8070 * Open all media in the source chain. 8071 */ 8072 MediumLockList::Base::const_iterator sourceListBegin = pMediumLockList->GetBegin(); 8073 MediumLockList::Base::const_iterator sourceListEnd = pMediumLockList->GetEnd(); 8074 for (MediumLockList::Base::const_iterator it = sourceListBegin; it != sourceListEnd; ++it) 8075 { 8076 const MediumLock &mediumLock = *it; 8077 const ComObjPtr<Medium> &pMedium = mediumLock.GetMedium(); 8078 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 8079 8080 /* sanity check */ 8081 Assert(pMedium->m->state == MediumState_LockedRead); 8082 8083 /* Open all media in read-only mode. */ 8084 vrc = VDOpen(pHdd, 8085 pMedium->m->strFormat.c_str(), 8086 pMedium->m->strLocationFull.c_str(), 8087 VD_OPEN_FLAGS_READONLY | m->uOpenFlagsDef, 8088 pMedium->m->vdImageIfaces); 8089 if (RT_FAILURE(vrc)) 8090 throw setError(VBOX_E_FILE_ERROR, 8091 tr("Could not open the medium storage unit '%s'%s"), 8092 pMedium->m->strLocationFull.c_str(), 8093 i_vdError(vrc).c_str()); 8094 } 8095 8096 Assert(m->state == MediumState_LockedRead); 8097 8098 /* 8099 * Done! 8100 */ 8101 *ppHdd = pHdd; 8102 return S_OK; 8103 } 8104 catch (HRESULT hrc2) 8105 { 8106 hrc = hrc2; 8107 } 8108 8109 VDDestroy(pHdd); 8110 return hrc; 8111 8070 8112 } 8071 8113 … … 9745 9787 itKeyId->second.c_str(), vrc); 9746 9788 9789 /** @todo r=bird: Someone explain why this continue to work when 9790 * CryptoSettingsRead goes out of the scope? */ 9747 9791 Medium::CryptoFilterSettings CryptoSettingsRead; 9748 9792 i_taskEncryptSettingsSetup(&CryptoSettingsRead, NULL, itKeyStore->second.c_str(), (const char *)pKey->getKeyBuffer(),
Note:
See TracChangeset
for help on using the changeset viewer.