| // Copyright 2023 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "secagentd/secagent.h" |
| |
| #include <sysexits.h> |
| |
| #include <cstring> |
| #include <memory> |
| |
| #include "absl/status/status.h" |
| #include "base/files/file_util.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/functional/bind.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/test/task_environment.h" |
| #include "gmock/gmock.h" |
| #include "gtest/gtest.h" |
| #include "secagentd/common.h" |
| #include "secagentd/policies_features_broker.h" |
| #include "secagentd/test/mock_device_user.h" |
| #include "secagentd/test/mock_message_sender.h" |
| #include "secagentd/test/mock_plugin_factory.h" |
| #include "secagentd/test/mock_policies_features_broker.h" |
| #include "secagentd/test/mock_process_cache.h" |
| |
| namespace secagentd::testing { |
| |
| namespace pb = cros_xdr::reporting; |
| |
| using ::testing::_; |
| using ::testing::AnyNumber; |
| using ::testing::AtLeast; |
| using ::testing::AtMost; |
| using ::testing::ByMove; |
| using ::testing::Invoke; |
| using ::testing::Return; |
| using ::testing::WithArg; |
| using ::testing::WithArgs; |
| |
| struct XdrFeatureAndPolicy { |
| bool xdr_feature_enabled; |
| bool xdr_policy_enabled; |
| }; |
| class MockSystemQuit { |
| public: |
| MOCK_METHOD(void, Quit, (int rv)); |
| base::WeakPtrFactory<MockSystemQuit> weak_factory_{this}; |
| }; |
| class SecAgentTestFixture |
| : public ::testing::TestWithParam<XdrFeatureAndPolicy> { |
| protected: |
| SecAgentTestFixture() = default; |
| |
| void CreateFakeFs(const base::FilePath& root) { |
| const base::FilePath bpf_dir = root.Append("sys/fs/bpf/secagentd"); |
| ASSERT_TRUE(base::CreateDirectory(bpf_dir)); |
| std::vector<std::string> bpf_maps{"shared_process_info"}; |
| for (auto& map : bpf_maps) { |
| pinned_maps_.push_back(bpf_dir.Append(map)); |
| ASSERT_TRUE(base::WriteFile(pinned_maps_.back(), map)); |
| } |
| } |
| |
| void SetUp() override { |
| ASSERT_TRUE(fake_root_.CreateUniqueTempDir()); |
| const base::FilePath& root = fake_root_.GetPath(); |
| CreateFakeFs(root); |
| |
| agent_plugin_ = std::make_unique<MockPlugin>(); |
| agent_plugin_ref_ = agent_plugin_.get(); |
| |
| process_plugin_ = std::make_unique<MockPlugin>(); |
| process_plugin_ref_ = process_plugin_.get(); |
| |
| network_plugin_ = std::make_unique<MockPlugin>(); |
| network_plugin_ref_ = network_plugin_.get(); |
| |
| authentication_plugin_ = std::make_unique<MockPlugin>(); |
| authentication_plugin_ref_ = authentication_plugin_.get(); |
| |
| file_plugin_ = std::make_unique<MockPlugin>(); |
| file_plugin_ref_ = file_plugin_.get(); |
| |
| plugin_factory_ = std::make_unique<MockPluginFactory>(); |
| plugin_factory_ref = plugin_factory_.get(); |
| |
| message_sender_ = base::MakeRefCounted<MockMessageSender>(); |
| process_cache_ = base::MakeRefCounted<MockProcessCache>(); |
| policies_features_broker_ = |
| base::MakeRefCounted<MockPoliciesFeaturesBroker>(); |
| device_user_ = base::MakeRefCounted<MockDeviceUser>(); |
| secagent_ = std::make_unique<SecAgent>( |
| base::BindOnce(&MockSystemQuit::Quit, |
| mock_system_quit_.weak_factory_.GetWeakPtr()), |
| message_sender_, process_cache_, device_user_, |
| std::move(plugin_factory_), |
| // attestation and tpm proxies. |
| nullptr /* Attestation */, nullptr /* Tpm */, |
| nullptr /* PlatformFeatures */, 0, 0, 0, 300, 120, 10, root); |
| secagent_->policies_features_broker_ = this->policies_features_broker_; |
| |
| ON_CALL(*process_plugin_ref_, GetName()) |
| .WillByDefault(Return("ProcessPluginTest")); |
| ON_CALL(*network_plugin_ref_, GetName()) |
| .WillByDefault(Return("NetworkPluginTest")); |
| ON_CALL(*authentication_plugin_ref_, GetName()) |
| .WillByDefault(Return("AuthenticationPluginTest")); |
| ON_CALL(*file_plugin_ref_, GetName()) |
| .WillByDefault(Return("FilePluginTest")); |
| ON_CALL(*agent_plugin_ref_, GetName()) |
| .WillByDefault(Return("AgentPluginRef")); |
| |
| ON_CALL(*process_plugin_ref_, IsActive).WillByDefault(Invoke([this]() { |
| return process_plugin_ref_->is_active_; |
| })); |
| ON_CALL(*agent_plugin_ref_, IsActive).WillByDefault(Invoke([this] { |
| return agent_plugin_ref_->is_active_; |
| })); |
| ON_CALL(*network_plugin_ref_, IsActive).WillByDefault(Invoke([this]() { |
| return network_plugin_ref_->is_active_; |
| })); |
| ON_CALL(*authentication_plugin_ref_, IsActive) |
| .WillByDefault(Invoke( |
| [this]() { return authentication_plugin_ref_->is_active_; })); |
| ON_CALL(*file_plugin_ref_, IsActive).WillByDefault(Invoke([this]() { |
| return file_plugin_ref_->is_active_; |
| })); |
| |
| // Default behavior for plugin creation. |
| ON_CALL(*plugin_factory_ref, CreateAgentPlugin) |
| .WillByDefault(WithArg<4>(Invoke([this](base::OnceCallback<void()> cb) { |
| agent_activation_callback_ = std::move(cb); |
| return std::move(agent_plugin_); |
| }))); |
| ON_CALL(*plugin_factory_ref, Create(Types::Plugin::kProcess, _, _, _, _, _)) |
| .WillByDefault(Return(ByMove(std::move(process_plugin_)))); |
| ON_CALL(*plugin_factory_ref, Create(Types::Plugin::kNetwork, _, _, _, _, _)) |
| .WillByDefault(Return(ByMove(std::move(network_plugin_)))); |
| ON_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kAuthenticate, _, _, _, _, _)) |
| .WillByDefault(Return(ByMove(std::move(authentication_plugin_)))); |
| ON_CALL(*plugin_factory_ref, Create(Types::Plugin::kFile, _, _, _, _, _)) |
| .WillByDefault(Return(ByMove(std::move(file_plugin_)))); |
| |
| // Default activate actions. |
| ON_CALL(*process_plugin_ref_, MockActivate()) |
| .WillByDefault(Return(absl::OkStatus())); |
| ON_CALL(*agent_plugin_ref_, MockActivate()).WillByDefault(Invoke([this]() { |
| std::move(agent_activation_callback_).Run(); |
| return absl::OkStatus(); |
| })); |
| ON_CALL(*network_plugin_ref_, MockActivate()) |
| .WillByDefault(Return(absl::OkStatus())); |
| ON_CALL(*authentication_plugin_ref_, MockActivate()) |
| .WillByDefault(Return(absl::OkStatus())); |
| ON_CALL(*file_plugin_ref_, MockActivate()) |
| .WillByDefault(Return(absl::OkStatus())); |
| } |
| |
| void InstallDontCarePluginIsActive() { |
| EXPECT_CALL(*process_plugin_ref_, IsActive()).Times(AnyNumber()); |
| EXPECT_CALL(*agent_plugin_ref_, IsActive()).Times(AnyNumber()); |
| EXPECT_CALL(*network_plugin_ref_, IsActive()).Times(AnyNumber()); |
| EXPECT_CALL(*authentication_plugin_ref_, IsActive()).Times(AnyNumber()); |
| EXPECT_CALL(*file_plugin_ref_, IsActive()).Times(AnyNumber()); |
| } |
| |
| void InstallDontCarePluginGetName() { |
| EXPECT_CALL(*process_plugin_ref_, GetName()).Times(AnyNumber()); |
| EXPECT_CALL(*agent_plugin_ref_, GetName()).Times(AnyNumber()); |
| EXPECT_CALL(*network_plugin_ref_, GetName()).Times(AnyNumber()); |
| EXPECT_CALL(*authentication_plugin_ref_, GetName()).Times(AnyNumber()); |
| EXPECT_CALL(*file_plugin_ref_, GetName()).Times(AnyNumber()); |
| } |
| |
| void InstallActivateExpectations() { |
| // An activated secagent should always fulfill these expectations. |
| EXPECT_CALL(*message_sender_, Initialize) |
| .WillOnce(Return(absl::OkStatus())); |
| EXPECT_CALL(*process_cache_, InitializeFilter); |
| EXPECT_CALL(*policies_features_broker_, StartAndBlockForSync); |
| } |
| base::OnceCallback<void()> agent_activation_callback_; |
| std::unique_ptr<SecAgent> secagent_; |
| std::unique_ptr<MockPluginFactory> plugin_factory_; |
| std::unique_ptr<MockPlugin> agent_plugin_; |
| MockPlugin* agent_plugin_ref_; |
| std::unique_ptr<MockPlugin> network_plugin_; |
| MockPlugin* network_plugin_ref_; |
| std::unique_ptr<MockPlugin> process_plugin_; |
| MockPlugin* process_plugin_ref_; |
| std::unique_ptr<MockPlugin> authentication_plugin_; |
| MockPlugin* authentication_plugin_ref_; |
| std::unique_ptr<MockPlugin> file_plugin_; |
| MockPlugin* file_plugin_ref_; |
| MockPluginFactory* plugin_factory_ref; |
| scoped_refptr<MockMessageSender> message_sender_; |
| scoped_refptr<MockProcessCache> process_cache_; |
| scoped_refptr<MockPoliciesFeaturesBroker> policies_features_broker_; |
| scoped_refptr<MockDeviceUser> device_user_; |
| ::testing::StrictMock<MockSystemQuit> mock_system_quit_; |
| base::test::TaskEnvironment task_environment_; |
| base::ScopedTempDir fake_root_; |
| std::vector<base::FilePath> pinned_maps_; |
| }; |
| |
| TEST_F(SecAgentTestFixture, TestPinnedBpfMapsCleanedUpOnActivate) { |
| secagent_->Activate(); |
| for (const auto& map : pinned_maps_) { |
| EXPECT_FALSE(base::PathExists(map)); |
| } |
| } |
| |
| TEST_F(SecAgentTestFixture, TestReportingEnabled) { |
| InstallActivateExpectations(); |
| InstallDontCarePluginIsActive(); |
| InstallDontCarePluginGetName(); |
| EXPECT_CALL(*policies_features_broker_, GetDeviceReportXDREventsPolicy) |
| .WillOnce(Return(true)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrosLateBootSecagentdXDRStopReportingForUnaffiliated)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature( |
| PoliciesFeaturesBroker::Feature::kCrOSLateBootSecagentdXDRReporting)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrOSLateBootSecagentdXDRNetworkEvents)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrOSLateBootSecagentdXDRAuthenticateEvents)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrOSLateBootSecagentdXDRFileEvents)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(true)); |
| |
| EXPECT_CALL(*device_user_, RegisterSessionChangeHandler); |
| // All plugins should be created. |
| EXPECT_CALL(*plugin_factory_ref, CreateAgentPlugin); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kAuthenticate, _, _, _, _, _)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kNetwork, _, _, _, _, _)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kProcess, _, _, _, _, _)); |
| EXPECT_CALL(*plugin_factory_ref, Create(Types::Plugin::kFile, _, _, _, _, _)); |
| |
| // Everything is enabled so all plugins should be activated. |
| EXPECT_CALL(*process_plugin_ref_, MockActivate); |
| EXPECT_CALL(*network_plugin_ref_, MockActivate); |
| EXPECT_CALL(*authentication_plugin_ref_, MockActivate); |
| EXPECT_CALL(*file_plugin_ref_, MockActivate); |
| EXPECT_CALL(*agent_plugin_ref_, MockActivate); |
| secagent_->Activate(); |
| secagent_->CheckPolicyAndFeature(); |
| } |
| |
| TEST_F(SecAgentTestFixture, TestEnabledToDisabled) { |
| InstallActivateExpectations(); |
| InstallDontCarePluginIsActive(); |
| InstallDontCarePluginGetName(); |
| EXPECT_CALL(*policies_features_broker_, GetDeviceReportXDREventsPolicy) |
| .WillOnce(Return(true)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrosLateBootSecagentdXDRStopReportingForUnaffiliated)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature( |
| PoliciesFeaturesBroker::Feature::kCrOSLateBootSecagentdXDRReporting)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrOSLateBootSecagentdXDRNetworkEvents)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrOSLateBootSecagentdXDRAuthenticateEvents)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrOSLateBootSecagentdXDRFileEvents)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(true)); |
| |
| EXPECT_CALL(*device_user_, RegisterSessionChangeHandler); |
| // All plugins should be created. |
| EXPECT_CALL(*plugin_factory_ref, CreateAgentPlugin); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kNetwork, _, _, _, _, _)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kProcess, _, _, _, _, _)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kAuthenticate, _, _, _, _, _)); |
| EXPECT_CALL(*plugin_factory_ref, Create(Types::Plugin::kFile, _, _, _, _, _)); |
| |
| // Everything is enabled so all plugins should be activated. |
| EXPECT_CALL(*process_plugin_ref_, MockActivate); |
| EXPECT_CALL(*network_plugin_ref_, MockActivate); |
| EXPECT_CALL(*authentication_plugin_ref_, MockActivate); |
| EXPECT_CALL(*file_plugin_ref_, MockActivate); |
| EXPECT_CALL(*agent_plugin_ref_, MockActivate); |
| secagent_->Activate(); |
| secagent_->CheckPolicyAndFeature(); |
| // Retire expectations. |
| ::testing::Mock::VerifyAndClearExpectations(process_plugin_ref_); |
| ::testing::Mock::VerifyAndClearExpectations(agent_plugin_ref_); |
| ::testing::Mock::VerifyAndClearExpectations(network_plugin_ref_); |
| ::testing::Mock::VerifyAndClearExpectations(authentication_plugin_ref_); |
| ::testing::Mock::VerifyAndClearExpectations(file_plugin_ref_); |
| ::testing::Mock::VerifyAndClearExpectations(policies_features_broker_.get()); |
| // Now on policy refresh show that we deactivate all the plugins when |
| // XDR policy is disabled or emergency-XDR-kill-switch is enabled. |
| EXPECT_CALL(*policies_features_broker_, GetDeviceReportXDREventsPolicy) |
| .WillRepeatedly(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrosLateBootSecagentdXDRStopReportingForUnaffiliated)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature( |
| PoliciesFeaturesBroker::Feature::kCrOSLateBootSecagentdXDRReporting)) |
| .WillOnce(Return(false)); |
| // If no plugins were activated then no XDR events are being generated. |
| EXPECT_CALL(*process_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*agent_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*network_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*authentication_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*file_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(mock_system_quit_, Quit(EX_OK)); |
| secagent_->CheckPolicyAndFeature(); |
| } |
| |
| TEST_F(SecAgentTestFixture, TestDisabledToEnabled) { |
| // Standard expectations of a just launched secagentd. |
| InstallActivateExpectations(); |
| InstallDontCarePluginIsActive(); |
| InstallDontCarePluginGetName(); |
| |
| EXPECT_CALL(*device_user_, RegisterSessionChangeHandler); |
| // Reporting is disabled. |
| EXPECT_CALL(*policies_features_broker_, GetDeviceReportXDREventsPolicy) |
| .WillOnce(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrosLateBootSecagentdXDRStopReportingForUnaffiliated)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature( |
| PoliciesFeaturesBroker::Feature::kCrOSLateBootSecagentdXDRReporting)) |
| .WillOnce(Return(false)); |
| // With everything disabled, plugins can be created but shouldn't be |
| // activated. |
| EXPECT_CALL(*plugin_factory_ref, CreateAgentPlugin).Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kProcess, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kNetwork, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kAuthenticate, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, Create(Types::Plugin::kFile, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| |
| EXPECT_CALL(*agent_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*process_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*network_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*authentication_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*file_plugin_ref_, MockActivate()).Times(0); |
| secagent_->Activate(); |
| secagent_->CheckPolicyAndFeature(); |
| // Retire expectations. |
| ::testing::Mock::VerifyAndClearExpectations(plugin_factory_ref); |
| ::testing::Mock::VerifyAndClearExpectations(process_plugin_ref_); |
| ::testing::Mock::VerifyAndClearExpectations(agent_plugin_ref_); |
| ::testing::Mock::VerifyAndClearExpectations(network_plugin_ref_); |
| ::testing::Mock::VerifyAndClearExpectations(authentication_plugin_ref_); |
| ::testing::Mock::VerifyAndClearExpectations(file_plugin_ref_); |
| |
| // Enable reporting. |
| EXPECT_CALL(*policies_features_broker_, GetDeviceReportXDREventsPolicy) |
| .WillOnce(Return(true)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrosLateBootSecagentdXDRStopReportingForUnaffiliated)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature( |
| PoliciesFeaturesBroker::Feature::kCrOSLateBootSecagentdXDRReporting)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBroker::Feature:: |
| kCrOSLateBootSecagentdXDRNetworkEvents)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBroker::Feature:: |
| kCrOSLateBootSecagentdXDRAuthenticateEvents)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature( |
| PoliciesFeaturesBroker::Feature::kCrOSLateBootSecagentdXDRFileEvents)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(*plugin_factory_ref, CreateAgentPlugin).Times(1); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kProcess, _, _, _, _, _)) |
| .Times(1); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kNetwork, _, _, _, _, _)) |
| .Times(1); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kAuthenticate, _, _, _, _, _)) |
| .Times(1); |
| EXPECT_CALL(*plugin_factory_ref, Create(Types::Plugin::kFile, _, _, _, _, _)) |
| .Times(1); |
| // If all plugins are activated then all XDR events are reporting. |
| EXPECT_CALL(*agent_plugin_ref_, MockActivate()); |
| EXPECT_CALL(*process_plugin_ref_, MockActivate()); |
| EXPECT_CALL(*network_plugin_ref_, MockActivate()); |
| EXPECT_CALL(*authentication_plugin_ref_, MockActivate()); |
| EXPECT_CALL(*file_plugin_ref_, MockActivate()); |
| secagent_->CheckPolicyAndFeature(); |
| } |
| |
| TEST_F(SecAgentTestFixture, TestFailedInitialization) { |
| InstallDontCarePluginIsActive(); |
| InstallDontCarePluginGetName(); |
| EXPECT_CALL(*message_sender_, Initialize) |
| .WillOnce(Return(absl::InternalError( |
| "InitializeQueues: Report queue failed to create"))); |
| // Creating plugins is fine, it's the activation that don't want to happen. |
| EXPECT_CALL(*plugin_factory_ref, CreateAgentPlugin).Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kProcess, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kNetwork, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kAuthenticate, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, Create(Types::Plugin::kFile, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*agent_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*process_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*network_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*authentication_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*file_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(mock_system_quit_, Quit(EX_SOFTWARE)); |
| secagent_->Activate(); |
| } |
| |
| TEST_F(SecAgentTestFixture, TestFailedPluginCreation) { |
| InstallActivateExpectations(); |
| InstallDontCarePluginIsActive(); |
| InstallDontCarePluginGetName(); |
| EXPECT_CALL(*device_user_, RegisterSessionChangeHandler); |
| |
| // It's fine if plugins are created very early and we never get to |
| // instantiating the policy manager, grabbing device policies etc.. |
| EXPECT_CALL(*plugin_factory_ref, CreateAgentPlugin).WillOnce(Return(nullptr)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kProcess, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kNetwork, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kAuthenticate, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| EXPECT_CALL(*plugin_factory_ref, Create(Types::Plugin::kFile, _, _, _, _, _)) |
| .Times(AtMost(1)); |
| |
| EXPECT_CALL(*policies_features_broker_, GetDeviceReportXDREventsPolicy) |
| .Times(AtMost(1)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrosLateBootSecagentdXDRStopReportingForUnaffiliated)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature( |
| PoliciesFeaturesBroker::Feature::kCrOSLateBootSecagentdXDRReporting)) |
| .Times(AtMost(1)) |
| .WillOnce(Return(true)); |
| // But we should never see an activation of the plugins. |
| EXPECT_CALL(*process_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*network_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*authentication_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*file_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(mock_system_quit_, Quit(EX_SOFTWARE)); |
| |
| secagent_->Activate(); |
| secagent_->CheckPolicyAndFeature(); |
| } |
| |
| TEST_F(SecAgentTestFixture, TestFailedPluginActivation) { |
| InstallActivateExpectations(); |
| InstallDontCarePluginIsActive(); |
| InstallDontCarePluginGetName(); |
| EXPECT_CALL(*policies_features_broker_, GetDeviceReportXDREventsPolicy) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrosLateBootSecagentdXDRStopReportingForUnaffiliated)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature( |
| PoliciesFeaturesBroker::Feature::kCrOSLateBootSecagentdXDRReporting)) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrOSLateBootSecagentdXDRNetworkEvents)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrOSLateBootSecagentdXDRAuthenticateEvents)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(*policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrOSLateBootSecagentdXDRFileEvents)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(true)); |
| |
| EXPECT_CALL(*device_user_, RegisterSessionChangeHandler); |
| // All plugins should be created. |
| EXPECT_CALL(*plugin_factory_ref, CreateAgentPlugin); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kNetwork, _, _, _, _, _)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kProcess, _, _, _, _, _)); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kAuthenticate, _, _, _, _, _)); |
| EXPECT_CALL(*plugin_factory_ref, Create(Types::Plugin::kFile, _, _, _, _, _)); |
| |
| // Everything is enabled so all plugins should be activated. |
| EXPECT_CALL(*process_plugin_ref_, MockActivate) |
| .WillOnce( |
| Return(absl::InternalError("Process plugin failed to activate."))); |
| EXPECT_CALL(*network_plugin_ref_, MockActivate).Times(1); |
| EXPECT_CALL(*agent_plugin_ref_, MockActivate).Times(1); |
| EXPECT_CALL(*authentication_plugin_ref_, MockActivate).Times(1); |
| EXPECT_CALL(*file_plugin_ref_, MockActivate).Times(1); |
| |
| secagent_->Activate(); |
| secagent_->CheckPolicyAndFeature(); |
| } |
| |
| TEST_P(SecAgentTestFixture, TestReportingDisabled) { |
| const XdrFeatureAndPolicy param = GetParam(); |
| |
| InstallActivateExpectations(); |
| EXPECT_CALL(*policies_features_broker_, GetDeviceReportXDREventsPolicy) |
| .WillOnce(Return(param.xdr_policy_enabled)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature(PoliciesFeaturesBrokerInterface::Feature:: |
| kCrosLateBootSecagentdXDRStopReportingForUnaffiliated)) |
| .Times(AtLeast(1)) |
| .WillRepeatedly(Return(false)); |
| EXPECT_CALL( |
| *policies_features_broker_, |
| GetFeature( |
| PoliciesFeaturesBroker::Feature::kCrOSLateBootSecagentdXDRReporting)) |
| .WillOnce(Return(param.xdr_feature_enabled)); |
| // It's fine for plugins to be created regardless of whether XDR reporting |
| // is enabled. It's the activation that we want to guard against. |
| EXPECT_CALL(*plugin_factory_ref, CreateAgentPlugin) |
| .Times(AtMost(1)) |
| .WillOnce(Return(ByMove(std::move(agent_plugin_)))); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kProcess, _, _, _, _, _)) |
| .Times(AtMost(1)) |
| .WillOnce(Return(ByMove(std::move(process_plugin_)))); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kNetwork, _, _, _, _, _)) |
| .Times(AtMost(1)) |
| .WillOnce(Return(ByMove(std::move(network_plugin_)))); |
| EXPECT_CALL(*plugin_factory_ref, |
| Create(Types::Plugin::kAuthenticate, _, _, _, _, _)) |
| .Times(AtMost(1)) |
| .WillOnce(Return(ByMove(std::move(authentication_plugin_)))); |
| EXPECT_CALL(*plugin_factory_ref, Create(Types::Plugin::kFile, _, _, _, _, _)) |
| .Times(AtMost(1)) |
| .WillOnce(Return(ByMove(std::move(file_plugin_)))); |
| EXPECT_CALL(*agent_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*process_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*network_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*authentication_plugin_ref_, MockActivate()).Times(0); |
| EXPECT_CALL(*file_plugin_ref_, MockActivate()).Times(0); |
| |
| secagent_->Activate(); |
| secagent_->CheckPolicyAndFeature(); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| SecAgentTestFixture, |
| SecAgentTestFixture, |
| // {featured, policy} |
| ::testing::ValuesIn<XdrFeatureAndPolicy>( |
| {{false, false}, {false, true}, {true, false}}), |
| [](const ::testing::TestParamInfo<SecAgentTestFixture::ParamType>& info) { |
| std::string featured = info.param.xdr_feature_enabled |
| ? "FeaturedEnabled" |
| : "FeaturedDisabled"; |
| std::string policy = |
| info.param.xdr_policy_enabled ? "PolicyEnabled" : "PolicyDisabled"; |
| |
| return base::StringPrintf("%s_%s", featured.c_str(), policy.c_str()); |
| }); |
| |
| } // namespace secagentd::testing |