Changeset 55182 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Apr 10, 2015 2:26:59 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r55180 r55182 430 430 #endif 431 431 , mBusMgr(NULL) 432 , m_pKeyStore(NULL) 432 433 , mpIfSecKey(NULL) 433 434 , mpIfSecKeyHlp(NULL) … … 627 628 #endif 628 629 630 unconst(m_pKeyStore) = new SecretKeyStore(true /* fKeyBufNonPageable */); 631 AssertReturn(m_pKeyStore, E_FAIL); 632 629 633 /* VirtualBox events registration. */ 630 634 { … … 768 772 } 769 773 774 if (m_pKeyStore) 775 { 776 delete m_pKeyStore; 777 unconst(m_pKeyStore) = NULL; 778 } 779 770 780 m_mapGlobalSharedFolders.clear(); 771 781 m_mapMachineSharedFolders.clear(); … … 774 784 mRemoteUSBDevices.clear(); 775 785 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();782 786 783 787 if (mVRDEServerInfo) … … 3368 3372 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3369 3373 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 3374 HRESULT hrc = S_OK; 3376 3375 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); 3379 3379 if (RT_SUCCESS(rc)) 3380 3380 { 3381 3381 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 3390 3383 hrc = i_configureEncryptionForDisk(aId, &cDisksConfigured); 3391 3384 if (SUCCEEDED(hrc)) 3392 3385 { 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); 3394 3393 m_cDisksPwProvided += cDisksConfigured; 3395 3394 … … 3411 3410 } 3412 3411 } 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")); 3416 3417 else 3417 return setError(E_FAIL, tr("Failed to allocate secure memory for thepassword (%Rrc)"), rc);3418 hrc = setError(E_FAIL, tr("Unknown error happened while adding a password (%Rrc)"), rc); 3418 3419 3419 3420 return hrc; … … 3437 3438 for (unsigned i = 0; i < aIds.size(); i++) 3438 3439 { 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(); 3441 3447 return setError(VBOX_E_OBJECT_IN_USE, tr("A password with the given ID already exists")); 3448 } 3442 3449 } 3443 3450 3444 3451 for (unsigned i = 0; i < aIds.size(); i++) 3445 3452 { 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); 3469 3454 if (FAILED(hrc)) 3470 3455 { … … 3484 3469 } 3485 3470 3486 if ( SUCCEEDED(hrc)3487 && m_cDisksPwProvided == m_cDisksEncrypted3488 && 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 3503 3471 return hrc; 3504 3472 } … … 3511 3479 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3512 3480 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); 3524 3496 3525 3497 return S_OK; … … 3530 3502 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3531 3503 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 3548 3510 m_cDisksPwProvided = 0; 3549 3550 3511 return S_OK; 3551 3512 } … … 3598 3559 case StorageControllerType_USB: 3599 3560 return "Msd"; 3561 case StorageControllerType_NVMe: 3562 return "nvme"; 3600 3563 default: 3601 3564 return NULL; … … 5073 5036 if (RT_SUCCESS(rc)) 5074 5037 { 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)) 5080 5040 { 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 } 5083 5048 } 5084 5049 } … … 5087 5052 tr("Failed to decode the key (%Rrc)"), 5088 5053 rc); 5054 5055 RTMemSaferFree(pbKey, cbKey); 5089 5056 } 5090 5057 else … … 5133 5100 { 5134 5101 /* 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 */); 5152 5103 } 5153 5104 … … 10682 10633 10683 10634 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; 10696 10645 } 10697 10646 … … 10705 10654 10706 10655 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)); 10716 10657 } 10717 10658 … … 10725 10666 10726 10667 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; 10743 10675 } 10744 10676 … … 10752 10684 10753 10685 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)); 10768 10687 } 10769 10688
Note:
See TracChangeset
for help on using the changeset viewer.