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 |