blob: 7fe0fd99b42de10dde78591770a8dd771e94b4a8 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/chrome_cleaner/components/system_report_component.h"
#include <shlobj.h>
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "base/strings/string16.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_path_override.h"
#include "base/test/test_reg_util_win.h"
#include "base/test/test_timeouts.h"
#include "base/win/registry.h"
#include "chrome/chrome_cleaner/constants/chrome_cleaner_switches.h"
#include "chrome/chrome_cleaner/constants/uws_id.h"
#include "chrome/chrome_cleaner/logging/cleaner_logging_service.h"
#include "chrome/chrome_cleaner/logging/logging_service_api.h"
#include "chrome/chrome_cleaner/logging/proto/chrome_cleaner_report.pb.h"
#include "chrome/chrome_cleaner/os/disk_util.h"
#include "chrome/chrome_cleaner/os/file_path_sanitization.h"
#include "chrome/chrome_cleaner/os/pre_fetched_paths.h"
#include "chrome/chrome_cleaner/os/registry_util.h"
#include "chrome/chrome_cleaner/parsers/json_parser/test_json_parser.h"
#include "chrome/chrome_cleaner/parsers/parser_utils/command_line_arguments_sanitizer.h"
#include "chrome/chrome_cleaner/parsers/shortcut_parser/broker/fake_shortcut_parser.h"
#include "chrome/chrome_cleaner/test/test_extensions.h"
#include "chrome/chrome_cleaner/test/test_file_util.h"
#include "chrome/chrome_cleaner/test/test_pup_data.h"
#include "chrome/chrome_cleaner/test/test_util.h"
#include "components/chrome_cleaner/public/constants/constants.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chrome_cleaner {
namespace {
using google::protobuf::RepeatedPtrField;
using InstalledExtension =
ChromeCleanerReport::SystemReport::InstalledExtension;
using base::WaitableEvent;
const int kExtensionIdLength = 32;
const wchar_t kRunKeyPath[] =
L"software\\microsoft\\windows\\currentversion\\run";
const wchar_t kRunTestName[] = L"test_chrome_cleanup_tool";
const wchar_t kRunTestValue[] = L"chrome_cleanup_tool.exe";
const wchar_t kNameServerKeyPath[] =
L"system\\currentcontrolset\\services\\tcpip\\parameters\\interfaces\\"
L"fishy";
const wchar_t kNameServerName[] = L"nameserver";
const wchar_t kNameServerValue[] = L"8.8.4.4";
const wchar_t kFakeProgramFolder[] = L"FakeProgram";
const char kFakeProgram[] = "FakeProgram";
const wchar_t kFakeAppDataProgramFolder[] = L"FakeAppDataProgram";
const char kFakeAppDataProgram[] = "FakeAppDataProgram";
const char kExtensionPoliciesNonExistent[] =
"software\\policies\\google\\chrome\\";
struct ReportTestData {
HKEY hkey;
const wchar_t* key_path;
const wchar_t* name;
const wchar_t* value;
};
const ReportTestData kExtensionPolicyEmpty{
HKEY_LOCAL_MACHINE, kChromePoliciesWhitelistKeyPath, L"test1", L""};
constexpr base::char16 kTestingExtensionId1[] =
L"ababababcdcdcdcdefefefefghghghgh";
constexpr base::char16 kTestingExtensionId1WithUpdateUrl[] =
L"ababababcdcdcdcdefefefefghghghgh;https://clients2.google.com/service/"
L"update2/crx";
constexpr base::char16 kTestingExtensionId2[] =
L"aaaabbbbccccddddeeeeffffgggghhhh";
constexpr base::char16 kTestingExtensionId2WithUpdateUrl[] =
L"aaaabbbbccccddddeeeeffffgggghhhh;https://clients2.google.com/service/"
L"update2/crx";
const ReportTestData extension_policies[] = {
{HKEY_LOCAL_MACHINE, kChromePoliciesWhitelistKeyPath, L"test1",
kTestingExtensionId1},
{HKEY_CURRENT_USER, kChromePoliciesWhitelistKeyPath, L"test2",
kTestingExtensionId1},
{HKEY_LOCAL_MACHINE, kChromePoliciesForcelistKeyPath, L"test3",
kTestingExtensionId2WithUpdateUrl},
{HKEY_CURRENT_USER, kChromePoliciesForcelistKeyPath, L"test4",
kTestingExtensionId2WithUpdateUrl},
{HKEY_LOCAL_MACHINE, kChromiumPoliciesWhitelistKeyPath, L"test5",
kTestingExtensionId1},
{HKEY_CURRENT_USER, kChromiumPoliciesWhitelistKeyPath, L"test6",
kTestingExtensionId1},
{HKEY_LOCAL_MACHINE, kChromiumPoliciesForcelistKeyPath, L"test7",
kTestingExtensionId2WithUpdateUrl},
{HKEY_CURRENT_USER, kChromiumPoliciesForcelistKeyPath, L"test8",
kTestingExtensionId2WithUpdateUrl},
};
const ReportTestData extension_forcelist_policies[] = {
{HKEY_LOCAL_MACHINE, kChromePoliciesForcelistKeyPath, L"test1",
kTestingExtensionId1WithUpdateUrl},
{HKEY_CURRENT_USER, kChromePoliciesForcelistKeyPath, L"test2",
kTestingExtensionId2WithUpdateUrl},
};
const UwSId kFakePupId = 42;
const wchar_t kFakeChromeFolderForTests[] =
L"google\\chrome\\application\\42.12.34.56";
const char kDefaultExtensionsJsonForTests[] = R"(
{
"ababababcdcdcdcdefefefefghghghgh" : {
"external_update_url": "https://clients2.google.com/service/update2/crx"
},
"aaaabbbbccccddddeeeeffffgggghhhh" : {
"external_update_url": "https://clients2.google.com/service/update2/crx"
}
})";
// Don't include the null-terminator in the length.
const int kDefaultExtensionsJsonForTestsSize =
sizeof(kDefaultExtensionsJsonForTests) - 1;
// ExtensionSettings that has two force_installed extensions and two not.
const wchar_t kExtensionSettingsJson[] =
LR"(
{
"ababababcdcdcdcdefefefefghghghgh": {
"installation_mode": "force_installed",
"update_url":"https://clients2.google.com/service/update2/crx"
},
"aaaabbbbccccddddeeeeffffgggghhhh": {
"installation_mode": "force_installed",
"update_url":"https://clients2.google.com/service/update2/crx"
},
"extensionwithinstallmodeblockeda": {
"installation_mode": "blocked",
"update_url":"https://clients2.google.com/service/update2/crx"
},
"extensionwithnosettingsabcdefghi": {}
})";
const ReportTestData extension_settings_entry = {
HKEY_LOCAL_MACHINE, kChromePoliciesKeyPath, L"ExtensionSettings",
kExtensionSettingsJson};
const wchar_t kChromeExePathForTests[] = L"google\\chrome\\application";
const wchar_t kMasterPreferencesFileNameForTests[] = L"master_preferences";
const char kMasterPreferencesJsonForTests[] = R"(
{
"homepage": "http://dev.chromium.org/",
"extensions": {
"settings": {
"ababababcdcdcdcdefefefefghghghgh": {
"location": 1,
"manifest": {
"name": "Test extension"
}
},
"aaaabbbbccccddddeeeeffffgggghhhh": {
"location": 1,
"manifest": {
"name": "Another one"
}
}
}
}
})";
const char kSanitizedLnkPath[] = "CSIDL_PROFILE\\appdata\\roaming";
typedef std::map<base::string16, std::vector<base::string16>>
ExtensionIdToFileNamesMap;
class SystemReportComponentTest : public testing::Test {
public:
SystemReportComponentTest() : component_(&json_parser_, &shortcut_parser_) {}
void SetUp() override {
cleaner_logging_service_ = CleanerLoggingService::GetInstance();
cleaner_logging_service_->Initialize(nullptr);
cleaner_logging_service_->EnableUploads(true, /*registry_logger=*/nullptr);
LoggingServiceAPI::SetInstanceForTesting(cleaner_logging_service_);
registry_override_.OverrideRegistry(HKEY_CURRENT_USER);
registry_override_.OverrideRegistry(HKEY_LOCAL_MACHINE);
base::PathService::Get(CsidlToPathServiceKey(CSIDL_APPDATA),
&appdata_file_path_);
ASSERT_TRUE(fake_user_data_.CreateUniqueTempDir());
extension_id_to_filenames_map_[kTestingExtensionId1] = {L"file1.test",
L"file2.test"};
ASSERT_TRUE(CreateProfileWithExtensionAndFiles(
fake_user_data_.GetPath().Append(L"Profile 1"), kTestingExtensionId1,
extension_id_to_filenames_map_[kTestingExtensionId1]));
extension_id_to_filenames_map_[kTestingExtensionId2] = {L"file1.test"};
ASSERT_TRUE(CreateProfileWithExtensionAndFiles(
fake_user_data_.GetPath().Append(L"Profile 2"), kTestingExtensionId2,
extension_id_to_filenames_map_[kTestingExtensionId2]));
component_.SetUserDataPathForTesting(fake_user_data_.GetPath());
}
void TearDown() override {
LoggingServiceAPI::SetInstanceForTesting(nullptr);
cleaner_logging_service_->Terminate();
}
ChromeCleanerReport GetChromeCleanerReport() {
ChromeCleanerReport report;
CHECK(report.ParseFromString(cleaner_logging_service_->RawReportContent()));
return report;
}
TestJsonParser json_parser_;
FakeShortcutParser shortcut_parser_;
SystemReportComponent component_;
CleanerLoggingService* cleaner_logging_service_ = nullptr;
registry_util::RegistryOverrideManager registry_override_;
base::FilePath appdata_file_path_;
base::ScopedTempDir fake_user_data_;
ExtensionIdToFileNamesMap extension_id_to_filenames_map_;
};
template <typename Component>
bool SomeComponentContainsPath(const RepeatedPtrField<Component>& components,
const base::FilePath& path) {
const std::string name = path.BaseName().MaybeAsASCII();
const std::string sanitized_path = base::UTF16ToUTF8(SanitizePath(path));
for (const auto component : components) {
if (component.name() == name &&
component.file_information().path() == sanitized_path) {
return true;
}
}
return false;
}
bool InstalledProgramCollected(
const RepeatedPtrField<ChromeCleanerReport::SystemReport::InstalledProgram>&
programs,
const std::string& folder_name) {
const std::string lower_case_folder_name = base::ToLowerASCII(folder_name);
for (const auto& program : programs) {
if (program.folder_information().path().find(lower_case_folder_name) !=
std::string::npos) {
return true;
}
}
return false;
}
bool RegistryEntryCollected(
const RepeatedPtrField<RegistryValue>& registry_values,
const std::string& key_path,
const std::string& value_name,
const std::string& data) {
for (const auto& registry_value : registry_values) {
if (StringContainsCaseInsensitive(registry_value.key_path(), key_path) &&
registry_value.value_name() == value_name &&
registry_value.data() == data) {
return true;
}
}
return false;
}
bool RegistryKeyCollected(
const RepeatedPtrField<RegistryValue>& registry_values,
const std::string& key_path) {
for (const auto& registry_value : registry_values) {
if (StringContainsCaseInsensitive(registry_value.key_path(), key_path))
return true;
}
return false;
}
// Returns whether |extension_files| contains the expected file information
// of |extension_id|.
::testing::AssertionResult ExtensionsReportedWithExpectedFiles(
const RepeatedPtrField<InstalledExtension>& reported_extensions,
const ExtensionIdToFileNamesMap& extension_id_to_filenames_map) {
for (const auto& installed_extension : reported_extensions) {
const RepeatedPtrField<FileInformation> extension_files =
installed_extension.extension_files();
std::unordered_set<base::string16> expected_files(
extension_id_to_filenames_map
.at(base::UTF8ToUTF16(installed_extension.extension_id()))
.begin(),
extension_id_to_filenames_map
.at(base::UTF8ToUTF16(installed_extension.extension_id()))
.end());
if (static_cast<size_t>(extension_files.size()) != expected_files.size())
return ::testing::AssertionFailure()
<< "Different number of files than expected for extension "
<< installed_extension.extension_id();
for (const auto& file : extension_files) {
base::string16 file_name =
base::FilePath(base::UTF8ToUTF16(file.path())).BaseName().value();
if (expected_files.find(file_name) == expected_files.end())
return ::testing::AssertionFailure()
<< "file : " << file_name << " not reported for extension "
<< installed_extension.extension_id();
}
}
return ::testing::AssertionSuccess();
}
// Returns whether |reported_extensions| contains an entry for an extension with
// |extension_id| and |install_method|.
bool InstalledExtensionReported(
const RepeatedPtrField<InstalledExtension>& reported_extensions,
const std::wstring& extension_id,
ExtensionInstallMethod install_method) {
for (const auto& installed_extension : reported_extensions) {
if (installed_extension.extension_id() == base::WideToUTF8(extension_id) &&
installed_extension.install_method() == install_method) {
return true;
}
}
return false;
}
} // namespace
TEST_F(SystemReportComponentTest, PreScan_NoDetailedReport) {
component_.PreScan();
EXPECT_FALSE(component_.created_report());
}
TEST_F(SystemReportComponentTest, PostScanNoUwS_DetailedReport) {
std::vector<UwSId> found_pups;
component_.PostScan(found_pups);
EXPECT_TRUE(component_.created_report());
}
TEST_F(SystemReportComponentTest, PostScanNonRemovalableUwS_DetailedReport) {
TestPUPData test_pup_data;
test_pup_data.AddPUP(kFakePupId, PUPData::FLAGS_NONE, nullptr,
PUPData::kMaxFilesToRemoveSmallUwS);
std::vector<UwSId> found_pups;
found_pups.push_back(kFakePupId);
component_.PostScan(found_pups);
EXPECT_TRUE(component_.created_report());
}
TEST_F(SystemReportComponentTest, PostScanRemovalableUwS_NoDetailedReport) {
TestPUPData test_pup_data;
test_pup_data.AddPUP(kFakePupId, PUPData::FLAGS_ACTION_REMOVE, nullptr,
PUPData::kMaxFilesToRemoveSmallUwS);
std::vector<UwSId> found_pups;
found_pups.push_back(kFakePupId);
component_.PostScan(found_pups);
EXPECT_FALSE(component_.created_report());
}
TEST_F(SystemReportComponentTest, PreCleanup_NoDetailedReport) {
component_.PreCleanup();
EXPECT_FALSE(component_.created_report());
}
TEST_F(SystemReportComponentTest, PostCleanup_DetailedReport) {
component_.PostCleanup(RESULT_CODE_SUCCESS, nullptr);
EXPECT_TRUE(component_.created_report());
}
TEST_F(SystemReportComponentTest, PostCleanup_canceled_NoDetailedReport) {
component_.PostCleanup(RESULT_CODE_CANCELED, nullptr);
EXPECT_FALSE(component_.created_report());
}
TEST_F(SystemReportComponentTest, PostValidation_NoDetailedReport) {
component_.PostValidation(RESULT_CODE_SUCCESS);
EXPECT_FALSE(component_.created_report());
}
TEST_F(SystemReportComponentTest, OnClose_NoDetailedReport) {
component_.OnClose(RESULT_CODE_SUCCESS);
EXPECT_FALSE(component_.created_report());
}
TEST_F(SystemReportComponentTest, DisableUploads) {
cleaner_logging_service_->EnableUploads(false, nullptr);
component_.CreateFullSystemReport();
EXPECT_FALSE(component_.created_report());
}
TEST_F(SystemReportComponentTest, NoRepeatedCollections) {
component_.CreateFullSystemReport();
EXPECT_TRUE(component_.created_report());
// Clear the report and ensure it isn't populated again, since
// |created_report| is still true.
EXPECT_LT(0, GetChromeCleanerReport().system_report().processes_size());
cleaner_logging_service_->Terminate();
cleaner_logging_service_->Initialize(/*registry_logger=*/nullptr);
EXPECT_EQ(0, GetChromeCleanerReport().system_report().processes_size());
component_.CreateFullSystemReport();
EXPECT_EQ(0, GetChromeCleanerReport().system_report().processes_size());
}
TEST_F(SystemReportComponentTest, DetectFakePrograms) {
base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES);
base::FilePath program_files_dir;
ASSERT_TRUE(
base::PathService::Get(base::DIR_PROGRAM_FILES, &program_files_dir));
base::ScopedPathOverride appdata_override(base::DIR_LOCAL_APP_DATA);
base::FilePath appdata_dir;
ASSERT_TRUE(base::PathService::Get(base::DIR_LOCAL_APP_DATA, &appdata_dir));
// Setup a fake program installation folder.
base::FilePath fake_program_dir(program_files_dir.Append(kFakeProgramFolder));
ASSERT_TRUE(base::CreateDirectoryAndGetError(fake_program_dir, nullptr));
ASSERT_TRUE(CreateFileInFolder(fake_program_dir, L"fake.exe"));
base::FilePath fake_appdata_dir(
appdata_dir.Append(kFakeAppDataProgramFolder));
ASSERT_TRUE(base::CreateDirectoryAndGetError(fake_appdata_dir, nullptr));
ASSERT_TRUE(CreateFileInFolder(fake_appdata_dir, L"fake.exe"));
// Setup a fake runonce keys.
base::win::RegKey run_once(HKEY_CURRENT_USER, kRunKeyPath, KEY_WRITE);
ASSERT_TRUE(run_once.Valid());
ASSERT_EQ(run_once.WriteValue(kRunTestName, kRunTestValue), ERROR_SUCCESS);
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
const auto& system_report = report.system_report();
const base::FilePath module_path =
PreFetchedPaths::GetInstance()->GetExecutablePath();
EXPECT_TRUE(
SomeComponentContainsPath(system_report.loaded_modules(), module_path));
EXPECT_TRUE(
SomeComponentContainsPath(system_report.processes(), module_path));
EXPECT_TRUE(RegistryEntryCollected(
system_report.registry_values(), base::UTF16ToASCII(kRunKeyPath),
base::UTF16ToASCII(kRunTestName), base::UTF16ToASCII(kRunTestValue)));
EXPECT_TRUE(InstalledProgramCollected(system_report.installed_programs(),
kFakeProgram));
EXPECT_TRUE(InstalledProgramCollected(system_report.installed_programs(),
kFakeAppDataProgram));
}
TEST_F(SystemReportComponentTest, ReportNameServer) {
// Setup a fake key that triggers nameserver check.
base::win::RegKey nameserver_key;
ASSERT_EQ(ERROR_SUCCESS,
nameserver_key.Create(HKEY_LOCAL_MACHINE, kNameServerKeyPath,
KEY_ALL_ACCESS));
ASSERT_TRUE(nameserver_key.Valid());
ASSERT_EQ(nameserver_key.WriteValue(kNameServerName, kNameServerValue),
ERROR_SUCCESS);
component_.CreateFullSystemReport();
EXPECT_TRUE(RegistryEntryCollected(
GetChromeCleanerReport().system_report().registry_values(),
base::UTF16ToASCII(kNameServerKeyPath),
base::UTF16ToASCII(kNameServerName),
base::UTF16ToASCII(kNameServerValue)));
}
TEST_F(SystemReportComponentTest, ReportNameServerBadValue) {
// Setup a fake key that triggers nameserver check.
base::win::RegKey nameserver_key;
ASSERT_EQ(ERROR_SUCCESS,
nameserver_key.Create(HKEY_LOCAL_MACHINE, kNameServerKeyPath,
KEY_ALL_ACCESS));
ASSERT_TRUE(nameserver_key.Valid());
ASSERT_EQ(nameserver_key.WriteValue(kNameServerName, L""), ERROR_SUCCESS);
component_.CreateFullSystemReport();
EXPECT_FALSE(RegistryKeyCollected(
GetChromeCleanerReport().system_report().registry_values(),
base::UTF16ToASCII(kNameServerKeyPath)));
}
TEST_F(SystemReportComponentTest, ReportNameServerNonExistent) {
component_.CreateFullSystemReport();
EXPECT_FALSE(RegistryKeyCollected(
GetChromeCleanerReport().system_report().registry_values(),
base::UTF16ToASCII(kNameServerKeyPath)));
}
TEST_F(SystemReportComponentTest, ReportExtensionPolicies) {
for (const auto& extension_policy : extension_policies) {
base::win::RegKey policy_key;
ASSERT_EQ(ERROR_SUCCESS,
policy_key.Create(extension_policy.hkey,
extension_policy.key_path, KEY_ALL_ACCESS));
ASSERT_TRUE(policy_key.Valid());
ASSERT_EQ(
policy_key.WriteValue(extension_policy.name, extension_policy.value),
ERROR_SUCCESS);
}
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
const auto& system_report = report.system_report();
for (const auto& extension_policy : extension_policies) {
EXPECT_TRUE(
RegistryEntryCollected(system_report.registry_values(),
base::UTF16ToASCII(extension_policy.key_path),
base::UTF16ToASCII(extension_policy.name),
base::UTF16ToASCII(extension_policy.value)));
}
}
TEST_F(SystemReportComponentTest, ReportExtensionPoliciesBadValue) {
base::win::RegKey policy_key;
ASSERT_EQ(ERROR_SUCCESS,
policy_key.Create(kExtensionPolicyEmpty.hkey,
kExtensionPolicyEmpty.key_path, KEY_ALL_ACCESS));
ASSERT_TRUE(policy_key.Valid());
ASSERT_EQ(policy_key.WriteValue(kExtensionPolicyEmpty.name,
kExtensionPolicyEmpty.value),
ERROR_SUCCESS);
component_.CreateFullSystemReport();
EXPECT_FALSE(RegistryKeyCollected(
GetChromeCleanerReport().system_report().registry_values(),
base::UTF16ToASCII(kExtensionPolicyEmpty.key_path)));
}
TEST_F(SystemReportComponentTest, ReportExtensionPoliciesNonExistent) {
component_.CreateFullSystemReport();
EXPECT_FALSE(RegistryKeyCollected(
GetChromeCleanerReport().system_report().registry_values(),
kExtensionPoliciesNonExistent));
}
TEST_F(SystemReportComponentTest, ReportForcelistExtensions) {
for (const ReportTestData& policy : extension_forcelist_policies) {
base::win::RegKey policy_key;
ASSERT_EQ(ERROR_SUCCESS,
policy_key.Create(policy.hkey, policy.key_path, KEY_ALL_ACCESS));
ASSERT_TRUE(policy_key.Valid());
ASSERT_EQ(ERROR_SUCCESS, policy_key.WriteValue(policy.name, policy.value));
}
base::test::ScopedCommandLine scoped_command_line;
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
for (const ReportTestData& expected : extension_forcelist_policies) {
std::wstring policy_value(expected.value);
EXPECT_TRUE(InstalledExtensionReported(
report.system_report().installed_extensions(),
policy_value.substr(0, kExtensionIdLength),
ExtensionInstallMethod::POLICY_EXTENSION_FORCELIST));
}
}
TEST_F(SystemReportComponentTest, ReportDefaultExtensions) {
// Set up a fake default extensions JSON file.
base::ScopedPathOverride program_files_x86_override(
base::DIR_PROGRAM_FILESX86);
base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES);
base::FilePath program_files_dir;
ASSERT_TRUE(
base::PathService::Get(base::DIR_PROGRAM_FILES, &program_files_dir));
base::FilePath fake_apps_dir(
program_files_dir.Append(kFakeChromeFolderForTests)
.Append(L"default_apps"));
ASSERT_TRUE(base::CreateDirectoryAndGetError(fake_apps_dir, nullptr));
base::FilePath default_extensions_file =
fake_apps_dir.Append(L"external_extensions.json");
CreateFileWithContent(default_extensions_file, kDefaultExtensionsJsonForTests,
kDefaultExtensionsJsonForTestsSize);
ASSERT_TRUE(base::PathExists(default_extensions_file));
base::test::ScopedCommandLine scoped_command_line;
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
EXPECT_EQ(2, report.system_report().installed_extensions().size());
EXPECT_TRUE(InstalledExtensionReported(
report.system_report().installed_extensions(), kTestingExtensionId1,
ExtensionInstallMethod::DEFAULT_APPS_EXTENSION));
EXPECT_TRUE(InstalledExtensionReported(
report.system_report().installed_extensions(), kTestingExtensionId2,
ExtensionInstallMethod::DEFAULT_APPS_EXTENSION));
EXPECT_TRUE(ExtensionsReportedWithExpectedFiles(
report.system_report().installed_extensions(),
extension_id_to_filenames_map_));
}
TEST_F(SystemReportComponentTest, ReportExtensionSettings) {
// Set up a fake ExtensionSettings registry key.
base::win::RegKey settings_key;
ASSERT_EQ(
ERROR_SUCCESS,
settings_key.Create(extension_settings_entry.hkey,
extension_settings_entry.key_path, KEY_ALL_ACCESS));
DCHECK(settings_key.Valid());
ASSERT_EQ(ERROR_SUCCESS,
settings_key.WriteValue(extension_settings_entry.name,
extension_settings_entry.value));
base::test::ScopedCommandLine scoped_command_line;
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
EXPECT_TRUE(InstalledExtensionReported(
report.system_report().installed_extensions(), kTestingExtensionId1,
ExtensionInstallMethod::POLICY_EXTENSION_SETTINGS));
EXPECT_TRUE(InstalledExtensionReported(
report.system_report().installed_extensions(), kTestingExtensionId2,
ExtensionInstallMethod::POLICY_EXTENSION_SETTINGS));
EXPECT_TRUE(ExtensionsReportedWithExpectedFiles(
report.system_report().installed_extensions(),
extension_id_to_filenames_map_));
}
TEST_F(SystemReportComponentTest, ReportMasterPreferencesExtensions) {
// Set up a fake master preferences file
base::ScopedPathOverride program_files_x86_override(
base::DIR_PROGRAM_FILESX86);
base::ScopedPathOverride program_files_override(base::DIR_PROGRAM_FILES);
base::FilePath program_files_dir;
ASSERT_TRUE(
base::PathService::Get(base::DIR_PROGRAM_FILES, &program_files_dir));
base::FilePath chrome_dir(program_files_dir.Append(kChromeExePathForTests));
ASSERT_TRUE(base::CreateDirectoryAndGetError(chrome_dir, nullptr));
base::FilePath master_preferences =
chrome_dir.Append(kMasterPreferencesFileNameForTests);
CreateFileWithContent(master_preferences, kMasterPreferencesJsonForTests,
sizeof(kMasterPreferencesJsonForTests) - 1);
ASSERT_TRUE(base::PathExists(master_preferences));
base::test::ScopedCommandLine scoped_command_line;
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
EXPECT_EQ(2, report.system_report().installed_extensions().size());
EXPECT_TRUE(InstalledExtensionReported(
report.system_report().installed_extensions(), kTestingExtensionId1,
ExtensionInstallMethod::POLICY_MASTER_PREFERENCES));
EXPECT_TRUE(InstalledExtensionReported(
report.system_report().installed_extensions(), kTestingExtensionId2,
ExtensionInstallMethod::POLICY_MASTER_PREFERENCES));
EXPECT_TRUE(ExtensionsReportedWithExpectedFiles(
report.system_report().installed_extensions(),
extension_id_to_filenames_map_));
}
TEST_F(SystemReportComponentTest,
ReportModifiedShortcutWithCommandLineArguments) {
const base::string16 kShortcutArguments =
L"--some-flag --some-other-scary-flag --flag-with-personal-data=" +
appdata_file_path_.value();
const int kArgumentSize = 3;
ShortcutInformation shortcut_with_command_line_arguments;
shortcut_with_command_line_arguments.lnk_path = appdata_file_path_;
shortcut_with_command_line_arguments.target_path =
(appdata_file_path_.Append(L"chrome.exe")).value();
shortcut_with_command_line_arguments.command_line_arguments =
kShortcutArguments;
std::vector<ShortcutInformation> fake_parsed_shortcuts;
fake_parsed_shortcuts.push_back(shortcut_with_command_line_arguments);
shortcut_parser_.SetShortcutsToReturn(fake_parsed_shortcuts);
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
ASSERT_EQ(report.system_report().shortcut_data().size(), 1);
ChromeCleanerReport_SystemReport_ShortcutData shortcut_data =
report.system_report().shortcut_data(0);
EXPECT_EQ(shortcut_data.lnk_path(), kSanitizedLnkPath);
const std::string kSanitizedFakeChromePath = "CSIDL_APPDATA\\chrome.exe";
EXPECT_EQ(shortcut_data.executable_path(), kSanitizedFakeChromePath);
ASSERT_EQ(shortcut_data.command_line_arguments().size(), kArgumentSize);
EXPECT_EQ(
shortcut_data.command_line_arguments(0),
base::JoinString({"--flag-with-personal-data=", kSanitizedLnkPath}, ""));
EXPECT_EQ(shortcut_data.command_line_arguments(1), "--some-flag");
EXPECT_EQ(shortcut_data.command_line_arguments(2), "--some-other-scary-flag");
}
TEST_F(SystemReportComponentTest, ReportShortcutWithPersonalSite) {
const base::string16 kPersonalSite =
L"http://www.somesite.com/user/happy_user";
const std::string kSanitizedPersonalSite = "http://www.somesite.com";
ShortcutInformation shortcut_with_personal_site;
shortcut_with_personal_site.lnk_path = appdata_file_path_;
shortcut_with_personal_site.target_path =
(appdata_file_path_.Append(L"chrome.exe")).value();
shortcut_with_personal_site.command_line_arguments = kPersonalSite;
std::vector<ShortcutInformation> fake_parsed_shortcuts;
fake_parsed_shortcuts.push_back(shortcut_with_personal_site);
shortcut_parser_.SetShortcutsToReturn(fake_parsed_shortcuts);
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
ASSERT_EQ(report.system_report().shortcut_data().size(), 1);
ChromeCleanerReport_SystemReport_ShortcutData shortcut_data =
report.system_report().shortcut_data(0);
ASSERT_EQ(shortcut_data.command_line_arguments().size(), 1);
EXPECT_EQ(shortcut_data.lnk_path(), kSanitizedLnkPath);
const std::string kSanitizedFakeChromePath = "CSIDL_APPDATA\\chrome.exe";
EXPECT_EQ(shortcut_data.executable_path(), kSanitizedFakeChromePath);
ASSERT_EQ(shortcut_data.command_line_arguments().size(), 1);
EXPECT_EQ(shortcut_data.command_line_arguments(0), kSanitizedPersonalSite);
}
TEST_F(SystemReportComponentTest, ReportShortcutWithDifferentTarget) {
ShortcutInformation shortcut_with_different_target;
shortcut_with_different_target.lnk_path = appdata_file_path_;
shortcut_with_different_target.target_path =
(appdata_file_path_.Append(L"totallynotuws.exe")).value();
shortcut_with_different_target.command_line_arguments = L"";
std::vector<ShortcutInformation> fake_parsed_shortcuts;
fake_parsed_shortcuts.push_back(shortcut_with_different_target);
shortcut_parser_.SetShortcutsToReturn(fake_parsed_shortcuts);
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
ASSERT_EQ(report.system_report().shortcut_data().size(), 1);
ChromeCleanerReport_SystemReport_ShortcutData shortcut_data =
report.system_report().shortcut_data(0);
EXPECT_EQ(shortcut_data.lnk_path(), kSanitizedLnkPath);
const std::string kSanitizedFakeUwSFile = "CSIDL_APPDATA\\totallynotuws.exe";
EXPECT_EQ(shortcut_data.executable_path(), kSanitizedFakeUwSFile);
EXPECT_EQ(shortcut_data.command_line_arguments().size(), 0);
}
TEST_F(SystemReportComponentTest, DoNotReportShortcutWithoutModifications) {
ShortcutInformation not_modified_shortcut;
not_modified_shortcut.lnk_path = appdata_file_path_;
not_modified_shortcut.target_path =
(appdata_file_path_.Append(L"chrome.exe")).value();
not_modified_shortcut.command_line_arguments = L"";
std::vector<ShortcutInformation> fake_parsed_shortcuts;
fake_parsed_shortcuts.push_back(not_modified_shortcut);
shortcut_parser_.SetShortcutsToReturn(fake_parsed_shortcuts);
component_.CreateFullSystemReport();
ChromeCleanerReport report = GetChromeCleanerReport();
EXPECT_EQ(report.system_report().shortcut_data().size(), 0);
}
} // namespace chrome_cleaner