From 5cb01b477d85920662112d63b5a44b75c03762a9 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sun, 2 May 2021 16:07:18 -0500 Subject: Allow launching approved exes from the original package cache. --- src/burn/engine/approvedexe.cpp | 16 +++++++- src/burn/engine/cache.cpp | 91 ++++++++++++++++++++++++++++++++--------- src/burn/engine/cache.h | 7 ++-- 3 files changed, 88 insertions(+), 26 deletions(-) (limited to 'src/burn') diff --git a/src/burn/engine/approvedexe.cpp b/src/burn/engine/approvedexe.cpp index 55518519..e3d51a47 100644 --- a/src/burn/engine/approvedexe.cpp +++ b/src/burn/engine/approvedexe.cpp @@ -217,6 +217,7 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation( { HRESULT hr = S_OK; LPWSTR scz = NULL; + LPWSTR sczSecondary = NULL; const LPCWSTR vrgSecureFolderVariables[] = { L"ProgramFiles64Folder", @@ -243,10 +244,20 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation( } // The problem with using a Variable for the root package cache folder is that it might not have been secured yet. - // Getting it through CacheGetRootCompletedPath makes sure it has been secured. - hr = CacheGetRootCompletedPath(TRUE, TRUE, &scz); + // Getting it through CacheGetPerMachineRootCompletedPath makes sure it has been secured. + hr = CacheGetPerMachineRootCompletedPath(&scz, &sczSecondary); ExitOnFailure(hr, "Failed to get the root package cache folder."); + // If the package cache is redirected, hr is S_FALSE. + if (S_FALSE == hr) + { + hr = PathDirectoryContainsPath(sczSecondary, pLaunchApprovedExe->sczExecutablePath); + if (S_OK == hr) + { + ExitFunction(); + } + } + hr = PathDirectoryContainsPath(scz, pLaunchApprovedExe->sczExecutablePath); if (S_OK == hr) { @@ -257,6 +268,7 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation( LExit: ReleaseStr(scz); + ReleaseStr(sczSecondary); return hr; } diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp index 59daf139..d1999a0d 100644 --- a/src/burn/engine/cache.cpp +++ b/src/burn/engine/cache.cpp @@ -25,10 +25,11 @@ static HRESULT GetLastUsedSourceFolder( __in BURN_VARIABLES* pVariables, __out_z LPWSTR* psczLastSource ); +static HRESULT SecurePerMachineCacheRoot(); static HRESULT CreateCompletedPath( __in BOOL fPerMachine, __in LPCWSTR wzCacheId, - __out LPWSTR* psczCacheDirectory + __out_z LPWSTR* psczCacheDirectory ); static HRESULT CreateUnverifiedPath( __in BOOL fPerMachine, @@ -341,23 +342,31 @@ LExit: return hr; } -extern "C" HRESULT CacheGetRootCompletedPath( - __in BOOL fPerMachine, - __in BOOL fForceInitialize, - __deref_out_z LPWSTR* psczRootCompletedPath +extern "C" HRESULT CacheGetPerMachineRootCompletedPath( + __out_z LPWSTR* psczCurrentRootCompletedPath, + __out_z LPWSTR* psczDefaultRootCompletedPath ) { HRESULT hr = S_OK; - if (fForceInitialize) - { - hr = CreateCompletedPath(fPerMachine, L"", psczRootCompletedPath); - } - else + *psczCurrentRootCompletedPath = NULL; + *psczDefaultRootCompletedPath = NULL; + + hr = SecurePerMachineCacheRoot(); + ExitOnFailure(hr, "Failed to secure per-machine cache root."); + + hr = GetRootPath(TRUE, TRUE, psczCurrentRootCompletedPath); + ExitOnFailure(hr, "Failed to get per-machine cache root."); + + if (S_FALSE == hr) { - hr = GetRootPath(fPerMachine, TRUE, psczRootCompletedPath); + hr = GetRootPath(TRUE, FALSE, psczDefaultRootCompletedPath); + ExitOnFailure(hr, "Failed to get default per-machine cache root."); + + hr = S_FALSE; } +LExit: return hr; } @@ -1337,24 +1346,24 @@ static HRESULT GetLastUsedSourceFolder( return hr; } -static HRESULT CreateCompletedPath( - __in BOOL fPerMachine, - __in LPCWSTR wzId, - __out LPWSTR* psczCacheDirectory - ) +static HRESULT SecurePerMachineCacheRoot() { static BOOL fPerMachineCacheRootVerified = FALSE; + static BOOL fOriginalPerMachineCacheRootVerified = FALSE; HRESULT hr = S_OK; + BOOL fRedirected = FALSE; LPWSTR sczCacheDirectory = NULL; - // If we are doing a permachine install but have not yet verified that the root cache folder - // was created with the correct ACLs yet, do that now. - if (fPerMachine && !fPerMachineCacheRootVerified) + if (!fPerMachineCacheRootVerified) { - hr = GetRootPath(fPerMachine, TRUE, &sczCacheDirectory); + // If we are doing a permachine install but have not yet verified that the root cache folder + // was created with the correct ACLs yet, do that now. + hr = GetRootPath(TRUE, TRUE, &sczCacheDirectory); ExitOnFailure(hr, "Failed to get cache directory."); + fRedirected = S_FALSE == hr; + hr = DirEnsureExists(sczCacheDirectory, NULL); ExitOnFailure(hr, "Failed to create cache directory: %ls", sczCacheDirectory); @@ -1362,6 +1371,48 @@ static HRESULT CreateCompletedPath( ExitOnFailure(hr, "Failed to secure cache directory: %ls", sczCacheDirectory); fPerMachineCacheRootVerified = TRUE; + + if (!fRedirected) + { + fOriginalPerMachineCacheRootVerified = TRUE; + } + } + + if (!fOriginalPerMachineCacheRootVerified) + { + // If we are doing a permachine install but have not yet verified that the original root cache folder + // was created with the correct ACLs yet, do that now. + hr = GetRootPath(TRUE, FALSE, &sczCacheDirectory); + ExitOnFailure(hr, "Failed to get original cache directory."); + + hr = DirEnsureExists(sczCacheDirectory, NULL); + ExitOnFailure(hr, "Failed to create original cache directory: %ls", sczCacheDirectory); + + hr = SecurePath(sczCacheDirectory); + ExitOnFailure(hr, "Failed to secure original cache directory: %ls", sczCacheDirectory); + + fOriginalPerMachineCacheRootVerified = TRUE; + } + +LExit: + ReleaseStr(sczCacheDirectory); + + return hr; +} + +static HRESULT CreateCompletedPath( + __in BOOL fPerMachine, + __in LPCWSTR wzId, + __out_z LPWSTR* psczCacheDirectory + ) +{ + HRESULT hr = S_OK; + LPWSTR sczCacheDirectory = NULL; + + if (fPerMachine) + { + hr = SecurePerMachineCacheRoot(); + ExitOnFailure(hr, "Failed to secure per-machine cache root."); } // Get the cache completed path, ensure it exists, and reset any permissions people diff --git a/src/burn/engine/cache.h b/src/burn/engine/cache.h index 0152d33b..a300e99d 100644 --- a/src/burn/engine/cache.h +++ b/src/burn/engine/cache.h @@ -80,10 +80,9 @@ HRESULT CacheCalculateContainerWorkingPath( __in BURN_CONTAINER* pContainer, __deref_out_z LPWSTR* psczWorkingPath ); -HRESULT CacheGetRootCompletedPath( - __in BOOL fPerMachine, - __in BOOL fForceInitialize, - __deref_out_z LPWSTR* psczRootCompletedPath +HRESULT CacheGetPerMachineRootCompletedPath( + __out_z LPWSTR* psczCurrentRootCompletedPath, + __out_z LPWSTR* psczDefaultRootCompletedPath ); HRESULT CacheGetCompletedPath( __in BOOL fPerMachine, -- cgit v1.2.3-55-g6feb