VirtualBox

Changeset 45354 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 5, 2013 6:07:36 AM (12 years ago)
Author:
vboxsync
Message:

Main: OVF 2.0 support. Part 2 - OVA package with SHA256 support has been implemented.

Location:
trunk/src/VBox
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/ApplianceImplPrivate.h

    r45227 r45354  
    4848{
    4949    enum ApplianceState { ApplianceIdle, ApplianceImporting, ApplianceExporting };
     50    enum digest_T {SHA1, SHA256};
    5051
    5152    Data()
     
    7576    bool                fManifest;      // Create a manifest file on export
    7677    bool                fSha256;        // true = SHA256 (OVF 2.0), false = SHA1 (OVF 1.0)
     78    Utf8Str             strOVFSHADigest;//SHA digest of OVf file. It is stored here after reading OVF file (before import)
     79
    7780    RTCList<ImportOptions_T> optList;
    7881
     
    8891    ULONG               ulTotalDisksMB;
    8992    ULONG               cDisks;
    90     Utf8Str             strOVFSHADigest;
    9193
    9294    std::list<Guid>     llGuidsMachinesCreated;
     
    226228Utf8Str convertNetworkAttachmentTypeToString(NetworkAttachmentType_T type);
    227229
     230bool checkComplianceDigestAndOVFVersion(bool digestType, ovf::OVFVersion_T ovfVersion);
     231
    228232typedef struct SHASTORAGE
    229233{
  • trunk/src/VBox/Main/include/ovfreader.h

    r45227 r45354  
    179179            return OVFVersion_unknown;
    180180    }
     181
     182
     183    RTCString getStringOVFVersion() const
     184    {
     185        if(version == "0.9")
     186            return "0.9";
     187        else if(version == "1.0")
     188            return "1.0";
     189        else if(version == "2.0")
     190            return "2.0";
     191        else
     192            return "";
     193    }
    181194};
    182195
  • trunk/src/VBox/Main/src-server/ApplianceImpl.cpp

    r42261 r45354  
    274274}
    275275
     276bool checkComplianceDigestAndOVFVersion(bool digestType, ovf::OVFVersion_T ovfVersion)
     277{
     278    bool res = false;
     279    if ((ovfVersion == ovf::OVFVersion_2_0 && digestType == true) ||
     280        (ovfVersion == ovf::OVFVersion_1_0 && digestType == false) ||
     281        (ovfVersion == ovf::OVFVersion_0_9 && digestType == false))
     282        res = true;
     283    return res;
     284}
     285
    276286////////////////////////////////////////////////////////////////////////////////
    277287//
  • trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp

    r45232 r45354  
    837837            Utf8Str strMfFile = Utf8Str(pTask->locInfo.strPath).stripExt().append(".mf");
    838838
     839            SHASTORAGE storage;
     840            RT_ZERO(storage);
     841
    839842            if (RTFileExists(strMfFile.c_str()))
    840843            {
    841                 SHASTORAGE storage;
    842                 RT_ZERO(storage);
    843 
    844844                pShaIo = ShaCreateInterface();
    845845                if (!pShaIo)
     
    851851                //read the manifest file and find a type of used digest
    852852                RTFILE pFile = NULL;
    853                 RTFileOpen(&pFile, strMfFile.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
     853                vrc = RTFileOpen(&pFile, strMfFile.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
    854854                if(RT_SUCCESS(vrc) && pFile != NULL)
    855855                {
    856856                    uint64_t cbFile = 0;
     857                    uint64_t maxFileSize = _1M;
    857858                    size_t cbRead = 0;
    858859                    void  *pBuf;
    859860
    860861                    vrc = RTFileGetSize(pFile, &cbFile);
    861                     if(RT_SUCCESS(vrc) && cbFile > 0)
     862                    if (cbFile > maxFileSize)
     863                        throw setError(VBOX_E_FILE_ERROR,
     864                                tr("Size of the manifest file '%s' is bigger than 1Mb. Check it, please."),
     865                                RTPathFilename(strMfFile.c_str()));
     866
     867                    if (RT_SUCCESS(vrc))
    862868                       pBuf = RTMemAllocZ(cbFile);
    863869                    else
    864                         throw vrc;
     870                        throw setError(VBOX_E_FILE_ERROR,
     871                                tr("Could not get size of the manifest file '%s' "),
     872                                RTPathFilename(strMfFile.c_str()));
    865873
    866874                    vrc = RTFileRead(pFile, pBuf, cbFile, &cbRead);
     
    871879                            RTMemFree(pBuf);
    872880                        throw setError(VBOX_E_FILE_ERROR,
    873                                tr("Could not read manifest file '%s' (%Rrc)"),
     881                               tr("Could not read the manifest file '%s' (%Rrc)"),
    874882                               RTPathFilename(strMfFile.c_str()), vrc);
    875883                    }
     
    893901                        storage.fSha256 = true;
    894902                    }
    895                     else
    896                     {
    897                         storage.fSha256 = false;
    898                     }
     903
     904                    vrc = VDInterfaceAdd(&pFileIo->Core, "Appliance::IOFile",
     905                                             VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
     906                                             &storage.pVDImageIfaces);
     907                    if (RT_FAILURE(vrc))
     908                        throw setError(VBOX_E_IPRT_ERROR, "Creation of the VD interface failed (%Rrc)", vrc);
     909
     910                    rc = readFSImpl(pTask, pTask->locInfo.strPath, pShaIo, &storage);
     911                    if (FAILED(rc))
     912                        break;
    899913                }
    900                    
    901                 ///////////////////////////////////////////
    902 
    903                 vrc = VDInterfaceAdd(&pFileIo->Core, "Appliance::IOFile",
    904                                          VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
    905                                          &storage.pVDImageIfaces);
    906                 if (RT_FAILURE(vrc))
    907                     rc = setError(VBOX_E_IPRT_ERROR, "Creation of the VD interface failed (%Rrc)", vrc);
    908 
    909                 storage.fCreateDigest = true;
    910 
    911                 rc = readFSImpl(pTask, pTask->locInfo.strPath, pShaIo, &storage);
     914                else
     915                {
     916                    throw setError(VBOX_E_FILE_ERROR,
     917                               tr("Could not open the manifest file '%s' (%Rrc)"),
     918                               RTPathFilename(strMfFile.c_str()), vrc);
     919                }
    912920            }
    913921            else
    914                 rc = readFSImpl(pTask, pTask->locInfo.strPath, pFileIo, NULL);
     922            {
     923                storage.fCreateDigest = false;
     924                rc = readFSImpl(pTask, pTask->locInfo.strPath, pFileIo, &storage);
     925                if (FAILED(rc))
     926                    break;
     927            }
    915928        }
    916929        catch (HRESULT rc2)
    917         {
    918             rc = rc2;
    919         }
    920         catch (int rc2)
    921930        {
    922931            rc = rc2;
     
    942951
    943952    RTTAR tar;
    944     int vrc = RTTarOpen(&tar, pTask->locInfo.strPath.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, true);
    945     if (RT_FAILURE(vrc))
    946         return setError(VBOX_E_FILE_ERROR,
    947                         tr("Could not open OVA file '%s' (%Rrc)"),
    948                         pTask->locInfo.strPath.c_str(), vrc);
    949 
    950953    HRESULT rc = S_OK;
    951 
     954    int vrc = 0;
    952955    PVDINTERFACEIO pShaIo = 0;
    953956    PVDINTERFACEIO pTarIo = 0;
    954957    char *pszFilename = 0;
    955     do
    956     {
     958    void *pBuf = NULL;
     959    SHASTORAGE storage;
     960
     961    RT_ZERO(storage);
     962
     963    try
     964    {
     965        vrc = RTTarOpen(&tar, pTask->locInfo.strPath.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, true);
     966        if (RT_FAILURE(vrc))
     967        {
     968            return setError(VBOX_E_FILE_ERROR,
     969                            tr("Could not open the OVA file '%s' (%Rrc)"),
     970                            pTask->locInfo.strPath.c_str(), vrc);
     971        }
     972
    957973        vrc = RTTarCurrentFile(tar, &pszFilename);
    958974        if (RT_FAILURE(vrc))
    959975        {
    960             rc = VBOX_E_FILE_ERROR;
    961             break;
     976            throw setError(VBOX_E_FILE_ERROR,
     977                            tr("Could not extract the OVF file from the OVA package (%Rrc)"),
     978                            vrc);
    962979        }
    963         pShaIo = ShaCreateInterface();
    964         if (!pShaIo)
    965         {
    966             rc = E_OUTOFMEMORY;
    967             break;
     980
     981        //find the manifest file
     982        Utf8Str strMfFile = Utf8Str(pszFilename).stripPath().stripExt().append(".mf");
     983        vrc = RTTarFileExists(pTask->locInfo.strPath.c_str(), strMfFile.c_str());
     984        if (RT_SUCCESS(vrc))
     985        {
     986            //read the manifest file and find a type of used digest
     987            size_t cbRead = 0;
     988            RTDIGESTTYPE digestType = RTDIGESTTYPE_UNKNOWN;
     989
     990            vrc = RTTarExtractFileToBuf(pTask->locInfo.strPath.c_str(), &pBuf, &cbRead, strMfFile.c_str(), NULL, NULL);
     991            if (RT_FAILURE(vrc))
     992            {
     993                throw setError(VBOX_E_FILE_ERROR,
     994                       tr("Could not read the manifest file '%s' (%Rrc) from OVA package"),
     995                       RTPathFilename(strMfFile.c_str()), vrc);
     996            }
     997
     998            vrc = RTManifestVerifyDigestType(pBuf, cbRead, digestType);
     999
     1000            if (RT_FAILURE(vrc))
     1001            {
     1002                throw setError(VBOX_E_FILE_ERROR,
     1003                       tr("Could not verify supported digest types in the manifest file '%s' (%Rrc)"),
     1004                       RTPathFilename(strMfFile.c_str()), vrc);
     1005            }
     1006
     1007            storage.fCreateDigest = true;
     1008
     1009            if (digestType == RTDIGESTTYPE_SHA256)
     1010            {
     1011                storage.fSha256 = true;
     1012            }
    9681013        }
    969         pTarIo = TarCreateInterface();
    970         if (!pTarIo)
    971         {
    972             rc = E_OUTOFMEMORY;
    973             break;
     1014    }
     1015    catch (HRESULT res)
     1016    {
     1017        rc = res;
     1018    }
     1019
     1020    if (pBuf)
     1021        RTMemFree(pBuf);
     1022
     1023    RTTarClose(tar);
     1024
     1025
     1026    if (SUCCEEDED(rc))
     1027    {
     1028        vrc = RTTarOpen(&tar, pTask->locInfo.strPath.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, true);
     1029        if (RT_FAILURE(vrc))
     1030            rc = setError(VBOX_E_FILE_ERROR,
     1031                            tr("Could not open the OVA file '%s' (%Rrc)"),
     1032                            pTask->locInfo.strPath.c_str(), vrc);
     1033        else
     1034        {
     1035            do
     1036            {
     1037                vrc = RTTarCurrentFile(tar, &pszFilename);
     1038                if (RT_FAILURE(vrc))
     1039                {
     1040                    rc = VBOX_E_FILE_ERROR;
     1041                    break;
     1042                }
     1043                pTarIo = TarCreateInterface();
     1044                if (!pTarIo)
     1045                {
     1046                    rc = E_OUTOFMEMORY;
     1047                    break;
     1048                }
     1049
     1050                pShaIo = ShaCreateInterface();
     1051                if (!pShaIo)
     1052                {
     1053                    rc = E_OUTOFMEMORY;
     1054                    break ;
     1055                }
     1056
     1057                vrc = VDInterfaceAdd(&pTarIo->Core, "Appliance::IOTar",
     1058                                     VDINTERFACETYPE_IO, tar, sizeof(VDINTERFACEIO),
     1059                                     &storage.pVDImageIfaces);
     1060                if (RT_FAILURE(vrc))
     1061                {
     1062                    rc = setError(VBOX_E_IPRT_ERROR, "Creation of the VD interface failed (%Rrc)", vrc);
     1063                    break;
     1064                }
     1065
     1066                rc = readFSImpl(pTask, pszFilename, pShaIo, &storage);
     1067                if (FAILED(rc))
     1068                    break;
     1069
     1070            }while(0);
     1071
     1072            RTTarClose(tar);
    9741073        }
    975         SHASTORAGE storage;
    976         RT_ZERO(storage);
    977         vrc = VDInterfaceAdd(&pTarIo->Core, "Appliance::IOTar",
    978                              VDINTERFACETYPE_IO, tar, sizeof(VDINTERFACEIO),
    979                              &storage.pVDImageIfaces);
    980         if (RT_FAILURE(vrc))
    981         {
    982             rc = setError(VBOX_E_IPRT_ERROR, "Creation of the VD interface failed (%Rrc)", vrc);
    983             break;
    984         }
    985         rc = readFSImpl(pTask, pszFilename, pShaIo, &storage);
    986     }while(0);
    987 
    988     RTTarClose(tar);
     1074    }
     1075
    9891076
    9901077    /* Cleanup */
     
    10071094
    10081095    HRESULT rc = S_OK;
    1009 
    1010     pStorage->fCreateDigest = true;
    10111096
    10121097    void *pvTmpBuf = 0;
     
    10231108        /* Copy the SHA1/SHA256 sum of the OVF file for later validation */
    10241109        m->strOVFSHADigest = pStorage->strDigest;
     1110
     1111        if (pStorage->fCreateDigest)
     1112        {
     1113            m->fManifest = true;
     1114            /* Save a type of used SHA algorithm. Type was extracted during pre-reading manifest (.mf) file*/
     1115            m->fSha256 = pStorage->fSha256;
     1116        }
     1117        else
     1118        {
     1119            m->fManifest = false;
     1120        }
     1121
    10251122        /* Read & parse the XML structure of the OVF file */
    10261123        m->pReader = new ovf::OVFReader(pvTmpBuf, cbSize, pTask->locInfo.strPath);
     
    13221419
    13231420        Utf8Str strMfFile = Utf8Str(pTask->locInfo.strPath).stripExt().append(".mf");
     1421        SHASTORAGE storage;
     1422        RT_ZERO(storage);
     1423
    13241424        /* Create the import stack for the rollback on errors. */
    13251425        ImportStack stack(pTask->locInfo, m->pReader->m_mapDisks, pTask->pProgress);
     
    13271427        if (RTFileExists(strMfFile.c_str()))
    13281428        {
    1329             SHASTORAGE storage;
    1330             RT_ZERO(storage);
    1331 
    13321429            pShaIo = ShaCreateInterface();
    13331430            if (!pShaIo)
     
    13351432
    13361433            storage.fCreateDigest = true;
     1434
    13371435            int vrc = VDInterfaceAdd(&pFileIo->Core, "Appliance::IOFile",
    13381436                                     VDINTERFACETYPE_IO, 0, sizeof(VDINTERFACEIO),
     
    13421440
    13431441            size_t cbMfSize = 0;
    1344             storage.fCreateDigest = true;
     1442           
    13451443            /* Now import the appliance. */
    13461444            importMachines(stack, pShaIo, &storage);
     
    13541452        }
    13551453        else
    1356             importMachines(stack, pFileIo, NULL);
     1454        {
     1455            storage.fCreateDigest = false;
     1456            importMachines(stack, pFileIo, &storage);
     1457        }
    13571458    }
    13581459    catch (HRESULT rc2)
     
    17411842    if (RT_UNLIKELY(vrc == VERR_MANIFEST_DIGEST_MISMATCH))
    17421843        rc = setError(VBOX_E_FILE_ERROR,
    1743                       tr("The SHA1 digest of '%s' does not match the one in '%s' (%Rrc)"),
     1844                      tr("The SHA digest of '%s' does not match the one in '%s' (%Rrc)"),
    17441845                      RTPathFilename(paTests[iFailed].pszTestFile), RTPathFilename(strFile.c_str()), vrc);
    17451846    else if (RT_FAILURE(vrc))
     
    29143015    const ovf::OVFVersion_T ovfVersion = reader.m_envelopeData.getOVFVersion();
    29153016
    2916     if ( ovfVersion == ovf::OVFVersion_2_0)
     3017    /* check compliance between OVF file and MF file (correctly used type of SHA digest)*/
     3018    if (m->fManifest && !checkComplianceDigestAndOVFVersion(m->fSha256, ovfVersion))
     3019    {
     3020        RTCString ovfVer = reader.m_envelopeData.getStringOVFVersion();
     3021        throw setError(VBOX_E_FILE_ERROR,
     3022                           tr("Incompliance between found OVF standard version %s in the OVF file and used digest %s"),
     3023                           ovfVer.c_str(), (m->fSha256 == false)? "SHA1":"SHA256");
     3024    }
     3025
     3026    if (ovfVersion == ovf::OVFVersion_2_0)
    29173027        pStorage->fSha256 = true;
    29183028
  • trunk/src/VBox/Runtime/VBox/VBoxRTImp.def

    r45227 r45354  
    664664    RTManifestVerifyFiles
    665665    RTManifestVerifyFilesBuf
     666    RTManifestVerifyDigestType
    666667    RTManifestWriteFiles
    667668    RTManifestWriteFilesBuf
  • trunk/src/VBox/Runtime/common/checksum/manifest.cpp

    r45227 r45354  
    322322            break;
    323323        }
     324
     325        pcBuf += cch;
     326        cbRead += cch;
    324327    }
    325328
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