| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 545 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 546 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 546 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 547 profile_(profile), | 547 profile_(profile), |
| 548 extension_prefs_(extension_prefs), | 548 extension_prefs_(extension_prefs), |
| 549 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 549 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 550 install_directory_(install_directory), | 550 install_directory_(install_directory), |
| 551 extensions_enabled_(extensions_enabled), | 551 extensions_enabled_(extensions_enabled), |
| 552 show_extensions_prompts_(true), | 552 show_extensions_prompts_(true), |
| 553 ready_(false), | 553 ready_(false), |
| 554 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 554 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 555 permissions_manager_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 555 apps_promo_(profile->GetPrefs()), | 556 apps_promo_(profile->GetPrefs()), |
| 556 event_routers_initialized_(false) { | 557 event_routers_initialized_(false) { |
| 557 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 558 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 558 | 559 |
| 559 // Figure out if extension installation should be enabled. | 560 // Figure out if extension installation should be enabled. |
| 560 if (command_line->HasSwitch(switches::kDisableExtensions)) { | 561 if (command_line->HasSwitch(switches::kDisableExtensions)) { |
| 561 extensions_enabled_ = false; | 562 extensions_enabled_ = false; |
| 562 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { | 563 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { |
| 563 extensions_enabled_ = false; | 564 extensions_enabled_ = false; |
| 564 } | 565 } |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 extension); | 968 extension); |
| 968 terminated_extensions_.erase(iter); | 969 terminated_extensions_.erase(iter); |
| 969 } | 970 } |
| 970 | 971 |
| 971 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE); | 972 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE); |
| 972 } | 973 } |
| 973 | 974 |
| 974 void ExtensionService::GrantPermissions(const Extension* extension) { | 975 void ExtensionService::GrantPermissions(const Extension* extension) { |
| 975 CHECK(extension); | 976 CHECK(extension); |
| 976 | 977 |
| 977 // We only maintain the granted permissions prefs for INTERNAL extensions. | 978 // We only maintain the granted permissions prefs for extensions that can't |
| 978 CHECK_EQ(Extension::INTERNAL, extension->location()); | 979 // silently increase their permissions. |
| 980 if (extension->CanSilentlyIncreasePermissions()) |
| 981 return; |
| 979 | 982 |
| 980 extension_prefs_->AddGrantedPermissions(extension->id(), | 983 extension_prefs_->AddGrantedPermissions(extension->id(), |
| 981 extension->permission_set()); | 984 extension->GetActivePermissions()); |
| 982 } | 985 } |
| 983 | 986 |
| 984 void ExtensionService::GrantPermissionsAndEnableExtension( | 987 void ExtensionService::GrantPermissionsAndEnableExtension( |
| 985 const Extension* extension) { | 988 const Extension* extension) { |
| 986 CHECK(extension); | 989 CHECK(extension); |
| 987 RecordPermissionMessagesHistogram( | 990 RecordPermissionMessagesHistogram( |
| 988 extension, "Extensions.Permissions_ReEnable"); | 991 extension, "Extensions.Permissions_ReEnable"); |
| 989 GrantPermissions(extension); | 992 GrantPermissions(extension); |
| 990 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); | 993 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); |
| 991 EnableExtension(extension->id()); | 994 EnableExtension(extension->id()); |
| 992 } | 995 } |
| 993 | 996 |
| 997 void ExtensionService::UpdateActivePermissions( |
| 998 const Extension* extension, |
| 999 const ExtensionPermissionSet* permissions) { |
| 1000 extension_prefs()->SetActivePermissions(extension->id(), permissions); |
| 1001 extension->SetActivePermissions(permissions); |
| 1002 } |
| 1003 |
| 994 void ExtensionService::LoadExtension(const FilePath& extension_path) { | 1004 void ExtensionService::LoadExtension(const FilePath& extension_path) { |
| 995 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 1005 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 996 NewRunnableMethod(backend_.get(), | 1006 NewRunnableMethod(backend_.get(), |
| 997 &ExtensionServiceBackend::LoadSingleExtension, | 1007 &ExtensionServiceBackend::LoadSingleExtension, |
| 998 extension_path, true)); | 1008 extension_path, true)); |
| 999 } | 1009 } |
| 1000 | 1010 |
| 1001 void ExtensionService::LoadExtensionFromCommandLine( | 1011 void ExtensionService::LoadExtensionFromCommandLine( |
| 1002 const FilePath& path_in) { | 1012 const FilePath& path_in) { |
| 1003 | 1013 |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1349 Source<Profile>(profile_), | 1359 Source<Profile>(profile_), |
| 1350 Details<const Extension>(extension)); | 1360 Details<const Extension>(extension)); |
| 1351 | 1361 |
| 1352 // Tell renderers about the new extension. | 1362 // Tell renderers about the new extension. |
| 1353 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); | 1363 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); |
| 1354 !i.IsAtEnd(); i.Advance()) { | 1364 !i.IsAtEnd(); i.Advance()) { |
| 1355 RenderProcessHost* host = i.GetCurrentValue(); | 1365 RenderProcessHost* host = i.GetCurrentValue(); |
| 1356 if (host->profile()->GetOriginalProfile() == | 1366 if (host->profile()->GetOriginalProfile() == |
| 1357 profile_->GetOriginalProfile()) { | 1367 profile_->GetOriginalProfile()) { |
| 1358 host->Send( | 1368 host->Send( |
| 1359 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params(extension))); | 1369 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params( |
| 1370 extension, extension->GetActivePermissions()))); |
| 1360 } | 1371 } |
| 1361 } | 1372 } |
| 1362 | 1373 |
| 1363 // Tell a random-ass collection of other subsystems about the new extension. | 1374 // Tell a random-ass collection of other subsystems about the new extension. |
| 1364 // TODO(aa): What should we do with all this goop? Can it move into the | 1375 // TODO(aa): What should we do with all this goop? Can it move into the |
| 1365 // relevant objects via EXTENSION_LOADED? | 1376 // relevant objects via EXTENSION_LOADED? |
| 1366 | 1377 |
| 1367 profile_->GetExtensionSpecialStoragePolicy()-> | 1378 profile_->GetExtensionSpecialStoragePolicy()-> |
| 1368 GrantRightsForExtension(extension); | 1379 GrantRightsForExtension(extension); |
| 1369 | 1380 |
| (...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1957 | 1968 |
| 1958 // If a terminated extension is loaded, remove it from the terminated list. | 1969 // If a terminated extension is loaded, remove it from the terminated list. |
| 1959 UntrackTerminatedExtension(extension->id()); | 1970 UntrackTerminatedExtension(extension->id()); |
| 1960 | 1971 |
| 1961 // If the extension was disabled for a reload, then enable it. | 1972 // If the extension was disabled for a reload, then enable it. |
| 1962 if (disabled_extension_paths_.erase(extension->id()) > 0) | 1973 if (disabled_extension_paths_.erase(extension->id()) > 0) |
| 1963 EnableExtension(extension->id()); | 1974 EnableExtension(extension->id()); |
| 1964 | 1975 |
| 1965 // Check if the extension's privileges have changed and disable the | 1976 // Check if the extension's privileges have changed and disable the |
| 1966 // extension if necessary. | 1977 // extension if necessary. |
| 1967 DisableIfPrivilegeIncrease(extension); | 1978 InitializePermissions(extension); |
| 1968 | 1979 |
| 1969 bool disabled = Extension::UserMayDisable(extension->location()) && | 1980 bool disabled = Extension::UserMayDisable(extension->location()) && |
| 1970 extension_prefs_->GetExtensionState(extension->id()) == | 1981 extension_prefs_->GetExtensionState(extension->id()) == |
| 1971 Extension::DISABLED; | 1982 Extension::DISABLED; |
| 1972 if (disabled) { | 1983 if (disabled) { |
| 1973 disabled_extensions_.push_back(scoped_extension); | 1984 disabled_extensions_.push_back(scoped_extension); |
| 1974 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called | 1985 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called |
| 1975 // with a disabled extension for other reasons other than that an update was | 1986 // with a disabled extension for other reasons other than that an update was |
| 1976 // disabled. | 1987 // disabled. |
| 1977 NotificationService::current()->Notify( | 1988 NotificationService::current()->Notify( |
| 1978 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 1989 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
| 1979 Source<Profile>(profile_), | 1990 Source<Profile>(profile_), |
| 1980 Details<const Extension>(extension)); | 1991 Details<const Extension>(extension)); |
| 1981 return; | 1992 return; |
| 1982 } | 1993 } |
| 1983 | 1994 |
| 1984 extensions_.push_back(scoped_extension); | 1995 extensions_.push_back(scoped_extension); |
| 1985 NotifyExtensionLoaded(extension); | 1996 NotifyExtensionLoaded(extension); |
| 1986 } | 1997 } |
| 1987 | 1998 |
| 1988 void ExtensionService::DisableIfPrivilegeIncrease(const Extension* extension) { | 1999 void ExtensionService::InitializePermissions(const Extension* extension) { |
| 2000 // If the extension has used the optional permissions API, it will have a |
| 2001 // custom set of active permissions defined in the extension prefs. Here, |
| 2002 // we update the extension's active permissions based on the prefs. |
| 2003 scoped_refptr<ExtensionPermissionSet> active_permissions = |
| 2004 extension_prefs()->GetActivePermissions(extension->id()); |
| 2005 |
| 2006 if (active_permissions.get()) { |
| 2007 // We restrict the active permissions to be within the bounds defined in the |
| 2008 // extension's manifest. |
| 2009 // a) active permissions must be a subset of optional + default permissions |
| 2010 // b) active permissions must contains all default permissions |
| 2011 scoped_refptr<ExtensionPermissionSet> total_permissions = |
| 2012 ExtensionPermissionSet::CreateUnion( |
| 2013 extension->required_permission_set(), |
| 2014 extension->optional_permission_set()); |
| 2015 |
| 2016 // Make sure the active permissions contain no more than optional + default. |
| 2017 scoped_refptr<ExtensionPermissionSet> adjusted_active = |
| 2018 ExtensionPermissionSet::CreateIntersection( |
| 2019 total_permissions.get(), active_permissions.get()); |
| 2020 |
| 2021 // Make sure the active permissions contain the default permissions. |
| 2022 adjusted_active = ExtensionPermissionSet::CreateUnion( |
| 2023 extension->required_permission_set(), adjusted_active.get()); |
| 2024 |
| 2025 UpdateActivePermissions(extension, adjusted_active); |
| 2026 } |
| 2027 |
| 1989 // We keep track of all permissions the user has granted each extension. | 2028 // We keep track of all permissions the user has granted each extension. |
| 1990 // This allows extensions to gracefully support backwards compatibility | 2029 // This allows extensions to gracefully support backwards compatibility |
| 1991 // by including unknown permissions in their manifests. When the user | 2030 // by including unknown permissions in their manifests. When the user |
| 1992 // installs the extension, only the recognized permissions are recorded. | 2031 // installs the extension, only the recognized permissions are recorded. |
| 1993 // When the unknown permissions become recognized (e.g., through browser | 2032 // When the unknown permissions become recognized (e.g., through browser |
| 1994 // upgrade), we can prompt the user to accept these new permissions. | 2033 // upgrade), we can prompt the user to accept these new permissions. |
| 1995 // Extensions can also silently upgrade to less permissions, and then | 2034 // Extensions can also silently upgrade to less permissions, and then |
| 1996 // silently upgrade to a version that adds these permissions back. | 2035 // silently upgrade to a version that adds these permissions back. |
| 1997 // | 2036 // |
| 1998 // For example, pretend that Chrome 10 includes a permission "omnibox" | 2037 // For example, pretend that Chrome 10 includes a permission "omnibox" |
| 1999 // for an API that adds suggestions to the omnibox. An extension can | 2038 // for an API that adds suggestions to the omnibox. An extension can |
| 2000 // maintain backwards compatibility while still having "omnibox" in the | 2039 // maintain backwards compatibility while still having "omnibox" in the |
| 2001 // manifest. If a user installs the extension on Chrome 9, the browser | 2040 // manifest. If a user installs the extension on Chrome 9, the browser |
| 2002 // will record the permissions it recognized, not including "omnibox." | 2041 // will record the permissions it recognized, not including "omnibox." |
| 2003 // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome | 2042 // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome |
| 2004 // will disable the extension and prompt the user to approve the increase | 2043 // will disable the extension and prompt the user to approve the increase |
| 2005 // in privileges. The extension could then release a new version that | 2044 // in privileges. The extension could then release a new version that |
| 2006 // removes the "omnibox" permission. When the user upgrades, Chrome will | 2045 // removes the "omnibox" permission. When the user upgrades, Chrome will |
| 2007 // still remember that "omnibox" had been granted, so that if the | 2046 // still remember that "omnibox" had been granted, so that if the |
| 2008 // extension once again includes "omnibox" in an upgrade, the extension | 2047 // extension once again includes "omnibox" in an upgrade, the extension |
| 2009 // can upgrade without requiring this user's approval. | 2048 // can upgrade without requiring this user's approval. |
| 2010 const Extension* old = GetExtensionByIdInternal(extension->id(), | 2049 const Extension* old = GetExtensionByIdInternal(extension->id(), |
| 2011 true, true, false); | 2050 true, true, false); |
| 2012 bool is_extension_upgrade = old != NULL; | 2051 bool is_extension_upgrade = old != NULL; |
| 2013 bool is_privilege_increase = false; | 2052 bool is_privilege_increase = false; |
| 2014 | 2053 |
| 2015 // We only record the granted permissions for INTERNAL extensions, since | 2054 // We only need to compare the granted permissions to the current permissions |
| 2016 // they can't silently increase privileges. | 2055 // if the extension is not allowed to silently increase its permissions. |
| 2017 if (extension->location() == Extension::INTERNAL) { | 2056 if (!extension->CanSilentlyIncreasePermissions()) { |
| 2018 // Add all the recognized permissions if the granted permissions list | 2057 // Add all the recognized permissions if the granted permissions list |
| 2019 // hasn't been initialized yet. | 2058 // hasn't been initialized yet. |
| 2020 scoped_ptr<ExtensionPermissionSet> granted_permissions( | 2059 scoped_refptr<ExtensionPermissionSet> granted_permissions = |
| 2021 extension_prefs_->GetGrantedPermissions(extension->id())); | 2060 extension_prefs_->GetGrantedPermissions(extension->id()); |
| 2022 CHECK(granted_permissions.get()); | 2061 CHECK(granted_permissions.get()); |
| 2023 | 2062 |
| 2024 // Here, we check if an extension's privileges have increased in a manner | 2063 // Here, we check if an extension's privileges have increased in a manner |
| 2025 // that requires the user's approval. This could occur because the browser | 2064 // that requires the user's approval. This could occur because the browser |
| 2026 // upgraded and recognized additional privileges, or an extension upgrades | 2065 // upgraded and recognized additional privileges, or an extension upgrades |
| 2027 // to a version that requires additional privileges. | 2066 // to a version that requires additional privileges. |
| 2028 is_privilege_increase = | 2067 is_privilege_increase = |
| 2029 granted_permissions->HasLessPrivilegesThan(extension->permission_set()); | 2068 granted_permissions->HasLessPrivilegesThan( |
| 2069 extension->GetActivePermissions()); |
| 2030 } | 2070 } |
| 2031 | 2071 |
| 2032 if (is_extension_upgrade) { | 2072 if (is_extension_upgrade) { |
| 2033 // Other than for unpacked extensions, CrxInstaller should have guaranteed | 2073 // Other than for unpacked extensions, CrxInstaller should have guaranteed |
| 2034 // that we aren't downgrading. | 2074 // that we aren't downgrading. |
| 2035 if (extension->location() != Extension::LOAD) | 2075 if (extension->location() != Extension::LOAD) |
| 2036 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); | 2076 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); |
| 2037 | 2077 |
| 2038 // Extensions get upgraded if the privileges are allowed to increase or | 2078 // Extensions get upgraded if the privileges are allowed to increase or |
| 2039 // the privileges haven't increased. | 2079 // the privileges haven't increased. |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2371 process->Send(new ExtensionMsg_SetFunctionNames(function_names)); | 2411 process->Send(new ExtensionMsg_SetFunctionNames(function_names)); |
| 2372 | 2412 |
| 2373 // Scripting whitelist. This is modified by tests and must be communicated | 2413 // Scripting whitelist. This is modified by tests and must be communicated |
| 2374 // to renderers. | 2414 // to renderers. |
| 2375 process->Send(new ExtensionMsg_SetScriptingWhitelist( | 2415 process->Send(new ExtensionMsg_SetScriptingWhitelist( |
| 2376 *Extension::GetScriptingWhitelist())); | 2416 *Extension::GetScriptingWhitelist())); |
| 2377 | 2417 |
| 2378 // Loaded extensions. | 2418 // Loaded extensions. |
| 2379 for (size_t i = 0; i < extensions_.size(); ++i) { | 2419 for (size_t i = 0; i < extensions_.size(); ++i) { |
| 2380 process->Send(new ExtensionMsg_Loaded( | 2420 process->Send(new ExtensionMsg_Loaded( |
| 2381 ExtensionMsg_Loaded_Params(extensions_[i]))); | 2421 ExtensionMsg_Loaded_Params( |
| 2422 extensions_[i], extensions_[i]->GetActivePermissions()))); |
| 2382 } | 2423 } |
| 2383 break; | 2424 break; |
| 2384 } | 2425 } |
| 2385 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { | 2426 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { |
| 2386 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); | 2427 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); |
| 2387 installed_app_hosts_.erase(process->id()); | 2428 installed_app_hosts_.erase(process->id()); |
| 2388 break; | 2429 break; |
| 2389 } | 2430 } |
| 2390 case chrome::NOTIFICATION_PREF_CHANGED: { | 2431 case chrome::NOTIFICATION_PREF_CHANGED: { |
| 2391 std::string* pref_name = Details<std::string>(details).ptr(); | 2432 std::string* pref_name = Details<std::string>(details).ptr(); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2519 | 2560 |
| 2520 ExtensionService::NaClModuleInfoList::iterator | 2561 ExtensionService::NaClModuleInfoList::iterator |
| 2521 ExtensionService::FindNaClModule(const GURL& url) { | 2562 ExtensionService::FindNaClModule(const GURL& url) { |
| 2522 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); | 2563 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); |
| 2523 iter != nacl_module_list_.end(); ++iter) { | 2564 iter != nacl_module_list_.end(); ++iter) { |
| 2524 if (iter->url == url) | 2565 if (iter->url == url) |
| 2525 return iter; | 2566 return iter; |
| 2526 } | 2567 } |
| 2527 return nacl_module_list_.end(); | 2568 return nacl_module_list_.end(); |
| 2528 } | 2569 } |
| OLD | NEW |