VirtualBox

Changeset 67237 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Jun 2, 2017 12:21:06 PM (8 years ago)
Author:
vboxsync
Message:

Main/Medium::i_addRawToFss: Split out the opening of the medium as we can share that with i_exportFile. Fixed decrypt problem.

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/MediumImpl.h

    r67231 r67237  
    368368                                                                const uint8_t *pbDek, size_t cbDek);
    369369
     370    struct CryptoFilterSettings;
     371    HRESULT i_openHddForReading(SecretKeyStore *pKeyStore, PVDISK *ppHdd, MediumLockList *pMediumLockList,
     372                                struct CryptoFilterSettings *pCryptoSettingsRead);
     373
    370374    class Task;
    371375    class CreateBaseTask;
     
    408412    HRESULT i_taskEncryptHandler(Medium::EncryptTask &task);
    409413
    410     struct CryptoFilterSettings;
    411414    void i_taskEncryptSettingsSetup(CryptoFilterSettings *pSettings, const char *pszCipher,
    412415                                    const char *pszKeyStore,  const char *pszPassword,
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r67234 r67237  
    61126112    AutoCaller autoCaller(this);
    61136113    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);
    61266114    if (SUCCEEDED(hrc))
    6127         hrc = SourceMediumLockList.Lock();
    6128     if (FAILED(hrc))
    6129         return hrc;
    6130 
    6131     try
    61326115    {
    61336116        /*
    6134          * Lock all in {parent,child} order.
     6117         * Get a readonly hdd for this medium.
    61356118         */
    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        {
    62396125            /*
    62406126             * Create a VFS file interface to the HDD and attach a progress wrapper
     
    62436129             */
    62446130            RTVFSFILE hVfsFileDisk = NIL_RTVFSFILE;
    6245             vrc = VDCreateVfsFileFromDisk(hdd, 0 /*fFlags*/, &hVfsFileDisk);
     6131            int vrc = VDCreateVfsFileFromDisk(pHdd, 0 /*fFlags*/, &hVfsFileDisk);
    62466132            if (RT_SUCCESS(vrc))
    62476133            {
     
    62496135                vrc = RTVfsCreateProgressForFile(hVfsFileDisk, aProgress->i_iprtProgressCallback, &*aProgress,
    62506136                                                 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*/,
    62526138                                                 0 /*cbExpectedWritten*/, &hVfsFileProgress);
    62536139                RTVfsFileRelease(hVfsFileDisk);
     
    62686154            else
    62696155                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    }
    62776159    return hrc;
    62786160}
     
    63106192{
    63116193    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);
    63146196
    63156197    AutoCaller autoCaller(this);
     
    80687950
    80697951    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 */
     7972HRESULT 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
    80708112}
    80718113
     
    97459787                                   itKeyId->second.c_str(), vrc);
    97469788
     9789/** @todo r=bird: Someone explain why this continue to work when
     9790 *        CryptoSettingsRead goes out of the scope? */
    97479791                Medium::CryptoFilterSettings CryptoSettingsRead;
    97489792                i_taskEncryptSettingsSetup(&CryptoSettingsRead, NULL, itKeyStore->second.c_str(), (const char *)pKey->getKeyBuffer(),
Note: See TracChangeset for help on using the changeset viewer.

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