VirtualBox

Changeset 59576 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Feb 4, 2016 1:48:57 PM (9 years ago)
Author:
vboxsync
Message:

i_readFSOVF,i_readFSImpl: Rewrote the digest detection in i_readFSOVF and fixed bug in i_readFSImpl where it got ignored. (The OVA code path does not have digest detection yet.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp

    r59567 r59576  
    938938    PVDINTERFACEIO pShaIo = 0;
    939939    PVDINTERFACEIO pFileIo = 0;
     940    RTMANIFEST hOvfManifest = NIL_RTMANIFEST;
     941
    940942    do
    941943    {
     
    944946            /* Create the necessary file access interfaces. */
    945947            pFileIo = FileCreateInterface();
    946             if (!pFileIo)
    947             {
    948                 rc = E_OUTOFMEMORY;
    949                 break;
    950             }
     948            AssertBreakStmt(pFileIo, rc = E_OUTOFMEMORY);
    951949
    952950            Utf8Str strMfFile = Utf8Str(pTask->locInfo.strPath).stripSuffix().append(".mf");
     
    955953            RT_ZERO(storage);
    956954
     955            /* Check and read the manifest file to determine the digests we need to calculate. */
     956            uint32_t fTypes = 0;
    957957            if (RTFileExists(strMfFile.c_str()))
    958958            {
     959                vrc = RTManifestCreate(0 /*fFlags*/, &hOvfManifest);
     960                AssertBreakStmt(RT_SUCCESS(vrc), rc = E_OUTOFMEMORY);
     961
     962                RTVFSFILE hManifestVfsFile;
     963                vrc = RTVfsFileOpenNormal(strMfFile.c_str(),
     964                                          RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, &hManifestVfsFile);
     965                if (RT_FAILURE(vrc))
     966                    throw setError(VBOX_E_FILE_ERROR,
     967                                   tr("Could not open the manifest file '%s' (%Rrc)"), strMfFile.c_str(), vrc);
     968                char szErr[256];
     969                RTVFSIOSTREAM hVfsIosTmp = RTVfsFileToIoStream(hManifestVfsFile);
     970                vrc = RTManifestReadStandardEx(hOvfManifest, hVfsIosTmp, szErr, sizeof(szErr));
     971                RTVfsIoStrmRelease(hVfsIosTmp);
     972                RTVfsFileRelease(hManifestVfsFile);
     973                if (RT_FAILURE(vrc))
     974                    throw setErrorVrc(vrc, tr("Failed to read or parse manifest file '%s' (%Rrc): %s"),
     975                                      strMfFile.c_str(), vrc, szErr);
     976
     977                vrc = RTManifestQueryAllAttrTypes(hOvfManifest, true /*fEntriesOnly*/, &fTypes);
     978                AssertRCBreakStmt(vrc, rc = Global::vboxStatusCodeToCOM(vrc));
     979            }
     980
     981            /* If any digests was found, we must wrap the I/O interface with a SHA calculator. */
     982            if (fTypes)
     983            {
    959984                pShaIo = ShaCreateInterface();
    960                 if (!pShaIo)
    961                 {
    962                     rc = E_OUTOFMEMORY;
     985                AssertBreakStmt(pShaIo, rc = E_OUTOFMEMORY);
     986
     987                storage.fCreateDigest = true;
     988
     989                Assert(RT_IS_POWER_OF_TWO(fTypes)); /** @todo support anything and mixed (easy when supporting SHA256 for OVA < v2.0).  */
     990                if (fTypes & RTMANIFEST_ATTR_SHA256)
     991                    storage.fSha256 = true;
     992
     993                Utf8Str name = i_applianceIOName(applianceIOFile);
     994
     995                vrc = VDInterfaceAdd(&pFileIo->Core, name.c_str(),
     996                                     VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
     997                                     &storage.pVDImageIfaces);
     998                if (RT_FAILURE(vrc))
     999                    throw setError(VBOX_E_IPRT_ERROR, "Creation of the VD interface failed (%Rrc)", vrc);
     1000
     1001                rc = i_readFSImpl(pTask, pTask->locInfo.strPath, pShaIo, &storage);
     1002                if (FAILED(rc))
    9631003                    break;
    964                 }
    965 
    966                 //read the manifest file and find a type of used digest
    967                 RTFILE pFile = NULL;
    968                 vrc = RTFileOpen(&pFile, strMfFile.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
    969                 if (RT_SUCCESS(vrc) && pFile != NULL)
    970                 {
    971                     uint64_t cbFile64 = 0;
    972                     uint32_t maxFileSize = _1M;
    973                     size_t cbRead = 0;
    974                     size_t cbFile;
    975                     void  *pBuf; /** @todo r=bird: You leak this buffer! throwing stuff is evil. */
    976 
    977                     vrc = RTFileGetSize(pFile, &cbFile64);
    978                     if (cbFile64 > maxFileSize)
    979                         throw setError(VBOX_E_FILE_ERROR,
    980                                 tr("Size of the manifest file '%s' is bigger than 1Mb. Check it, please."),
    981                                 RTPathFilename(strMfFile.c_str()));
    982 
    983                     cbFile = (size_t)cbFile64;    /* We know it's <= 1M. */
    984                     if (RT_SUCCESS(vrc))
    985                        pBuf = RTMemAllocZ(cbFile);
    986                     else
    987                         throw setError(VBOX_E_FILE_ERROR,
    988                                 tr("Could not get size of the manifest file '%s' "),
    989                                 RTPathFilename(strMfFile.c_str()));
    990 
    991                     vrc = RTFileRead(pFile, pBuf, cbFile, &cbRead);
    992 
    993                     if (RT_FAILURE(vrc))
    994                     {
    995                         if (pBuf)
    996                             RTMemFree(pBuf);
    997                         throw setError(VBOX_E_FILE_ERROR,
    998                                tr("Could not read the manifest file '%s' (%Rrc)"),
    999                                RTPathFilename(strMfFile.c_str()), vrc);
    1000                     }
    1001 
    1002                     RTFileClose(pFile);
    1003 
    1004                     RTDIGESTTYPE digestType;
    1005                     vrc = RTManifestVerifyDigestType(pBuf, cbRead, &digestType);
    1006 
    1007                     if (pBuf)
    1008                         RTMemFree(pBuf);
    1009 
    1010                     if (RT_FAILURE(vrc))
    1011                     {
    1012                         throw setError(VBOX_E_FILE_ERROR,
    1013                                tr("Could not verify supported digest types in the manifest file '%s' (%Rrc)"),
    1014                                RTPathFilename(strMfFile.c_str()), vrc);
    1015                     }
    1016 
    1017                     storage.fCreateDigest = true;
    1018 
    1019                     if (digestType == RTDIGESTTYPE_SHA256)
    1020                     {
    1021                         storage.fSha256 = true;
    1022                     }
    1023 
    1024                     Utf8Str name = i_applianceIOName(applianceIOFile);
    1025 
    1026                     vrc = VDInterfaceAdd(&pFileIo->Core, name.c_str(),
    1027                                          VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
    1028                                          &storage.pVDImageIfaces);
    1029                     if (RT_FAILURE(vrc))
    1030                         throw setError(VBOX_E_IPRT_ERROR, "Creation of the VD interface failed (%Rrc)", vrc);
    1031 
    1032                     rc = i_readFSImpl(pTask, pTask->locInfo.strPath, pShaIo, &storage);
    1033                     if (FAILED(rc))
    1034                         break;
    1035                 }
    1036                 else
    1037                 {
    1038                     throw setError(VBOX_E_FILE_ERROR,
    1039                                tr("Could not open the manifest file '%s' (%Rrc)"),
    1040                                RTPathFilename(strMfFile.c_str()), vrc);
    1041                 }
    10421004            }
    10431005            else
     
    10541016        }
    10551017
    1056     }while (0);
     1018    } while (0);
    10571019
    10581020    /* Cleanup */
     
    10611023    if (pFileIo)
    10621024        RTMemFree(pFileIo);
     1025    if (hOvfManifest != NIL_RTMANIFEST)
     1026        RTManifestRelease(hOvfManifest);
    10631027
    10641028    LogFlowFunc(("rc=%Rhrc\n", rc));
     
    11551119        m->pReader = new ovf::OVFReader(pvTmpBuf, cbSize, pTask->locInfo.strPath);
    11561120
    1157         if (m->pReader->m_envelopeData.getOVFVersion() == ovf::OVFVersion_2_0)
     1121        if (   pStorage->fSha256
     1122            || m->pReader->m_envelopeData.getOVFVersion() == ovf::OVFVersion_2_0)
    11581123        {
    11591124            m->fSha256 = true;
    11601125
    1161             uint8_t digest[RTSHA256_HASH_SIZE];
    1162             size_t cchDigest = RTSHA256_DIGEST_LEN;
    1163             char *pszDigest;
    1164 
    1165             RTSha256(pvTmpBuf, cbSize, &digest[0]);
    1166 
    1167             vrc = RTStrAllocEx(&pszDigest, cchDigest + 1);
    1168             if (RT_FAILURE(vrc))
    1169                 throw setError(E_OUTOFMEMORY, tr("Could not allocate string for SHA256 digest (%Rrc)"), vrc);
    1170 
    1171             vrc = RTSha256ToString(digest, pszDigest, cchDigest + 1);
    1172             if (RT_SUCCESS(vrc))
    1173                 /* Copy the SHA256 sum of the OVF file for later validation */
    1174                 m->strOVFSHADigest = pszDigest;
    1175             else
    1176                 throw setError(VBOX_E_FILE_ERROR, tr("Converting SHA256 digest to a string was failed (%Rrc)"), vrc);
    1177 
    1178             RTStrFree(pszDigest);
    1179 
     1126            /* Calc the SHA256 sum of the OVF file for later validation */
     1127            uint8_t abHash[RTSHA256_HASH_SIZE];
     1128            RTSha256(pvTmpBuf, cbSize, abHash);
     1129
     1130            char szDigest[RTSHA256_DIGEST_LEN + 1];
     1131            vrc = RTSha256ToString(abHash, szDigest, sizeof(szDigest));
     1132            AssertStmt(RT_SUCCESS(vrc), throw VBOX_E_IPRT_ERROR);
     1133
     1134            m->strOVFSHADigest = szDigest;
    11801135        }
    11811136        else
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