winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 23f9942415b83e6187beac122de6bd1c0bc2a009
parent bc9d2194647d14e21fc375c74b5b80ee60fe34fe
Author: Kaleb Luedtke <jluedtk@jci.com>
Date:   Wed, 14 Dec 2022 17:38:04 -0600

Separate Archive Scan argument related to security from `--force` (#2622)


Diffstat:
Mdoc/admx/DesktopAppInstaller.admx | 13+++++++++++--
Mdoc/admx/en-US/DesktopAppInstaller.adml | 7+++++++
Mdoc/specs/#140 - ZIP Support.md | 5+++--
Msrc/AppInstallerCLICore/Argument.cpp | 2++
Msrc/AppInstallerCLICore/Commands/InstallCommand.cpp | 1+
Msrc/AppInstallerCLICore/Commands/UpgradeCommand.cpp | 3+++
Msrc/AppInstallerCLICore/ExecutionArgs.h | 1+
Msrc/AppInstallerCLICore/Resources.h | 1+
Msrc/AppInstallerCLICore/Workflows/ArchiveFlow.cpp | 4++--
Msrc/AppInstallerCLIE2ETests/GroupPolicy.cs | 12++++++++++++
Msrc/AppInstallerCLIE2ETests/GroupPolicyHelper.cs | 6++++++
Msrc/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw | 17+++++++++++------
Msrc/AppInstallerCLITests/GroupPolicy.cpp | 4++--
Msrc/AppInstallerCLITests/TestSettings.h | 1+
Msrc/AppInstallerCLITests/WorkFlow.cpp | 2+-
Msrc/AppInstallerCommonCore/GroupPolicy.cpp | 2++
Msrc/AppInstallerCommonCore/Public/winget/GroupPolicy.h | 4++--
Msrc/AppInstallerCommonCore/Public/winget/Resources.h | 1+
18 files changed, 69 insertions(+), 17 deletions(-)

diff --git a/doc/admx/DesktopAppInstaller.admx b/doc/admx/DesktopAppInstaller.admx @@ -73,6 +73,16 @@ <decimal value="0" /> </disabledValue> </policy> + <policy name="EnableLocalArchiveMalwareScanOverride" class="Machine" displayName="$(string.EnableLocalArchiveMalwareScanOverride)" explainText="$(string.EnableLocalArchiveMalwareScanOverrideExplanation)" key="Software\Policies\Microsoft\Windows\AppInstaller" valueName="EnableLocalArchiveMalwareScanOverride"> + <parentCategory ref="AppInstaller" /> + <supportedOn ref="windows:SUPPORTED_Windows_10_0_RS5" /> + <enabledValue> + <decimal value="1" /> + </enabledValue> + <disabledValue> + <decimal value="0" /> + </disabledValue> + </policy> <policy name="EnableDefaultSource" class="Machine" displayName="$(string.EnableDefaultSource)" explainText="$(string.EnableDefaultSourceExplanation)" key="Software\Policies\Microsoft\Windows\AppInstaller" valueName="EnableDefaultSource"> <parentCategory ref="AppInstaller" /> <supportedOn ref="windows:SUPPORTED_Windows_10_0_RS5" /> @@ -137,4 +147,4 @@ </disabledValue> </policy> </policies> -</policyDefinitions>- \ No newline at end of file +</policyDefinitions> diff --git a/doc/admx/en-US/DesktopAppInstaller.adml b/doc/admx/en-US/DesktopAppInstaller.adml @@ -44,6 +44,13 @@ If you do not configure this policy, the Windows Package Manager administrator s If you enable or do not configure this policy, users will be able to enable the ability override the SHA256 security validation in the Windows Package Manager settings. If you disable this policy, users will not be able to enable the ability override the SHA256 security validation in the Windows Package Manager settings.</string> + <string id="EnableLocalArchiveMalwareScanOverride">Enable App Installer Local Archive Malware Scan Override</string> + <string id="EnableLocalArchiveMalwareScanOverrideExplanation">This policy controls the ability to override malware vulnerability scans when installing an archive file using a local manifest using the command line arguments. +If you enable this policy, users can override the malware scan when performing a local manifest install of an archive file. + +If you disable this policy, users will be unable to override the malware scan of an archive file when installing using a local manifest. + +If you do not configure this policy, the Windows Package Manager administrator settings will be adhered to.</string> <string id="EnableDefaultSource">Enable App Installer Default Source</string> <string id="EnableDefaultSourceExplanation">This policy controls the default source included with the Windows Package Manager. diff --git a/doc/specs/#140 - ZIP Support.md b/doc/specs/#140 - ZIP Support.md @@ -1,7 +1,7 @@ --- author: Ryan Fu @ryfu-msft created on: 2022-05-24 -last updated: 2022-06-23 +last updated: 2022-12-13 issue id: 140 --- @@ -68,7 +68,8 @@ In order to protect our users from these possible threats, we will need to scan > Pure is licensed under the [MIT license](https://github.com/ronomon/pure/blob/master/LICENSE). -If the Pure library functions that are called on a given ZIP file detect malware, the process will terminate and a warning will be displayed to the user. The user can include `--override-archive-malware-checks` to bypass this check and continue installation at their own risk. +If the Pure library functions that are called on a given ZIP file detect malware, the process will terminate and a warning will be displayed to the user. The user can include `--ignore-local-archive-malware-scan` to bypass this check and continue installation at their own risk. + To minimize unnecessary costs on performance during installation, these checks will only be applied when any of the following conditions are met: - Hash mismatch was overridden diff --git a/src/AppInstallerCLICore/Argument.cpp b/src/AppInstallerCLICore/Argument.cpp @@ -71,6 +71,8 @@ namespace AppInstaller::CLI return Argument{ "versions"_liv, NoAlias, Args::Type::ListVersions, Resource::String::VersionsArgumentDescription, ArgumentType::Flag }; case Args::Type::Help: return Argument{ "help"_liv, APPINSTALLER_CLI_HELP_ARGUMENT_TEXT_CHAR, Args::Type::Help, Resource::String::HelpArgumentDescription, ArgumentType::Flag }; + case Args::Type::IgnoreLocalArchiveMalwareScan: + return Argument{ "ignore-local-archive-malware-scan"_liv, NoAlias, Args::Type::IgnoreLocalArchiveMalwareScan, Resource::String::IgnoreLocalArchiveMalwareScanArgumentDescription, ArgumentType::Flag, Settings::TogglePolicy::Policy::LocalArchiveMalwareScanOverride }; case Args::Type::SourceName: return Argument{ "name"_liv, 'n', Args::Type::SourceName,Resource::String::SourceNameArgumentDescription, ArgumentType::Positional, false }; case Args::Type::SourceArg: diff --git a/src/AppInstallerCLICore/Commands/InstallCommand.cpp b/src/AppInstallerCLICore/Commands/InstallCommand.cpp @@ -41,6 +41,7 @@ namespace AppInstaller::CLI Argument::ForType(Args::Type::Override), Argument::ForType(Args::Type::InstallLocation), Argument::ForType(Args::Type::HashOverride), + Argument::ForType(Args::Type::IgnoreLocalArchiveMalwareScan), Argument::ForType(Args::Type::DependencySource), Argument::ForType(Args::Type::AcceptPackageAgreements), Argument::ForType(Args::Type::NoUpgrade), diff --git a/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp b/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp @@ -58,6 +58,7 @@ namespace AppInstaller::CLI execArgs.Contains(Args::Type::Override) || execArgs.Contains(Args::Type::InstallLocation) || execArgs.Contains(Args::Type::HashOverride) || + execArgs.Contains(Args::Type::IgnoreLocalArchiveMalwareScan) || execArgs.Contains(Args::Type::AcceptPackageAgreements); } @@ -102,6 +103,7 @@ namespace AppInstaller::CLI Argument::ForType(Args::Type::InstallArchitecture), // -a Argument::ForType(Args::Type::Locale), Argument::ForType(Args::Type::HashOverride), + Argument::ForType(Args::Type::IgnoreLocalArchiveMalwareScan), Argument::ForType(Args::Type::AcceptPackageAgreements), Argument::ForType(Args::Type::AcceptSourceAgreements), Argument::ForType(Execution::Args::Type::CustomHeader), @@ -184,6 +186,7 @@ namespace AppInstaller::CLI execArgs.Contains(Args::Type::Override) || execArgs.Contains(Args::Type::InstallLocation) || execArgs.Contains(Args::Type::HashOverride) || + execArgs.Contains(Args::Type::IgnoreLocalArchiveMalwareScan) || execArgs.Contains(Args::Type::AcceptPackageAgreements))) { throw CommandException(Resource::String::InvalidArgumentWithoutQueryError); diff --git a/src/AppInstallerCLICore/ExecutionArgs.h b/src/AppInstallerCLICore/ExecutionArgs.h @@ -40,6 +40,7 @@ namespace AppInstaller::CLI::Execution InstallScope, InstallArchitecture, HashOverride, // Ignore hash mismatches + IgnoreLocalArchiveMalwareScan, // Ignore the local malware scan on archive files AcceptPackageAgreements, // Accept all license agreements for packages Rename, // Renames the file of the executable. Only applies to the portable installerType NoUpgrade, // Install flow should not try to convert to upgrade flow upon finding existing installed version diff --git a/src/AppInstallerCLICore/Resources.h b/src/AppInstallerCLICore/Resources.h @@ -109,6 +109,7 @@ namespace AppInstaller::CLI::Resource WINGET_DEFINE_RESOURCE_STRINGID(HelpForDetails); WINGET_DEFINE_RESOURCE_STRINGID(HelpLinkPreamble); WINGET_DEFINE_RESOURCE_STRINGID(IdArgumentDescription); + WINGET_DEFINE_RESOURCE_STRINGID(IgnoreLocalArchiveMalwareScanArgumentDescription); WINGET_DEFINE_RESOURCE_STRINGID(ImportCommandLongDescription); WINGET_DEFINE_RESOURCE_STRINGID(ImportCommandReportDependencies); WINGET_DEFINE_RESOURCE_STRINGID(ImportCommandShortDescription); diff --git a/src/AppInstallerCLICore/Workflows/ArchiveFlow.cpp b/src/AppInstallerCLICore/Workflows/ArchiveFlow.cpp @@ -27,9 +27,9 @@ namespace AppInstaller::CLI::Workflow } else { - if (context.Args.Contains(Execution::Args::Type::Force)) + if (context.Args.Contains(Execution::Args::Type::IgnoreLocalArchiveMalwareScan)) { - AICLI_LOG(CLI, Warning, << "Archive malware scan failed; proceeding due to --force override"); + AICLI_LOG(CLI, Warning, << "Archive scan detected malware. Proceeding due to --ignore-local-archive-malware-scan"); context.Reporter.Warn() << Resource::String::ArchiveFailedMalwareScanOverridden << std::endl; } else diff --git a/src/AppInstallerCLIE2ETests/GroupPolicy.cs b/src/AppInstallerCLIE2ETests/GroupPolicy.cs @@ -96,6 +96,18 @@ namespace AppInstallerCLIE2ETests } /// <summary> + /// Test install ignoring the malware scan is disabled by policy. + /// </summary> + [Test] + public void EnableIgnoreLocalArchiveMalwareScanOverride() + { + GroupPolicyHelper.EnableLocalArchiveMalwareScanOverride.Disable(); + var result = TestCommon.RunAICLICommand("install", "AnyPackage --ignore-local-archive-malware-scan"); + + Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); + } + + /// <summary> /// Test winget source is enabled by policy. /// </summary> [Test] diff --git a/src/AppInstallerCLIE2ETests/GroupPolicyHelper.cs b/src/AppInstallerCLIE2ETests/GroupPolicyHelper.cs @@ -83,6 +83,11 @@ namespace AppInstallerCLIE2ETests public static GroupPolicyHelper EnableHashOverride { get; private set; } = new GroupPolicyHelper("EnableHashOverride"); /// <summary> + /// Gets the Enable ignore malware scan policy. + /// </summary> + public static GroupPolicyHelper EnableLocalArchiveMalwareScanOverride { get; private set; } = new GroupPolicyHelper("EnableLocalArchiveMalwareScanOverride"); + + /// <summary> /// Gets the Enable default source policy. /// </summary> public static GroupPolicyHelper EnableDefaultSource { get; private set; } = new GroupPolicyHelper("EnableDefaultSource"); @@ -114,6 +119,7 @@ namespace AppInstallerCLIE2ETests EnableExperimentalFeatures, EnableLocalManifests, EnableHashOverride, + EnableLocalArchiveMalwareScanOverride, EnableDefaultSource, EnableMicrosoftStoreSource, EnableAdditionalSources, diff --git a/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw b/src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw @@ -292,6 +292,9 @@ They can be configured through the settings file 'winget settings'.</value> <data name="HashOverrideArgumentDescription" xml:space="preserve"> <value>Ignore the installer hash check failure</value> </data> + <data name="IgnoreLocalArchiveMalwareScanArgumentDescription" xml:space="preserve"> + <value>Ignore the malware scan performed as part of installing an archive type package from local manifest</value> + </data> <data name="InteractiveArgumentDescription" xml:space="preserve"> <value>Request interactive installation; user input may be needed</value> </data> @@ -889,6 +892,9 @@ They can be configured through the settings file 'winget settings'.</value> <data name="PolicyEnableBypassCertificatePinningForMicrosoftStore" xml:space="preserve"> <value>Enable Windows App Installer Microsoft Store Source Pinned Certificate Bypass</value> </data> + <data name="PolicyEnableLocalArchiveMalwareScanOverride" xml:space="preserve"> + <value>Enable Windows App Installer Local Archive Malware Scan Override</value> + </data> <data name="SettingsWarningField" xml:space="preserve"> <value>Field:</value> </data> @@ -1464,12 +1470,12 @@ Please specify one of them using the --source option to proceed.</value> <value>Extracting archive...</value> </data> <data name="ArchiveFailedMalwareScan" xml:space="preserve"> - <value>Archive scan detected malware; to override this check use --force</value> - <comment>{Locked="--force"}</comment> + <value>Archive scan detected malware. To override this check use --ignore-local-archive-malware-scan</value> + <comment>{Locked="--ignore-local-archive-malware-scan"}</comment> </data> <data name="ArchiveFailedMalwareScanOverridden" xml:space="preserve"> - <value>Archive scan detected malware; proceeding due to --force</value> - <comment>{Locked="--force"}</comment> + <value>Archive scan detected malware. Proceeding due to --ignore-local-archive-malware-scan</value> + <comment>{Locked="--ignore-local-archive-malware-scan"}</comment> </data> <data name="NoUpgradeArgumentDescription" xml:space="preserve"> <value>Skips upgrade if an installed version already exists</value> @@ -1535,4 +1541,4 @@ Please specify one of them using the --source option to proceed.</value> <data name="UserSettings" xml:space="preserve"> <value>User Settings</value> </data> -</root>- \ No newline at end of file +</root> diff --git a/src/AppInstallerCLITests/GroupPolicy.cpp b/src/AppInstallerCLITests/GroupPolicy.cpp @@ -368,6 +368,7 @@ TEST_CASE("GroupPolicy_AllEnabled", "[groupPolicy]") SetRegistryValue(policiesKey.get(), ExperimentalFeaturesPolicyValueName, 1); SetRegistryValue(policiesKey.get(), LocalManifestsPolicyValueName, 1); SetRegistryValue(policiesKey.get(), EnableHashOverridePolicyValueName, 1); + SetRegistryValue(policiesKey.get(), EnableLocalArchiveMalwareScanOverridePolicyValueName, 1); SetRegistryValue(policiesKey.get(), DefaultSourcePolicyValueName, 1); SetRegistryValue(policiesKey.get(), MSStoreSourcePolicyValueName, 1);; SetRegistryValue(policiesKey.get(), AdditionalSourcesPolicyValueName, 1); @@ -379,4 +380,4 @@ TEST_CASE("GroupPolicy_AllEnabled", "[groupPolicy]") { REQUIRE(groupPolicy.GetState(policy.GetPolicy()) == PolicyState::Enabled); } -}- \ No newline at end of file +} diff --git a/src/AppInstallerCLITests/TestSettings.h b/src/AppInstallerCLITests/TestSettings.h @@ -14,6 +14,7 @@ namespace TestCommon const std::wstring ExperimentalFeaturesPolicyValueName = L"EnableExperimentalFeatures"; const std::wstring LocalManifestsPolicyValueName = L"EnableLocalManifestFiles"; const std::wstring EnableHashOverridePolicyValueName = L"EnableHashOverride"; + const std::wstring EnableLocalArchiveMalwareScanOverridePolicyValueName = L"EnableLocalArchiveMalwareScanOverride"; const std::wstring DefaultSourcePolicyValueName = L"EnableDefaultSource"; const std::wstring MSStoreSourcePolicyValueName = L"EnableMicrosoftStoreSource"; const std::wstring AdditionalSourcesPolicyValueName = L"EnableAdditionalSources"; diff --git a/src/AppInstallerCLITests/WorkFlow.cpp b/src/AppInstallerCLITests/WorkFlow.cpp @@ -1298,7 +1298,7 @@ TEST_CASE("InstallFlow_Zip_ArchiveScanOverride", "[InstallFlow][workflow]") OverrideForExtractInstallerFromArchive(context); OverrideForVerifyAndSetNestedInstaller(context); context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile("InstallFlowTest_Zip_Exe.yaml").GetPath().u8string()); - context.Args.AddArg(Execution::Args::Type::Force); + context.Args.AddArg(Execution::Args::Type::IgnoreLocalArchiveMalwareScan); bool overrideArchiveScanResult = false; AppInstaller::Archive::TestHook_SetScanArchiveResult_Override(&overrideArchiveScanResult); diff --git a/src/AppInstallerCommonCore/GroupPolicy.cpp b/src/AppInstallerCommonCore/GroupPolicy.cpp @@ -273,6 +273,8 @@ namespace AppInstaller::Settings return TogglePolicy(policy, "EnableLocalManifestFiles"sv, String::PolicyEnableLocalManifests); case TogglePolicy::Policy::HashOverride: return TogglePolicy(policy, "EnableHashOverride"sv, String::PolicyEnableHashOverride); + case TogglePolicy::Policy::LocalArchiveMalwareScanOverride: + return TogglePolicy(policy, "EnableLocalArchiveMalwareScanOverride"sv, String::PolicyEnableLocalArchiveMalwareScanOverride); case TogglePolicy::Policy::DefaultSource: return TogglePolicy(policy, "EnableDefaultSource"sv, String::PolicyEnableDefaultSource); case TogglePolicy::Policy::MSStoreSource: diff --git a/src/AppInstallerCommonCore/Public/winget/GroupPolicy.h b/src/AppInstallerCommonCore/Public/winget/GroupPolicy.h @@ -37,6 +37,7 @@ namespace AppInstaller::Settings ExperimentalFeatures, LocalManifestFiles, HashOverride, + LocalArchiveMalwareScanOverride, DefaultSource, MSStoreSource, AdditionalSources, @@ -240,4 +241,4 @@ namespace AppInstaller::Settings TogglePolicy::Policy m_policy; }; -}- \ No newline at end of file +} diff --git a/src/AppInstallerCommonCore/Public/winget/Resources.h b/src/AppInstallerCommonCore/Public/winget/Resources.h @@ -30,6 +30,7 @@ namespace AppInstaller WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableExperimentalFeatures); WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableLocalManifests); WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableHashOverride); + WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableLocalArchiveMalwareScanOverride); WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableDefaultSource); WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableMSStoreSource); WINGET_DEFINE_RESOURCE_STRINGID(PolicyAdditionalSources);