1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_WIN_CONFLICTS_THIRD_PARTY_CONFLICTS_MANAGER_H_
#define CHROME_BROWSER_WIN_CONFLICTS_THIRD_PARTY_CONFLICTS_MANAGER_H_
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/win/conflicts/installed_applications.h"
#include "chrome/browser/win/conflicts/module_blocklist_cache_updater.h"
#include "chrome/browser/win/conflicts/module_database_observer.h"
#include "chrome/browser/win/conflicts/module_list_component_updater.h"
#include "chrome/chrome_elf/third_party_dlls/packed_list_format.h"
class IncompatibleApplicationsUpdater;
class InstalledApplications;
class ModuleListFilter;
class PrefRegistrySimple;
struct CertificateInfo;
namespace base {
class FilePath;
class SequencedTaskRunner;
class TaskRunner;
class Version;
} // namespace base
// This class is responsible for the initialization of the
// IncompatibleApplicationsWarning and ThirdPartyModulesBlocking features. Each
// feature requires a set of dependencies to be initialized on a background
// sequence because their main class can be created
// (IncompatibleApplicationsUpdater and ModuleBlocklistCacheUpdater
// respectively).
//
// Dependencies list
// For both features:
// 1. |exe_certificate_info_| contains info about the certificate of the current
// executable.
// 2. |module_list_filter_| is used to determine if a module should be blocked
// or allowed. The Module List component is received from the component
// update service, which invokes OnModuleListComponentRegistered() and
// LoadModuleList() when appropriate.
//
// For the IncompatibleApplicationsWarning feature only:
// 3. |installed_applications_| allows to tie a loaded module to an application
// installed on the computer.
//
// For the ThirdPartyModulesBlocking feature only:
// 4. |initial_blocklisted_modules_| contains the list of modules that were
// blocklisted at the time the browser was launched. Modifications to that
// list do not take effect until a restart.
//
class ThirdPartyConflictsManager : public ModuleDatabaseObserver {
public:
// |module_database_event_source| must outlive this.
explicit ThirdPartyConflictsManager(
ModuleDatabaseEventSource* module_database_event_source);
ThirdPartyConflictsManager(const ThirdPartyConflictsManager&) = delete;
ThirdPartyConflictsManager& operator=(const ThirdPartyConflictsManager&) =
delete;
~ThirdPartyConflictsManager() override;
static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
// Explicitely disables the third-party module blocking feature. This is
// needed because simply turning off the feature using either the Feature List
// API or via group policy is not sufficient. Disabling the blocking requires
// the deletion of the module blocklist cache. This task is executed on
// |background_sequence|.
static void DisableThirdPartyModuleBlocking(
base::TaskRunner* background_sequence);
// Explicitely disables the blocking of third-party modules for the next
// browser launch and prevent |instance| from reenabling it. Basically calls
// the above function in the background sequence of |instance| and then
// deletes that instance.
static void ShutdownAndDestroy(
std::unique_ptr<ThirdPartyConflictsManager> instance);
// ModuleDatabaseObserver:
void OnNewModuleFound(const ModuleInfoKey& module_key,
const ModuleInfoData& module_data) override;
void OnModuleDatabaseIdle() override;
// Invoked when the Third Party Module List component is registered with the
// component update service. Checks if the component is currently installed or
// if an update is required.
void OnModuleListComponentRegistered(std::string_view component_id,
const base::Version& component_version);
// Loads the |module_list_filter_| using the Module List at |path|.
void LoadModuleList(const base::FilePath& path);
void SetInstalledApplicationsForTesting(
std::unique_ptr<InstalledApplications> installed_applications) {
installed_applications_ = std::move(installed_applications);
}
// Force the initialization of the IncompatibleApplicationsUpdater and the
// ModuleBlocklistCacheUpdater instances by triggering an update of the module
// list component, if needed. Immediately invokes
// |on_initialization_event_callback| if this instance is already in a final
// state (Failed to initialize or fully initialized). This is only meant to be
// used when the chrome://conflicts page is opened by the user.
enum class State {
// The initialization failed because the Module List component couldn't be
// used to initialize the ModuleListFilter.
kModuleListInvalidFailure,
// The initialization failed because there was no Module List version
// available to install.
kNoModuleListAvailableFailure,
// Only the IncompatibleApplicationsWarning feature is enabled and active.
kWarningInitialized,
// Only the ThirdPartyModulesBlocking feature is enabled and active.
kBlockingInitialized,
// Both the IncompatibleApplicationsWarning and ThirdPartyModulesBlocking
// features are enabled and active.
kWarningAndBlockingInitialized,
// The instance is about to be deleted.
kDestroyed,
};
using OnInitializationCompleteCallback =
base::OnceCallback<void(State state)>;
void ForceInitialization(
OnInitializationCompleteCallback on_initialization_complete_callback);
// Returns the IncompatibleApplicationsUpdater instance. Returns null if the
// corresponding feature is disabled (IncompatibleApplicationsWarning).
IncompatibleApplicationsUpdater* incompatible_applications_updater() {
return incompatible_applications_updater_.get();
}
// Returns the ModuleBlocklistCacheUpdater instance. Returns null if the
// corresponding feature is disabled (ThirdPartyModulesBlocking).
ModuleBlocklistCacheUpdater* module_blocklist_cache_updater() {
return module_blocklist_cache_updater_.get();
}
// Disables the analysis of newly found modules.
void DisableModuleAnalysis();
private:
// Called when |module_list_filter_| finishes its initialization.
void OnModuleListFilterCreated(
scoped_refptr<ModuleListFilter> module_list_filter);
// Called when |installed_applications_| finishes its initialization.
void OnInstalledApplicationsCreated(
std::unique_ptr<InstalledApplications> installed_applications);
// Called when |initial_blocklisted_modules_| finishes its initialization.
void OnInitialBlocklistedModulesRead(
std::unique_ptr<std::vector<third_party_dlls::PackedListModule>>
initial_blocklisted_modules);
// Initializes either or both |incompatible_applications_updater_| and
// |module_blocklist_cache_updater_| when the exe_certificate_info_, the
// module_list_filter_ and the installed_applications_ are available.
void InitializeIfReady();
// Checks if the |old_md5_digest| matches the expected one from the Local
// State file, and updates it to |new_md5_digest|.
void OnModuleBlocklistCacheUpdated(
const ModuleBlocklistCacheUpdater::CacheUpdateResult& result);
// Forcibly triggers an update of the Third Party Module List component. Only
// invoked when ForceInitialization() is called.
void ForceModuleListComponentUpdate();
// Callback for when the component update service was not able to download the
// module list component. Successful updates will cause the LoadModuleList()
// function to be invoked instead.
void OnModuleListComponentNotUpdated();
// Modifies the current state and invokes
// |on_initialization_complete_callback_|.
void SetTerminalState(State terminal_state);
const raw_ptr<ModuleDatabaseEventSource> module_database_event_source_;
scoped_refptr<base::SequencedTaskRunner> background_sequence_;
// Indicates if the initial Module List has been received. Used to prevent the
// creation of multiple ModuleListFilter instances.
bool module_list_received_;
// Indicates if the OnModuleDatabaseIdle() function has been called once
// already. Used to prevent the creation of multiple InstalledApplications
// instances.
bool on_module_database_idle_called_;
// Path to the current executable (expected to be chrome.exe).
base::FilePath exe_path_;
// The certificate info of the current executable.
std::unique_ptr<CertificateInfo> exe_certificate_info_;
// Holds the id of the Third Party Module List component.
std::string module_list_component_id_;
// Remembers if ForceInitialization() was invoked.
bool initialization_forced_;
// Indicates if an update to the Module List component is needed to initialize
// the ModuleListFilter.
bool module_list_update_needed_;
// Responsible for forcing an update to the Module List component on the UI
// thread if none is currently installed.
ModuleListComponentUpdater::UniquePtr module_list_component_updater_;
// Filters third-party modules against an allowlist and a blocklist. This
// instance is ref counted because the |module_blocklist_cache_updater_| must
// use it on a background sequence.
scoped_refptr<ModuleListFilter> module_list_filter_;
// The blocklisted modules contained in the cache used to initialize the
// blocking in chrome_elf.
std::unique_ptr<std::vector<third_party_dlls::PackedListModule>>
initial_blocklisted_modules_;
// Retrieves the list of installed applications.
std::unique_ptr<InstalledApplications> installed_applications_;
// Maintains the module blocklist cache. This member is only initialized when
// the ThirdPartyModuleBlocking feature is enabled.
std::unique_ptr<ModuleBlocklistCacheUpdater> module_blocklist_cache_updater_;
// Maintains the cache of incompatible applications. This member is only
// initialized when the IncompatibleApplicationsWarning feature is enabled.
std::unique_ptr<IncompatibleApplicationsUpdater>
incompatible_applications_updater_;
// The final state of this instance.
std::optional<State> terminal_state_;
// The callback that is invoked when |state_| changes.
OnInitializationCompleteCallback on_initialization_complete_callback_;
// Indicates if the analysis of newly found modules is disabled. Used as a
// workaround for https://crbug.com/892294.
bool module_analysis_disabled_ = false;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<ThirdPartyConflictsManager> weak_ptr_factory_;
};
#endif // CHROME_BROWSER_WIN_CONFLICTS_THIRD_PARTY_CONFLICTS_MANAGER_H_
|