| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_function_dispatcher.h" | 5 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/json/json_string_value_serializer.h" | 9 #include "base/json/json_string_value_serializer.h" |
| 10 #include "base/lazy_instance.h" | |
| 11 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| 12 #include "base/process_util.h" | 11 #include "base/process_util.h" |
| 13 #include "base/values.h" | 12 #include "base/values.h" |
| 14 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 15 #include "chrome/browser/extensions/extension_activity_log.h" | 14 #include "chrome/browser/extensions/extension_activity_log.h" |
| 16 #include "chrome/browser/extensions/extension_function.h" | 15 #include "chrome/browser/extensions/extension_function.h" |
| 17 #include "chrome/browser/extensions/extension_function_registry.h" | 16 #include "chrome/browser/extensions/extension_function_registry.h" |
| 18 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| 19 #include "chrome/browser/extensions/extension_web_ui.h" | 18 #include "chrome/browser/extensions/extension_web_ui.h" |
| 20 #include "chrome/browser/extensions/extensions_quota_service.h" | 19 #include "chrome/browser/extensions/extensions_quota_service.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 33 #include "ipc/ipc_message.h" | 32 #include "ipc/ipc_message.h" |
| 34 #include "ipc/ipc_message_macros.h" | 33 #include "ipc/ipc_message_macros.h" |
| 35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" | 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
| 36 #include "third_party/skia/include/core/SkBitmap.h" | 35 #include "third_party/skia/include/core/SkBitmap.h" |
| 37 #include "webkit/glue/resource_type.h" | 36 #include "webkit/glue/resource_type.h" |
| 38 | 37 |
| 39 using extensions::ExtensionAPI; | 38 using extensions::ExtensionAPI; |
| 40 using content::RenderViewHost; | 39 using content::RenderViewHost; |
| 41 using WebKit::WebSecurityOrigin; | 40 using WebKit::WebSecurityOrigin; |
| 42 | 41 |
| 43 namespace { | |
| 44 | |
| 45 const char kAccessDenied[] = "access denied"; | 42 const char kAccessDenied[] = "access denied"; |
| 46 const char kQuotaExceeded[] = "quota exceeded"; | 43 const char kQuotaExceeded[] = "quota exceeded"; |
| 47 | 44 |
| 48 void LogSuccess(const Extension* extension, | 45 void LogSuccess(const Extension* extension, |
| 49 const ExtensionHostMsg_Request_Params& params) { | 46 const ExtensionHostMsg_Request_Params& params) { |
| 50 ExtensionActivityLog* extension_activity_log = | 47 ExtensionActivityLog* extension_activity_log = |
| 51 ExtensionActivityLog::GetInstance(); | 48 ExtensionActivityLog::GetInstance(); |
| 52 if (extension_activity_log->HasObservers(extension)) { | 49 if (extension_activity_log->HasObservers(extension)) { |
| 53 std::string call_signature = params.name + "("; | 50 std::string call_signature = params.name + "("; |
| 54 ListValue::const_iterator it = params.arguments.begin(); | 51 ListValue::const_iterator it = params.arguments.begin(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 76 ExtensionActivityLog* extension_activity_log = | 73 ExtensionActivityLog* extension_activity_log = |
| 77 ExtensionActivityLog::GetInstance(); | 74 ExtensionActivityLog::GetInstance(); |
| 78 if (extension_activity_log->HasObservers(extension)) { | 75 if (extension_activity_log->HasObservers(extension)) { |
| 79 extension_activity_log->Log( | 76 extension_activity_log->Log( |
| 80 extension, | 77 extension, |
| 81 ExtensionActivityLog::ACTIVITY_EXTENSION_API_BLOCK, | 78 ExtensionActivityLog::ACTIVITY_EXTENSION_API_BLOCK, |
| 82 func_name + ": " + reason); | 79 func_name + ": " + reason); |
| 83 } | 80 } |
| 84 } | 81 } |
| 85 | 82 |
| 86 // Separate copy of ExtensionAPI used for IO thread extension functions. We need | |
| 87 // this because ExtensionAPI has mutable data. It should be possible to remove | |
| 88 // this once all the extension APIs are updated to the feature system. | |
| 89 struct Static { | |
| 90 Static() | |
| 91 : api(extensions::ExtensionAPI::CreateWithDefaultConfiguration()) { | |
| 92 } | |
| 93 scoped_ptr<extensions::ExtensionAPI> api; | |
| 94 }; | |
| 95 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; | |
| 96 | |
| 97 } // namespace | |
| 98 | |
| 99 | |
| 100 void ExtensionFunctionDispatcher::GetAllFunctionNames( | 83 void ExtensionFunctionDispatcher::GetAllFunctionNames( |
| 101 std::vector<std::string>* names) { | 84 std::vector<std::string>* names) { |
| 102 ExtensionFunctionRegistry::GetInstance()->GetAllNames(names); | 85 ExtensionFunctionRegistry::GetInstance()->GetAllNames(names); |
| 103 } | 86 } |
| 104 | 87 |
| 105 bool ExtensionFunctionDispatcher::OverrideFunction( | 88 bool ExtensionFunctionDispatcher::OverrideFunction( |
| 106 const std::string& name, ExtensionFunctionFactory factory) { | 89 const std::string& name, ExtensionFunctionFactory factory) { |
| 107 return ExtensionFunctionRegistry::GetInstance()->OverrideFunction(name, | 90 return ExtensionFunctionRegistry::GetInstance()->OverrideFunction(name, |
| 108 factory); | 91 factory); |
| 109 } | 92 } |
| 110 | 93 |
| 111 void ExtensionFunctionDispatcher::ResetFunctions() { | 94 void ExtensionFunctionDispatcher::ResetFunctions() { |
| 112 ExtensionFunctionRegistry::GetInstance()->ResetFunctions(); | 95 ExtensionFunctionRegistry::GetInstance()->ResetFunctions(); |
| 113 } | 96 } |
| 114 | 97 |
| 115 // static | 98 // static |
| 116 void ExtensionFunctionDispatcher::DispatchOnIOThread( | 99 void ExtensionFunctionDispatcher::DispatchOnIOThread( |
| 117 ExtensionInfoMap* extension_info_map, | 100 ExtensionInfoMap* extension_info_map, |
| 118 void* profile, | 101 void* profile, |
| 119 int render_process_id, | 102 int render_process_id, |
| 120 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender, | 103 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender, |
| 121 int routing_id, | 104 int routing_id, |
| 122 const ExtensionHostMsg_Request_Params& params) { | 105 const ExtensionHostMsg_Request_Params& params) { |
| 123 const Extension* extension = | 106 const Extension* extension = |
| 124 extension_info_map->extensions().GetByID(params.extension_id); | 107 extension_info_map->extensions().GetByID(params.extension_id); |
| 125 | 108 |
| 126 scoped_refptr<ExtensionFunction> function( | 109 scoped_refptr<ExtensionFunction> function( |
| 127 CreateExtensionFunction(params, extension, render_process_id, | 110 CreateExtensionFunction(params, extension, render_process_id, |
| 128 extension_info_map->process_map(), | 111 extension_info_map->process_map(), profile, |
| 129 g_global_io_data.Get().api.get(), | |
| 130 profile, | |
| 131 ipc_sender, routing_id)); | 112 ipc_sender, routing_id)); |
| 132 if (!function) { | 113 if (!function) { |
| 133 LogFailure(extension, params.name, kAccessDenied); | 114 LogFailure(extension, params.name, kAccessDenied); |
| 134 return; | 115 return; |
| 135 } | 116 } |
| 136 | 117 |
| 137 IOThreadExtensionFunction* function_io = | 118 IOThreadExtensionFunction* function_io = |
| 138 function->AsIOThreadExtensionFunction(); | 119 function->AsIOThreadExtensionFunction(); |
| 139 if (!function_io) { | 120 if (!function_io) { |
| 140 NOTREACHED(); | 121 NOTREACHED(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 params.extension_id); | 184 params.extension_id); |
| 204 if (!extension) | 185 if (!extension) |
| 205 extension = service->extensions()->GetHostedAppByURL(ExtensionURLInfo( | 186 extension = service->extensions()->GetHostedAppByURL(ExtensionURLInfo( |
| 206 WebSecurityOrigin::createFromString(params.source_origin), | 187 WebSecurityOrigin::createFromString(params.source_origin), |
| 207 params.source_url)); | 188 params.source_url)); |
| 208 | 189 |
| 209 scoped_refptr<ExtensionFunction> function( | 190 scoped_refptr<ExtensionFunction> function( |
| 210 CreateExtensionFunction(params, extension, | 191 CreateExtensionFunction(params, extension, |
| 211 render_view_host->GetProcess()->GetID(), | 192 render_view_host->GetProcess()->GetID(), |
| 212 *(service->process_map()), | 193 *(service->process_map()), |
| 213 extensions::ExtensionAPI::GetSharedInstance(), | |
| 214 profile(), render_view_host, | 194 profile(), render_view_host, |
| 215 render_view_host->GetRoutingID())); | 195 render_view_host->GetRoutingID())); |
| 216 if (!function) { | 196 if (!function) { |
| 217 LogFailure(extension, params.name, kAccessDenied); | 197 LogFailure(extension, params.name, kAccessDenied); |
| 218 return; | 198 return; |
| 219 } | 199 } |
| 220 | 200 |
| 221 UIThreadExtensionFunction* function_ui = | 201 UIThreadExtensionFunction* function_ui = |
| 222 function->AsUIThreadExtensionFunction(); | 202 function->AsUIThreadExtensionFunction(); |
| 223 if (!function_ui) { | 203 if (!function_ui) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 profile()->GetExtensionProcessManager()->DecrementLazyKeepaliveCount( | 235 profile()->GetExtensionProcessManager()->DecrementLazyKeepaliveCount( |
| 256 extension); | 236 extension); |
| 257 } | 237 } |
| 258 | 238 |
| 259 // static | 239 // static |
| 260 ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( | 240 ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( |
| 261 const ExtensionHostMsg_Request_Params& params, | 241 const ExtensionHostMsg_Request_Params& params, |
| 262 const Extension* extension, | 242 const Extension* extension, |
| 263 int requesting_process_id, | 243 int requesting_process_id, |
| 264 const extensions::ProcessMap& process_map, | 244 const extensions::ProcessMap& process_map, |
| 265 extensions::ExtensionAPI* api, | |
| 266 void* profile, | 245 void* profile, |
| 267 IPC::Message::Sender* ipc_sender, | 246 IPC::Message::Sender* ipc_sender, |
| 268 int routing_id) { | 247 int routing_id) { |
| 269 if (!extension) { | 248 if (!extension) { |
| 270 LOG(ERROR) << "Specified extension does not exist."; | 249 LOG(ERROR) << "Specified extension does not exist."; |
| 271 SendAccessDenied(ipc_sender, routing_id, params.request_id); | 250 SendAccessDenied(ipc_sender, routing_id, params.request_id); |
| 272 return NULL; | 251 return NULL; |
| 273 } | 252 } |
| 274 | 253 |
| 275 if (api->IsPrivileged(params.name) && | 254 if (ExtensionAPI::GetInstance()->IsPrivileged(params.name) && |
| 276 !process_map.Contains(extension->id(), requesting_process_id)) { | 255 !process_map.Contains(extension->id(), requesting_process_id)) { |
| 277 LOG(ERROR) << "Extension API called from incorrect process " | 256 LOG(ERROR) << "Extension API called from incorrect process " |
| 278 << requesting_process_id | 257 << requesting_process_id |
| 279 << " from URL " << params.source_url.spec(); | 258 << " from URL " << params.source_url.spec(); |
| 280 SendAccessDenied(ipc_sender, routing_id, params.request_id); | 259 SendAccessDenied(ipc_sender, routing_id, params.request_id); |
| 281 return NULL; | 260 return NULL; |
| 282 } | 261 } |
| 283 | 262 |
| 284 if (!extension->HasAPIPermission(params.name)) { | 263 if (!extension->HasAPIPermission(params.name)) { |
| 285 LOG(ERROR) << "Extension " << extension->id() << " does not have " | 264 LOG(ERROR) << "Extension " << extension->id() << " does not have " |
| (...skipping 14 matching lines...) Expand all Loading... |
| 300 return function; | 279 return function; |
| 301 } | 280 } |
| 302 | 281 |
| 303 // static | 282 // static |
| 304 void ExtensionFunctionDispatcher::SendAccessDenied( | 283 void ExtensionFunctionDispatcher::SendAccessDenied( |
| 305 IPC::Message::Sender* ipc_sender, int routing_id, int request_id) { | 284 IPC::Message::Sender* ipc_sender, int routing_id, int request_id) { |
| 306 ipc_sender->Send(new ExtensionMsg_Response( | 285 ipc_sender->Send(new ExtensionMsg_Response( |
| 307 routing_id, request_id, false, std::string(), | 286 routing_id, request_id, false, std::string(), |
| 308 "Access to extension API denied.")); | 287 "Access to extension API denied.")); |
| 309 } | 288 } |
| OLD | NEW |