diff options
author | karen@chromium.org <karen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-15 22:14:58 +0000 |
---|---|---|
committer | karen@chromium.org <karen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-15 22:14:58 +0000 |
commit | b00aa0204f72bd60e7808a9daf3cd1fcb0df81bb (patch) | |
tree | 8051f3fa477bf278c8da014d158bf19dfb47190e | |
parent | b38236af7251c13b6d0f58a6ee002c3fe1bd3d04 (diff) | |
download | chromium_src-b00aa0204f72bd60e7808a9daf3cd1fcb0df81bb.zip chromium_src-b00aa0204f72bd60e7808a9daf3cd1fcb0df81bb.tar.gz chromium_src-b00aa0204f72bd60e7808a9daf3cd1fcb0df81bb.tar.bz2 |
Merge 121111 - Add a centralized mechanism for whitelisting access to extension permissions.
This also updates the following permissions to use the whitelist:
- terminalPrivate
- webSocketProxyPrivate
- chromePrivate
- inputMethodPrivate
- chromeAuthPrivate
- webstorePrivate
Includes more tests to verify that Extension loading fails for different permission parameters:
- by extension type
- component only flag
- whitelists
BUG=84211, 111314
TEST=extension unit and browser tests
Review URL: http://codereview.chromium.org/9317013
TBR=jstritar@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9703090
git-svn-id: svn://svn.chromium.org/chrome/branches/1025/src@127007 0039d316-1c4b-4281-b951-d872f2087c98
39 files changed, 383 insertions, 647 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index aa330cd..1632936 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -684,15 +684,19 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches( switches::kProfilingFile, switches::kProfilingFlush, switches::kSilentDumpOnDCHECK, + switches::kWhitelistedExtensionID, }; command_line->CopySwitchesFrom(browser_command_line, kSwitchNames, arraysize(kSwitchNames)); } else if (process_type == switches::kUtilityProcess) { - if (browser_command_line.HasSwitch( - switches::kEnableExperimentalExtensionApis)) { - command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis); - } + static const char* const kSwitchNames[] = { + switches::kEnableExperimentalExtensionApis, + switches::kWhitelistedExtensionID, + }; + + command_line->CopySwitchesFrom(browser_command_line, kSwitchNames, + arraysize(kSwitchNames)); } else if (process_type == switches::kPluginProcess) { static const char* const kSwitchNames[] = { #if defined(OS_CHROMEOS) diff --git a/chrome/browser/chromeos/extensions/input_method_event_router.cc b/chrome/browser/chromeos/extensions/input_method_event_router.cc index 18a06f6..975c157 100644 --- a/chrome/browser/chromeos/extensions/input_method_event_router.cc +++ b/chrome/browser/chromeos/extensions/input_method_event_router.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -7,7 +7,6 @@ #include <algorithm> #include "base/json/json_writer.h" -#include "base/lazy_instance.h" #include "base/values.h" #include "chrome/browser/chromeos/web_socket_proxy_controller.h" #include "chrome/browser/extensions/extension_event_names.h" @@ -20,30 +19,6 @@ namespace { // Prefix, which is used by XKB. const char kXkbPrefix[] = "xkb:"; -// Extension ID which is used in browser_tests. -const char kInputMethodTestExtensionID[] = "ilanclmaeigfpnmdlgelmhkpkegdioip"; - -class InputMethodPrivateExtensionsWhitelist { - public: - InputMethodPrivateExtensionsWhitelist() { - chromeos::FillWithExtensionsIdsWithPrivateAccess(&ids_); - ids_.push_back(kInputMethodTestExtensionID); - std::sort(ids_.begin(), ids_.end()); - } - - bool HasId(const std::string& id) { - return std::binary_search(ids_.begin(), ids_.end(), id); - } - - const std::vector<std::string>& ids() { return ids_; } - - private: - std::vector<std::string> ids_; -}; - -base::LazyInstance<InputMethodPrivateExtensionsWhitelist> - g_input_method_private_extensions_whitelist = LAZY_INSTANCE_INITIALIZER; - } // namespace namespace chromeos { @@ -73,16 +48,10 @@ void ExtensionInputMethodEventRouter::InputMethodChanged( std::string args_json; base::JSONWriter::Write(&args, false, &args_json); - const std::vector<std::string>& ids = - g_input_method_private_extensions_whitelist.Get().ids(); - - for (size_t i = 0; i < ids.size(); ++i) { - // ExtensionEventRoutner will check that the extension is listening for the - // event. - router->DispatchEventToExtension( - ids[i], extension_event_names::kOnInputMethodChanged, - args_json, profile, GURL()); - } + // The router will only send the event to extensions that are listening. + router->DispatchEventToRenderers( + extension_event_names::kOnInputMethodChanged, + args_json, profile, GURL()); } void ExtensionInputMethodEventRouter::ActiveInputMethodsChanged( @@ -103,9 +72,4 @@ std::string ExtensionInputMethodEventRouter::GetInputMethodForXkb( return xkb_id.substr(prefix_length); } -bool ExtensionInputMethodEventRouter::IsExtensionWhitelisted( - const std::string& extension_id) { - return g_input_method_private_extensions_whitelist.Get().HasId(extension_id); -} - } // namespace chromeos diff --git a/chrome/browser/chromeos/extensions/input_method_event_router.h b/chrome/browser/chromeos/extensions/input_method_event_router.h index 1dc7412..f9ba5d7 100644 --- a/chrome/browser/chromeos/extensions/input_method_event_router.h +++ b/chrome/browser/chromeos/extensions/input_method_event_router.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -34,9 +34,6 @@ class ExtensionInputMethodEventRouter // Window System) id. std::string GetInputMethodForXkb(const std::string& xkb_id); - // Returns whether the extension is allowed to use input method API. - bool IsExtensionWhitelisted(const std::string& extension_id); - private: DISALLOW_COPY_AND_ASSIGN(ExtensionInputMethodEventRouter); }; diff --git a/chrome/browser/chromeos/web_socket_proxy.cc b/chrome/browser/chromeos/web_socket_proxy.cc index 53ce784..66a3e1a 100644 --- a/chrome/browser/chromeos/web_socket_proxy.cc +++ b/chrome/browser/chromeos/web_socket_proxy.cc @@ -177,7 +177,7 @@ class Conn; // Websocket to TCP proxy server. class Serv { public: - explicit Serv(const std::vector<std::string>& allowed_origins); + Serv(); ~Serv(); // Do not call it twice. @@ -192,7 +192,6 @@ class Serv { void MarkConnImportance(Conn*, bool important); Conn* GetFreshConn(); bool IsConnSane(Conn*); - bool IsOriginAllowed(const std::string& origin); void CloseAll(); static void OnConnect(int listening_sock, short event, void*); @@ -200,10 +199,6 @@ class Serv { struct event_base* evbase() { return evbase_; } - // Checked against value of Origin field specified - // in a client websocket handshake. - std::vector<std::string> allowed_origins_; - // Libevent base. struct event_base* evbase_; @@ -803,13 +798,11 @@ class SSLChan : public MessageLoopForIO::Watcher { DISALLOW_COPY_AND_ASSIGN(SSLChan); }; -Serv::Serv(const std::vector<std::string>& allowed_origins) - : allowed_origins_(allowed_origins), - evbase_(NULL), +Serv::Serv() + : evbase_(NULL), listening_sock_(-1), extra_listening_sock_(-1), shutdown_requested_(false) { - std::sort(allowed_origins_.begin(), allowed_origins_.end()); control_descriptor_[0] = -1; control_descriptor_[1] = -1; } @@ -1052,11 +1045,6 @@ bool Serv::IsConnSane(Conn* cs) { return rev_map_.find(cs) != rev_map_.end(); } -bool Serv::IsOriginAllowed(const std::string& origin) { - return allowed_origins_.empty() || std::binary_search( - allowed_origins_.begin(), allowed_origins_.end(), origin); -} - // static void Serv::OnConnect(int listening_sock, short event, void* ctx) { Serv* self = static_cast<Serv*>(ctx); @@ -1265,8 +1253,6 @@ Conn::Status Conn::ConsumeHeader(struct evbuffer* evb) { GURL origin = GURL(GetOrigin()).GetOrigin(); if (!origin.is_valid()) return STATUS_ABORT; - if (!master_->IsOriginAllowed(origin.spec())) - return STATUS_ABORT; if (!requested_parameters_.empty()) { destname_ = requested_parameters_["hostname"]; @@ -1898,8 +1884,7 @@ base::LazyInstance<Conn::EventKeyMap>::Leaky } // namespace -WebSocketProxy::WebSocketProxy(const std::vector<std::string>& allowed_origins) - : impl_(new Serv(allowed_origins)) { +WebSocketProxy::WebSocketProxy() : impl_(new Serv()) { } WebSocketProxy::~WebSocketProxy() { diff --git a/chrome/browser/chromeos/web_socket_proxy.h b/chrome/browser/chromeos/web_socket_proxy.h index 5e2fb3b..08436f5 100644 --- a/chrome/browser/chromeos/web_socket_proxy.h +++ b/chrome/browser/chromeos/web_socket_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -22,8 +22,7 @@ class WebSocketProxy { // Limits number of simultaneously open connections. static const size_t kConnPoolLimit = 40; - // Empty |allowed_origins| vector disables check for origin. - explicit WebSocketProxy(const std::vector<std::string>& allowed_origins); + WebSocketProxy(); ~WebSocketProxy(); // Do not call it twice. diff --git a/chrome/browser/chromeos/web_socket_proxy_controller.cc b/chrome/browser/chromeos/web_socket_proxy_controller.cc index 478e3c2..50d286c 100644 --- a/chrome/browser/chromeos/web_socket_proxy_controller.cc +++ b/chrome/browser/chromeos/web_socket_proxy_controller.cc @@ -32,72 +32,6 @@ namespace { -const char* kAllowedIds[] = { - "haiffjcadagjlijoggckpgfnoeiflnem", - "gnedhmakppccajfpfiihfcdlnpgomkcf", - "fjcibdnjlbfnbfdjneajpipnlcppleek", - "okddffdblfhhnmhodogpojmfkjmhinfp", - "pnhechapfaindjhompbnflcldabbghjo" // HTerm App (SSH Client) -}; - -class OriginValidator { - public: - OriginValidator() { - chromeos::FillWithExtensionsIdsWithPrivateAccess(&allowed_ids_); - CommandLine* command_line = CommandLine::ForCurrentProcess(); - DCHECK(command_line); - std::string allowed_list = - command_line->GetSwitchValueASCII(switches::kAllowWebSocketProxy); - if (!allowed_list.empty()) { - StringTokenizer t(allowed_list, ","); - while (t.GetNext()) { - // It must be either extension id or origin. - if (Extension::IdIsValid(t.token())) { - allowed_ids_.push_back(t.token()); - } else { - // It is not extension id, check if it is an origin. - GURL origin = GURL(t.token()).GetOrigin(); - if (!origin.is_valid()) { - LOG(ERROR) << "Invalid extension id or origin specified via " - << switches::kAllowWebSocketProxy << " switch"; - break; - } - allowed_origins_.push_back(origin.spec()); - if (origin.SchemeIs(chrome::kExtensionScheme)) - allowed_ids_.push_back(origin.host()); - } - } - } - for (size_t i = 0; i < allowed_ids_.size(); ++i) { - allowed_origins_.push_back(Extension::GetBaseURLFromExtensionId( - allowed_ids_[i]).GetOrigin().spec()); - } - std::sort(allowed_ids_.begin(), allowed_ids_.end()); - allowed_ids_.resize(std::unique( - allowed_ids_.begin(), allowed_ids_.end()) - allowed_ids_.begin()); - std::sort(allowed_origins_.begin(), allowed_origins_.end()); - allowed_origins_.resize(std::unique(allowed_origins_.begin(), - allowed_origins_.end()) - allowed_origins_.begin()); - } - - bool CheckCredentials( - const std::string& extension_id, - const std::string& hostname, - unsigned short port, - chromeos::WebSocketProxyController::ConnectionFlags flags) { - return std::binary_search( - allowed_ids_.begin(), allowed_ids_.end(), extension_id); - } - - const std::vector<std::string>& allowed_origins() { return allowed_origins_; } - - private: - std::vector<std::string> allowed_ids_; - std::vector<std::string> allowed_origins_; -}; - -base::LazyInstance<OriginValidator> g_validator = LAZY_INSTANCE_INITIALIZER; - class ProxyLifetime : public net::NetworkChangeNotifier::OnlineStateObserver, public content::NotificationObserver { @@ -145,8 +79,7 @@ class ProxyLifetime void ProxyCallback() { LOG(INFO) << "Attempt to run web socket proxy task"; - chromeos::WebSocketProxy* server = new chromeos::WebSocketProxy( - g_validator.Get().allowed_origins()); + chromeos::WebSocketProxy* server = new chromeos::WebSocketProxy(); { base::AutoLock alk(lock_); if (shutdown_requested_) @@ -193,12 +126,6 @@ base::LazyInstance<ProxyLifetime> g_proxy_lifetime = LAZY_INSTANCE_INITIALIZER; namespace chromeos { -void FillWithExtensionsIdsWithPrivateAccess(std::vector<std::string>* ids) { - ids->clear(); - for (size_t i = 0; i < arraysize(kAllowedIds); ++i) - ids->push_back(kAllowedIds[i]); -} - // static void WebSocketProxyController::Initiate() { g_proxy_lifetime.Get(); @@ -231,14 +158,4 @@ void WebSocketProxyController::Shutdown() { g_proxy_lifetime.Get().web_socket_proxy_thread_.Stop(); } -// static -bool WebSocketProxyController::CheckCredentials( - const std::string& extension_id, - const std::string& hostname, - unsigned short port, - ConnectionFlags flags) { - return g_validator.Get().CheckCredentials( - extension_id, hostname, port, flags); -} - } // namespace chromeos diff --git a/chrome/browser/chromeos/web_socket_proxy_controller.h b/chrome/browser/chromeos/web_socket_proxy_controller.h index 4e8ad0d..bfde94e 100644 --- a/chrome/browser/chromeos/web_socket_proxy_controller.h +++ b/chrome/browser/chromeos/web_socket_proxy_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -11,10 +11,6 @@ namespace chromeos { -// Fills vector with extensions IDs which are allowed to use private -// extension API (WebSocketProxyPrivate, InputMethodPrivate, etc.) -void FillWithExtensionsIdsWithPrivateAccess(std::vector<std::string>* ids); - // Controls webproxy to TCP service. class WebSocketProxyController { public: @@ -30,12 +26,6 @@ class WebSocketProxyController { static void Shutdown(); static bool IsInitiated(); static int GetPort(); // Returns port listening websocket connections. - - static bool CheckCredentials( - const std::string& extension_id, - const std::string& hostname, - unsigned short port, - ConnectionFlags); }; } // namespace chromeos diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.cc b/chrome/browser/extensions/api/terminal/terminal_private_api.cc index be76747..bf9140a 100644 --- a/chrome/browser/extensions/api/terminal/terminal_private_api.cc +++ b/chrome/browser/extensions/api/terminal/terminal_private_api.cc @@ -22,32 +22,6 @@ const char kCroshCommand[] = "/usr/bin/crosh"; // We make stubbed crosh just echo back input. const char kStubbedCroshCommand[] = "cat"; -const char kPermissionError[] = - "Extension does not have the permission to use this API"; - -const char* kAllowedExtensionIds[] ={ - "okddffdblfhhnmhodogpojmfkjmhinfp", // test SSH/Crosh Client - "pnhechapfaindjhompbnflcldabbghjo" // HTerm App -}; - -// Allow component and whitelisted extensions. -bool AllowAccessToExtension(Profile* profile, const std::string& extension_id) { - ExtensionService* service = profile->GetExtensionService(); - const Extension* extension = service->GetExtensionById(extension_id, false); - - if (!extension) - return false; - - if (extension->location() == Extension::COMPONENT) - return true; - - for (size_t i = 0; i < arraysize(kAllowedExtensionIds); i++) { - if (extension->id() == kAllowedExtensionIds[i]) - return true; - } - return false; -} - const char* GetCroshPath() { if (chromeos::system::runtime_environment::IsRunningOnChromeOS()) return kCroshCommand; @@ -75,8 +49,6 @@ void NotifyProcessOutput(Profile* profile, return; } - CHECK(AllowAccessToExtension(profile, extension_id)); - base::ListValue args; args.Append(new base::FundamentalValue(pid)); args.Append(new base::StringValue(output_type)); @@ -101,11 +73,6 @@ TerminalPrivateFunction::~TerminalPrivateFunction() { } bool TerminalPrivateFunction::RunImpl() { - if (!AllowAccessToExtension(profile_, extension_id())) { - error_ = kPermissionError; - return false; - } - return RunTerminalFunction(); } diff --git a/chrome/browser/extensions/extension_chrome_auth_private_api.cc b/chrome/browser/extensions/extension_chrome_auth_private_api.cc index 1f4e6db..fcc4e2b 100644 --- a/chrome/browser/extensions/extension_chrome_auth_private_api.cc +++ b/chrome/browser/extensions/extension_chrome_auth_private_api.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -13,24 +13,8 @@ namespace { -bool IsCloudPrintEnableURL(Profile* profile, const GURL& url) { - ExtensionService* service = profile->GetExtensionService(); - const Extension* cloud_print_app = service->GetExtensionById( - extension_misc::kCloudPrintAppId, false); - if (!cloud_print_app) { -#if !defined(OS_CHROMEOS) - NOTREACHED(); -#endif // !defined(OS_CHROMEOS) - return false; - } - return (service->extensions()->GetHostedAppByURL(ExtensionURLInfo(url)) == - cloud_print_app); -} - bool test_mode = false; -const char kAccessDeniedError[] = - "Cannot call this API from a non-cloudprint URL."; } // namespace SetCloudPrintCredentialsFunction::SetCloudPrintCredentialsFunction() { @@ -40,12 +24,6 @@ SetCloudPrintCredentialsFunction::~SetCloudPrintCredentialsFunction() { } bool SetCloudPrintCredentialsFunction::RunImpl() { - // This has to be called from the specific cloud print app. - if (!IsCloudPrintEnableURL(profile_, source_url())) { - error_ = kAccessDeniedError; - return false; - } - std::string user_email; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &user_email)); std::string robot_email; diff --git a/chrome/browser/extensions/extension_chrome_auth_private_apitest.cc b/chrome/browser/extensions/extension_chrome_auth_private_apitest.cc index b35ef72a..a7a2c57 100644 --- a/chrome/browser/extensions/extension_chrome_auth_private_apitest.cc +++ b/chrome/browser/extensions/extension_chrome_auth_private_apitest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -58,11 +58,3 @@ IN_PROC_BROWSER_TEST_F(ExtensionChromeAuthPrivateApiTest, SetCloudPrintCredentialsFunction::SetTestMode(false); } #endif // !defined(OS_CHROMEOS) - -IN_PROC_BROWSER_TEST_F(ExtensionChromeAuthPrivateApiTest, - SetCloudPrintCredentialsFailureInstalledComponent) { - // Run this as an installed component app. This should also fail because of - // the explicit URL check in the API. - ASSERT_TRUE(RunComponentExtensionTest( - "chrome_auth_private/installed_component_app")); -} diff --git a/chrome/browser/extensions/extension_chrome_private_apitest.cc b/chrome/browser/extensions/extension_chrome_private_apitest.cc new file mode 100644 index 0000000..37203b7 --- /dev/null +++ b/chrome/browser/extensions/extension_chrome_private_apitest.cc @@ -0,0 +1,19 @@ +// Copyright (c) 2012 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 "base/command_line.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/common/chrome_switches.h" + +class ExtensionChromePrivateApiTest : public ExtensionApiTest { + virtual void SetUpCommandLine(CommandLine* command_line) { + ExtensionApiTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII( + switches::kWhitelistedExtensionID, "oflbaaikkabfdfkimeclgkackhdkpnip"); + } +}; + +IN_PROC_BROWSER_TEST_F(ExtensionChromePrivateApiTest, DecodeJPEG) { + ASSERT_TRUE(RunExtensionTest("decode_jpeg")) << message_; +} diff --git a/chrome/browser/extensions/extension_decode_jpeg_apitest.cc b/chrome/browser/extensions/extension_decode_jpeg_apitest.cc deleted file mode 100644 index bd917f8..0000000 --- a/chrome/browser/extensions/extension_decode_jpeg_apitest.cc +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2011 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/browser/extensions/extension_apitest.h" - -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DecodeJPEG) { - ASSERT_TRUE(RunExtensionTest("decode_jpeg")) << message_; -} diff --git a/chrome/browser/extensions/extension_input_method_api.cc b/chrome/browser/extensions/extension_input_method_api.cc index cf2bbd2..040bbbb 100644 --- a/chrome/browser/extensions/extension_input_method_api.cc +++ b/chrome/browser/extensions/extension_input_method_api.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -10,12 +10,6 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" -namespace { - -const char kErrorInputMethodPrivateApi[] = "Input method API is private"; - -} // namespace - GetInputMethodFunction::GetInputMethodFunction() { } @@ -24,15 +18,10 @@ GetInputMethodFunction::~GetInputMethodFunction() { bool GetInputMethodFunction::RunImpl() { #if !defined(OS_CHROMEOS) - error_ = kErrorInputMethodPrivateApi; - return false; + NOTREACHED(); #else chromeos::ExtensionInputMethodEventRouter* router = profile_->GetExtensionService()->input_method_event_router(); - if (!router->IsExtensionWhitelisted(extension_id())) { - error_ = kErrorInputMethodPrivateApi; - return false; - } chromeos::input_method::InputMethodManager* manager = chromeos::input_method::InputMethodManager::GetInstance(); const std::string input_method = diff --git a/chrome/browser/extensions/extension_input_method_apitest.cc b/chrome/browser/extensions/extension_input_method_apitest.cc index a019386..6223e05 100644 --- a/chrome/browser/extensions/extension_input_method_apitest.cc +++ b/chrome/browser/extensions/extension_input_method_apitest.cc @@ -1,14 +1,16 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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/browser/extensions/extension_apitest.h" +#include "base/command_line.h" #include "base/stringprintf.h" #include "chrome/browser/chromeos/extensions/input_method_event_router.h" #include "chrome/browser/chromeos/input_method/input_method_manager.h" #include "chrome/browser/extensions/extension_test_api.h" #include "chrome/common/chrome_notification_types.h" +#include "chrome/common/chrome_switches.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" @@ -59,9 +61,17 @@ class SetInputMethodListener : public content::NotificationObserver { int count_; }; +class ExtensionInputMethodApiTest : public ExtensionApiTest { + virtual void SetUpCommandLine(CommandLine* command_line) { + ExtensionApiTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII( + switches::kWhitelistedExtensionID, "ilanclmaeigfpnmdlgelmhkpkegdioip"); + } +}; + } // namespace -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, InputMethodApiBasic) { +IN_PROC_BROWSER_TEST_F(ExtensionInputMethodApiTest, Basic) { // Two test, two calls. See JS code for more info. SetInputMethodListener listener(2); diff --git a/chrome/browser/extensions/extension_web_socket_proxy_private_api.cc b/chrome/browser/extensions/extension_web_socket_proxy_private_api.cc index 367bdfb..be377c2 100644 --- a/chrome/browser/extensions/extension_web_socket_proxy_private_api.cc +++ b/chrome/browser/extensions/extension_web_socket_proxy_private_api.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -26,11 +26,6 @@ #include "chrome/browser/chromeos/web_socket_proxy_controller.h" #endif -namespace { -const char kPermissionDeniedError[] = - "Extension does not have permission to use this method."; -} - WebSocketProxyPrivate::WebSocketProxyPrivate() : port_(-1), listening_port_(-1), @@ -106,24 +101,16 @@ bool WebSocketProxyPrivate::RunImpl() { EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &hostname_)); EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &port_)); - if (chromeos::WebSocketProxyController::CheckCredentials( - extension_id(), hostname_, port_, - do_tls_ ? chromeos::WebSocketProxyController::TLS_OVER_TCP : - chromeos::WebSocketProxyController::PLAIN_TCP)) { - listening_port_ = chromeos::WebSocketProxyController::GetPort(); - if (listening_port_ < 1) { - delay_response = true; - registrar_.Add( - this, chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED, - content::NotificationService::AllSources()); - } - map_["hostname"] = hostname_; - map_["port"] = base::IntToString(port_); - map_["extension_id"] = extension_id(); - } else { - error_ = kPermissionDeniedError; - return false; + listening_port_ = chromeos::WebSocketProxyController::GetPort(); + if (listening_port_ < 1) { + delay_response = true; + registrar_.Add( + this, chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED, + content::NotificationService::AllSources()); } + map_["hostname"] = hostname_; + map_["port"] = base::IntToString(port_); + map_["extension_id"] = extension_id(); if (delay_response) { const int kTimeout = 12; diff --git a/chrome/browser/extensions/extension_web_socket_proxy_private_apitest.cc b/chrome/browser/extensions/extension_web_socket_proxy_private_apitest.cc index 060583e..2a6c4ab 100644 --- a/chrome/browser/extensions/extension_web_socket_proxy_private_apitest.cc +++ b/chrome/browser/extensions/extension_web_socket_proxy_private_apitest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -9,7 +9,7 @@ class ExtensionWebSocketProxyPrivateApiTest : public ExtensionApiTest { void SetUpCommandLine(CommandLine* command_line) { ExtensionApiTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII( - switches::kAllowWebSocketProxy, "mknjjldhaihcdajjbihghhiehamnpcak"); + switches::kWhitelistedExtensionID, "mknjjldhaihcdajjbihghhiehamnpcak"); } }; @@ -22,4 +22,3 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebSocketProxyPrivateApiTest, Pass) { ASSERT_TRUE(RunExtensionTest("web_socket_proxy_private")) << message_; #endif } - diff --git a/chrome/browser/extensions/extension_webstore_private_api.cc b/chrome/browser/extensions/extension_webstore_private_api.cc index 27ae847..8d18ff6 100644 --- a/chrome/browser/extensions/extension_webstore_private_api.cc +++ b/chrome/browser/extensions/extension_webstore_private_api.cc @@ -53,8 +53,6 @@ const char kInvalidManifestError[] = "Invalid manifest"; const char kNoPreviousBeginInstallWithManifestError[] = "* does not match a previous call to beginInstallWithManifest3"; const char kUserCancelledError[] = "User cancelled install"; -const char kPermissionDeniedError[] = - "You do not have permission to use this method."; ProfileSyncService* test_sync_service = NULL; @@ -68,17 +66,6 @@ ProfileSyncService* GetSyncService(Profile* profile) { return ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile); } -bool IsWebStoreURL(Profile* profile, const GURL& url) { - ExtensionService* service = profile->GetExtensionService(); - const Extension* store = service->GetWebStoreApp(); - if (!store) { - NOTREACHED(); - return false; - } - return (service->extensions()->GetHostedAppByURL(ExtensionURLInfo(url)) == - store); -} - // Whitelists extension IDs for use by webstorePrivate.silentlyInstall. bool trust_test_ids = false; @@ -153,11 +140,6 @@ BeginInstallWithManifestFunction::BeginInstallWithManifestFunction() BeginInstallWithManifestFunction::~BeginInstallWithManifestFunction() {} bool BeginInstallWithManifestFunction::RunImpl() { - if (!IsWebStoreURL(profile_, source_url())) { - SetResult(PERMISSION_DENIED); - return false; - } - DictionaryValue* details = NULL; EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); CHECK(details); @@ -354,9 +336,6 @@ void BeginInstallWithManifestFunction::InstallUIAbort(bool user_initiated) { } bool CompleteInstallFunction::RunImpl() { - if (!IsWebStoreURL(profile_, source_url())) - return false; - std::string id; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &id)); if (!Extension::IdIsValid(id)) { @@ -387,11 +366,6 @@ SilentlyInstallFunction::SilentlyInstallFunction() {} SilentlyInstallFunction::~SilentlyInstallFunction() {} bool SilentlyInstallFunction::RunImpl() { - if (!IsWebStoreURL(profile_, source_url())) { - error_ = kPermissionDeniedError; - return false; - } - DictionaryValue* details = NULL; EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details)); CHECK(details); @@ -467,15 +441,11 @@ void SilentlyInstallFunction::OnExtensionInstallFailure( } bool GetBrowserLoginFunction::RunImpl() { - if (!IsWebStoreURL(profile_, source_url())) - return false; result_.reset(CreateLoginResult(profile_->GetOriginalProfile())); return true; } bool GetStoreLoginFunction::RunImpl() { - if (!IsWebStoreURL(profile_, source_url())) - return false; ExtensionService* service = profile_->GetExtensionService(); ExtensionPrefs* prefs = service->extension_prefs(); std::string login; @@ -488,8 +458,6 @@ bool GetStoreLoginFunction::RunImpl() { } bool SetStoreLoginFunction::RunImpl() { - if (!IsWebStoreURL(profile_, source_url())) - return false; std::string login; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &login)); ExtensionService* service = profile_->GetExtensionService(); diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 1705c6b..d5964bb 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -2580,6 +2580,7 @@ 'browser/extensions/extension_browsertest.h', 'browser/extensions/extension_browsertests_misc.cc', 'browser/extensions/extension_chrome_auth_private_apitest.cc', + 'browser/extensions/extension_chrome_private_apitest.cc', 'browser/extensions/extension_clear_test.cc', 'browser/extensions/extension_content_settings_apitest.cc', 'browser/extensions/extension_context_menu_apitest.cc', @@ -2587,7 +2588,6 @@ 'browser/extensions/extension_cookies_apitest.cc', 'browser/extensions/extension_crash_recovery_browsertest.cc', 'browser/extensions/extension_debugger_apitest.cc', - 'browser/extensions/extension_decode_jpeg_apitest.cc', 'browser/extensions/extension_devtools_browsertest.cc', 'browser/extensions/extension_devtools_browsertest.h', 'browser/extensions/extension_devtools_browsertests.cc', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 36b10b7..8068ce7 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -50,9 +50,6 @@ const char kAllowRunningInsecureContent[] = "allow-running-insecure-content"; // automation testing of the gallery. const char kAllowScriptingGallery[] = "allow-scripting-gallery"; -// Specifies comma-separated list of extension ids to grant access to local -// websocket proxy. -const char kAllowWebSocketProxy[] = "allow-websocket-proxy"; // Allow compositing on chrome:// pages. const char kAllowWebUICompositing[] = "allow-webui-compositing"; @@ -1183,6 +1180,9 @@ const char kUserDataDir[] = "user-data-dir"; // Prints version information and quits. const char kVersion[] = "version"; +// Adds the given extension ID to all the permission whitelists. +const char kWhitelistedExtensionID[] = "whitelisted-extension-id"; + // Uses WinHTTP to fetch and evaluate PAC scripts. Otherwise the default is to // use Chromium's network stack to fetch, and V8 to evaluate. const char kWinHttpProxyResolver[] = "winhttp-proxy-resolver"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index c9b8e8d..4c285f8 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -31,7 +31,6 @@ extern const char kAllowNaClSocketAPI[]; extern const char kAllowOutdatedPlugins[]; extern const char kAllowRunningInsecureContent[]; extern const char kAllowScriptingGallery[]; -extern const char kAllowWebSocketProxy[]; extern const char kAllowWebUICompositing[]; extern const char kAlwaysAuthorizePlugins[]; extern const char kAppId[]; @@ -322,6 +321,7 @@ extern const char kMaxSpdySessionsPerDomain[]; extern const char kMaxSpdyConcurrentStreams[]; extern const char kUserDataDir[]; extern const char kVersion[]; +extern const char kWhitelistedExtensionID[]; extern const char kWinHttpProxyResolver[]; extern const char kMemoryWidget[]; diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index 454230e..9863db4 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -2853,12 +2853,23 @@ bool Extension::ImplicitlyDelaysNetworkStartup() const { bool Extension::CanSpecifyAPIPermission( const ExtensionAPIPermission* permission, string16* error) const { - if (permission->is_component_only()) { - if (!CanSpecifyComponentOnlyPermission()) { - *error = ExtensionErrorUtils::FormatErrorMessageUTF16( - errors::kPermissionNotAllowed, permission->name()); - return false; - } + if (location_ == Extension::COMPONENT) + return true; + + bool access_denied = false; + if (permission->HasWhitelist()) { + if (permission->IsWhitelisted(id_)) + return true; + else + access_denied = true; + } else if (permission->is_component_only()) { + access_denied = true; + } + + if (access_denied) { + *error = ExtensionErrorUtils::FormatErrorMessageUTF16( + errors::kPermissionNotAllowed, permission->name()); + return false; } if (permission->id() == ExtensionAPIPermission::kExperimental) { @@ -2868,9 +2879,6 @@ bool Extension::CanSpecifyAPIPermission( } } - if (location_ == Extension::COMPONENT) - return true; - bool supports_type = false; switch (GetType()) { case TYPE_USER_SCRIPT: // Pass through. @@ -2910,13 +2918,6 @@ bool Extension::CanSpecifyAPIPermission( return true; } -bool Extension::CanSpecifyComponentOnlyPermission() const { - // Only COMPONENT extensions can use private APIs. - // TODO(asargent) - We want a more general purpose mechanism for this, - // and better error messages. (http://crbug.com/54013) - return location_ == Extension::COMPONENT; -} - bool Extension::CanSpecifyExperimentalPermission() const { if (location_ == Extension::COMPONENT) return true; diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index 7bd51eb..f74bae6 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -713,7 +713,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> { // Returns true if this extension can specify |api|. bool CanSpecifyAPIPermission(const ExtensionAPIPermission* api, string16* error) const; - bool CanSpecifyComponentOnlyPermission() const; bool CanSpecifyExperimentalPermission() const; // Checks whether the host |pattern| is allowed for this extension, given API diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 4203070..3ac6212 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -513,6 +513,12 @@ const char kGeneratedBackgroundPageFilename[] = namespace extension_misc { const char kBookmarkManagerId[] = "eemcgdkfndhakfknompkggombfjjjeno"; +const char kCitrixReceiverAppId[] = "haiffjcadagjlijoggckpgfnoeiflnem"; +const char kCitrixReceiverAppBetaId[] = "gnedhmakppccajfpfiihfcdlnpgomkcf"; +const char kCitrixReceiverAppDevId[] = "fjcibdnjlbfnbfdjneajpipnlcppleek"; +const char kEnterpriseWebStoreAppId[] = "afchcafgojfnemjkcbhfekplkmjaldaa"; +const char kHTermAppId[] = "pnhechapfaindjhompbnflcldabbghjo"; +const char kHTermDevAppId[] = "okddffdblfhhnmhodogpojmfkjmhinfp"; const char kWebStoreAppId[] = "ahfgeienlihckogmohjhadlkjgocpleb"; const char kCloudPrintAppId[] = "mfehgcgbbipciphmccgaenjidiccnmng"; const char kAppsPromoHistogram[] = "Extensions.AppsPromo"; diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index 2d8baf6..7f68323 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -350,6 +350,24 @@ namespace extension_misc { // The extension id of the bookmark manager. extern const char kBookmarkManagerId[]; + // The extension id of the Citrix Receiver application. + extern const char kCitrixReceiverAppId[]; + + // The extension id of the beta Citrix Receiver application. + extern const char kCitrixReceiverAppBetaId[]; + + // The extension id of the dev Citrix Receiver application. + extern const char kCitrixReceiverAppDevId[]; + + // The extension id of the Enterprise Web Store component application. + extern const char kEnterpriseWebStoreAppId[]; + + // The extension id of the HTerm app for ChromeOS. + extern const char kHTermAppId[]; + + // The extension id of the HTerm dev app for ChromeOS. + extern const char kHTermDevAppId[]; + // The extension id of the Web Store component application. extern const char kWebStoreAppId[]; diff --git a/chrome/common/extensions/extension_manifests_unittest.cc b/chrome/common/extensions/extension_manifests_unittest.cc index 77416e6..4a7dac9 100644 --- a/chrome/common/extensions/extension_manifests_unittest.cc +++ b/chrome/common/extensions/extension_manifests_unittest.cc @@ -575,106 +575,6 @@ TEST_F(ExtensionManifestTest, OptionsPageInApps) { errors::kInvalidOptionsPageExpectUrlInPackage); } -TEST_F(ExtensionManifestTest, HostedAppPermissions) { - std::string error; - scoped_ptr<DictionaryValue> manifest( - LoadManifestFile("hosted_app_absolute_options.json", &error)); - ASSERT_TRUE(manifest.get()); - ListValue* permissions = NULL; - ASSERT_TRUE(manifest->GetList("permissions", &permissions)); - - int platform_app = ExtensionAPIPermission::kTypePlatformApp; - ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); - ExtensionAPIPermissionSet api_perms = info->GetAll(); - for (ExtensionAPIPermissionSet::iterator i = api_perms.begin(); - i != api_perms.end(); ++i) { - if (*i == ExtensionAPIPermission::kExperimental) - continue; - - ExtensionAPIPermission* permission = info->GetByID(*i); - const char* name = permission->name(); - StringValue* p = new StringValue(name); - permissions->Clear(); - permissions->Append(p); - - // Some permissions are only available to component hosted apps. - if (permission->is_component_only()) { - LoadAndExpectError(Manifest(manifest.get(), name), - errors::kPermissionNotAllowed, - Extension::INTERNAL); - scoped_refptr<Extension> extension( - LoadAndExpectSuccess(Manifest(manifest.get(), name), - Extension::COMPONENT)); - EXPECT_TRUE(extension->GetActivePermissions()->HasAPIPermission( - permission->id())); - - } else if (permission->type_restrictions() == platform_app) { - LoadAndExpectError(Manifest(manifest.get(), name), - errors::kPermissionNotAllowed, - Extension::INTERNAL, - Extension::STRICT_ERROR_CHECKS); - } else if (!permission->supports_hosted_apps()) { - // Most normal extension permissions also aren't available to hosted apps. - // For these, the error is only reported in strict mode for legacy - // reasons: crbug.com/101993. - LoadAndExpectError(Manifest(manifest.get(), name), - errors::kPermissionNotAllowed, - Extension::INTERNAL, - Extension::STRICT_ERROR_CHECKS); - scoped_refptr<Extension> extension( - LoadAndExpectSuccess(Manifest(manifest.get(), name), - Extension::INTERNAL)); - EXPECT_FALSE(extension->GetActivePermissions()->HasAPIPermission( - permission->id())); - - // These permissions are also allowed for component hosted apps. - extension = LoadAndExpectSuccess(Manifest(manifest.get(), name), - Extension::COMPONENT); - EXPECT_TRUE(extension->GetActivePermissions()->HasAPIPermission( - permission->id())); - - } else { - scoped_refptr<Extension> extension( - LoadAndExpectSuccess(Manifest(manifest.get(), name))); - EXPECT_TRUE(extension->GetActivePermissions()->HasAPIPermission( - permission->id())); - } - } -} - -TEST_F(ExtensionManifestTest, ComponentOnlyPermission) { - std::string error; - scoped_ptr<DictionaryValue> manifest( - LoadManifestFile("init_valid_minimal.json", &error)); - ASSERT_TRUE(manifest.get()); - ListValue* permissions = new ListValue(); - manifest->Set("permissions", permissions); - - ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); - ExtensionAPIPermissionSet api_perms = info->GetAll(); - for (ExtensionAPIPermissionSet::iterator i = api_perms.begin(); - i != api_perms.end(); ++i) { - if (*i == ExtensionAPIPermission::kExperimental) - continue; - - ExtensionAPIPermission* permission = info->GetByID(*i); - const char* name = permission->name(); - StringValue* p = new StringValue(name); - permissions->Clear(); - permissions->Append(p); - - if (!permission->is_component_only()) - continue; - - // Component-only extensions should only be enabled for component - // extensions. - LoadAndExpectError(Manifest(manifest.get(), name), - errors::kPermissionNotAllowed); - LoadAndExpectSuccess(Manifest(manifest.get(), name), - Extension::COMPONENT); - } -} - TEST_F(ExtensionManifestTest, AllowUnrecognizedPermissions) { std::string error; scoped_ptr<DictionaryValue> manifest( diff --git a/chrome/common/extensions/extension_permission_set.cc b/chrome/common/extensions/extension_permission_set.cc index 787200e..a805826 100644 --- a/chrome/common/extensions/extension_permission_set.cc +++ b/chrome/common/extensions/extension_permission_set.cc @@ -7,10 +7,12 @@ #include <algorithm> #include <string> +#include "base/command_line.h" #include "base/memory/singleton.h" #include "base/values.h" #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_l10n_util.h" @@ -21,6 +23,7 @@ #include "net/base/registry_controlled_domain.h" #include "ui/base/l10n/l10n_util.h" +namespace ids = extension_misc; namespace { // Helper for GetDistinctHosts(): com > net > org > everything else. @@ -196,19 +199,6 @@ void ExtensionAPIPermission::RegisterAllPermissions( kUnlimitedStorage, "unlimitedStorage", 0, ExtensionPermissionMessage::kNone, kFlagCannotBeOptional, kTypeAll); - // Register hosted app permissions that are also private. - info->RegisterPermission( - kChromePrivate, "chromePrivate", 0, - ExtensionPermissionMessage::kNone, kFlagCannotBeOptional, - kTypeAll - kTypePlatformApp); - info->RegisterPermission( - kChromeAuthPrivate, "chromeAuthPrivate", 0, - ExtensionPermissionMessage::kNone, - kFlagComponentOnly | kFlagCannotBeOptional, kTypeAll - kTypePlatformApp); - info->RegisterPermission( - kWebstorePrivate, "webstorePrivate", 0, - ExtensionPermissionMessage::kNone, - kFlagComponentOnly | kFlagCannotBeOptional, kTypeAll - kTypePlatformApp); // Register hosted and packaged app permissions. info->RegisterPermission( @@ -245,9 +235,6 @@ void ExtensionAPIPermission::RegisterAllPermissions( kInput, "input", 0, ExtensionPermissionMessage::kNone, kFlagImpliesFullURLAccess, kTypeDefault); info->RegisterPermission( - kInputMethodPrivate, "inputMethodPrivate", 0, - ExtensionPermissionMessage::kNone, kFlagCannotBeOptional, kTypeDefault); - info->RegisterPermission( kManagement, "management", IDS_EXTENSION_PROMPT_WARNING_MANAGEMENT, ExtensionPermissionMessage::kManagement, kFlagNone, kTypeDefault); info->RegisterPermission( @@ -262,9 +249,6 @@ void ExtensionAPIPermission::RegisterAllPermissions( ExtensionPermissionMessage::kTabs, kFlagNone, kTypeDefault - kTypePlatformApp); info->RegisterPermission( - kTerminalPrivate, "terminalPrivate", 0, - ExtensionPermissionMessage::kNone, kFlagCannotBeOptional, kTypeDefault); - info->RegisterPermission( kTts, "tts", 0, ExtensionPermissionMessage::kNone, kFlagCannotBeOptional, kTypeDefault); info->RegisterPermission( @@ -282,32 +266,73 @@ void ExtensionAPIPermission::RegisterAllPermissions( kWebRequestBlocking, "webRequestBlocking", 0, ExtensionPermissionMessage::kNone, kFlagNone, kTypeDefault - kTypePlatformApp); - info->RegisterPermission( - kWebSocketProxyPrivate, "webSocketProxyPrivate", 0, - ExtensionPermissionMessage::kNone, kFlagCannotBeOptional, - kTypeDefault - kTypePlatformApp); // Register private permissions. info->RegisterPermission( kChromeosInfoPrivate, "chromeosInfoPrivate", 0, ExtensionPermissionMessage::kNone, - kFlagComponentOnly | kFlagCannotBeOptional, kTypeDefault); + kFlagComponentOnly_Deprecated | kFlagCannotBeOptional, kTypeDefault); info->RegisterPermission( kFileBrowserPrivate, "fileBrowserPrivate", 0, ExtensionPermissionMessage::kNone, - kFlagComponentOnly | kFlagCannotBeOptional, kTypeDefault); + kFlagComponentOnly_Deprecated | kFlagCannotBeOptional, kTypeDefault); info->RegisterPermission( kMediaPlayerPrivate, "mediaPlayerPrivate", 0, ExtensionPermissionMessage::kNone, - kFlagComponentOnly | kFlagCannotBeOptional, kTypeDefault); + kFlagComponentOnly_Deprecated | kFlagCannotBeOptional, kTypeDefault); info->RegisterPermission( kMetricsPrivate, "metricsPrivate", 0, ExtensionPermissionMessage::kNone, - kFlagComponentOnly | kFlagCannotBeOptional, kTypeDefault); + kFlagComponentOnly_Deprecated | kFlagCannotBeOptional, kTypeDefault); info->RegisterPermission( kSystemPrivate, "systemPrivate", 0, ExtensionPermissionMessage::kNone, - kFlagComponentOnly | kFlagCannotBeOptional, kTypeDefault); + kFlagComponentOnly_Deprecated | kFlagCannotBeOptional, kTypeDefault); + + ExtensionAPIPermission* chromeAuthPrivate = info->RegisterPermission( + kChromeAuthPrivate, "chromeAuthPrivate", 0, + ExtensionPermissionMessage::kNone, + kFlagCannotBeOptional, kTypeAll - kTypePlatformApp); + chromeAuthPrivate->AddToWhitelist(ids::kCloudPrintAppId); + + ExtensionAPIPermission* chromePrivate = info->RegisterPermission( + kChromePrivate, "chromePrivate", 0, ExtensionPermissionMessage::kNone, + kFlagCannotBeOptional, kTypeAll - kTypePlatformApp); + chromePrivate->AddToWhitelist(ids::kCitrixReceiverAppId); + chromePrivate->AddToWhitelist(ids::kCitrixReceiverAppBetaId); + chromePrivate->AddToWhitelist(ids::kCitrixReceiverAppDevId); + + ExtensionAPIPermission* inputMethodPrivate = info->RegisterPermission( + kInputMethodPrivate, "inputMethodPrivate", 0, + ExtensionPermissionMessage::kNone, kFlagCannotBeOptional, kTypeDefault); + inputMethodPrivate->AddToWhitelist(ids::kCitrixReceiverAppId); + inputMethodPrivate->AddToWhitelist(ids::kCitrixReceiverAppBetaId); + inputMethodPrivate->AddToWhitelist(ids::kCitrixReceiverAppDevId); + inputMethodPrivate->AddToWhitelist(ids::kHTermAppId); + inputMethodPrivate->AddToWhitelist(ids::kHTermDevAppId); + + ExtensionAPIPermission* terminalPrivate = info->RegisterPermission( + kTerminalPrivate, "terminalPrivate", 0, ExtensionPermissionMessage::kNone, + kFlagCannotBeOptional, kTypeDefault); + terminalPrivate->AddToWhitelist(ids::kHTermAppId); + terminalPrivate->AddToWhitelist(ids::kHTermDevAppId); + + ExtensionAPIPermission* webSocketProxyPrivate = info->RegisterPermission( + kWebSocketProxyPrivate, "webSocketProxyPrivate", 0, + ExtensionPermissionMessage::kNone, + kFlagCannotBeOptional, kTypeDefault - kTypePlatformApp); + webSocketProxyPrivate->AddToWhitelist(ids::kCitrixReceiverAppId); + webSocketProxyPrivate->AddToWhitelist(ids::kCitrixReceiverAppBetaId); + webSocketProxyPrivate->AddToWhitelist(ids::kCitrixReceiverAppDevId); + webSocketProxyPrivate->AddToWhitelist(ids::kHTermAppId); + webSocketProxyPrivate->AddToWhitelist(ids::kHTermDevAppId); + + ExtensionAPIPermission* webstorePrivate = info->RegisterPermission( + kWebstorePrivate, "webstorePrivate", 0, + ExtensionPermissionMessage::kNone, + kFlagCannotBeOptional, kTypeAll - kTypePlatformApp); + webstorePrivate->AddToWhitelist(ids::kEnterpriseWebStoreAppId); + webstorePrivate->AddToWhitelist(ids::kWebStoreAppId); // Full url access permissions. info->RegisterPermission( @@ -338,6 +363,25 @@ void ExtensionAPIPermission::RegisterAllPermissions( info->RegisterAlias("tabs", kWindowsPermission); } +bool ExtensionAPIPermission::HasWhitelist() const { + return !whitelist_.empty(); +} + +bool ExtensionAPIPermission::IsWhitelisted( + const std::string& extension_id) const { + CommandLine* command_line = CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kWhitelistedExtensionID)) { + if (extension_id == command_line->GetSwitchValueASCII( + switches::kWhitelistedExtensionID)) + return true; + } + return whitelist_.find(extension_id) != whitelist_.end(); +} + +void ExtensionAPIPermission::AddToWhitelist(const std::string& extension_id) { + whitelist_.insert(extension_id); +} + // // ExtensionPermissionsInfo // @@ -395,7 +439,7 @@ void ExtensionPermissionsInfo::RegisterAlias( name_map_[alias] = name_map_[name]; } -void ExtensionPermissionsInfo::RegisterPermission( +ExtensionAPIPermission* ExtensionPermissionsInfo::RegisterPermission( ExtensionAPIPermission::ID id, const char* name, int l10n_message_id, @@ -412,6 +456,8 @@ void ExtensionPermissionsInfo::RegisterPermission( name_map_[name] = permission; permission_count_++; + + return permission; } // diff --git a/chrome/common/extensions/extension_permission_set.h b/chrome/common/extensions/extension_permission_set.h index b56d12ed..99046e1 100644 --- a/chrome/common/extensions/extension_permission_set.h +++ b/chrome/common/extensions/extension_permission_set.h @@ -18,6 +18,8 @@ #include "base/string16.h" #include "chrome/common/extensions/url_pattern_set.h" +// TODO(jstritar): Move each class to its own file in extensions/permissions. + class Extension; class ExtensionPermissionsInfo; @@ -146,10 +148,11 @@ class ExtensionAPIPermission { kFlagImpliesFullURLAccess = 1 << 1, // Indicates that the permission is private to COMPONENT extensions. - kFlagComponentOnly = 1 << 2, + // Depcrecated: please use the whitelist. + kFlagComponentOnly_Deprecated = 1 << 2, // Indicates that extensions cannot specify the permission as optional. - kFlagCannotBeOptional = 1 << 3, + kFlagCannotBeOptional = 1 << 3 }; // Flags for specifying what extension types can use the permission. @@ -209,9 +212,16 @@ class ExtensionAPIPermission { // Returns true if this permission can only be acquired by COMPONENT // extensions. bool is_component_only() const { - return (flags_ & kFlagComponentOnly) != 0; + return (flags_ & kFlagComponentOnly_Deprecated) != 0; } + // Returns true if access to this permission is restricted by a whitelist. + bool HasWhitelist() const; + + // Returns true if |extension_id| is whitelisted. The return value is only + // relevant if this permission has a whitelist. + bool IsWhitelisted(const std::string& extension_id) const; + // Returns true if regular extensions can specify this permission. bool supports_extensions() const { return (type_restrictions_ & kTypeExtension) != 0; @@ -250,6 +260,8 @@ class ExtensionAPIPermission { // Register ALL the permissions! static void RegisterAllPermissions(ExtensionPermissionsInfo* info); + typedef std::set<std::string> ExtensionWhitelist; + explicit ExtensionAPIPermission( ID id, const char* name, @@ -258,12 +270,16 @@ class ExtensionAPIPermission { int flags, int type_restrictions); + // Adds |extension_id| to the whitelist for this permission. + void AddToWhitelist(const std::string& extension_id); + ID id_; const char* name_; int flags_; int type_restrictions_; int l10n_message_id_; ExtensionPermissionMessage::ID message_id_; + ExtensionWhitelist whitelist_; }; typedef std::set<ExtensionAPIPermission::ID> ExtensionAPIPermissionSet; @@ -302,7 +318,7 @@ class ExtensionPermissionsInfo { void RegisterAlias(const char* name, const char* alias); // Registers a permission with the specified attributes and flags. - void RegisterPermission( + ExtensionAPIPermission* RegisterPermission( ExtensionAPIPermission::ID id, const char* name, int l10n_message_id, @@ -435,7 +451,7 @@ class ExtensionPermissionSet const URLPatternSet& scriptable_hosts() const { return scriptable_hosts_; } private: - FRIEND_TEST_ALL_PREFIXES(ExtensionPermissionSetTest, + FRIEND_TEST_ALL_PREFIXES(ExtensionPermissionsTest, HasLessHostPrivilegesThan); friend class base::RefCountedThreadSafe<ExtensionPermissionSet>; diff --git a/chrome/common/extensions/extension_permission_set_unittest.cc b/chrome/common/extensions/extension_permission_set_unittest.cc index 0267bf6..782146f 100644 --- a/chrome/common/extensions/extension_permission_set_unittest.cc +++ b/chrome/common/extensions/extension_permission_set_unittest.cc @@ -10,8 +10,14 @@ #include "base/utf_string_conversions.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_constants.h" +#include "chrome/common/extensions/extension_error_utils.h" +#include "chrome/common/extensions/extension_permission_set.h" #include "testing/gtest/include/gtest/gtest.h" +namespace errors = extension_manifest_errors; +namespace keys = extension_manifest_keys; +namespace values = extension_manifest_values; namespace { static scoped_refptr<Extension> LoadManifest(const std::string& dir, @@ -44,6 +50,27 @@ static scoped_refptr<Extension> LoadManifest(const std::string& dir, return LoadManifest(dir, test_file, Extension::NO_FLAGS); } +static scoped_refptr<Extension> LoadManifestFromValue( + DictionaryValue* manifest, + Extension::Location location, + std::string* error) { + return Extension::Create(FilePath(), location, *manifest, + Extension::STRICT_ERROR_CHECKS, error); +} + +static void LoadManifestAndExpectError(DictionaryValue* manifest, + Extension::Location location, + const std::string& permission) { + std::string error; + scoped_refptr<Extension> extension = + LoadManifestFromValue(manifest, location, &error); + + std::string expected_error = ExtensionErrorUtils::FormatErrorMessage( + errors::kPermissionNotAllowed, permission); + EXPECT_FALSE(extension); + EXPECT_EQ(expected_error, error); +} + void CompareLists(const std::vector<std::string>& expected, const std::vector<std::string>& actual) { ASSERT_EQ(expected.size(), actual.size()); @@ -60,15 +87,11 @@ static void AddPattern(URLPatternSet* extent, const std::string& pattern) { } // namespace -class ExtensionAPIPermissionTest : public testing::Test { +class ExtensionPermissionsTest : public testing::Test { }; -class ExtensionPermissionSetTest : public testing::Test { -}; - - // Tests GetByID. -TEST(ExtensionPermissionsInfoTest, GetByID) { +TEST(ExtensionPermissionsTest, GetByID) { ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); ExtensionAPIPermissionSet ids = info->GetAll(); for (ExtensionAPIPermissionSet::iterator i = ids.begin(); @@ -78,7 +101,7 @@ TEST(ExtensionPermissionsInfoTest, GetByID) { } // Tests that GetByName works with normal permission names and aliases. -TEST(ExtensionPermissionsInfoTest, GetByName) { +TEST(ExtensionPermissionsTest, GetByName) { ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); EXPECT_EQ(ExtensionAPIPermission::kTab, info->GetByName("tabs")->id()); EXPECT_EQ(ExtensionAPIPermission::kManagement, @@ -86,7 +109,7 @@ TEST(ExtensionPermissionsInfoTest, GetByName) { EXPECT_FALSE(info->GetByName("alsdkfjasldkfj")); } -TEST(ExtensionPermissionsInfoTest, GetAll) { +TEST(ExtensionPermissionsTest, GetAll) { size_t count = 0; ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); ExtensionAPIPermissionSet apis = info->GetAll(); @@ -100,7 +123,7 @@ TEST(ExtensionPermissionsInfoTest, GetAll) { EXPECT_EQ(count, info->get_permission_count()); } -TEST(ExtensionPermissionInfoTest, GetAllByName) { +TEST(ExtensionPermissionsTest, GetAllByName) { std::set<std::string> names; names.insert("background"); names.insert("management"); @@ -121,7 +144,7 @@ TEST(ExtensionPermissionInfoTest, GetAllByName) { } // Tests that the aliases are properly mapped. -TEST(ExtensionAPIPermissionTest, Aliases) { +TEST(ExtensionPermissionsTest, Aliases) { ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); // tabs: tabs, windows std::string tabs_name = "tabs"; @@ -139,7 +162,7 @@ TEST(ExtensionAPIPermissionTest, Aliases) { info->GetByName("unlimited_storage")->id()); } -TEST(ExtensionAPIPermissionTest, HostedAppPermissions) { +TEST(ExtensionPermissionsTest, HostedAppPermissions) { ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); ExtensionAPIPermissionSet hosted_perms; hosted_perms.insert(ExtensionAPIPermission::kAppNotifications); @@ -154,19 +177,41 @@ TEST(ExtensionAPIPermissionTest, HostedAppPermissions) { hosted_perms.insert(ExtensionAPIPermission::kUnlimitedStorage); hosted_perms.insert(ExtensionAPIPermission::kWebstorePrivate); + DictionaryValue source; + source.SetString(keys::kName, "permission hosted app test"); + source.SetString(keys::kVersion, "1"); + source.SetInteger(keys::kManifestVersion, 2); + ListValue* urls = new ListValue(); + urls->Append(Value::CreateStringValue("http://localhost/test.html")); + source.Set(keys::kWebURLs, urls); + source.SetString(keys::kLaunchWebURL, "http://localhost/test.html"); + ExtensionAPIPermissionSet perms = info->GetAll(); size_t count = 0; for (ExtensionAPIPermissionSet::iterator i = perms.begin(); i != perms.end(); ++i) { - count += hosted_perms.count(*i); - EXPECT_EQ(hosted_perms.count(*i) > 0, - info->GetByID(*i)->supports_hosted_apps()); + ExtensionAPIPermission* permission = info->GetByID(*i); + if (permission->supports_hosted_apps()) { + count++; + EXPECT_TRUE(hosted_perms.count(*i)); + continue; + } + + scoped_ptr<DictionaryValue> manifest(source.DeepCopy()); + ListValue* permissions = new ListValue(); + permissions->Append(Value::CreateStringValue(permission->name())); + manifest->Set(keys::kPermissions, permissions); + + // This error may be generated for other reasons too, like if the permission + // has a whitelist. + LoadManifestAndExpectError( + manifest.get(), Extension::INTERNAL, permission->name()); } EXPECT_EQ(hosted_perms.size(), count); } -TEST(ExtensionAPIPermissionTest, PlatformAppPermissions) { +TEST(ExtensionPermissionsTest, PlatformAppPermissions) { ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); ExtensionAPIPermissionSet blacklist; blacklist.insert(ExtensionAPIPermission::kAppNotifications); @@ -180,42 +225,125 @@ TEST(ExtensionAPIPermissionTest, PlatformAppPermissions) { blacklist.insert(ExtensionAPIPermission::kWebSocketProxyPrivate); blacklist.insert(ExtensionAPIPermission::kWebstorePrivate); + DictionaryValue source; + source.SetString(keys::kName, "permission platform app test"); + source.SetString(keys::kVersion, "1"); + source.SetInteger(keys::kManifestVersion, 2); + source.SetBoolean(keys::kPlatformApp, true); + source.SetString(keys::kLaunchLocalPath, "test.html"); + source.SetString(keys::kLaunchContainer, values::kLaunchContainerShell); + ExtensionAPIPermissionSet perms = info->GetAll(); size_t count = 0; for (ExtensionAPIPermissionSet::iterator i = perms.begin(); i != perms.end(); ++i) { - count += blacklist.count(*i); - EXPECT_EQ(blacklist.count(*i) > 0, - !info->GetByID(*i)->supports_platform_apps()); + ExtensionAPIPermission* permission = info->GetByID(*i); + if (permission->supports_platform_apps()) + continue; + + count++; + EXPECT_TRUE(blacklist.count(*i)); + + scoped_ptr<DictionaryValue> manifest(source.DeepCopy()); + ListValue* permissions = new ListValue(); + permissions->Append(Value::CreateStringValue(permission->name())); + manifest->Set(keys::kPermissions, permissions); + + // This error may be generated for other reasons too, like if the permission + // has a whitelist. + LoadManifestAndExpectError( + manifest.get(), Extension::INTERNAL, permission->name()); } EXPECT_EQ(blacklist.size(), count); } -TEST(ExtensionAPIPermissionTest, ComponentOnlyPermissions) { +TEST(ExtensionPermissionsTest, ComponentOnlyPermissions) { ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); ExtensionAPIPermissionSet private_perms; - private_perms.insert(ExtensionAPIPermission::kChromeAuthPrivate); private_perms.insert(ExtensionAPIPermission::kChromeosInfoPrivate); private_perms.insert(ExtensionAPIPermission::kFileBrowserPrivate); private_perms.insert(ExtensionAPIPermission::kMediaPlayerPrivate); private_perms.insert(ExtensionAPIPermission::kMetricsPrivate); private_perms.insert(ExtensionAPIPermission::kSystemPrivate); - private_perms.insert(ExtensionAPIPermission::kWebstorePrivate); + + DictionaryValue source; + source.SetString(keys::kName, "component only permission test"); + source.SetString(keys::kVersion, "1"); + source.SetInteger(keys::kManifestVersion, 2); ExtensionAPIPermissionSet perms = info->GetAll(); - int count = 0; + size_t count = 0; for (ExtensionAPIPermissionSet::iterator i = perms.begin(); i != perms.end(); ++i) { - count += private_perms.count(*i); - EXPECT_EQ(private_perms.count(*i) > 0, - info->GetByID(*i)->is_component_only()); + ExtensionAPIPermission* permission = info->GetByID(*i); + + scoped_ptr<DictionaryValue> manifest(source.DeepCopy()); + ListValue* permissions = new ListValue(); + permissions->Append(Value::CreateStringValue(permission->name())); + manifest->Set(keys::kPermissions, permissions); + + // COMPONENT extensions can access any permission. + std::string error; + scoped_refptr<Extension> extension = LoadManifestFromValue( + manifest.get(), Extension::COMPONENT, &error); + EXPECT_TRUE(extension); + + if (!permission->is_component_only()) + continue; + + count++; + EXPECT_TRUE(private_perms.count(*i)); + + // But INTERNAL extensions can't access component only permissions. + LoadManifestAndExpectError( + manifest.get(), Extension::INTERNAL, permission->name()); + } + + EXPECT_EQ(private_perms.size(), count); +} + +// Tests that permission whitelists are enforced. +TEST(ExtensionPermissionsTest, Whitelists) { + ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); + ExtensionAPIPermissionSet ids = info->GetAll(); + + ExtensionAPIPermissionSet expected_whitelists; + expected_whitelists.insert(ExtensionAPIPermission::kChromeAuthPrivate); + expected_whitelists.insert(ExtensionAPIPermission::kChromePrivate); + expected_whitelists.insert(ExtensionAPIPermission::kInputMethodPrivate); + expected_whitelists.insert(ExtensionAPIPermission::kTerminalPrivate); + expected_whitelists.insert(ExtensionAPIPermission::kWebSocketProxyPrivate); + expected_whitelists.insert(ExtensionAPIPermission::kWebstorePrivate); + + DictionaryValue source; + source.SetString(keys::kName, "permission whitelist test"); + source.SetString(keys::kVersion, "1"); + source.SetInteger(keys::kManifestVersion, 2); + + size_t whitelists = 0; + for (ExtensionAPIPermissionSet::iterator i = ids.begin(); + i != ids.end(); ++i) { + ExtensionAPIPermission* permission = info->GetByID(*i); + if (!permission->HasWhitelist()) + continue; + + whitelists++; + EXPECT_TRUE(expected_whitelists.count(*i)); + + scoped_ptr<DictionaryValue> manifest(source.DeepCopy()); + ListValue* permissions = new ListValue(); + permissions->Append(Value::CreateStringValue(permission->name())); + manifest->Set(keys::kPermissions, permissions); + + LoadManifestAndExpectError( + manifest.get(), Extension::INTERNAL, permission->name()); } - EXPECT_EQ(7, count); + EXPECT_EQ(expected_whitelists.size(), whitelists); } -TEST(ExtensionPermissionSetTest, EffectiveHostPermissions) { +TEST(ExtensionPermissionsTest, EffectiveHostPermissions) { scoped_refptr<Extension> extension; scoped_refptr<const ExtensionPermissionSet> permissions; @@ -291,7 +419,7 @@ TEST(ExtensionPermissionSetTest, EffectiveHostPermissions) { EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); } -TEST(ExtensionPermissionSetTest, ExplicitAccessToOrigin) { +TEST(ExtensionPermissionsTest, ExplicitAccessToOrigin) { ExtensionAPIPermissionSet apis; URLPatternSet explicit_hosts; URLPatternSet scriptable_hosts; @@ -314,7 +442,7 @@ TEST(ExtensionPermissionSetTest, ExplicitAccessToOrigin) { GURL("http://test.example.com"))); } -TEST(ExtensionPermissionSetTest, CreateUnion) { +TEST(ExtensionPermissionsTest, CreateUnion) { ExtensionAPIPermissionSet apis1; ExtensionAPIPermissionSet apis2; ExtensionAPIPermissionSet expected_apis; @@ -395,7 +523,7 @@ TEST(ExtensionPermissionSetTest, CreateUnion) { EXPECT_EQ(effective_hosts, union_set->effective_hosts()); } -TEST(ExtensionPermissionSetTest, CreateIntersection) { +TEST(ExtensionPermissionsTest, CreateIntersection) { ExtensionAPIPermissionSet apis1; ExtensionAPIPermissionSet apis2; ExtensionAPIPermissionSet expected_apis; @@ -471,7 +599,7 @@ TEST(ExtensionPermissionSetTest, CreateIntersection) { EXPECT_EQ(effective_hosts, new_set->effective_hosts()); } -TEST(ExtensionPermissionSetTest, CreateDifference) { +TEST(ExtensionPermissionsTest, CreateDifference) { ExtensionAPIPermissionSet apis1; ExtensionAPIPermissionSet apis2; ExtensionAPIPermissionSet expected_apis; @@ -535,7 +663,7 @@ TEST(ExtensionPermissionSetTest, CreateDifference) { EXPECT_TRUE(set1->IsEmpty()); } -TEST(ExtensionPermissionSetTest, HasLessPrivilegesThan) { +TEST(ExtensionPermissionsTest, HasLessPrivilegesThan) { const struct { const char* base_name; // Increase these sizes if you have more than 10. @@ -628,7 +756,7 @@ TEST(ExtensionPermissionSetTest, HasLessPrivilegesThan) { } } -TEST(ExtensionPermissionSetTest, PermissionMessages) { +TEST(ExtensionPermissionsTest, PermissionMessages) { // Ensure that all permissions that needs to show install UI actually have // strings associated with them. ExtensionAPIPermissionSet skip; @@ -702,7 +830,7 @@ TEST(ExtensionPermissionSetTest, PermissionMessages) { } // Tests the default permissions (empty API permission set). -TEST(ExtensionPermissionSetTest, DefaultFunctionAccess) { +TEST(ExtensionPermissionsTest, DefaultFunctionAccess) { const struct { const char* permission_name; bool expect_success; @@ -770,7 +898,7 @@ TEST(ExtensionPermissionSetTest, DefaultAnyAPIAccess) { } } -TEST(ExtensionPermissionSetTest, GetWarningMessages_ManyHosts) { +TEST(ExtensionPermissionsTest, GetWarningMessages_ManyHosts) { scoped_refptr<Extension> extension; extension = LoadManifest("permissions", "many-hosts.json"); @@ -781,7 +909,7 @@ TEST(ExtensionPermissionSetTest, GetWarningMessages_ManyHosts) { UTF16ToUTF8(warnings[0])); } -TEST(ExtensionPermissionSetTest, GetWarningMessages_Plugins) { +TEST(ExtensionPermissionsTest, GetWarningMessages_Plugins) { scoped_refptr<Extension> extension; scoped_refptr<ExtensionPermissionSet> permissions; @@ -799,7 +927,7 @@ TEST(ExtensionPermissionSetTest, GetWarningMessages_Plugins) { #endif } -TEST(ExtensionPermissionSetTest, GetDistinctHostsForDisplay) { +TEST(ExtensionPermissionsTest, GetDistinctHostsForDisplay) { scoped_refptr<ExtensionPermissionSet> perm_set; ExtensionAPIPermissionSet empty_perms; std::set<std::string> expected; @@ -955,7 +1083,7 @@ TEST(ExtensionPermissionSetTest, GetDistinctHostsForDisplay) { } } -TEST(ExtensionPermissionSetTest, GetDistinctHostsForDisplay_ComIsBestRcd) { +TEST(ExtensionPermissionsTest, GetDistinctHostsForDisplay_ComIsBestRcd) { scoped_refptr<ExtensionPermissionSet> perm_set; ExtensionAPIPermissionSet empty_perms; URLPatternSet explicit_hosts; @@ -980,7 +1108,7 @@ TEST(ExtensionPermissionSetTest, GetDistinctHostsForDisplay_ComIsBestRcd) { EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); } -TEST(ExtensionPermissionSetTest, GetDistinctHostsForDisplay_NetIs2ndBestRcd) { +TEST(ExtensionPermissionsTest, GetDistinctHostsForDisplay_NetIs2ndBestRcd) { scoped_refptr<ExtensionPermissionSet> perm_set; ExtensionAPIPermissionSet empty_perms; URLPatternSet explicit_hosts; @@ -1004,7 +1132,7 @@ TEST(ExtensionPermissionSetTest, GetDistinctHostsForDisplay_NetIs2ndBestRcd) { EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); } -TEST(ExtensionPermissionSetTest, +TEST(ExtensionPermissionsTest, GetDistinctHostsForDisplay_OrgIs3rdBestRcd) { scoped_refptr<ExtensionPermissionSet> perm_set; ExtensionAPIPermissionSet empty_perms; @@ -1028,7 +1156,7 @@ TEST(ExtensionPermissionSetTest, EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); } -TEST(ExtensionPermissionSetTest, +TEST(ExtensionPermissionsTest, GetDistinctHostsForDisplay_FirstInListIs4thBestRcd) { scoped_refptr<ExtensionPermissionSet> perm_set; ExtensionAPIPermissionSet empty_perms; @@ -1051,7 +1179,7 @@ TEST(ExtensionPermissionSetTest, EXPECT_EQ(expected, perm_set->GetDistinctHostsForDisplay()); } -TEST(ExtensionPermissionSetTest, HasLessHostPrivilegesThan) { +TEST(ExtensionPermissionsTest, HasLessHostPrivilegesThan) { URLPatternSet elist1; URLPatternSet elist2; URLPatternSet slist1; @@ -1120,7 +1248,7 @@ TEST(ExtensionPermissionSetTest, HasLessHostPrivilegesThan) { EXPECT_TRUE(set2->HasLessHostPrivilegesThan(set1.get())); } -TEST(ExtensionPermissionSetTest, GetAPIsAsStrings) { +TEST(ExtensionPermissionsTest, GetAPIsAsStrings) { ExtensionAPIPermissionSet apis; URLPatternSet empty_set; @@ -1140,7 +1268,7 @@ TEST(ExtensionPermissionSetTest, GetAPIsAsStrings) { ExtensionPermissionsInfo::GetInstance()->GetAllByName(api_names)); } -TEST(ExtensionPermissionSetTest, IsEmpty) { +TEST(ExtensionPermissionsTest, IsEmpty) { ExtensionAPIPermissionSet empty_apis; URLPatternSet empty_extent; diff --git a/chrome/renderer/extensions/chrome_private_custom_bindings.cc b/chrome/renderer/extensions/chrome_private_custom_bindings.cc index 223f197..a1e4fbb 100644 --- a/chrome/renderer/extensions/chrome_private_custom_bindings.cc +++ b/chrome/renderer/extensions/chrome_private_custom_bindings.cc @@ -31,25 +31,12 @@ ChromePrivateCustomBindings::ChromePrivateCustomBindings( // static v8::Handle<v8::Value> ChromePrivateCustomBindings::DecodeJPEG( const v8::Arguments& args) { - static const char* kAllowedIds[] = { - "haiffjcadagjlijoggckpgfnoeiflnem", - "gnedhmakppccajfpfiihfcdlnpgomkcf", - "fjcibdnjlbfnbfdjneajpipnlcppleek", - "oflbaaikkabfdfkimeclgkackhdkpnip" // Testing extension. - }; - const std::vector<std::string> allowed_ids( - kAllowedIds, kAllowedIds + arraysize(kAllowedIds)); - ChromePrivateCustomBindings* v8_extension = GetFromArguments<ChromePrivateCustomBindings>(args); const ::Extension* extension = v8_extension->GetExtensionForCurrentRenderView(); if (!extension) return v8::Undefined(); - if (allowed_ids.end() == std::find( - allowed_ids.begin(), allowed_ids.end(), extension->id())) { - return v8::Undefined(); - } DCHECK(args.Length() == 1); DCHECK(args[0]->IsArray()); diff --git a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_app/background.html b/chrome/test/data/extensions/api_test/chrome_auth_private/installed_app/background.html deleted file mode 100644 index d9fc1c8..0000000 --- a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_app/background.html +++ /dev/null @@ -1,6 +0,0 @@ -<!-- - * Copyright (c) 2011 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. ---> -<script src="cloud_print_exception.js"></script> diff --git a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_app/cloud_print_exception.js b/chrome/test/data/extensions/api_test/chrome_auth_private/installed_app/cloud_print_exception.js deleted file mode 100644 index 56aef5b..0000000 --- a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_app/cloud_print_exception.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2011 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. - -// This test is invoked from a non-component app. So this call should throw an -// exception when we try and access the chromeAuthPrivate API. -var tests = [ - function exceptionSetCreds() { - var expectedException = - "Error: You do not have permission to use " + - "'chromeAuthPrivate.setCloudPrintCredentials'. Be sure to declare in " + - "your manifest what permissions you need."; - var userEmail = 'foo@gmail.com'; - var robotEmail = 'foorobot@googleusercontent.com'; - var credentials = '1/23546efa54'; - try { - chrome.chromeAuthPrivate.setCloudPrintCredentials( - userEmail, robotEmail, credentials); - } catch (err) { - chrome.test.assertEq(expectedException, err.toString()); - chrome.test.succeed(); - return; - } - chrome.test.fail(); - } -]; - -chrome.test.runTests(tests); diff --git a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_app/manifest.json b/chrome/test/data/extensions/api_test/chrome_auth_private/installed_app/manifest.json deleted file mode 100644 index 50d9768..0000000 --- a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_app/manifest.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "Cloud Print Installed App", - "version": "0.1", - "manifest_version": 2, - "description": "Cloud Print Installed App Test For Failure", - "background": { - "page": "background.html" - }, - "permissions": [ - "chromeAuthPrivate" - ] -} diff --git a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_component_app/background.html b/chrome/test/data/extensions/api_test/chrome_auth_private/installed_component_app/background.html deleted file mode 100644 index 5c94fc4..0000000 --- a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_component_app/background.html +++ /dev/null @@ -1,6 +0,0 @@ -<!-- - * Copyright (c) 2011 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. ---> -<script src="cloud_print_fail.js"></script> diff --git a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_component_app/cloud_print_fail.js b/chrome/test/data/extensions/api_test/chrome_auth_private/installed_component_app/cloud_print_fail.js deleted file mode 100644 index c5db1102b6..0000000 --- a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_component_app/cloud_print_fail.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2011 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. - -// This test is invoked from an installed component app. Since we have an -// explicit URL check in the API, this should fail. -var tests = [ - function failureSetCreds() { - var expectedError = "Cannot call this API from a non-cloudprint URL." - var userEmail = 'foo@gmail.com'; - var robotEmail = 'foorobot@googleusercontent.com'; - var credentials = '1/23546efa54'; - chrome.chromeAuthPrivate.setCloudPrintCredentials( - userEmail, robotEmail, credentials, - chrome.test.callbackFail(expectedError)); - } -]; - -chrome.test.runTests(tests); diff --git a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_component_app/manifest.json b/chrome/test/data/extensions/api_test/chrome_auth_private/installed_component_app/manifest.json deleted file mode 100644 index 4e32220..0000000 --- a/chrome/test/data/extensions/api_test/chrome_auth_private/installed_component_app/manifest.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp40PYAXfSDlzCW1f5MDzRW64h0YhgV7MX8Frem0vO1ZAlq/mlUO4KxwkF2AZliFScO4Cc3CYpO6jpHXwz27tUwaN46C/LzYO7u/kb2piOep8gClvZ64EMnDv5PIoIeZlOJhkpnfs/5FbQt5sqT9avXX7YfLCLBJBql0U/V5615wIDAQAB", - "name": "Cloud Print Installed Component App", - "version": "0.1", - "manifest_version": 2, - "description": "Cloud Print App Test For Failure", - "background": { - "page": "background.html" - }, - "permissions": [ - "chromeAuthPrivate" - ] -} diff --git a/chrome/test/data/extensions/api_test/terminal/component_extension/background.html b/chrome/test/data/extensions/api_test/terminal/component_extension/background.html deleted file mode 100644 index 8d32ce8..0000000 --- a/chrome/test/data/extensions/api_test/terminal/component_extension/background.html +++ /dev/null @@ -1,5 +0,0 @@ -<script> -chrome.tabs.create({ - url: "test.html" -}); -</script> diff --git a/chrome/test/data/extensions/api_test/terminal/component_extension/manifest.json b/chrome/test/data/extensions/api_test/terminal/component_extension/manifest.json index aa036e7..629c551 100644 --- a/chrome/test/data/extensions/api_test/terminal/component_extension/manifest.json +++ b/chrome/test/data/extensions/api_test/terminal/component_extension/manifest.json @@ -3,8 +3,5 @@ "name": "chrome.terminalPrivate.apitest", "version": "0.1", "description": "end-to-end test for terminalPrivate api. Test opens two crosh processes, starts infinite loop that echos 'aaaa' in both of them and observes output.", - "background": { - "page": "background.html" - }, "permissions": ["terminalPrivate"] } diff --git a/chrome/test/data/extensions/api_test/terminal/no_permission/manifest.json b/chrome/test/data/extensions/api_test/terminal/no_permission/manifest.json deleted file mode 100644 index 812f991..0000000 --- a/chrome/test/data/extensions/api_test/terminal/no_permission/manifest.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "chrome.terminalPrivate.apitest.permissions", - "version": "0.1", - "description": "Test that non-component extension cannot use the terminalPrivateApi.", - "background": { - "scripts": ["test.js"] - }, - "permissions": ["terminalPrivate"] -} diff --git a/chrome/test/data/extensions/api_test/terminal/no_permission/test.js b/chrome/test/data/extensions/api_test/terminal/no_permission/test.js deleted file mode 100644 index a8c5389..0000000 --- a/chrome/test/data/extensions/api_test/terminal/no_permission/test.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2012 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. - -var kPermissionError = "Extension does not have the permission to use this API"; - -chrome.test.runTests([ - function tryOpenExtension() { - chrome.terminalPrivate.openTerminalProcess("crosh", - chrome.test.callbackFail(kPermissionError)); - }, - function trySendInput() { - chrome.terminalPrivate.sendInput(1222, "some input", - chrome.test.callbackFail(kPermissionError)); - }, - function tryClose() { - chrome.terminalPrivate.closeTerminalProcess(1222, - chrome.test.callbackFail(kPermissionError)); - } -]); |