- 時間撮記:
- 2014-5-22 上午10:24:53 (11 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r51292 r51342 92 92 #include <iprt/string.h> 93 93 #include <iprt/system.h> 94 #include <iprt/base64.h> 94 95 95 96 #include <VBox/vmm/vmapi.h> … … 4442 4443 { 4443 4444 return mDisplay; 4445 } 4446 4447 /** 4448 * Parses one key value pair. 4449 * 4450 * @returns VBox status code. 4451 * @param psz Configuration string. 4452 * @param ppszEnd Where to store the pointer to the string following the key value pair. 4453 * @param ppszKey Where to store the key on success. 4454 * @param ppszVal Where to store the value on success. 4455 */ 4456 int Console::consoleParseKeyValue(const char *psz, const char **ppszEnd, 4457 char **ppszKey, char **ppszVal) 4458 { 4459 int rc = VINF_SUCCESS; 4460 const char *pszKeyStart = psz; 4461 const char *pszValStart = NULL; 4462 size_t cchKey = 0; 4463 size_t cchVal = 0; 4464 4465 while ( *psz != '=' 4466 && *psz) 4467 psz++; 4468 4469 /* End of string at this point is invalid. */ 4470 if (*psz == '\0') 4471 return VERR_INVALID_PARAMETER; 4472 4473 cchKey = psz - pszKeyStart; 4474 psz++; /* Skip = character */ 4475 pszValStart = psz; 4476 4477 while ( *psz != ',' 4478 && *psz != '\n' 4479 && *psz != '\r' 4480 && *psz) 4481 psz++; 4482 4483 cchVal = psz - pszValStart; 4484 4485 if (cchKey && cchVal) 4486 { 4487 *ppszKey = RTStrDupN(pszKeyStart, cchKey); 4488 if (*ppszKey) 4489 { 4490 *ppszVal = RTStrDupN(pszValStart, cchVal); 4491 if (!*ppszVal) 4492 { 4493 RTStrFree(*ppszKey); 4494 rc = VERR_NO_MEMORY; 4495 } 4496 } 4497 else 4498 rc = VERR_NO_MEMORY; 4499 } 4500 else 4501 rc = VERR_INVALID_PARAMETER; 4502 4503 if (RT_SUCCESS(rc)) 4504 *ppszEnd = psz; 4505 4506 return rc; 4507 } 4508 4509 /** 4510 * Configures the encryption support for the disk identified by the gien UUID with 4511 * the given key. 4512 * 4513 * @returns COM status code. 4514 * @param pszUuid The UUID of the disk to configure encryption for. 4515 * @param pbKey The key to use 4516 * @param cbKey Size of the key in bytes. 4517 */ 4518 HRESULT Console::configureEncryptionForDisk(const char *pszUuid, const uint8_t *pbKey, size_t cbKey) 4519 { 4520 HRESULT hrc = S_OK; 4521 SafeIfaceArray<IMediumAttachment> sfaAttachments; 4522 4523 AutoCaller autoCaller(this); 4524 AssertComRCReturnRC(autoCaller.rc()); 4525 4526 /* Get the VM - must be done before the read-locking. */ 4527 SafeVMPtr ptrVM(this); 4528 if (!ptrVM.isOk()) 4529 return ptrVM.rc(); 4530 4531 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 4532 4533 hrc = mMachine->COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(sfaAttachments)); 4534 if (FAILED(hrc)) 4535 return hrc; 4536 4537 /* Find the correct attachment. */ 4538 for (unsigned i = 0; i < sfaAttachments.size(); i++) 4539 { 4540 const ComPtr<IMediumAttachment> &pAtt = sfaAttachments[i]; 4541 ComPtr<IMedium> pMedium; 4542 ComPtr<IMedium> pBase; 4543 Bstr uuid; 4544 4545 hrc = pAtt->COMGETTER(Medium)(pMedium.asOutParam()); 4546 if (FAILED(hrc)) 4547 break; 4548 4549 /* Skip non hard disk attachments. */ 4550 if (pMedium.isNull()) 4551 continue; 4552 4553 /* Get the UUID of the base medium and compare. */ 4554 hrc = pMedium->COMGETTER(Base)(pBase.asOutParam()); 4555 if (FAILED(hrc)) 4556 break; 4557 4558 hrc = pBase->COMGETTER(Id)(uuid.asOutParam()); 4559 if (FAILED(hrc)) 4560 break; 4561 4562 if (!RTUuidCompare2Strs(Utf8Str(uuid).c_str(), pszUuid)) 4563 { 4564 /* 4565 * Found the matching medium, query storage controller, port and device 4566 * to identify the correct driver. 4567 */ 4568 ComPtr<IStorageController> pStorageCtrl; 4569 Bstr storageCtrlName; 4570 LONG lPort, lDev; 4571 ULONG ulStorageCtrlInst; 4572 4573 hrc = pAtt->COMGETTER(Controller)(storageCtrlName.asOutParam()); 4574 if (FAILED(hrc)) 4575 break; 4576 4577 hrc = pAtt->COMGETTER(Port)(&lPort); 4578 if (FAILED(hrc)) 4579 break; 4580 4581 hrc = pAtt->COMGETTER(Device)(&lDev); 4582 if (FAILED(hrc)) 4583 break; 4584 4585 hrc = mMachine->GetStorageControllerByName(storageCtrlName.raw(), pStorageCtrl.asOutParam()); 4586 if (FAILED(hrc)) 4587 break; 4588 4589 hrc = pStorageCtrl->COMGETTER(Instance)(&ulStorageCtrlInst); 4590 if (FAILED(hrc)) 4591 break; 4592 4593 StorageControllerType_T enmCtrlType; 4594 hrc = pStorageCtrl->COMGETTER(ControllerType)(&enmCtrlType); 4595 AssertComRC(hrc); 4596 const char *pcszDevice = convertControllerTypeToDev(enmCtrlType); 4597 4598 StorageBus_T enmBus; 4599 hrc = pStorageCtrl->COMGETTER(Bus)(&enmBus); 4600 AssertComRC(hrc); 4601 4602 unsigned uLUN; 4603 hrc = Console::convertBusPortDeviceToLun(enmBus, lPort, lDev, uLUN); 4604 AssertComRCReturnRC(hrc); 4605 4606 PPDMIBASE pIBase = NULL; 4607 PPDMIMEDIA pIMedium = NULL; 4608 int rc = PDMR3QueryDriverOnLun(ptrVM.rawUVM(), pcszDevice, ulStorageCtrlInst, uLUN, "VD", &pIBase); 4609 if (RT_SUCCESS(rc)) 4610 { 4611 if (pIBase) 4612 { 4613 pIMedium = (PPDMIMEDIA)pIBase->pfnQueryInterface(pIBase, PDMIMEDIA_IID); 4614 if (!pIMedium) 4615 return setError(E_FAIL, tr("could not query medium interface of controller")); 4616 } 4617 else 4618 return setError(E_FAIL, tr("could not query base interface of controller")); 4619 } 4620 4621 rc = pIMedium->pfnSetKey(pIMedium, pbKey, cbKey); 4622 if (RT_FAILURE(rc)) 4623 return setError(E_FAIL, tr("Failed to set the encryption key (%Rrc)"), rc); 4624 } 4625 } 4626 4627 return hrc; 4628 } 4629 4630 /** 4631 * Parses the encryption configuration for one disk. 4632 * 4633 * @returns Pointer to the string following encryption configuration. 4634 * @param psz Pointer to the configuration for the encryption of one disk. 4635 */ 4636 HRESULT Console::consoleParseDiskEncryption(const char *psz, const char **ppszEnd) 4637 { 4638 char *pszUuid = NULL; 4639 char *pszKeyEnc = NULL; 4640 int rc = VINF_SUCCESS; 4641 HRESULT hrc = S_OK; 4642 4643 while ( *psz 4644 && RT_SUCCESS(rc)) 4645 { 4646 char *pszKey = NULL; 4647 char *pszVal = NULL; 4648 const char *pszEnd = NULL; 4649 4650 rc = consoleParseKeyValue(psz, &pszEnd, &pszKey, &pszVal); 4651 if (RT_SUCCESS(rc)) 4652 { 4653 if (!RTStrCmp(pszKey, "uuid")) 4654 pszUuid = pszVal; 4655 else if (!RTStrCmp(pszKey, "dek")) 4656 pszKeyEnc = pszVal; 4657 else 4658 rc = VERR_INVALID_PARAMETER; 4659 4660 RTStrFree(pszKey); 4661 4662 if (*pszEnd == ',') 4663 psz = pszEnd + 1; 4664 else 4665 { 4666 /* 4667 * End of the configuration for the current disk, skip linefeed and 4668 * carriage returns. 4669 */ 4670 while ( *pszEnd == '\n' 4671 || *pszEnd == '\r') 4672 pszEnd++; 4673 4674 psz = pszEnd; 4675 break; /* Stop parsing */ 4676 } 4677 4678 } 4679 } 4680 4681 if ( RT_SUCCESS(rc) 4682 && pszUuid 4683 && pszKeyEnc) 4684 { 4685 ssize_t cbKey = 0; 4686 4687 /* Decode the key. */ 4688 cbKey = RTBase64DecodedSize(pszKeyEnc, NULL); 4689 if (cbKey != -1) 4690 { 4691 uint8_t *pbKey = (uint8_t *)RTMemLockedAlloc(cbKey); 4692 if (pbKey) 4693 { 4694 rc = RTBase64Decode(pszKeyEnc, pbKey, cbKey, NULL, NULL); 4695 if (RT_SUCCESS(rc)) 4696 hrc = configureEncryptionForDisk(pszUuid, pbKey, cbKey); 4697 else 4698 hrc = setError(E_FAIL, 4699 tr("Failed to decode the key (%Rrc)"), 4700 rc); 4701 4702 RTMemWipeThoroughly(pbKey, cbKey, 10 /* cMinPasses */); 4703 RTMemLockedFree(pbKey); 4704 } 4705 else 4706 hrc = setError(E_FAIL, 4707 tr("Failed to allocate secure memory for the key")); 4708 } 4709 else 4710 hrc = setError(E_FAIL, 4711 tr("The base64 encoding of the passed key is incorrect")); 4712 } 4713 else if (RT_SUCCESS(rc)) 4714 hrc = setError(E_FAIL, 4715 tr("The encryption configuration is incomplete")); 4716 4717 if (pszUuid) 4718 RTStrFree(pszUuid); 4719 if (pszKeyEnc) 4720 { 4721 RTMemWipeThoroughly(pszKeyEnc, strlen(pszKeyEnc), 10 /* cMinPasses */); 4722 RTStrFree(pszKeyEnc); 4723 } 4724 4725 if (ppszEnd) 4726 *ppszEnd = psz; 4727 4728 return hrc; 4729 } 4730 4731 HRESULT Console::setDiskEncryptionKeys(const Utf8Str &strCfg) 4732 { 4733 HRESULT hrc = S_OK; 4734 const char *pszCfg = strCfg.c_str(); 4735 4736 while ( *pszCfg 4737 && SUCCEEDED(hrc)) 4738 { 4739 const char *pszNext = NULL; 4740 hrc = consoleParseDiskEncryption(pszCfg, &pszNext); 4741 pszCfg = pszNext; 4742 } 4743 4744 return hrc; 4444 4745 } 4445 4746 … … 8654 8955 LogRel(("Console: VM runtime error: fatal=%RTbool, errorID=%s message=\"%s\"\n", 8655 8956 fFatal, pszErrorId, message.c_str())); 8957 8958 /* Set guest property if the reason of the error is a missing DEK for a disk. */ 8959 if (!RTStrCmp(pszErrorId, "DrvVD_DEKMISSING")) 8960 { 8961 that->mMachine->DeleteGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw()); 8962 that->mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw(), 8963 Bstr("1").raw(), Bstr("RDONLYGUEST").raw()); 8964 that->mMachine->SaveSettings(); 8965 } 8966 8656 8967 8657 8968 that->onRuntimeError(BOOL(fFatal), Bstr(pszErrorId).raw(), Bstr(message).raw());
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器