c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync/* $Id$ */
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync/** @file
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync * IPRT - Manifest file handling, old style - deprecated.
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync */
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync/*
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync * Copyright (C) 2009-2013 Oracle Corporation
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync *
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * available from http://www.virtualbox.org. This file is free software;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * General Public License (GPL) as published by the Free Software
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync *
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * The contents of this file may alternatively be used under the terms
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * of the Common Development and Distribution License Version 1.0
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * VirtualBox OSE distribution, in which case the provisions of the
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * CDDL are applicable instead of those of the GPL.
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync *
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * You may elect to license modified versions of this file under the
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * terms and conditions of either the GPL or the CDDL or both.
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync */
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
70dd77b2f7732defac9d929109f20d92676f0570vboxsync/*******************************************************************************
70dd77b2f7732defac9d929109f20d92676f0570vboxsync* Header Files *
70dd77b2f7732defac9d929109f20d92676f0570vboxsync*******************************************************************************/
70dd77b2f7732defac9d929109f20d92676f0570vboxsync#include "internal/iprt.h"
70dd77b2f7732defac9d929109f20d92676f0570vboxsync#include <iprt/manifest.h>
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
70dd77b2f7732defac9d929109f20d92676f0570vboxsync#include <iprt/err.h>
70dd77b2f7732defac9d929109f20d92676f0570vboxsync#include <iprt/file.h>
70dd77b2f7732defac9d929109f20d92676f0570vboxsync#include <iprt/mem.h>
70dd77b2f7732defac9d929109f20d92676f0570vboxsync#include <iprt/path.h>
e9b9aa0cb0196b30917a7756bc124db5e7e9ca76vboxsync#include <iprt/sha.h>
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync#include <iprt/stream.h>
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync#include <iprt/string.h>
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync/*******************************************************************************
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync* Structures and Typedefs *
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync*******************************************************************************/
70dd77b2f7732defac9d929109f20d92676f0570vboxsync/**
70dd77b2f7732defac9d929109f20d92676f0570vboxsync * Internal per file structure used by RTManifestVerify
70dd77b2f7732defac9d929109f20d92676f0570vboxsync */
70dd77b2f7732defac9d929109f20d92676f0570vboxsynctypedef struct RTMANIFESTFILEENTRY
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync{
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync char *pszManifestFile;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync char *pszManifestDigest;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync PRTMANIFESTTEST pTestPattern;
70dd77b2f7732defac9d929109f20d92676f0570vboxsync} RTMANIFESTFILEENTRY;
70dd77b2f7732defac9d929109f20d92676f0570vboxsynctypedef RTMANIFESTFILEENTRY* PRTMANIFESTFILEENTRY;
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync/**
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync * Internal structure used for the progress callback
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync */
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsynctypedef struct RTMANIFESTCALLBACKDATA
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync{
44918d7b9fb45f0d3e2ba56bf6d2cede9a2ae566vboxsync PFNRTPROGRESS pfnProgressCallback;
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync void *pvUser;
5c90ca78888c7bb1632ef4c131cc668b03227271vboxsync size_t cMaxFiles;
5c90ca78888c7bb1632ef4c131cc668b03227271vboxsync size_t cCurrentFile;
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync} RTMANIFESTCALLBACKDATA;
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsynctypedef RTMANIFESTCALLBACKDATA* PRTMANIFESTCALLBACKDATA;
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync/*******************************************************************************
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync* Private functions
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync*******************************************************************************/
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsyncDECLINLINE(char *) rtManifestPosOfCharInBuf(char const *pv, size_t cb, char c)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync{
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync char *pb = (char *)pv;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync for (; cb; --cb, ++pb)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_UNLIKELY(*pb == c))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync return pb;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync return NULL;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync}
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsyncDECLINLINE(size_t) rtManifestIndexOfCharInBuf(char const *pv, size_t cb, char c)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync{
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync char const *pb = (char const *)pv;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync for (size_t i=0; i < cb; ++i, ++pb)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_UNLIKELY(*pb == c))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync return i;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync return cb;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync}
44918d7b9fb45f0d3e2ba56bf6d2cede9a2ae566vboxsync
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsyncint rtSHAProgressCallback(unsigned uPercent, void *pvUser)
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync{
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync PRTMANIFESTCALLBACKDATA pData = (PRTMANIFESTCALLBACKDATA)pvUser;
44918d7b9fb45f0d3e2ba56bf6d2cede9a2ae566vboxsync return pData->pfnProgressCallback((unsigned)( (uPercent + (float)pData->cCurrentFile * 100.0)
44918d7b9fb45f0d3e2ba56bf6d2cede9a2ae566vboxsync / (float)pData->cMaxFiles),
44918d7b9fb45f0d3e2ba56bf6d2cede9a2ae566vboxsync pData->pvUser);
510dd1bd989d25f95680fc2a3b51bf11854bc6a4vboxsync}
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync/*******************************************************************************
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync* Public functions
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync*******************************************************************************/
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
0aa6851583f4cb074ccc163d5b53948b9429ab77vboxsyncRTR3DECL(int) RTManifestVerify(const char *pszManifestFile, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync{
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Validate input */
70dd77b2f7732defac9d929109f20d92676f0570vboxsync AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Open the manifest file */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTFILE file;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync int rc = RTFileOpen(&file, pszManifestFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync if (RT_FAILURE(rc))
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync return rc;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync void *pvBuf = 0;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync do
70dd77b2f7732defac9d929109f20d92676f0570vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync uint64_t cbSize;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = RTFileGetSize(file, &cbSize);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_FAILURE(rc))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync break;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Cast down for the case size_t < uint64_t. This isn't really correct,
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync but we consider manifest files bigger than size_t as not supported
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync by now. */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync size_t cbToRead = (size_t)cbSize;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync pvBuf = RTMemAlloc(cbToRead);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (!pvBuf)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = VERR_NO_MEMORY;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync break;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync size_t cbRead = 0;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = RTFileRead(file, pvBuf, cbToRead, &cbRead);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_FAILURE(rc))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync break;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = RTManifestVerifyFilesBuf(pvBuf, cbRead, paTests, cTests, piFailed);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }while (0);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Cleanup */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (pvBuf)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTMemFree(pvBuf);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTFileClose(file);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync return rc;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync}
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsyncRTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed,
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync PFNRTPROGRESS pfnProgressCallback, void *pvUser)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync{
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Validate input */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync int rc = VINF_SUCCESS;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Create our compare list */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync PRTMANIFESTTEST paFiles = (PRTMANIFESTTEST)RTMemTmpAllocZ(sizeof(RTMANIFESTTEST) * cFiles);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (!paFiles)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync return VERR_NO_MEMORY;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 };
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Fill our compare list */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync for (size_t i = 0; i < cFiles; ++i)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync char *pszDigest;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (pfnProgressCallback)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync callback.cCurrentFile = i;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = RTSha1DigestFromFile(papszFiles[i], &pszDigest, rtSHAProgressCallback, &callback);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync else
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = RTSha1DigestFromFile(papszFiles[i], &pszDigest, NULL, NULL);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_FAILURE(rc))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync break;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync paFiles[i].pszTestFile = (char*)papszFiles[i];
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync paFiles[i].pszTestDigest = pszDigest;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Do the verification */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_SUCCESS(rc))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = RTManifestVerify(pszManifestFile, paFiles, cFiles, piFailed);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Cleanup */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync for (size_t i = 0; i < cFiles; ++i)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (paFiles[i].pszTestDigest)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTStrFree((char*)paFiles[i].pszTestDigest);
70dd77b2f7732defac9d929109f20d92676f0570vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTMemTmpFree(paFiles);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync return rc;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync}
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
454ac5c6ef4960887035ceea6b5247789d3272davboxsyncRTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, RTDIGESTTYPE enmDigestType,
454ac5c6ef4960887035ceea6b5247789d3272davboxsync const char * const *papszFiles, size_t cFiles,
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync PFNRTPROGRESS pfnProgressCallback, void *pvUser)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync{
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Validate input */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTFILE file;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync int rc = RTFileOpen(&file, pszManifestFile, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_FAILURE(rc))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync return rc;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync PRTMANIFESTTEST paFiles = 0;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync void *pvBuf = 0;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync do
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync paFiles = (PRTMANIFESTTEST)RTMemAllocZ(sizeof(RTMANIFESTTEST) * cFiles);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (!paFiles)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = VERR_NO_MEMORY;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync break;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 };
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync for (size_t i = 0; i < cFiles; ++i)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync paFiles[i].pszTestFile = papszFiles[i];
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Calculate the SHA1 digest of every file */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (pfnProgressCallback)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync callback.cCurrentFile = i;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = RTSha1DigestFromFile(paFiles[i].pszTestFile, (char**)&paFiles[i].pszTestDigest, rtSHAProgressCallback, &callback);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync else
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = RTSha1DigestFromFile(paFiles[i].pszTestFile, (char**)&paFiles[i].pszTestDigest, NULL, NULL);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_FAILURE(rc))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync break;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_SUCCESS(rc))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync size_t cbSize = 0;
454ac5c6ef4960887035ceea6b5247789d3272davboxsync rc = RTManifestWriteFilesBuf(&pvBuf, &cbSize, enmDigestType, paFiles, cFiles);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_FAILURE(rc))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync break;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = RTFileWrite(file, pvBuf, cbSize, 0);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }while (0);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTFileClose(file);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Cleanup */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (pvBuf)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTMemFree(pvBuf);
15c9dd245e18b5ed97c0fd67b6601c956d667e9bvboxsync if (paFiles)
15c9dd245e18b5ed97c0fd67b6601c956d667e9bvboxsync {
15c9dd245e18b5ed97c0fd67b6601c956d667e9bvboxsync for (size_t i = 0; i < cFiles; ++i)
15c9dd245e18b5ed97c0fd67b6601c956d667e9bvboxsync if (paFiles[i].pszTestDigest)
15c9dd245e18b5ed97c0fd67b6601c956d667e9bvboxsync RTStrFree((char*)paFiles[i].pszTestDigest);
15c9dd245e18b5ed97c0fd67b6601c956d667e9bvboxsync RTMemFree(paFiles);
15c9dd245e18b5ed97c0fd67b6601c956d667e9bvboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Delete the manifest file on failure */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (RT_FAILURE(rc))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTFileDelete(pszManifestFile);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync return rc;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync}
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync
3ebe113eb15a12d6c582ae88a0dae0d70a536b17vboxsyncRTR3DECL(int) RTManifestVerifyDigestType(void const *pvBuf, size_t cbSize, RTDIGESTTYPE *penmDigestType)
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync{
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync /* Validate input */
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync AssertReturn(cbSize > 0, VERR_INVALID_PARAMETER);
b5bd02feb556d7d95f484d9cbd87c97888e9cc9avboxsync AssertPtrReturn(penmDigestType, VERR_INVALID_POINTER);
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync int rc = VINF_SUCCESS;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync char const *pcBuf = (char *)pvBuf;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync size_t cbRead = 0;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync /* Parse the manifest file line by line */
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync for (;;)
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync {
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync if (cbRead >= cbSize)
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync return VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync size_t cch = rtManifestIndexOfCharInBuf(pcBuf, cbSize - cbRead, '\n') + 1;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync /* Skip empty lines (UNIX/DOS format) */
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync if ( ( cch == 1
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync && pcBuf[0] == '\n')
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync || ( cch == 2
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync && pcBuf[0] == '\r'
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync && pcBuf[1] == '\n'))
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync {
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync pcBuf += cch;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync cbRead += cch;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync continue;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync }
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync/** @todo r=bird: Missing space check here. */
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync /* Check for the digest algorithm */
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync if ( pcBuf[0] == 'S'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[1] == 'H'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[2] == 'A'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[3] == '1')
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync {
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync *penmDigestType = RTDIGESTTYPE_SHA1;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync break;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync }
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync if ( pcBuf[0] == 'S'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[1] == 'H'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[2] == 'A'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[3] == '2'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[4] == '5'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[5] == '6')
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync {
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync *penmDigestType = RTDIGESTTYPE_SHA256;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync break;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync }
a536b4958564d95ba9fb795645a7b876e6b409edvboxsync
a536b4958564d95ba9fb795645a7b876e6b409edvboxsync pcBuf += cch;
a536b4958564d95ba9fb795645a7b876e6b409edvboxsync cbRead += cch;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync }
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync return rc;
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync}
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsyncRTR3DECL(int) RTManifestVerifyFilesBuf(void *pvBuf, size_t cbSize, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync{
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Validate input */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertReturn(cbSize > 0, VERR_INVALID_PARAMETER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrReturn(paTests, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertReturn(cTests > 0, VERR_INVALID_PARAMETER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrNullReturn(piFailed, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync int rc = VINF_SUCCESS;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync PRTMANIFESTFILEENTRY paFiles = (PRTMANIFESTFILEENTRY)RTMemTmpAllocZ(sizeof(RTMANIFESTFILEENTRY) * cTests);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (!paFiles)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync return VERR_NO_MEMORY;
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Fill our compare list */
70dd77b2f7732defac9d929109f20d92676f0570vboxsync for (size_t i = 0; i < cTests; ++i)
70dd77b2f7732defac9d929109f20d92676f0570vboxsync paFiles[i].pTestPattern = &paTests[i];
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync char *pcBuf = (char*)pvBuf;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync size_t cbRead = 0;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Parse the manifest file line by line */
70dd77b2f7732defac9d929109f20d92676f0570vboxsync for (;;)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (cbRead >= cbSize)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync size_t cch = rtManifestIndexOfCharInBuf(pcBuf, cbSize - cbRead, '\n') + 1;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Skip empty lines (UNIX/DOS format) */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if ( ( cch == 1
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync && pcBuf[0] == '\n')
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync || ( cch == 2
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync && pcBuf[0] == '\r'
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync && pcBuf[1] == '\n'))
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync pcBuf += cch;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync cbRead += cch;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync continue;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
70dd77b2f7732defac9d929109f20d92676f0570vboxsync /** @todo r=bird:
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync * -# Better deal with this EOF line platform dependency
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync * -# The SHA1 and SHA256 tests should probably include a blank space check.
70dd77b2f7732defac9d929109f20d92676f0570vboxsync * -# If there is a specific order to the elements in the string, it would be
70dd77b2f7732defac9d929109f20d92676f0570vboxsync * good if the delimiter searching checked for it.
70dd77b2f7732defac9d929109f20d92676f0570vboxsync * -# Deal with filenames containing delimiter characters.
70dd77b2f7732defac9d929109f20d92676f0570vboxsync */
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Check for the digest algorithm */
64eea8161bef2aa3c6516481383c830bca27abfevboxsync if ( cch < 4
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync || ( !( pcBuf[0] == 'S'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[1] == 'H'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[2] == 'A'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[3] == '1')
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync &&
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync !( pcBuf[0] == 'S'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[1] == 'H'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[2] == 'A'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[3] == '2'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[4] == '5'
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync && pcBuf[5] == '6')
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync )
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync )
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Digest unsupported */
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync rc = VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Try to find the filename */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync char *pszNameStart = rtManifestPosOfCharInBuf(pcBuf, cch, '(');
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync if (!pszNameStart)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync rc = VERR_MANIFEST_WRONG_FILE_FORMAT;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync char *pszNameEnd = rtManifestPosOfCharInBuf(pcBuf, cch, ')');
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync if (!pszNameEnd)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync rc = VERR_MANIFEST_WRONG_FILE_FORMAT;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Copy the filename part */
70dd77b2f7732defac9d929109f20d92676f0570vboxsync size_t cchName = pszNameEnd - pszNameStart - 1;
70dd77b2f7732defac9d929109f20d92676f0570vboxsync char *pszName = (char *)RTMemTmpAlloc(cchName + 1);
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync if (!pszName)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync rc = VERR_NO_MEMORY;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
70dd77b2f7732defac9d929109f20d92676f0570vboxsync memcpy(pszName, pszNameStart + 1, cchName);
70dd77b2f7732defac9d929109f20d92676f0570vboxsync pszName[cchName] = '\0';
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Try to find the digest sum */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync char *pszDigestStart = rtManifestPosOfCharInBuf(pcBuf, cch, '=') + 1;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync if (!pszDigestStart)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
70dd77b2f7732defac9d929109f20d92676f0570vboxsync RTMemTmpFree(pszName);
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync rc = VERR_MANIFEST_WRONG_FILE_FORMAT;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync char *pszDigestEnd = rtManifestPosOfCharInBuf(pcBuf, cch, '\r');
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (!pszDigestEnd)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync pszDigestEnd = rtManifestPosOfCharInBuf(pcBuf, cch, '\n');
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (!pszDigestEnd)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
0dabe3e0e6f599b3b145b971cdfded9a3d1606fcvboxsync RTMemTmpFree(pszName);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = VERR_MANIFEST_WRONG_FILE_FORMAT;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync break;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync /* Copy the digest part */
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync size_t cchDigest = pszDigestEnd - pszDigestStart - 1;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync char *pszDigest = (char *)RTMemTmpAlloc(cchDigest + 1);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync if (!pszDigest)
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync {
0dabe3e0e6f599b3b145b971cdfded9a3d1606fcvboxsync RTMemTmpFree(pszName);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync rc = VERR_NO_MEMORY;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync break;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync memcpy(pszDigest, pszDigestStart + 1, cchDigest);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync pszDigest[cchDigest] = '\0';
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Check our file list against the extracted data */
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync bool fFound = false;
70dd77b2f7732defac9d929109f20d92676f0570vboxsync for (size_t i = 0; i < cTests; ++i)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
13194d15bc799cdfb231c1ba3fa26674334601b5vboxsync /** @todo r=bird: Using RTStrStr here looks bogus. */
25479956e51de7af723c8958182331275d25542dvboxsync if (RTStrStr(paFiles[i].pTestPattern->pszTestFile, RTStrStrip(pszName)) != NULL)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Add the data of the manifest file to the file list */
70dd77b2f7732defac9d929109f20d92676f0570vboxsync paFiles[i].pszManifestFile = RTStrDup(RTStrStrip(pszName));
70dd77b2f7732defac9d929109f20d92676f0570vboxsync paFiles[i].pszManifestDigest = RTStrDup(RTStrStrip(pszDigest));
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync fFound = true;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
70dd77b2f7732defac9d929109f20d92676f0570vboxsync RTMemTmpFree(pszName);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync RTMemTmpFree(pszDigest);
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync if (!fFound)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* There have to be an entry in the file list */
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync rc = VERR_MANIFEST_FILE_MISMATCH;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync pcBuf += cch;
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync cbRead += cch;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
70dd77b2f7732defac9d929109f20d92676f0570vboxsync if ( rc == VINF_SUCCESS
70dd77b2f7732defac9d929109f20d92676f0570vboxsync || rc == VERR_EOF)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync rc = VINF_SUCCESS;
70dd77b2f7732defac9d929109f20d92676f0570vboxsync for (size_t i = 0; i < cTests; ++i)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* If there is an entry in the file list, which hasn't an
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync * equivalent in the manifest file, its an error. */
70dd77b2f7732defac9d929109f20d92676f0570vboxsync if ( !paFiles[i].pszManifestFile
70dd77b2f7732defac9d929109f20d92676f0570vboxsync || !paFiles[i].pszManifestDigest)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync rc = VERR_MANIFEST_FILE_MISMATCH;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
70dd77b2f7732defac9d929109f20d92676f0570vboxsync
25479956e51de7af723c8958182331275d25542dvboxsync /* Do the manifest SHA digest match against the actual digest? */
70dd77b2f7732defac9d929109f20d92676f0570vboxsync if (RTStrICmp(paFiles[i].pszManifestDigest, paFiles[i].pTestPattern->pszTestDigest))
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
0aa6851583f4cb074ccc163d5b53948b9429ab77vboxsync if (piFailed)
0aa6851583f4cb074ccc163d5b53948b9429ab77vboxsync *piFailed = i;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync rc = VERR_MANIFEST_DIGEST_MISMATCH;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync break;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync /* Cleanup */
70dd77b2f7732defac9d929109f20d92676f0570vboxsync for (size_t i = 0; i < cTests; ++i)
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync {
70dd77b2f7732defac9d929109f20d92676f0570vboxsync if (paFiles[i].pszManifestFile)
70dd77b2f7732defac9d929109f20d92676f0570vboxsync RTStrFree(paFiles[i].pszManifestFile);
70dd77b2f7732defac9d929109f20d92676f0570vboxsync if (paFiles[i].pszManifestDigest)
70dd77b2f7732defac9d929109f20d92676f0570vboxsync RTStrFree(paFiles[i].pszManifestDigest);
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync }
70dd77b2f7732defac9d929109f20d92676f0570vboxsync RTMemTmpFree(paFiles);
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync return rc;
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync}
c40afa339b10a23d6fffcbeb7d4572bb494685f0vboxsync
454ac5c6ef4960887035ceea6b5247789d3272davboxsyncRTR3DECL(int) RTManifestWriteFilesBuf(void **ppvBuf, size_t *pcbSize, RTDIGESTTYPE enmDigestType, PRTMANIFESTTEST paFiles, size_t cFiles)
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync{
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync /* Validate input */
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync AssertPtrReturn(ppvBuf, VERR_INVALID_POINTER);
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync AssertPtrReturn(paFiles, VERR_INVALID_POINTER);
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync AssertReturn(cFiles > 0, VERR_INVALID_PARAMETER);
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync const char *pcszDigestType;
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync switch (enmDigestType)
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync {
2cc6ff50968f2560102f978e15835298ecfb6f2fvboxsync case RTDIGESTTYPE_CRC32: pcszDigestType = "CRC32"; break;
2cc6ff50968f2560102f978e15835298ecfb6f2fvboxsync case RTDIGESTTYPE_CRC64: pcszDigestType = "CRC64"; break;
2cc6ff50968f2560102f978e15835298ecfb6f2fvboxsync case RTDIGESTTYPE_MD5: pcszDigestType = "MD5"; break;
2cc6ff50968f2560102f978e15835298ecfb6f2fvboxsync case RTDIGESTTYPE_SHA1: pcszDigestType = "SHA1"; break;
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync case RTDIGESTTYPE_SHA256: pcszDigestType = "SHA256"; break;
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync default: return VERR_INVALID_PARAMETER;
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync }
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync /* Calculate the size necessary for the memory buffer. */
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync size_t cbSize = 0;
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync size_t cbMaxSize = 0;
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync for (size_t i = 0; i < cFiles; ++i)
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync {
2cc6ff50968f2560102f978e15835298ecfb6f2fvboxsync size_t cbTmp = strlen(RTPathFilename(paFiles[i].pszTestFile))
64eea8161bef2aa3c6516481383c830bca27abfevboxsync + strlen(paFiles[i].pszTestDigest)
2cc6ff50968f2560102f978e15835298ecfb6f2fvboxsync + strlen(pcszDigestType)
2cc6ff50968f2560102f978e15835298ecfb6f2fvboxsync + 6;
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync cbMaxSize = RT_MAX(cbMaxSize, cbTmp);
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync cbSize += cbTmp;
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync }
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync /* Create the memory buffer */
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync void *pvBuf = RTMemAlloc(cbSize);
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync if (!pvBuf)
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync return VERR_NO_MEMORY;
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync /* Allocate a temporary string buffer. */
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync char *pszTmp = RTStrAlloc(cbMaxSize + 1);
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync if (!pszTmp)
454ac5c6ef4960887035ceea6b5247789d3272davboxsync {
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync RTMemFree(pvBuf);
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync return VERR_NO_MEMORY;
454ac5c6ef4960887035ceea6b5247789d3272davboxsync }
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync size_t cbPos = 0;
24048050269b0c5b8eafb93ffee96baf17c4f23cvboxsync
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync for (size_t i = 0; i < cFiles; ++i)
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync {
454ac5c6ef4960887035ceea6b5247789d3272davboxsync size_t cch = RTStrPrintf(pszTmp, cbMaxSize + 1, "%s (%s)= %s\n", pcszDigestType, RTPathFilename(paFiles[i].pszTestFile), paFiles[i].pszTestDigest);
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync memcpy(&((char*)pvBuf)[cbPos], pszTmp, cch);
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync cbPos += cch;
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync }
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync RTStrFree(pszTmp);
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync /* Results */
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync *ppvBuf = pvBuf;
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync *pcbSize = cbSize;
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync return VINF_SUCCESS;
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync}
42f4857b15e5d875e39345f1d1b804c2c1313e91vboxsync