Treat MSI and CAB files as containers - #873
Conversation
|
Note, there's still an embedded CAB file inside the MSI that doesn't get signed. But AFAICT, it never gets laid out on disk, and its container--the MSI--gets signed anyway, so integrity is still guaranteed. |
| <add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" /> | ||
| <add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" /> | ||
| <!-- TODO: Mirror WixToolset.Dtf.WindowsInstaller.Package and dependencies --> | ||
| <add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> |
There was a problem hiding this comment.
This should be resolved before this PR is merged.
There was a problem hiding this comment.
Here are the instructions for mirroring a package. Also be sure to revert update this file.
This comment was marked as resolved.
This comment was marked as resolved.
Just a follow-up: it's probably OK for this regression as long as it doesn't roll out in a release. We'd like to add a new flag that doesn't recurse into file containers to go along with this. |
|
@bricelam please rebase since we migrated tests from Moq to NSubstitute. |
Recursively extract, sign, and re-assemble the contents of install packages and cabinets before signing the files themselves. Some files own others that sit beside them on disk. An MSI owns the cabinets that aren't embedded in it, and the payload files that aren't compressed at all. Signer gives every input its own temporary directory, so an MSI couldn't see its external cabinets and InstallPackage.ExtractFiles failed looking for them. When both the MSI and its cabinet were matched as inputs, they were signed independently and in parallel, racing on the output path and leaving the MSI's File table describing payloads that were never shipped. Add ISigningDependencyReader so a format can declare the files it owns, and ISigningDependencyProvider to resolve ownership across a set of files. Signer removes owned files from the input list, AggregatingSigner copies the declared dependencies into and back out of the working directory and signs them once their owner has rebuilt them, and MsiContainer moves the cabinets UpdateFiles rebuilds back beside the package. CabContainer preserves the order of the entries it repacks. Windows Installer requires the order of the files in a cabinet to match the order of the File table's Sequence column, and CabInfo.Pack used the order the file system happened to enumerate them in. MsiCreator builds minimal install packages at test time--with an embedded or an external cabinet--so the tests cover extraction, re-packaging, and the File table without checking in a binary package. ClickOnce has the same ownership problem and should move onto the same mechanism. See dotnet#1065. Fixes dotnet#673 Fixes dotnet#874 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GUPH4yvFhrR4W1jPi12P5f
|
PR updated. This should be good to go now. MSI tests added. |
|
From Claude Code A note on test coverage, since one behavior here is less covered than the rest. Two files are now signed as a unit: an MSI and any cabinet it owns. What is covered deterministically: What is not: The deterministic version would assert the decision rather than the outcome: capture the container logger in the test service provider and assert that no container is ever opened for an owned cabinet. That flips reliably when the pre-pass is disabled, because it depends only on Happy to add it if you would like it in this PR. |
Fixes #673, fixes #874