Changeset 55182 in vbox for trunk/src/VBox
- Timestamp:
- Apr 10, 2015 2:26:59 PM (10 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 2 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r54885 r55182 301 301 return rcExit; 302 302 } 303 304 RTEXITCODE readPasswordFromConsole(com::Utf8Str *pPassword, const char *pszPrompt, ...) 305 { 306 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 307 char aszPwdInput[_1K] = { 0 }; 308 va_list vaArgs; 309 310 va_start(vaArgs, pszPrompt); 311 int vrc = RTStrmPrintfV(g_pStdOut, pszPrompt, vaArgs); 312 if (RT_SUCCESS(vrc)) 313 { 314 bool fEchoOld = false; 315 vrc = RTStrmInputGetEchoChars(g_pStdIn, &fEchoOld); 316 if (RT_SUCCESS(vrc)) 317 { 318 vrc = RTStrmInputSetEchoChars(g_pStdIn, false); 319 if (RT_SUCCESS(vrc)) 320 { 321 vrc = RTStrmGetLine(g_pStdIn, &aszPwdInput[0], sizeof(aszPwdInput)); 322 if (RT_SUCCESS(vrc)) 323 *pPassword = aszPwdInput; 324 else 325 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed read password from command line (%Rrc)", vrc); 326 327 int vrc2 = RTStrmInputSetEchoChars(g_pStdIn, fEchoOld); 328 AssertRC(vrc2); 329 } 330 else 331 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to disable echoing typed characters (%Rrc)", vrc); 332 } 333 else 334 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to retrieve echo setting (%Rrc)", vrc); 335 336 RTStrmPutStr(g_pStdOut, "\n"); 337 } 338 else 339 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to print prompt (%Rrc)", vrc); 340 va_end(vaArgs); 341 342 return rcExit; 343 } 344 303 345 #endif 304 346 -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r54885 r55182 188 188 #ifndef VBOX_ONLY_DOCS 189 189 RTEXITCODE readPasswordFile(const char *pszFilename, com::Utf8Str *pPasswd); 190 RTEXITCODE readPasswordFromConsole(com::Utf8Str *pPassword, const char *pszPrompt, ...); 190 191 191 192 int handleInternalCommands(HandlerArg *a); -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageAppliance.cpp
r54991 r55182 1202 1202 break; 1203 1203 1204 /* Query required passwords and supply them to the appliance. */ 1205 com::SafeArray<BSTR> aIdentifiers; 1206 1207 CHECK_ERROR_BREAK(pAppliance, GetPasswordIds(ComSafeArrayAsOutParam(aIdentifiers))); 1208 1209 if (aIdentifiers.size() > 0) 1210 { 1211 com::SafeArray<BSTR> aPasswords(aIdentifiers.size()); 1212 RTPrintf("Enter the passwords for the following identifiers to export the apppliance:\n"); 1213 for (unsigned idxId = 0; idxId < aIdentifiers.size(); idxId++) 1214 { 1215 com::Utf8Str strPassword; 1216 Bstr bstrPassword; 1217 Bstr bstrId = aIdentifiers[idxId]; 1218 1219 RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Password ID %s:", Utf8Str(bstrId).c_str()); 1220 if (rcExit == RTEXITCODE_FAILURE) 1221 return rcExit; 1222 1223 bstrPassword = strPassword; 1224 bstrPassword.detachTo(&aPasswords[idxId]); 1225 } 1226 1227 CHECK_ERROR_BREAK(pAppliance, AddPasswords(ComSafeArrayAsInParam(aIdentifiers), 1228 ComSafeArrayAsInParam(aPasswords))); 1229 } 1230 1204 1231 if (fManifest) 1205 1232 options.push_back(ExportOptions_CreateManifest); -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
r54885 r55182 50 50 RTMsgErrorV(pszFormat, va); 51 51 RTMsgError("Error code %Rrc at %s(%u) in function %s", rc, RT_SRC_POS_ARGS); 52 }53 54 static int getPassword(const char *pszPrompt, Utf8Str *pPassword)55 {56 char aszPwdInput[_1K] = { 0 };57 58 int vrc = RTStrmPutStr(g_pStdOut, pszPrompt);59 if (RT_SUCCESS(vrc))60 {61 bool fEchoOld = false;62 vrc = RTStrmInputGetEchoChars(g_pStdIn, &fEchoOld);63 if (RT_SUCCESS(vrc))64 {65 vrc = RTStrmInputSetEchoChars(g_pStdIn, false);66 if (RT_SUCCESS(vrc))67 {68 vrc = RTStrmGetLine(g_pStdIn, &aszPwdInput[0], sizeof(aszPwdInput));69 if (RT_SUCCESS(vrc))70 *pPassword = aszPwdInput;71 72 int vrc2 = RTStrmInputSetEchoChars(g_pStdIn, fEchoOld);73 AssertRC(vrc2);74 }75 }76 RTStrmPutStr(g_pStdOut, "\n");77 }78 79 return vrc;80 52 } 81 53 … … 1767 1739 { 1768 1740 /* Get password from console. */ 1769 vrc = getPassword("Enter new password:", &strPasswordNew); 1770 if (RT_FAILURE(vrc)) 1771 { 1772 RTMsgError("Failed to read new password from standard input"); 1773 return 1; 1774 } 1741 RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordNew, "Enter new password:"); 1742 if (rcExit == RTEXITCODE_FAILURE) 1743 return rcExit; 1775 1744 } 1776 1745 else … … 1790 1759 { 1791 1760 /* Get password from console. */ 1792 vrc = getPassword("Enter old password:", &strPasswordOld); 1793 if (RT_FAILURE(vrc)) 1794 { 1795 RTMsgError("Failed to read old password from standard input"); 1796 return 1; 1797 } 1761 RTEXITCODE rcExit = readPasswordFromConsole(&strPasswordOld, "Enter old password:"); 1762 if (rcExit == RTEXITCODE_FAILURE) 1763 return rcExit; 1798 1764 } 1799 1765 else … … 1857 1823 { 1858 1824 /* Get password from console. */ 1859 vrc = getPassword("Enter password:", &strPassword); 1860 if (RT_FAILURE(vrc)) 1861 { 1862 RTMsgError("Failed to read password from standard input"); 1863 return 1; 1864 } 1825 RTEXITCODE rcExit = readPasswordFromConsole(&strPassword, "Enter password:"); 1826 if (rcExit == RTEXITCODE_FAILURE) 1827 return rcExit; 1865 1828 } 1866 1829 else -
trunk/src/VBox/Main/Makefile.kmk
r55095 r55182 357 357 src-all/ProgressImpl.cpp \ 358 358 src-all/QMTranslatorImpl.cpp \ 359 src-all/SecretKeyStore.cpp \ 359 360 src-all/SharedFolderImpl.cpp \ 360 361 src-all/AutoCaller.cpp \ … … 716 717 src-all/PCIDeviceAttachmentImpl.cpp \ 717 718 src-all/ProgressImpl.cpp \ 719 src-all/SecretKeyStore.cpp \ 718 720 src-all/SharedFolderImpl.cpp \ 719 721 src-all/AutoCaller.cpp \ -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r55133 r55182 2987 2987 <interface 2988 2988 name="IAppliance" extends="$unknown" 2989 uuid=" 3059cf9e-25c7-4f0b-9fa5-3c42e441670b"2989 uuid="d9432012-2740-499f-b3b3-0991da3679f3" 2990 2990 wsmap="managed" 2991 2991 > … … 3240 3240 <param name="warnings" type="wstring" dir="return" safearray="yes"> 3241 3241 <desc></desc> 3242 </param> 3243 </method> 3244 3245 <method name="getPasswordIds"> 3246 <desc> 3247 Returns a list of password identifiers which must be supplied to import or export 3248 encrypted virtual machines. 3249 </desc> 3250 3251 <param name="identifiers" type="wstring" dir="return" safearray="yes"> 3252 The list of password identifiers required on success. 3253 </param> 3254 </method> 3255 3256 <method name="addPasswords"> 3257 <desc> 3258 Adds a list of passwords required to import or export encrypted virtual 3259 machines. 3260 </desc> 3261 3262 <param name="identifiers" type="wstring" dir="in" safearray="yes"> 3263 <desc>List of identifiers.</desc> 3264 </param> 3265 3266 <param name="passwords" type="wstring" dir="in" safearray="yes"> 3267 <desc>List of matching passwords.</desc> 3242 3268 </param> 3243 3269 </method> -
trunk/src/VBox/Main/include/MediumImpl.h
r54948 r55182 24 24 #include "VirtualBoxBase.h" 25 25 #include "AutoCaller.h" 26 #include "SecretKeyStore.h" 26 27 class Progress; 27 28 class MediumFormat; … … 204 205 const ComObjPtr<MediumFormat> &aFormat, 205 206 MediumVariant_T aVariant, 207 SecretKeyStore *pKeyStore, 206 208 PVDINTERFACEIO aVDImageIOIf, void *aVDImageIOUser, 207 209 const ComObjPtr<Progress> &aProgress); … … 216 218 const ComObjPtr<Medium> &aParent, IProgress **aProgress, 217 219 uint32_t idxSrcImageSame, uint32_t idxDstImageSame); 220 221 const Utf8Str& i_getKeyId(); 218 222 219 223 private: -
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 -
trunk/src/VBox/Main/src-server/ApplianceImpl.cpp
r54979 r55182 404 404 // initialize data 405 405 m = new Data; 406 m->m_pSecretKeyStore = new SecretKeyStore(false /* fRequireNonPageable*/); 407 AssertReturn(m->m_pSecretKeyStore, E_FAIL); 406 408 407 409 i_initApplianceIONameMap(); … … 425 427 if (autoUninitSpan.uninitDone()) 426 428 return; 429 430 if (m->m_pSecretKeyStore) 431 delete m->m_pSecretKeyStore; 427 432 428 433 delete m; … … 601 606 } 602 607 608 HRESULT Appliance::getPasswordIds(std::vector<com::Utf8Str> &aIdentifiers) 609 { 610 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 611 612 aIdentifiers = m->m_vecPasswordIdentifiers; 613 return S_OK; 614 } 615 616 HRESULT Appliance::addPasswords(const std::vector<com::Utf8Str> &aIdentifiers, 617 const std::vector<com::Utf8Str> &aPasswords) 618 { 619 HRESULT hrc = S_OK; 620 621 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 622 623 /* Check that the IDs do not exist already before changing anything. */ 624 for (unsigned i = 0; i < aIdentifiers.size(); i++) 625 { 626 SecretKey *pKey = NULL; 627 int rc = m->m_pSecretKeyStore->retainSecretKey(aIdentifiers[i], &pKey); 628 if (rc != VERR_NOT_FOUND) 629 { 630 AssertPtr(pKey); 631 if (pKey) 632 pKey->release(); 633 return setError(VBOX_E_OBJECT_IN_USE, tr("A password with the given ID already exists")); 634 } 635 } 636 637 for (unsigned i = 0; i < aIdentifiers.size() && SUCCEEDED(hrc); i++) 638 { 639 size_t cbKey = aPasswords[i].length() + 1; /* Include terminator */ 640 const uint8_t *pbKey = (const uint8_t *)aPasswords[i].c_str(); 641 642 int rc = m->m_pSecretKeyStore->addSecretKey(aIdentifiers[i], pbKey, cbKey); 643 if (RT_SUCCESS(rc)) 644 m->m_cPwProvided++; 645 else if (rc == VERR_NO_MEMORY) 646 hrc = setError(E_OUTOFMEMORY, tr("Failed to allocate enough secure memory for the key")); 647 else 648 hrc = setError(E_FAIL, tr("Unknown error happened while adding a password (%Rrc)"), rc); 649 } 650 651 return hrc; 652 } 653 603 654 //////////////////////////////////////////////////////////////////////////////// 604 655 // -
trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
r52856 r55182 358 358 rc = pBaseMedium->COMGETTER(Size)(&llSize); 359 359 if (FAILED(rc)) throw rc; 360 361 /* If the medium is encrypted add the key identifier to the */ 362 IMedium *iBaseMedium = pBaseMedium; 363 Medium *pBase = static_cast<Medium*>(iBaseMedium); 364 const com::Utf8Str strKeyId = pBase->i_getKeyId(); 365 if (!strKeyId.isEmpty()) 366 { 367 bool fKnown = false; 368 369 /* Check whether the ID is already in our sequence, add it otherwise. */ 370 for (unsigned i = 0; i < pAppliance->m->m_vecPasswordIdentifiers.size(); i++) 371 { 372 if (strKeyId.equals(pAppliance->m->m_vecPasswordIdentifiers[i])) 373 { 374 fKnown = true; 375 break; 376 } 377 } 378 379 if (!fKnown) 380 pAppliance->m->m_vecPasswordIdentifiers.push_back(strKeyId); 381 } 360 382 } 361 383 else if ( deviceType == DeviceType_DVD … … 649 671 return setError(VBOX_E_FILE_ERROR, 650 672 tr("Invalid format \"%s\" specified"), aFormat.c_str()); 673 674 /* Check whether all passwords are supplied or error out. */ 675 if (m->m_cPwProvided < m->m_vecPasswordIdentifiers.size()) 676 return setError(VBOX_E_INVALID_OBJECT_STATE, 677 tr("Appliance export failed because not all passwords were provided for all encrypted media")); 651 678 652 679 /* as of OVF 2.0 we have to use SHA256 */ … … 2168 2195 format, 2169 2196 MediumVariant_VmdkStreamOptimized, 2197 m->m_pSecretKeyStore, 2170 2198 pIfIo, 2171 2199 pStorage, -
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r54950 r55182 572 572 MediumFormat *aFormat, 573 573 MediumVariant_T aVariant, 574 SecretKeyStore *pSecretKeyStore, 574 575 VDINTERFACEIO *aVDImageIOIf, 575 576 void *aVDImageIOUser, … … 581 582 mFormat(aFormat), 582 583 mVariant(aVariant), 584 m_pSecretKeyStore(pSecretKeyStore), 583 585 mfKeepSourceMediumLockList(fKeepSourceMediumLockList) 584 586 { … … 606 608 MediumVariant_T mVariant; 607 609 PVDINTERFACE mVDImageIfaces; 610 SecretKeyStore *m_pSecretKeyStore; 608 611 609 612 private: … … 5587 5590 * @param aVariant Which exact image format variant to use 5588 5591 * for the destination image. 5592 * @param pKeyStore The optional key store for decrypting the data 5593 * for encrypted media during the export. 5589 5594 * @param aVDImageIOCallbacks Pointer to the callback table for a 5590 5595 * VDINTERFACEIO interface. May be NULL. … … 5597 5602 const ComObjPtr<MediumFormat> &aFormat, 5598 5603 MediumVariant_T aVariant, 5604 SecretKeyStore *pKeyStore, 5599 5605 PVDINTERFACEIO aVDImageIOIf, void *aVDImageIOUser, 5600 5606 const ComObjPtr<Progress> &aProgress) … … 5638 5644 /* setup task object to carry out the operation asynchronously */ 5639 5645 pTask = new Medium::ExportTask(this, aProgress, aFilename, aFormat, 5640 aVariant, aVDImageIOIf,5646 aVariant, pKeyStore, aVDImageIOIf, 5641 5647 aVDImageIOUser, pSourceMediumLockList); 5642 5648 rc = pTask->rc(); … … 5898 5904 5899 5905 return rc; 5906 } 5907 5908 /** 5909 * Returns the key identifier for this medium if encryption is configured. 5910 * 5911 * @returns Key identifier or empty string if no encryption is configured. 5912 */ 5913 const Utf8Str& Medium::i_getKeyId() 5914 { 5915 ComObjPtr<Medium> pBase = i_getBase(); 5916 5917 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 5918 5919 settings::StringsMap::const_iterator it = pBase->m->mapProperties.find("CRYPT/KeyId"); 5920 if (it == pBase->m->mapProperties.end()) 5921 return Utf8Str::Empty; 5922 5923 return it->second; 5900 5924 } 5901 5925 … … 8728 8752 * signal from the task initiator (which releases it only after 8729 8753 * RTThreadCreate()) that we can start the job. */ 8754 ComObjPtr<Medium> pBase = i_getBase(); 8730 8755 AutoWriteLock thisLock(this COMMA_LOCKVAL_SRC_POS); 8731 8756 … … 8736 8761 try 8737 8762 { 8763 settings::StringsMap::iterator itKeyStore = pBase->m->mapProperties.find("CRYPT/KeyStore"); 8764 if (itKeyStore != pBase->m->mapProperties.end()) 8765 { 8766 settings::StringsMap::iterator itKeyId = pBase->m->mapProperties.find("CRYPT/KeyId"); 8767 8768 #ifdef VBOX_WITH_EXTPACK 8769 static const Utf8Str strExtPackPuel("Oracle VM VirtualBox Extension Pack"); 8770 static const char *s_pszVDPlugin = "VDPluginCrypt"; 8771 ExtPackManager *pExtPackManager = m->pVirtualBox->i_getExtPackManager(); 8772 if (pExtPackManager->i_isExtPackUsable(strExtPackPuel.c_str())) 8773 { 8774 /* Load the plugin */ 8775 Utf8Str strPlugin; 8776 rc = pExtPackManager->i_getLibraryPathForExtPack(s_pszVDPlugin, &strExtPackPuel, &strPlugin); 8777 if (SUCCEEDED(rc)) 8778 { 8779 vrc = VDPluginLoadFromFilename(strPlugin.c_str()); 8780 if (RT_FAILURE(vrc)) 8781 throw setError(VBOX_E_NOT_SUPPORTED, 8782 tr("Retrieving encryption settings of the image failed because the encryption plugin could not be loaded (%s)"), 8783 i_vdError(vrc).c_str()); 8784 } 8785 else 8786 throw setError(VBOX_E_NOT_SUPPORTED, 8787 tr("Encryption is not supported because the extension pack '%s' is missing the encryption plugin (old extension pack installed?)"), 8788 strExtPackPuel.c_str()); 8789 } 8790 else 8791 throw setError(VBOX_E_NOT_SUPPORTED, 8792 tr("Encryption is not supported because the extension pack '%s' is missing"), 8793 strExtPackPuel.c_str()); 8794 #else 8795 throw setError(VBOX_E_NOT_SUPPORTED, 8796 tr("Encryption is not supported because extension pack support is not built in")); 8797 #endif 8798 8799 if (itKeyId == pBase->m->mapProperties.end()) 8800 throw setError(VBOX_E_INVALID_OBJECT_STATE, 8801 tr("Image '%s' is configured for encryption but doesn't has a key identifier set"), 8802 pBase->m->strLocationFull.c_str()); 8803 8804 /* Find the proper secret key in the key store. */ 8805 if (!task.m_pSecretKeyStore) 8806 throw setError(VBOX_E_INVALID_OBJECT_STATE, 8807 tr("Image '%s' is configured for encryption but there is no key store to retrieve the password from"), 8808 pBase->m->strLocationFull.c_str()); 8809 8810 SecretKey *pKey = NULL; 8811 vrc = task.m_pSecretKeyStore->retainSecretKey(itKeyId->second, &pKey); 8812 if (RT_FAILURE(vrc)) 8813 throw setError(VBOX_E_INVALID_OBJECT_STATE, 8814 tr("Failed to retrieve the secret key with ID \"%s\" from the store (%Rrc)"), 8815 itKeyId->second.c_str(), vrc); 8816 8817 Medium::CryptoFilterSettings CryptoSettingsRead; 8818 i_taskEncryptSettingsSetup(&CryptoSettingsRead, NULL, itKeyStore->second.c_str(), (const char *)pKey->getKeyBuffer(), 8819 false /* fCreateKeyStore */); 8820 vrc = VDFilterAdd(hdd, "CRYPT", VD_FILTER_FLAGS_READ, CryptoSettingsRead.vdFilterIfaces); 8821 if (vrc == VERR_VD_PASSWORD_INCORRECT) 8822 { 8823 task.m_pSecretKeyStore->releaseSecretKey(itKeyId->second); 8824 throw setError(VBOX_E_PASSWORD_INCORRECT, 8825 tr("The password to decrypt the image is incorrect")); 8826 } 8827 else if (RT_FAILURE(vrc)) 8828 { 8829 task.m_pSecretKeyStore->releaseSecretKey(itKeyId->second); 8830 throw setError(VBOX_E_INVALID_OBJECT_STATE, 8831 tr("Failed to load the decryption filter: %s"), 8832 i_vdError(vrc).c_str()); 8833 } 8834 8835 task.m_pSecretKeyStore->releaseSecretKey(itKeyId->second); 8836 } 8837 8738 8838 /* Open all media in the source chain. */ 8739 8839 MediumLockList::Base::const_iterator sourceListBegin =
Note:
See TracChangeset
for help on using the changeset viewer.