VirtualBox

Changeset 55182 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Apr 10, 2015 2:26:59 PM (10 years ago)
Author:
vboxsync
Message:

Main,FE/VBoxManage: Support exporting machines as appliances which have encrypted disks. Because the OVF standard doesn't support encrypted disks so far we always decrypt exported images which requires the password before starting the export proess

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r55180 r55182  
    430430#endif
    431431    , mBusMgr(NULL)
     432    , m_pKeyStore(NULL)
    432433    , mpIfSecKey(NULL)
    433434    , mpIfSecKeyHlp(NULL)
     
    627628#endif
    628629
     630        unconst(m_pKeyStore) = new SecretKeyStore(true /* fKeyBufNonPageable */);
     631        AssertReturn(m_pKeyStore, E_FAIL);
     632
    629633        /* VirtualBox events registration. */
    630634        {
     
    768772    }
    769773
     774    if (m_pKeyStore)
     775    {
     776        delete m_pKeyStore;
     777        unconst(m_pKeyStore) = NULL;
     778    }
     779
    770780    m_mapGlobalSharedFolders.clear();
    771781    m_mapMachineSharedFolders.clear();
     
    774784    mRemoteUSBDevices.clear();
    775785    mUSBDevices.clear();
    776 
    777     for (SecretKeyMap::iterator it = m_mapSecretKeys.begin();
    778          it != m_mapSecretKeys.end();
    779          it++)
    780         delete it->second;
    781     m_mapSecretKeys.clear();
    782786
    783787    if (mVRDEServerInfo)
     
    33683372    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    33693373
    3370     /* Check that the ID is not existing already. */
    3371     SecretKeyMap::const_iterator it = m_mapSecretKeys.find(aId);
    3372     if (it != m_mapSecretKeys.end())
    3373         return setError(VBOX_E_OBJECT_IN_USE, tr("A password with the given ID already exists"));
    3374 
    33753374    HRESULT hrc = S_OK;
    33763375    size_t cbKey = aPassword.length() + 1; /* Include terminator */
    3377     uint8_t *pbKey = NULL;
    3378     int rc = RTMemSaferAllocZEx((void **)&pbKey, cbKey, RTMEMSAFER_F_REQUIRE_NOT_PAGABLE);
     3376    const uint8_t *pbKey = (const uint8_t *)aPassword.c_str();
     3377
     3378    int rc = m_pKeyStore->addSecretKey(aId, pbKey, cbKey);
    33793379    if (RT_SUCCESS(rc))
    33803380    {
    33813381        unsigned cDisksConfigured = 0;
    3382         memcpy(pbKey, aPassword.c_str(), cbKey);
    3383 
    3384         /* Scramble content to make retrieving the key more difficult. */
    3385         rc = RTMemSaferScramble(pbKey, cbKey);
    3386         AssertRC(rc);
    3387         SecretKey *pKey = new SecretKey(pbKey, cbKey, !!aClearOnSuspend);
    3388         /* Add the key to the map */
    3389         m_mapSecretKeys.insert(std::make_pair(aId, pKey));
     3382
    33903383        hrc = i_configureEncryptionForDisk(aId, &cDisksConfigured);
    33913384        if (SUCCEEDED(hrc))
    33923385        {
    3393             pKey->m_cDisks = cDisksConfigured;
     3386            SecretKey *pKey = NULL;
     3387            rc = m_pKeyStore->retainSecretKey(aId, &pKey);
     3388            AssertRCReturn(rc, E_FAIL);
     3389
     3390            pKey->setUsers(cDisksConfigured);
     3391            pKey->setRemoveOnSuspend(!!aClearOnSuspend);
     3392            m_pKeyStore->releaseSecretKey(aId);
    33943393            m_cDisksPwProvided += cDisksConfigured;
    33953394
     
    34113410            }
    34123411        }
    3413         else
    3414             m_mapSecretKeys.erase(aId);
    3415     }
     3412    }
     3413    else if (rc == VERR_ALREADY_EXISTS)
     3414        hrc = setError(VBOX_E_OBJECT_IN_USE, tr("A password with the given ID already exists"));
     3415    else if (rc == VERR_NO_MEMORY)
     3416        hrc = setError(E_FAIL, tr("Failed to allocate enough secure memory for the key"));
    34163417    else
    3417         return setError(E_FAIL, tr("Failed to allocate secure memory for the password (%Rrc)"), rc);
     3418        hrc = setError(E_FAIL, tr("Unknown error happened while adding a password (%Rrc)"), rc);
    34183419
    34193420    return hrc;
     
    34373438    for (unsigned i = 0; i < aIds.size(); i++)
    34383439    {
    3439         SecretKeyMap::const_iterator it = m_mapSecretKeys.find(aIds[i]);
    3440         if (it != m_mapSecretKeys.end())
     3440        SecretKey *pKey = NULL;
     3441        int rc = m_pKeyStore->retainSecretKey(aIds[i], &pKey);
     3442        if (rc != VERR_NOT_FOUND)
     3443        {
     3444            AssertPtr(pKey);
     3445            if (pKey)
     3446                pKey->release();
    34413447            return setError(VBOX_E_OBJECT_IN_USE, tr("A password with the given ID already exists"));
     3448        }
    34423449    }
    34433450
    34443451    for (unsigned i = 0; i < aIds.size(); i++)
    34453452    {
    3446         size_t cbKey = aPasswords[i].length() + 1; /* Include terminator */
    3447         uint8_t *pbKey = NULL;
    3448         int rc = RTMemSaferAllocZEx((void **)&pbKey, cbKey, RTMEMSAFER_F_REQUIRE_NOT_PAGABLE);
    3449         if (RT_SUCCESS(rc))
    3450         {
    3451             unsigned cDisksConfigured = 0;
    3452             memcpy(pbKey, aPasswords[i].c_str(), cbKey);
    3453 
    3454             /* Scramble content to make retrieving the key more difficult. */
    3455             rc = RTMemSaferScramble(pbKey, cbKey);
    3456             AssertRC(rc);
    3457             SecretKey *pKey = new SecretKey(pbKey, cbKey, !!aClearOnSuspend);
    3458             /* Add the key to the map */
    3459             m_mapSecretKeys.insert(std::make_pair(aIds[i], pKey));
    3460             hrc = i_configureEncryptionForDisk(aIds[i], &cDisksConfigured);
    3461             if (FAILED(hrc))
    3462                 m_mapSecretKeys.erase(aIds[i]);
    3463             else
    3464                 pKey->m_cDisks = cDisksConfigured;
    3465         }
    3466         else
    3467             hrc = setError(E_FAIL, tr("Failed to allocate secure memory for the password (%Rrc)"), rc);
    3468 
     3453        hrc = addDiskEncryptionPassword(aIds[i], aPasswords[i], aClearOnSuspend);
    34693454        if (FAILED(hrc))
    34703455        {
     
    34843469    }
    34853470
    3486     if (   SUCCEEDED(hrc)
    3487         && m_cDisksPwProvided == m_cDisksEncrypted
    3488         && mMachineState == MachineState_Paused)
    3489     {
    3490         /* get the VM handle. */
    3491         SafeVMPtr ptrVM(this);
    3492         if (!ptrVM.isOk())
    3493             return ptrVM.rc();
    3494 
    3495         alock.release();
    3496         int vrc = VMR3Resume(ptrVM.rawUVM(), VMRESUMEREASON_RECONFIG);
    3497 
    3498         hrc = RT_SUCCESS(vrc) ? S_OK :
    3499                 setError(VBOX_E_VM_ERROR,
    3500                          tr("Could not resume the machine execution (%Rrc)"), vrc);
    3501     }
    3502 
    35033471    return hrc;
    35043472}
     
    35113479    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    35123480
    3513     SecretKeyMap::iterator it = m_mapSecretKeys.find(aId);
    3514     if (it == m_mapSecretKeys.end())
    3515         return setError(VBOX_E_OBJECT_NOT_FOUND, tr("A password with the given ID does not exist"));
    3516 
    3517     SecretKey *pKey = it->second;
    3518     if (pKey->m_cRefs)
    3519         return setError(VBOX_E_OBJECT_IN_USE, tr("The password is still in use by the VM"));
    3520 
    3521     m_cDisksPwProvided -= pKey->m_cDisks;
    3522     m_mapSecretKeys.erase(it);
    3523     delete pKey;
     3481    SecretKey *pKey = NULL;
     3482    int rc = m_pKeyStore->retainSecretKey(aId, &pKey);
     3483    if (RT_SUCCESS(rc))
     3484    {
     3485        m_cDisksPwProvided -= pKey->getUsers();
     3486        m_pKeyStore->releaseSecretKey(aId);
     3487        rc = m_pKeyStore->deleteSecretKey(aId);
     3488        AssertRCReturn(rc, E_FAIL);
     3489    }
     3490    else if (rc == VERR_NOT_FOUND)
     3491        return setError(VBOX_E_OBJECT_NOT_FOUND, tr("A password with the ID \"%s\" does not exist"),
     3492                                                 aId.c_str());
     3493    else
     3494        return setError(E_FAIL, tr("Failed to remove password with ID \"%s\" (%Rrc)"),
     3495                                aId.c_str(), rc);
    35243496
    35253497    return S_OK;
     
    35303502    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    35313503
    3532     /* First check whether a password is still in use. */
    3533     for (SecretKeyMap::iterator it = m_mapSecretKeys.begin();
    3534         it != m_mapSecretKeys.end();
    3535         it++)
    3536     {
    3537         SecretKey *pKey = it->second;
    3538         if (pKey->m_cRefs)
    3539             return setError(VBOX_E_OBJECT_IN_USE, tr("The password with ID \"%s\" is still in use by the VM"),
    3540                             it->first.c_str());
    3541     }
    3542 
    3543     for (SecretKeyMap::iterator it = m_mapSecretKeys.begin();
    3544         it != m_mapSecretKeys.end();
    3545         it++)
    3546         delete it->second;
    3547     m_mapSecretKeys.clear();
     3504    int rc = m_pKeyStore->deleteAllSecretKeys(false /* fSuspend */, false /* fForce */);
     3505    if (rc == VERR_RESOURCE_IN_USE)
     3506        return setError(VBOX_E_OBJECT_IN_USE, tr("A password is still in use by the VM"));
     3507    else if (RT_FAILURE(rc))
     3508        return setError(E_FAIL, tr("Deleting all passwords failed (%Rrc)"));
     3509
    35483510    m_cDisksPwProvided = 0;
    3549 
    35503511    return S_OK;
    35513512}
     
    35983559        case StorageControllerType_USB:
    35993560            return "Msd";
     3561        case StorageControllerType_NVMe:
     3562            return "nvme";
    36003563        default:
    36013564            return NULL;
     
    50735036                if (RT_SUCCESS(rc))
    50745037                {
    5075                     SecretKey *pKey = new SecretKey(pbKey, cbKey, true /* fRemoveOnSuspend */);
    5076                     /* Add the key to the map */
    5077                     m_mapSecretKeys.insert(std::make_pair(Utf8Str(pszUuid), pKey));
    5078                     hrc = i_configureEncryptionForDisk(Utf8Str(pszUuid), NULL);
    5079                     if (FAILED(hrc))
     5038                    rc = m_pKeyStore->addSecretKey(Utf8Str(pszUuid), pbKey, cbKey);
     5039                    if (RT_SUCCESS(rc))
    50805040                    {
    5081                         /* Delete the key from the map. */
    5082                         m_mapSecretKeys.erase(Utf8Str(pszUuid));
     5041                        hrc = i_configureEncryptionForDisk(Utf8Str(pszUuid), NULL);
     5042                        if (FAILED(hrc))
     5043                        {
     5044                            /* Delete the key from the map. */
     5045                            rc = m_pKeyStore->deleteSecretKey(Utf8Str(pszUuid));
     5046                            AssertRC(rc);
     5047                        }
    50835048                    }
    50845049                }
     
    50875052                                   tr("Failed to decode the key (%Rrc)"),
    50885053                                   rc);
     5054
     5055                RTMemSaferFree(pbKey, cbKey);
    50895056            }
    50905057            else
     
    51335100{
    51345101    /* Remove keys which are supposed to be removed on a suspend. */
    5135     SecretKeyMap::iterator it = m_mapSecretKeys.begin();
    5136     while (it != m_mapSecretKeys.end())
    5137     {
    5138         SecretKey *pKey = it->second;
    5139         if (pKey->m_fRemoveOnSuspend)
    5140         {
    5141             /* Unconfigure disk encryption from all attachments associated with this key. */
    5142             i_clearDiskEncryptionKeysOnAllAttachmentsWithKeyId(it->first);
    5143 
    5144             AssertMsg(!pKey->m_cRefs, ("No one should access the stored key at this point anymore!\n"));
    5145             m_cDisksPwProvided -= pKey->m_cDisks;
    5146             delete pKey;
    5147             m_mapSecretKeys.erase(it++);
    5148         }
    5149         else
    5150             it++;
    5151     }
     5102    int rc = m_pKeyStore->deleteAllSecretKeys(true /* fSuspend */, true /* fForce */);
    51525103}
    51535104
     
    1068210633
    1068310634    AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
    10684     SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
    10685     if (it != pConsole->m_mapSecretKeys.end())
    10686     {
    10687         SecretKey *pKey = (*it).second;
    10688 
    10689         ASMAtomicIncU32(&pKey->m_cRefs);
    10690         *ppbKey = pKey->m_pbKey;
    10691         *pcbKey = pKey->m_cbKey;
    10692         return VINF_SUCCESS;
    10693     }
    10694 
    10695     return VERR_NOT_FOUND;
     10635    SecretKey *pKey = NULL;
     10636
     10637    int rc = pConsole->m_pKeyStore->retainSecretKey(Utf8Str(pszId), &pKey);
     10638    if (RT_SUCCESS(rc))
     10639    {
     10640        *ppbKey = (const uint8_t *)pKey->getKeyBuffer();
     10641        *pcbKey = pKey->getKeySize();
     10642    }
     10643
     10644    return rc;
    1069610645}
    1069710646
     
    1070510654
    1070610655    AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
    10707     SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
    10708     if (it != pConsole->m_mapSecretKeys.end())
    10709     {
    10710         SecretKey *pKey = (*it).second;
    10711         ASMAtomicDecU32(&pKey->m_cRefs);
    10712         return VINF_SUCCESS;
    10713     }
    10714 
    10715     return VERR_NOT_FOUND;
     10656    return pConsole->m_pKeyStore->releaseSecretKey(Utf8Str(pszId));
    1071610657}
    1071710658
     
    1072510666
    1072610667    AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
    10727     SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
    10728     if (it != pConsole->m_mapSecretKeys.end())
    10729     {
    10730         SecretKey *pKey = (*it).second;
    10731 
    10732         uint32_t cRefs = ASMAtomicIncU32(&pKey->m_cRefs);
    10733         if (cRefs == 1)
    10734         {
    10735             int rc = RTMemSaferUnscramble(pKey->m_pbKey, pKey->m_cbKey);
    10736             AssertRC(rc);
    10737         }
    10738         *ppszPassword = (const char *)pKey->m_pbKey;
    10739         return VINF_SUCCESS;
    10740     }
    10741 
    10742     return VERR_NOT_FOUND;
     10668    SecretKey *pKey = NULL;
     10669
     10670    int rc = pConsole->m_pKeyStore->retainSecretKey(Utf8Str(pszId), &pKey);
     10671    if (RT_SUCCESS(rc))
     10672        *ppszPassword = (const char *)pKey->getKeyBuffer();
     10673
     10674    return rc;
    1074310675}
    1074410676
     
    1075210684
    1075310685    AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
    10754     SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
    10755     if (it != pConsole->m_mapSecretKeys.end())
    10756     {
    10757         SecretKey *pKey = (*it).second;
    10758         uint32_t cRefs = ASMAtomicDecU32(&pKey->m_cRefs);
    10759         if (!cRefs)
    10760         {
    10761             int rc = RTMemSaferScramble(pKey->m_pbKey, pKey->m_cbKey);
    10762             AssertRC(rc);
    10763         }
    10764         return VINF_SUCCESS;
    10765     }
    10766 
    10767     return VERR_NOT_FOUND;
     10686    return pConsole->m_pKeyStore->releaseSecretKey(Utf8Str(pszId));
    1076810687}
    1076910688
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