VirtualBox

忽略:
時間撮記:
2015-3-2 下午07:55:29 (10 年 以前)
作者:
vboxsync
訊息:

Add support to supply passwords for disk encryption while the VM is running

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r54230 r54591  
    55
    66/*
    7  * Copyright (C) 2005-2014 Oracle Corporation
     7 * Copyright (C) 2005-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    474474    pIfSecKey->pfnKeyRetain             = Console::i_pdmIfSecKey_KeyRetain;
    475475    pIfSecKey->pfnKeyRelease            = Console::i_pdmIfSecKey_KeyRelease;
     476    pIfSecKey->pfnPasswordRetain        = Console::i_pdmIfSecKey_PasswordRetain;
     477    pIfSecKey->pfnPasswordRelease       = Console::i_pdmIfSecKey_PasswordRelease;
    476478    pIfSecKey->pConsole                 = this;
    477479    mpIfSecKey = pIfSecKey;
     
    33543356
    33553357    i_setMachineStateLocally(machineState);
     3358    return S_OK;
     3359}
     3360
     3361HRESULT Console::addDiskEncryptionPassword(const com::Utf8Str &aId, const com::Utf8Str &aPassword,
     3362                                           BOOL aClearOnSuspend)
     3363{
     3364    if (   aId.isEmpty()
     3365        || aPassword.isEmpty())
     3366        return setError(E_FAIL, tr("The ID and password must be both valid"));
     3367
     3368    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     3369
     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
     3375    HRESULT hrc = S_OK;
     3376    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);
     3379    if (RT_SUCCESS(rc))
     3380    {
     3381        memcpy(pbKey, aPassword.c_str(), cbKey);
     3382        SecretKey *pKey = new SecretKey(pbKey, cbKey, !!aClearOnSuspend);
     3383        /* Add the key to the map */
     3384        m_mapSecretKeys.insert(std::make_pair(aId, pKey));
     3385        hrc = i_configureEncryptionForDisk(aId);
     3386        if (FAILED(hrc))
     3387            m_mapSecretKeys.erase(aId);
     3388    }
     3389    else
     3390        return setError(E_FAIL, tr("Failed to allocate secure memory for the password (%Rrc)"), rc);
     3391
     3392    return hrc;
     3393}
     3394
     3395HRESULT Console::removeDiskEncryptionPassword(const com::Utf8Str &aId)
     3396{
     3397    if (aId.isEmpty())
     3398        return setError(E_FAIL, tr("The ID must be valid"));
     3399
     3400    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     3401
     3402    SecretKeyMap::const_iterator it = m_mapSecretKeys.find(aId);
     3403    if (it == m_mapSecretKeys.end())
     3404        return setError(VBOX_E_OBJECT_NOT_FOUND, tr("A password with the given ID does not exist"));
     3405
     3406    SecretKey *pKey = it->second;
     3407    if (pKey->m_cRefs)
     3408        return setError(VBOX_E_OBJECT_IN_USE, tr("The password is still in use by the VM"));
     3409
     3410    m_mapSecretKeys.erase(it);
     3411    delete pKey;
     3412
     3413    return S_OK;
     3414}
     3415
     3416HRESULT Console::clearAllDiskEncryptionPasswords()
     3417{
     3418    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     3419
     3420    /* First check whether a password is still in use. */
     3421    for (SecretKeyMap::iterator it = m_mapSecretKeys.begin();
     3422        it != m_mapSecretKeys.end();
     3423        it++)
     3424    {
     3425        SecretKey *pKey = it->second;
     3426        if (pKey->m_cRefs)
     3427            return setError(VBOX_E_OBJECT_IN_USE, tr("The password with ID \"%s\" is still in use by the VM"),
     3428                            it->first.c_str());
     3429    }
     3430
     3431    for (SecretKeyMap::iterator it = m_mapSecretKeys.begin();
     3432        it != m_mapSecretKeys.end();
     3433        it++)
     3434        delete it->second;
     3435    m_mapSecretKeys.clear();
     3436
    33563437    return S_OK;
    33573438}
     
    45494630
    45504631/**
    4551  * Configures the encryption support for the disk identified by the gien UUID with
    4552  * the given key.
     4632 * Configures the encryption support for the disk which have encryption conigured
     4633 * with the configured key.
    45534634 *
    45544635 * @returns COM status code.
    4555  * @param   pszUuid   The UUID of the disk to configure encryption for.
     4636 * @param   aId    The ID of the password.
    45564637 */
    4557 HRESULT Console::i_configureEncryptionForDisk(const char *pszUuid)
     4638HRESULT Console::i_configureEncryptionForDisk(const com::Utf8Str &strId)
    45584639{
    45594640    HRESULT hrc = S_OK;
     
    45804661        ComPtr<IMedium> pMedium;
    45814662        ComPtr<IMedium> pBase;
    4582         Bstr uuid;
     4663        Bstr bstrKeyId;
    45834664
    45844665        hrc = pAtt->COMGETTER(Medium)(pMedium.asOutParam());
     
    45954676            break;
    45964677
    4597         hrc = pBase->COMGETTER(Id)(uuid.asOutParam());
    4598         if (FAILED(hrc))
     4678        hrc = pBase->GetProperty(Bstr("CRYPT/KeyId").raw(), bstrKeyId.asOutParam());
     4679        if (hrc == VBOX_E_OBJECT_NOT_FOUND)
     4680            continue;
     4681        else if (FAILED(hrc))
    45994682            break;
    46004683
    4601         if (!RTUuidCompare2Strs(Utf8Str(uuid).c_str(), pszUuid))
     4684        if (strId.equals(Utf8Str(bstrKeyId)))
    46024685        {
    46034686            /*
     
    47374820                if (RT_SUCCESS(rc))
    47384821                {
    4739                     SecretKey *pKey = new SecretKey(pbKey, cbKey);
     4822                    SecretKey *pKey = new SecretKey(pbKey, cbKey, true /* fRemoveOnSuspend */);
    47404823                    /* Add the key to the map */
    47414824                    m_mapSecretKeys.insert(std::make_pair(Utf8Str(pszUuid), pKey));
    4742                     hrc = i_configureEncryptionForDisk(pszUuid);
     4825                    hrc = i_configureEncryptionForDisk(Utf8Str(pszUuid));
    47434826                    if (FAILED(hrc))
    47444827                    {
     
    1032810411    Console *pConsole = ((MYPDMISECKEY *)pInterface)->pConsole;
    1032910412
     10413    AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
    1033010414    SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
    1033110415    if (it != pConsole->m_mapSecretKeys.end())
     
    1034910433{
    1035010434    Console *pConsole = ((MYPDMISECKEY *)pInterface)->pConsole;
     10435
     10436    AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
     10437    SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
     10438    if (it != pConsole->m_mapSecretKeys.end())
     10439    {
     10440        SecretKey *pKey = (*it).second;
     10441        ASMAtomicDecU32(&pKey->m_cRefs);
     10442        return VINF_SUCCESS;
     10443    }
     10444
     10445    return VERR_NOT_FOUND;
     10446}
     10447
     10448/**
     10449 * @interface_method_impl{PDMISECKEY,pfnPasswordRetain}
     10450 */
     10451/*static*/ DECLCALLBACK(int)
     10452Console::i_pdmIfSecKey_PasswordRetain(PPDMISECKEY pInterface, const char *pszId, const char **ppszPassword)
     10453{
     10454    Console *pConsole = ((MYPDMISECKEY *)pInterface)->pConsole;
     10455
     10456    AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
     10457    SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
     10458    if (it != pConsole->m_mapSecretKeys.end())
     10459    {
     10460        SecretKey *pKey = (*it).second;
     10461
     10462        ASMAtomicIncU32(&pKey->m_cRefs);
     10463        *ppszPassword = (const char *)pKey->m_pbKey;
     10464        return VINF_SUCCESS;
     10465    }
     10466
     10467    return VERR_NOT_FOUND;
     10468}
     10469
     10470/**
     10471 * @interface_method_impl{PDMISECKEY,pfnPasswordRelease}
     10472 */
     10473/*static*/ DECLCALLBACK(int)
     10474Console::i_pdmIfSecKey_PasswordRelease(PPDMISECKEY pInterface, const char *pszId)
     10475{
     10476    Console *pConsole = ((MYPDMISECKEY *)pInterface)->pConsole;
     10477
     10478    AutoReadLock thatLock(pConsole COMMA_LOCKVAL_SRC_POS);
    1035110479    SecretKeyMap::const_iterator it = pConsole->m_mapSecretKeys.find(Utf8Str(pszId));
    1035210480    if (it != pConsole->m_mapSecretKeys.end())
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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