1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/extension_system_impl.h" 6 7 #include "base/base_switches.h" 8 #include "base/bind.h" 9 #include "base/command_line.h" 10 #include "base/files/file_path.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/strings/string_tokenizer.h" 13 #include "chrome/browser/browser_process.h" 14 #include "chrome/browser/content_settings/cookie_settings.h" 15 #include "chrome/browser/extensions/blacklist.h" 16 #include "chrome/browser/extensions/component_loader.h" 17 #include "chrome/browser/extensions/error_console/error_console.h" 18 #include "chrome/browser/extensions/extension_error_reporter.h" 19 #include "chrome/browser/extensions/extension_service.h" 20 #include "chrome/browser/extensions/extension_system_factory.h" 21 #include "chrome/browser/extensions/extension_util.h" 22 #include "chrome/browser/extensions/extension_warning_badge_service.h" 23 #include "chrome/browser/extensions/extension_warning_set.h" 24 #include "chrome/browser/extensions/install_verifier.h" 25 #include "chrome/browser/extensions/navigation_observer.h" 26 #include "chrome/browser/extensions/shared_module_service.h" 27 #include "chrome/browser/extensions/standard_management_policy_provider.h" 28 #include "chrome/browser/extensions/state_store.h" 29 #include "chrome/browser/extensions/unpacked_installer.h" 30 #include "chrome/browser/extensions/updater/manifest_fetch_data.h" 31 #include "chrome/browser/extensions/user_script_master.h" 32 #include "chrome/browser/profiles/profile.h" 33 #include "chrome/browser/profiles/profile_manager.h" 34 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 35 #include "chrome/common/chrome_switches.h" 36 #include "chrome/common/chrome_version_info.h" 37 #include "chrome/common/extensions/extension_constants.h" 38 #include "chrome/common/extensions/extension_file_util.h" 39 #include "chrome/common/extensions/features/feature_channel.h" 40 #include "chrome/common/extensions/manifest_url_handler.h" 41 #include "content/public/browser/browser_thread.h" 42 #include "content/public/browser/url_data_source.h" 43 #include "extensions/browser/content_verifier.h" 44 #include "extensions/browser/content_verifier_delegate.h" 45 #include "extensions/browser/event_router.h" 46 #include "extensions/browser/extension_pref_store.h" 47 #include "extensions/browser/extension_pref_value_map.h" 48 #include "extensions/browser/extension_pref_value_map_factory.h" 49 #include "extensions/browser/extension_prefs.h" 50 #include "extensions/browser/extension_registry.h" 51 #include "extensions/browser/info_map.h" 52 #include "extensions/browser/lazy_background_task_queue.h" 53 #include "extensions/browser/management_policy.h" 54 #include "extensions/browser/process_manager.h" 55 #include "extensions/browser/quota_service.h" 56 #include "extensions/browser/runtime_data.h" 57 #include "extensions/common/constants.h" 58 #include "extensions/common/extension.h" 59 #include "extensions/common/manifest.h" 60 #include "net/base/escape.h" 61 62 #if defined(ENABLE_NOTIFICATIONS) 63 #include "chrome/browser/notifications/desktop_notification_service.h" 64 #include "chrome/browser/notifications/desktop_notification_service_factory.h" 65 #include "ui/message_center/notifier_settings.h" 66 #endif 67 68 #if defined(OS_CHROMEOS) 69 #include "chrome/browser/app_mode/app_mode_utils.h" 70 #include "chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.h" 71 #include "chrome/browser/chromeos/login/users/user.h" 72 #include "chrome/browser/chromeos/login/users/user_manager.h" 73 #include "chrome/browser/chromeos/policy/device_local_account.h" 74 #include "chromeos/chromeos_switches.h" 75 #include "chromeos/login/login_state.h" 76 #endif 77 78 using content::BrowserThread; 79 80 namespace extensions { 81 82 // 83 // ExtensionSystemImpl::Shared 84 // 85 86 ExtensionSystemImpl::Shared::Shared(Profile* profile) 87 : profile_(profile) { 88 } 89 90 ExtensionSystemImpl::Shared::~Shared() { 91 } 92 93 void ExtensionSystemImpl::Shared::InitPrefs() { 94 lazy_background_task_queue_.reset(new LazyBackgroundTaskQueue(profile_)); 95 event_router_.reset(new EventRouter(profile_, ExtensionPrefs::Get(profile_))); 96 // TODO(yoz): Remove once crbug.com/159265 is fixed. 97 #if defined(ENABLE_EXTENSIONS) 98 // Two state stores. The latter, which contains declarative rules, must be 99 // loaded immediately so that the rules are ready before we issue network 100 // requests. 101 state_store_.reset(new StateStore( 102 profile_, 103 profile_->GetPath().AppendASCII(extensions::kStateStoreName), 104 true)); 105 106 rules_store_.reset(new StateStore( 107 profile_, 108 profile_->GetPath().AppendASCII(extensions::kRulesStoreName), 109 false)); 110 111 blacklist_.reset(new Blacklist(ExtensionPrefs::Get(profile_))); 112 113 standard_management_policy_provider_.reset( 114 new StandardManagementPolicyProvider(ExtensionPrefs::Get(profile_))); 115 116 #if defined (OS_CHROMEOS) 117 const chromeos::User* user = chromeos::UserManager::Get()->GetActiveUser(); 118 policy::DeviceLocalAccount::Type device_local_account_type; 119 if (user && policy::IsDeviceLocalAccountUser(user->email(), 120 &device_local_account_type)) { 121 device_local_account_management_policy_provider_.reset( 122 new chromeos::DeviceLocalAccountManagementPolicyProvider( 123 device_local_account_type)); 124 } 125 #endif // defined (OS_CHROMEOS) 126 127 #endif // defined(ENABLE_EXTENSIONS) 128 } 129 130 void ExtensionSystemImpl::Shared::RegisterManagementPolicyProviders() { 131 // TODO(yoz): Remove once crbug.com/159265 is fixed. 132 #if defined(ENABLE_EXTENSIONS) 133 DCHECK(standard_management_policy_provider_.get()); 134 management_policy_->RegisterProvider( 135 standard_management_policy_provider_.get()); 136 137 #if defined (OS_CHROMEOS) 138 if (device_local_account_management_policy_provider_) { 139 management_policy_->RegisterProvider( 140 device_local_account_management_policy_provider_.get()); 141 } 142 #endif // defined (OS_CHROMEOS) 143 144 management_policy_->RegisterProvider(install_verifier_.get()); 145 146 #endif // defined(ENABLE_EXTENSIONS) 147 } 148 149 namespace { 150 151 class ContentVerifierDelegateImpl : public ContentVerifierDelegate { 152 public: 153 explicit ContentVerifierDelegateImpl(ExtensionService* service) 154 : service_(service->AsWeakPtr()) {} 155 156 virtual ~ContentVerifierDelegateImpl() {} 157 158 virtual bool ShouldBeVerified(const Extension& extension) OVERRIDE { 159 if (!extension.is_extension() && !extension.is_legacy_packaged_app()) 160 return false; 161 if (!Manifest::IsAutoUpdateableLocation(extension.location())) 162 return false; 163 164 if (!ManifestURL::UpdatesFromGallery(&extension)) { 165 // It's possible that the webstore update url was overridden for testing 166 // so also consider extensions with the default (production) update url 167 // to be from the store as well. 168 GURL default_webstore_url = extension_urls::GetDefaultWebstoreUpdateUrl(); 169 if (ManifestURL::GetUpdateURL(&extension) != default_webstore_url) 170 return false; 171 } 172 173 return true; 174 } 175 176 virtual const ContentVerifierKey& PublicKey() OVERRIDE { 177 static ContentVerifierKey key( 178 extension_misc::kWebstoreSignaturesPublicKey, 179 extension_misc::kWebstoreSignaturesPublicKeySize); 180 return key; 181 } 182 183 virtual GURL GetSignatureFetchUrl(const std::string& extension_id, 184 const base::Version& version) OVERRIDE { 185 // TODO(asargent) Factor out common code from the extension updater's 186 // ManifestFetchData class that can be shared for use here. 187 std::vector<std::string> parts; 188 parts.push_back("uc"); 189 parts.push_back("installsource=signature"); 190 parts.push_back("id=" + extension_id); 191 parts.push_back("v=" + version.GetString()); 192 std::string x_value = 193 net::EscapeQueryParamValue(JoinString(parts, "&"), true); 194 std::string query = "response=redirect&x=" + x_value; 195 196 GURL base_url = extension_urls::GetWebstoreUpdateUrl(); 197 GURL::Replacements replacements; 198 replacements.SetQuery(query.c_str(), url::Component(0, query.length())); 199 return base_url.ReplaceComponents(replacements); 200 } 201 202 virtual std::set<base::FilePath> GetBrowserImagePaths( 203 const extensions::Extension* extension) OVERRIDE { 204 return extension_file_util::GetBrowserImagePaths(extension); 205 } 206 207 virtual void VerifyFailed(const std::string& extension_id) OVERRIDE { 208 if (service_) 209 service_->DisableExtension(extension_id, Extension::DISABLE_CORRUPTED); 210 } 211 212 private: 213 base::WeakPtr<ExtensionService> service_; 214 DISALLOW_COPY_AND_ASSIGN(ContentVerifierDelegateImpl); 215 }; 216 217 } // namespace 218 219 void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) { 220 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 221 222 navigation_observer_.reset(new NavigationObserver(profile_)); 223 224 bool allow_noisy_errors = !command_line->HasSwitch(switches::kNoErrorDialogs); 225 ExtensionErrorReporter::Init(allow_noisy_errors); 226 227 user_script_master_ = new UserScriptMaster(profile_); 228 229 // ExtensionService depends on RuntimeData. 230 runtime_data_.reset(new RuntimeData(ExtensionRegistry::Get(profile_))); 231 232 bool autoupdate_enabled = !profile_->IsGuestSession(); 233 #if defined(OS_CHROMEOS) 234 if (!extensions_enabled) 235 autoupdate_enabled = false; 236 #endif 237 extension_service_.reset(new ExtensionService( 238 profile_, 239 CommandLine::ForCurrentProcess(), 240 profile_->GetPath().AppendASCII(extensions::kInstallDirectoryName), 241 ExtensionPrefs::Get(profile_), 242 blacklist_.get(), 243 autoupdate_enabled, 244 extensions_enabled, 245 &ready_)); 246 247 // These services must be registered before the ExtensionService tries to 248 // load any extensions. 249 { 250 install_verifier_.reset( 251 new InstallVerifier(ExtensionPrefs::Get(profile_), profile_)); 252 install_verifier_->Init(); 253 content_verifier_ = new ContentVerifier( 254 profile_, new ContentVerifierDelegateImpl(extension_service_.get())); 255 content_verifier_->Start(); 256 info_map()->SetContentVerifier(content_verifier_.get()); 257 258 management_policy_.reset(new ManagementPolicy); 259 RegisterManagementPolicyProviders(); 260 } 261 262 bool skip_session_extensions = false; 263 #if defined(OS_CHROMEOS) 264 // Skip loading session extensions if we are not in a user session. 265 skip_session_extensions = !chromeos::LoginState::Get()->IsUserLoggedIn(); 266 if (chrome::IsRunningInForcedAppMode()) { 267 extension_service_->component_loader()-> 268 AddDefaultComponentExtensionsForKioskMode(skip_session_extensions); 269 } else { 270 extension_service_->component_loader()->AddDefaultComponentExtensions( 271 skip_session_extensions); 272 } 273 #else 274 extension_service_->component_loader()->AddDefaultComponentExtensions( 275 skip_session_extensions); 276 #endif 277 if (command_line->HasSwitch(switches::kLoadComponentExtension)) { 278 CommandLine::StringType path_list = command_line->GetSwitchValueNative( 279 switches::kLoadComponentExtension); 280 base::StringTokenizerT<CommandLine::StringType, 281 CommandLine::StringType::const_iterator> t(path_list, 282 FILE_PATH_LITERAL(",")); 283 while (t.GetNext()) { 284 // Load the component extension manifest synchronously. 285 // Blocking the UI thread is acceptable here since 286 // this flag designated for developers. 287 base::ThreadRestrictions::ScopedAllowIO allow_io; 288 extension_service_->component_loader()->AddOrReplace( 289 base::FilePath(t.token())); 290 } 291 } 292 extension_service_->Init(); 293 294 // Make the chrome://extension-icon/ resource available. 295 content::URLDataSource::Add(profile_, new ExtensionIconSource(profile_)); 296 297 extension_warning_service_.reset(new ExtensionWarningService(profile_)); 298 extension_warning_badge_service_.reset( 299 new ExtensionWarningBadgeService(profile_)); 300 extension_warning_service_->AddObserver( 301 extension_warning_badge_service_.get()); 302 error_console_.reset(new ErrorConsole(profile_)); 303 quota_service_.reset(new QuotaService); 304 305 if (extensions_enabled) { 306 // Load any extensions specified with --load-extension. 307 // TODO(yoz): Seems like this should move into ExtensionService::Init. 308 // But maybe it's no longer important. 309 if (command_line->HasSwitch(switches::kLoadExtension)) { 310 CommandLine::StringType path_list = command_line->GetSwitchValueNative( 311 switches::kLoadExtension); 312 base::StringTokenizerT<CommandLine::StringType, 313 CommandLine::StringType::const_iterator> t(path_list, 314 FILE_PATH_LITERAL(",")); 315 while (t.GetNext()) { 316 std::string extension_id; 317 UnpackedInstaller::Create(extension_service_.get())-> 318 LoadFromCommandLine(base::FilePath(t.token()), &extension_id); 319 } 320 } 321 } 322 } 323 324 void ExtensionSystemImpl::Shared::Shutdown() { 325 if (extension_warning_service_) { 326 extension_warning_service_->RemoveObserver( 327 extension_warning_badge_service_.get()); 328 } 329 if (content_verifier_) 330 content_verifier_->Shutdown(); 331 if (extension_service_) 332 extension_service_->Shutdown(); 333 } 334 335 StateStore* ExtensionSystemImpl::Shared::state_store() { 336 return state_store_.get(); 337 } 338 339 StateStore* ExtensionSystemImpl::Shared::rules_store() { 340 return rules_store_.get(); 341 } 342 343 ExtensionService* ExtensionSystemImpl::Shared::extension_service() { 344 return extension_service_.get(); 345 } 346 347 RuntimeData* ExtensionSystemImpl::Shared::runtime_data() { 348 return runtime_data_.get(); 349 } 350 351 ManagementPolicy* ExtensionSystemImpl::Shared::management_policy() { 352 return management_policy_.get(); 353 } 354 355 UserScriptMaster* ExtensionSystemImpl::Shared::user_script_master() { 356 return user_script_master_.get(); 357 } 358 359 InfoMap* ExtensionSystemImpl::Shared::info_map() { 360 if (!extension_info_map_.get()) 361 extension_info_map_ = new InfoMap(); 362 return extension_info_map_.get(); 363 } 364 365 LazyBackgroundTaskQueue* 366 ExtensionSystemImpl::Shared::lazy_background_task_queue() { 367 return lazy_background_task_queue_.get(); 368 } 369 370 EventRouter* ExtensionSystemImpl::Shared::event_router() { 371 return event_router_.get(); 372 } 373 374 ExtensionWarningService* ExtensionSystemImpl::Shared::warning_service() { 375 return extension_warning_service_.get(); 376 } 377 378 Blacklist* ExtensionSystemImpl::Shared::blacklist() { 379 return blacklist_.get(); 380 } 381 382 ErrorConsole* ExtensionSystemImpl::Shared::error_console() { 383 return error_console_.get(); 384 } 385 386 InstallVerifier* ExtensionSystemImpl::Shared::install_verifier() { 387 return install_verifier_.get(); 388 } 389 390 QuotaService* ExtensionSystemImpl::Shared::quota_service() { 391 return quota_service_.get(); 392 } 393 394 ContentVerifier* ExtensionSystemImpl::Shared::content_verifier() { 395 return content_verifier_.get(); 396 } 397 398 // 399 // ExtensionSystemImpl 400 // 401 402 ExtensionSystemImpl::ExtensionSystemImpl(Profile* profile) 403 : profile_(profile) { 404 shared_ = ExtensionSystemSharedFactory::GetForBrowserContext(profile); 405 406 if (profile->IsOffTheRecord()) { 407 process_manager_.reset(ProcessManager::Create(profile)); 408 } else { 409 shared_->InitPrefs(); 410 } 411 } 412 413 ExtensionSystemImpl::~ExtensionSystemImpl() { 414 } 415 416 void ExtensionSystemImpl::Shutdown() { 417 process_manager_.reset(); 418 } 419 420 void ExtensionSystemImpl::InitForRegularProfile(bool extensions_enabled) { 421 DCHECK(!profile_->IsOffTheRecord()); 422 if (user_script_master() || extension_service()) 423 return; // Already initialized. 424 425 // The InfoMap needs to be created before the ProcessManager. 426 shared_->info_map(); 427 428 process_manager_.reset(ProcessManager::Create(profile_)); 429 430 shared_->Init(extensions_enabled); 431 } 432 433 ExtensionService* ExtensionSystemImpl::extension_service() { 434 return shared_->extension_service(); 435 } 436 437 RuntimeData* ExtensionSystemImpl::runtime_data() { 438 return shared_->runtime_data(); 439 } 440 441 ManagementPolicy* ExtensionSystemImpl::management_policy() { 442 return shared_->management_policy(); 443 } 444 445 UserScriptMaster* ExtensionSystemImpl::user_script_master() { 446 return shared_->user_script_master(); 447 } 448 449 ProcessManager* ExtensionSystemImpl::process_manager() { 450 return process_manager_.get(); 451 } 452 453 StateStore* ExtensionSystemImpl::state_store() { 454 return shared_->state_store(); 455 } 456 457 StateStore* ExtensionSystemImpl::rules_store() { 458 return shared_->rules_store(); 459 } 460 461 InfoMap* ExtensionSystemImpl::info_map() { return shared_->info_map(); } 462 463 LazyBackgroundTaskQueue* ExtensionSystemImpl::lazy_background_task_queue() { 464 return shared_->lazy_background_task_queue(); 465 } 466 467 EventRouter* ExtensionSystemImpl::event_router() { 468 return shared_->event_router(); 469 } 470 471 ExtensionWarningService* ExtensionSystemImpl::warning_service() { 472 return shared_->warning_service(); 473 } 474 475 Blacklist* ExtensionSystemImpl::blacklist() { 476 return shared_->blacklist(); 477 } 478 479 const OneShotEvent& ExtensionSystemImpl::ready() const { 480 return shared_->ready(); 481 } 482 483 ErrorConsole* ExtensionSystemImpl::error_console() { 484 return shared_->error_console(); 485 } 486 487 InstallVerifier* ExtensionSystemImpl::install_verifier() { 488 return shared_->install_verifier(); 489 } 490 491 QuotaService* ExtensionSystemImpl::quota_service() { 492 return shared_->quota_service(); 493 } 494 495 ContentVerifier* ExtensionSystemImpl::content_verifier() { 496 return shared_->content_verifier(); 497 } 498 499 scoped_ptr<ExtensionSet> ExtensionSystemImpl::GetDependentExtensions( 500 const Extension* extension) { 501 return extension_service()->shared_module_service()->GetDependentExtensions( 502 extension); 503 } 504 505 void ExtensionSystemImpl::RegisterExtensionWithRequestContexts( 506 const Extension* extension) { 507 base::Time install_time; 508 if (extension->location() != Manifest::COMPONENT) { 509 install_time = ExtensionPrefs::Get(profile_)-> 510 GetInstallTime(extension->id()); 511 } 512 bool incognito_enabled = util::IsIncognitoEnabled(extension->id(), profile_); 513 514 bool notifications_disabled = false; 515 #if defined(ENABLE_NOTIFICATIONS) 516 message_center::NotifierId notifier_id( 517 message_center::NotifierId::APPLICATION, 518 extension->id()); 519 520 DesktopNotificationService* notification_service = 521 DesktopNotificationServiceFactory::GetForProfile(profile_); 522 notifications_disabled = 523 !notification_service->IsNotifierEnabled(notifier_id); 524 #endif 525 526 BrowserThread::PostTask( 527 BrowserThread::IO, FROM_HERE, 528 base::Bind(&InfoMap::AddExtension, info_map(), 529 make_scoped_refptr(extension), install_time, 530 incognito_enabled, notifications_disabled)); 531 } 532 533 void ExtensionSystemImpl::UnregisterExtensionWithRequestContexts( 534 const std::string& extension_id, 535 const UnloadedExtensionInfo::Reason reason) { 536 BrowserThread::PostTask( 537 BrowserThread::IO, 538 FROM_HERE, 539 base::Bind(&InfoMap::RemoveExtension, info_map(), extension_id, reason)); 540 } 541 542 } // namespace extensions 543