Skip to content

Commit

Permalink
WinGetCommandLineInterfaces Group Policy Exception for COM API Calls
Browse files Browse the repository at this point in the history
[WHY:]
Currently, the policy check within Command::Execute, which is executed for all command implementations,
also inadvertently blocks COM API calls due to inheritance from the command class.

[FIX:]
Allow COM API calls while the WinGetCommandLineInterfaces group policy is disabled.

The fix involves bypassing the policy check for calls originating from COM API,
identified by a context flag set in the overridden Execute method in COMCommand.

[TODOs:]
- Test run to make sure fix works as expected
  • Loading branch information
Madhusudhan-MSFT committed Mar 20, 2024
1 parent 256c385 commit dfc73b6
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 10 deletions.
18 changes: 11 additions & 7 deletions src/AppInstallerCLICore/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ namespace AppInstaller::CLI
if (!commandAliases.empty())
{
infoOut << Resource::String::AvailableCommandAliases << std::endl;

for (const auto& commandAlias : commandAliases)
{
infoOut << " "_liv << Execution::HelpCommandEmphasis << commandAlias << std::endl;
Expand Down Expand Up @@ -283,7 +283,7 @@ namespace AppInstaller::CLI
if (
Utility::CaseInsensitiveEquals(*itr, command->Name()) ||
Utility::CaseInsensitiveContains(command->Aliases(), *itr)
)
)
{
if (!ExperimentalFeature::IsEnabled(command->Feature()))
{
Expand Down Expand Up @@ -555,7 +555,7 @@ namespace AppInstaller::CLI
if (
Utility::CaseInsensitiveEquals(argName, arg.Name()) ||
Utility::CaseInsensitiveEquals(argName, arg.AlternateName())
)
)
{
if (arg.Type() == ArgumentType::Flag)
{
Expand Down Expand Up @@ -668,7 +668,7 @@ namespace AppInstaller::CLI
}

if (execArgs.Contains(Execution::Args::Type::CustomHeader) && !execArgs.Contains(Execution::Args::Type::Source) &&
!execArgs.Contains(Execution::Args::Type::SourceName))
!execArgs.Contains(Execution::Args::Type::SourceName))
{
throw CommandException(Resource::String::HeaderArgumentNotApplicableWithoutSource(Argument::ForType(Execution::Args::Type::CustomHeader).Name()));
}
Expand Down Expand Up @@ -864,8 +864,12 @@ namespace AppInstaller::CLI
throw GroupPolicyException(Settings::TogglePolicy::Policy::WinGet);
}

// Block CLI execution if WinGetCommandLineInterfaces is disabled by Policy
if (!Settings::GroupPolicies().IsEnabled(Settings::TogglePolicy::Policy::WinGetCommandLineInterfaces))
bool comApiCall = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::WinGetCOMApiCall);

// Block command-line interface operations if WinGetCommandLineInterfaces is turned off by policy,
// but maintain access to COM API calls.
if (!comApiCall &&
!Settings::GroupPolicies().IsEnabled(Settings::TogglePolicy::Policy::WinGetCommandLineInterfaces))
{
AICLI_LOG(CLI, Error, << "WinGet is disabled by group policy");
throw GroupPolicyException(Settings::TogglePolicy::Policy::WinGetCommandLineInterfaces);
Expand Down Expand Up @@ -929,7 +933,7 @@ namespace AppInstaller::CLI
context.Reporter.Error() << Resource::String::CommandDoesNotSupportResumeMessage << std::endl;
AICLI_TERMINATE_CONTEXT(E_NOTIMPL);
}

void Command::SelectCurrentCommandIfUnrecognizedSubcommandFound(bool value)
{
m_selectCurrentCommandIfUnrecognizedSubcommandFound = value;
Expand Down
18 changes: 18 additions & 0 deletions src/AppInstallerCLICore/Commands/COMCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ namespace AppInstaller::CLI
Workflow::SetDownloadDirectory <<
Workflow::DownloadPackageDependencies <<
Workflow::DownloadInstaller;
}

void COMDownloadCommand::Execute(Context& context) const
{
context.SetFlags(Execution::ContextFlag::WinGetCOMApiCall);
Command::Execute(context);
}

// IMPORTANT: To use this command, the caller should have already executed the COMDownloadCommand
Expand All @@ -37,6 +43,12 @@ namespace AppInstaller::CLI
Workflow::InstallDependencies <<
Workflow::ReverifyInstallerHash <<
Workflow::InstallPackageInstaller;
}

void COMInstallCommand::Execute(Context& context) const
{
context.SetFlags(Execution::ContextFlag::WinGetCOMApiCall);
Command::Execute(context);
}

// IMPORTANT: To use this command, the caller should have already retrieved the InstalledPackageVersion and added it to the Context Data
Expand All @@ -45,4 +57,10 @@ namespace AppInstaller::CLI
context <<
Workflow::UninstallSinglePackage;
}

void COMUninstallCommand::Execute(Execution::Context& context) const
{
context.SetFlags(Execution::ContextFlag::WinGetCOMApiCall);
Command::Execute(context);
}
}
12 changes: 9 additions & 3 deletions src/AppInstallerCLICore/Commands/COMCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ namespace AppInstaller::CLI
struct COMDownloadCommand final : public Command
{
constexpr static std::string_view CommandName = "download"sv;
COMDownloadCommand(std::string_view parent) : Command(CommandName, parent) {}
COMDownloadCommand(std::string_view parent) : Command(CommandName, parent) {}

void Execute(Execution::Context& context) const override;

protected:
void ExecuteInternal(Execution::Context& context) const override;
Expand All @@ -19,7 +21,9 @@ namespace AppInstaller::CLI
struct COMInstallCommand final : public Command
{
constexpr static std::string_view CommandName = "install"sv;
COMInstallCommand(std::string_view parent) : Command(CommandName, parent) {}
COMInstallCommand(std::string_view parent) : Command(CommandName, parent) {}

void Execute(Execution::Context& context) const override;

protected:
void ExecuteInternal(Execution::Context& context) const override;
Expand All @@ -29,7 +33,9 @@ namespace AppInstaller::CLI
struct COMUninstallCommand final : public Command
{
constexpr static std::string_view CommandName = "uninstall"sv;
COMUninstallCommand(std::string_view parent) : Command(CommandName, parent) {}
COMUninstallCommand(std::string_view parent) : Command(CommandName, parent) {}

void Execute(Execution::Context& context) const override;

protected:
void ExecuteInternal(Execution::Context& context) const override;
Expand Down
1 change: 1 addition & 0 deletions src/AppInstallerCLICore/ExecutionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ namespace AppInstaller::CLI::Execution
RebootRequired = 0x400,
RegisterResume = 0x800,
InstallerExecutionUseRepair = 0x1000,
WinGetCOMApiCall = 0x2000,
};

DEFINE_ENUM_FLAG_OPERATORS(ContextFlag);
Expand Down

0 comments on commit dfc73b6

Please sign in to comment.