| Index: chrome/browser/extensions/extension_function_dispatcher.cc
|
| diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
|
| index d326e6219e180754a508b1d25c0f1a63b2081db5..09830bbc403b1849e4420b187cb7da8c0bfe8343 100644
|
| --- a/chrome/browser/extensions/extension_function_dispatcher.cc
|
| +++ b/chrome/browser/extensions/extension_function_dispatcher.cc
|
| @@ -45,6 +45,7 @@
|
| #include "chrome/browser/extensions/extensions_quota_service.h"
|
| #include "chrome/browser/external_protocol/external_protocol_handler.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
|
| #include "chrome/browser/ui/browser_list.h"
|
| #include "chrome/browser/ui/browser_window.h"
|
| #include "chrome/common/extensions/extension_messages.h"
|
| @@ -405,6 +406,36 @@ void ExtensionFunctionDispatcher::ResetFunctions() {
|
| FactoryRegistry::GetInstance()->ResetFunctions();
|
| }
|
|
|
| +// static
|
| +void ExtensionFunctionDispatcher::DispatchOnIOThread(
|
| + const ExtensionInfoMap* extension_info_map,
|
| + ProfileId profile_id,
|
| + int render_process_id,
|
| + base::WeakPtr<ChromeRenderMessageFilter> ipc_sender,
|
| + int routing_id,
|
| + const ExtensionHostMsg_Request_Params& params) {
|
| + const Extension* extension =
|
| + extension_info_map->extensions().GetByURL(params.source_url);
|
| +
|
| + scoped_refptr<ExtensionFunction> function(
|
| + CreateExtensionFunction(params, extension, profile_id, render_process_id,
|
| + ipc_sender, routing_id));
|
| + if (!function)
|
| + return;
|
| +
|
| + IOThreadExtensionFunction* function_io =
|
| + function->AsIOThreadExtensionFunction();
|
| + if (!function_io) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| + function_io->set_ipc_sender(ipc_sender, routing_id);
|
| + function_io->set_extension_info_map(extension_info_map);
|
| + function->set_include_incognito(
|
| + extension_info_map->IsIncognitoEnabled(extension->id()));
|
| + function->Run();
|
| +}
|
| +
|
| ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(Profile* profile,
|
| Delegate* delegate)
|
| : profile_(profile),
|
| @@ -442,21 +473,6 @@ Browser* ExtensionFunctionDispatcher::GetCurrentBrowser(
|
| void ExtensionFunctionDispatcher::Dispatch(
|
| const ExtensionHostMsg_Request_Params& params,
|
| RenderViewHost* render_view_host) {
|
| - // TODO(aa): It would be cool to use ExtensionProcessManager to track which
|
| - // processes are extension processes rather than ChildProcessSecurityPolicy.
|
| - // EPM has richer information: it not only knows which processes contain
|
| - // at least one extension, but it knows which extensions are inside and what
|
| - // permissions the have. So we would be able to enforce permissions more
|
| - // granularly.
|
| - if (!ChildProcessSecurityPolicy::GetInstance()->HasExtensionBindings(
|
| - render_view_host->process()->id())) {
|
| - // TODO(aa): Allow content scripts access to low-threat extension APIs.
|
| - // See: crbug.com/80308.
|
| - LOG(ERROR) << "Extension API called from non-extension process.";
|
| - SendAccessDenied(render_view_host, params.request_id);
|
| - return;
|
| - }
|
| -
|
| ExtensionService* service = profile()->GetExtensionService();
|
| if (!service)
|
| return;
|
| @@ -464,7 +480,8 @@ void ExtensionFunctionDispatcher::Dispatch(
|
| if (!service->ExtensionBindingsAllowed(params.source_url)) {
|
| LOG(ERROR) << "Extension bindings not allowed for URL: "
|
| << params.source_url.spec();
|
| - SendAccessDenied(render_view_host, params.request_id);
|
| + SendAccessDenied(render_view_host, render_view_host->routing_id(),
|
| + params.request_id);
|
| return;
|
| }
|
|
|
| @@ -473,22 +490,14 @@ void ExtensionFunctionDispatcher::Dispatch(
|
| const Extension* extension = service->GetExtensionByURL(params.source_url);
|
| if (!extension)
|
| extension = service->GetExtensionByWebExtent(params.source_url);
|
| - if (!extension) {
|
| - LOG(ERROR) << "Extension does not exist for URL: "
|
| - << params.source_url.spec();
|
| - SendAccessDenied(render_view_host, params.request_id);
|
| - return;
|
| - }
|
|
|
| - if (!extension->HasApiPermission(params.name)) {
|
| - LOG(ERROR) << "Extension " << extension->id() << " does not have "
|
| - << "permission to function: " << params.name;
|
| - SendAccessDenied(render_view_host, params.request_id);
|
| + scoped_refptr<ExtensionFunction> function(CreateExtensionFunction(
|
| + params, extension, profile_->GetRuntimeId(),
|
| + render_view_host->process()->id(),
|
| + render_view_host, render_view_host->routing_id()));
|
| + if (!function)
|
| return;
|
| - }
|
|
|
| - scoped_refptr<ExtensionFunction> function(
|
| - FactoryRegistry::GetInstance()->NewFunction(params.name));
|
| UIThreadExtensionFunction* function_ui =
|
| function->AsUIThreadExtensionFunction();
|
| if (!function_ui) {
|
| @@ -498,14 +507,6 @@ void ExtensionFunctionDispatcher::Dispatch(
|
| function_ui->SetRenderViewHost(render_view_host);
|
| function_ui->set_dispatcher(AsWeakPtr());
|
| function_ui->set_profile(profile_);
|
| -
|
| - function->set_profile_id(profile_->GetRuntimeId());
|
| - function->set_extension(extension);
|
| - function->SetArgs(¶ms.arguments);
|
| - function->set_source_url(params.source_url);
|
| - function->set_request_id(params.request_id);
|
| - function->set_has_callback(params.has_callback);
|
| - function->set_user_gesture(params.user_gesture);
|
| function->set_include_incognito(service->CanCrossIncognito(extension));
|
|
|
| ExtensionsQuotaService* quota = service->quota_service();
|
| @@ -522,9 +523,59 @@ void ExtensionFunctionDispatcher::Dispatch(
|
| }
|
| }
|
|
|
| +// static
|
| +ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction(
|
| + const ExtensionHostMsg_Request_Params& params,
|
| + const Extension* extension,
|
| + ProfileId profile_id,
|
| + int render_process_id,
|
| + IPC::Message::Sender* ipc_sender,
|
| + int routing_id) {
|
| + // TODO(aa): It would be cool to use ExtensionProcessManager to track which
|
| + // processes are extension processes rather than ChildProcessSecurityPolicy.
|
| + // EPM has richer information: it not only knows which processes contain
|
| + // at least one extension, but it knows which extensions are inside and what
|
| + // permissions the have. So we would be able to enforce permissions more
|
| + // granularly.
|
| + if (!ChildProcessSecurityPolicy::GetInstance()->HasExtensionBindings(
|
| + render_process_id)) {
|
| + // TODO(aa): Allow content scripts access to low-threat extension APIs.
|
| + // See: crbug.com/80308.
|
| + LOG(ERROR) << "Extension API called from non-extension process.";
|
| + SendAccessDenied(ipc_sender, routing_id, params.request_id);
|
| + return NULL;
|
| + }
|
| +
|
| + if (!extension) {
|
| + LOG(ERROR) << "Extension does not exist for URL: "
|
| + << params.source_url.spec();
|
| + SendAccessDenied(ipc_sender, routing_id, params.request_id);
|
| + return NULL;
|
| + }
|
| +
|
| + if (!extension->HasApiPermission(params.name)) {
|
| + LOG(ERROR) << "Extension " << extension->id() << " does not have "
|
| + << "permission to function: " << params.name;
|
| + SendAccessDenied(ipc_sender, routing_id, params.request_id);
|
| + return NULL;
|
| + }
|
| +
|
| + ExtensionFunction* function =
|
| + FactoryRegistry::GetInstance()->NewFunction(params.name);
|
| + function->SetArgs(¶ms.arguments);
|
| + function->set_source_url(params.source_url);
|
| + function->set_request_id(params.request_id);
|
| + function->set_has_callback(params.has_callback);
|
| + function->set_user_gesture(params.user_gesture);
|
| + function->set_extension(extension);
|
| + function->set_profile_id(profile_id);
|
| + return function;
|
| +}
|
| +
|
| +// static
|
| void ExtensionFunctionDispatcher::SendAccessDenied(
|
| - RenderViewHost* render_view_host, int request_id) {
|
| - render_view_host->Send(new ExtensionMsg_Response(
|
| - render_view_host->routing_id(), request_id, false, std::string(),
|
| + IPC::Message::Sender* ipc_sender, int routing_id, int request_id) {
|
| + ipc_sender->Send(new ExtensionMsg_Response(
|
| + routing_id, request_id, false, std::string(),
|
| "Access to extension API denied."));
|
| }
|
|
|