@joebigelow / wix / commits / 5cb01b47

Allow launching approved exes from the original package cache.

Sean Hall committed May 2, 2021 at 16:07 UTC 5cb01b477d85920662112d63b5a44b75c03762a9
3 files changed +88 -26
src/burn/engine/approvedexe.cpp
+14 -2
@@ -217,6 +217,7 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation(
217 {
218 HRESULT hr = S_OK;
219 LPWSTR scz = NULL;
220 + LPWSTR sczSecondary = NULL;
221
222 const LPCWSTR vrgSecureFolderVariables[] = {
223 L"ProgramFiles64Folder",
@@ -243,10 +244,20 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation(
244 }
245
246 // The problem with using a Variable for the root package cache folder is that it might not have been secured yet.
246 - // Getting it through CacheGetRootCompletedPath makes sure it has been secured.
247 - hr = CacheGetRootCompletedPath(TRUE, TRUE, &scz);
247 + // Getting it through CacheGetPerMachineRootCompletedPath makes sure it has been secured.
248 + hr = CacheGetPerMachineRootCompletedPath(&scz, &sczSecondary);
249 ExitOnFailure(hr, "Failed to get the root package cache folder.");
250
251 + // If the package cache is redirected, hr is S_FALSE.
252 + if (S_FALSE == hr)
253 + {
254 + hr = PathDirectoryContainsPath(sczSecondary, pLaunchApprovedExe->sczExecutablePath);
255 + if (S_OK == hr)
256 + {
257 + ExitFunction();
258 + }
259 + }
260 +
261 hr = PathDirectoryContainsPath(scz, pLaunchApprovedExe->sczExecutablePath);
262 if (S_OK == hr)
263 {
@@ -257,6 +268,7 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation(
268
269 LExit:
270 ReleaseStr(scz);
271 + ReleaseStr(sczSecondary);
272
273 return hr;
274 }
src/burn/engine/cache.cpp
+71 -20
@@ -25,10 +25,11 @@ static HRESULT GetLastUsedSourceFolder(
25 __in BURN_VARIABLES* pVariables,
26 __out_z LPWSTR* psczLastSource
27 );
28 +static HRESULT SecurePerMachineCacheRoot();
29 static HRESULT CreateCompletedPath(
30 __in BOOL fPerMachine,
31 __in LPCWSTR wzCacheId,
31 - __out LPWSTR* psczCacheDirectory
32 + __out_z LPWSTR* psczCacheDirectory
33 );
34 static HRESULT CreateUnverifiedPath(
35 __in BOOL fPerMachine,
@@ -341,23 +342,31 @@ LExit:
342 return hr;
343 }
344
344 -extern "C" HRESULT CacheGetRootCompletedPath(
345 - __in BOOL fPerMachine,
346 - __in BOOL fForceInitialize,
347 - __deref_out_z LPWSTR* psczRootCompletedPath
345 +extern "C" HRESULT CacheGetPerMachineRootCompletedPath(
346 + __out_z LPWSTR* psczCurrentRootCompletedPath,
347 + __out_z LPWSTR* psczDefaultRootCompletedPath
348 )
349 {
350 HRESULT hr = S_OK;
351
352 - if (fForceInitialize)
353 - {
354 - hr = CreateCompletedPath(fPerMachine, L"", psczRootCompletedPath);
355 - }
356 - else
352 + *psczCurrentRootCompletedPath = NULL;
353 + *psczDefaultRootCompletedPath = NULL;
354 +
355 + hr = SecurePerMachineCacheRoot();
356 + ExitOnFailure(hr, "Failed to secure per-machine cache root.");
357 +
358 + hr = GetRootPath(TRUE, TRUE, psczCurrentRootCompletedPath);
359 + ExitOnFailure(hr, "Failed to get per-machine cache root.");
360 +
361 + if (S_FALSE == hr)
362 {
358 - hr = GetRootPath(fPerMachine, TRUE, psczRootCompletedPath);
363 + hr = GetRootPath(TRUE, FALSE, psczDefaultRootCompletedPath);
364 + ExitOnFailure(hr, "Failed to get default per-machine cache root.");
365 +
366 + hr = S_FALSE;
367 }
368
369 +LExit:
370 return hr;
371 }
372
@@ -1337,24 +1346,24 @@ static HRESULT GetLastUsedSourceFolder(
1346 return hr;
1347 }
1348
1340 -static HRESULT CreateCompletedPath(
1341 - __in BOOL fPerMachine,
1342 - __in LPCWSTR wzId,
1343 - __out LPWSTR* psczCacheDirectory
1344 - )
1349 +static HRESULT SecurePerMachineCacheRoot()
1350 {
1351 static BOOL fPerMachineCacheRootVerified = FALSE;
1352 + static BOOL fOriginalPerMachineCacheRootVerified = FALSE;
1353
1354 HRESULT hr = S_OK;
1355 + BOOL fRedirected = FALSE;
1356 LPWSTR sczCacheDirectory = NULL;
1357
1351 - // If we are doing a permachine install but have not yet verified that the root cache folder
1352 - // was created with the correct ACLs yet, do that now.
1353 - if (fPerMachine && !fPerMachineCacheRootVerified)
1358 + if (!fPerMachineCacheRootVerified)
1359 {
1355 - hr = GetRootPath(fPerMachine, TRUE, &sczCacheDirectory);
1360 + // If we are doing a permachine install but have not yet verified that the root cache folder
1361 + // was created with the correct ACLs yet, do that now.
1362 + hr = GetRootPath(TRUE, TRUE, &sczCacheDirectory);
1363 ExitOnFailure(hr, "Failed to get cache directory.");
1364
1365 + fRedirected = S_FALSE == hr;
1366 +
1367 hr = DirEnsureExists(sczCacheDirectory, NULL);
1368 ExitOnFailure(hr, "Failed to create cache directory: %ls", sczCacheDirectory);
1369
@@ -1362,6 +1371,48 @@ static HRESULT CreateCompletedPath(
1371 ExitOnFailure(hr, "Failed to secure cache directory: %ls", sczCacheDirectory);
1372
1373 fPerMachineCacheRootVerified = TRUE;
1374 +
1375 + if (!fRedirected)
1376 + {
1377 + fOriginalPerMachineCacheRootVerified = TRUE;
1378 + }
1379 + }
1380 +
1381 + if (!fOriginalPerMachineCacheRootVerified)
1382 + {
1383 + // If we are doing a permachine install but have not yet verified that the original root cache folder
1384 + // was created with the correct ACLs yet, do that now.
1385 + hr = GetRootPath(TRUE, FALSE, &sczCacheDirectory);
1386 + ExitOnFailure(hr, "Failed to get original cache directory.");
1387 +
1388 + hr = DirEnsureExists(sczCacheDirectory, NULL);
1389 + ExitOnFailure(hr, "Failed to create original cache directory: %ls", sczCacheDirectory);
1390 +
1391 + hr = SecurePath(sczCacheDirectory);
1392 + ExitOnFailure(hr, "Failed to secure original cache directory: %ls", sczCacheDirectory);
1393 +
1394 + fOriginalPerMachineCacheRootVerified = TRUE;
1395 + }
1396 +
1397 +LExit:
1398 + ReleaseStr(sczCacheDirectory);
1399 +
1400 + return hr;
1401 +}
1402 +
1403 +static HRESULT CreateCompletedPath(
1404 + __in BOOL fPerMachine,
1405 + __in LPCWSTR wzId,
1406 + __out_z LPWSTR* psczCacheDirectory
1407 + )
1408 +{
1409 + HRESULT hr = S_OK;
1410 + LPWSTR sczCacheDirectory = NULL;
1411 +
1412 + if (fPerMachine)
1413 + {
1414 + hr = SecurePerMachineCacheRoot();
1415 + ExitOnFailure(hr, "Failed to secure per-machine cache root.");
1416 }
1417
1418 // Get the cache completed path, ensure it exists, and reset any permissions people
src/burn/engine/cache.h
+3 -4
@@ -80,10 +80,9 @@ HRESULT CacheCalculateContainerWorkingPath(
80 __in BURN_CONTAINER* pContainer,
81 __deref_out_z LPWSTR* psczWorkingPath
82 );
83 -HRESULT CacheGetRootCompletedPath(
84 - __in BOOL fPerMachine,
85 - __in BOOL fForceInitialize,
86 - __deref_out_z LPWSTR* psczRootCompletedPath
83 +HRESULT CacheGetPerMachineRootCompletedPath(
84 + __out_z LPWSTR* psczCurrentRootCompletedPath,
85 + __out_z LPWSTR* psczDefaultRootCompletedPath
86 );
87 HRESULT CacheGetCompletedPath(
88 __in BOOL fPerMachine,