OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/chrome_content_renderer_client.h" | 5 #include "chrome/renderer/chrome_content_renderer_client.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 if (plugin_setting == CONTENT_SETTING_ALLOW || | 410 if (plugin_setting == CONTENT_SETTING_ALLOW || |
411 host_setting == CONTENT_SETTING_ALLOW || | 411 host_setting == CONTENT_SETTING_ALLOW || |
412 plugin.path.value() == webkit::npapi::kDefaultPluginLibraryName) { | 412 plugin.path.value() == webkit::npapi::kDefaultPluginLibraryName) { |
413 // Delay loading plugins if prerendering. | 413 // Delay loading plugins if prerendering. |
414 if (prerender::PrerenderHelper::IsPrerendering(render_view)) { | 414 if (prerender::PrerenderHelper::IsPrerendering(render_view)) { |
415 return CreatePluginPlaceholder( | 415 return CreatePluginPlaceholder( |
416 render_view, frame, plugin, params, group.get(), | 416 render_view, frame, plugin, params, group.get(), |
417 IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD, true, true); | 417 IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD, true, true); |
418 } | 418 } |
419 | 419 |
420 // Enforce the Chrome WebStore restriction on the Native Client plugin. | 420 if (is_nacl_plugin && |
421 if (is_nacl_plugin) { | 421 !IsNaClAllowed(plugin, |
422 bool allow_nacl = cmd->HasSwitch(switches::kEnableNaCl); | 422 url, |
423 if (!allow_nacl) { | 423 actual_mime_type, |
424 const char* kNaClPluginMimeType = "application/x-nacl"; | 424 cmd->HasSwitch(switches::kEnableNaCl), |
425 const char* kNaClPluginManifestAttribute = "nacl"; | 425 params)) { |
426 | |
427 GURL nexe_url; | |
428 if (actual_mime_type == kNaClPluginMimeType) { | |
429 nexe_url = url; // Normal embedded NaCl plugin. | |
430 } else { | |
431 // Content type handling NaCl plugin; the "nacl" param on the | |
432 // MIME type holds the nexe URL. | |
433 string16 nacl_attr = ASCIIToUTF16(kNaClPluginManifestAttribute); | |
434 for (size_t i = 0; i < plugin.mime_types.size(); ++i) { | |
435 if (plugin.mime_types[i].mime_type == actual_mime_type) { | |
436 const webkit::WebPluginMimeType& content_type = | |
437 plugin.mime_types[i]; | |
438 for (size_t i = 0; | |
439 i < content_type.additional_param_names.size(); ++i) { | |
440 if (content_type.additional_param_names[i] == nacl_attr) { | |
441 nexe_url = GURL(content_type.additional_param_values[i]); | |
442 break; | |
443 } | |
444 } | |
445 break; | |
446 } | |
447 } | |
448 } | |
449 | |
450 // Create the NaCl plugin only if the .nexe is part of an extension | |
451 // that was installed from the Chrome Web Store, or part of a component | |
452 // extension, or part of an unpacked extension. | |
453 const Extension* extension = | |
454 extension_dispatcher_->extensions()->GetByURL(nexe_url); | |
455 allow_nacl = extension && | |
456 (extension->from_webstore() || | |
457 extension->location() == Extension::COMPONENT || | |
458 extension->location() == Extension::LOAD); | |
459 } | |
460 | |
461 if (!allow_nacl) { | |
462 // TODO(bbudge) Webkit will crash if this is a full-frame plug-in and | |
463 // we return NULL. Prepare a patch to fix that, and return NULL here. | |
464 return CreatePluginPlaceholder( | 426 return CreatePluginPlaceholder( |
465 render_view, frame, plugin, params, group.get(), | 427 render_view, frame, plugin, params, group.get(), |
466 IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED, false, false); | 428 IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED, false, false); |
467 } | |
468 } | 429 } |
469 | 430 |
470 return render_view->CreatePlugin(frame, plugin, params); | 431 return render_view->CreatePlugin(frame, plugin, params); |
471 } | 432 } |
472 | 433 |
473 observer->DidBlockContentType(content_type, resource); | 434 observer->DidBlockContentType(content_type, resource); |
474 if (plugin_setting == CONTENT_SETTING_ASK) { | 435 if (plugin_setting == CONTENT_SETTING_ASK) { |
475 RenderThread::Get()->RecordUserMetrics("Plugin_ClickToPlay"); | 436 RenderThread::Get()->RecordUserMetrics("Plugin_ClickToPlay"); |
476 return CreatePluginPlaceholder( | 437 return CreatePluginPlaceholder( |
477 render_view, frame, plugin, params, group.get(), | 438 render_view, frame, plugin, params, group.get(), |
478 IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD, false, true); | 439 IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD, false, true); |
479 } else { | 440 } else { |
480 RenderThread::Get()->RecordUserMetrics("Plugin_Blocked"); | 441 RenderThread::Get()->RecordUserMetrics("Plugin_Blocked"); |
481 return CreatePluginPlaceholder( | 442 return CreatePluginPlaceholder( |
482 render_view, frame, plugin, params, group.get(), | 443 render_view, frame, plugin, params, group.get(), |
483 IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED, false, true); | 444 IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED, false, true); |
484 } | 445 } |
485 } | 446 } |
486 | 447 |
| 448 bool ChromeContentRendererClient::IsNaClAllowed( |
| 449 const webkit::WebPluginInfo& plugin, |
| 450 const GURL& url, |
| 451 const std::string& actual_mime_type, |
| 452 bool enable_nacl, |
| 453 WebKit::WebPluginParams& params) { |
| 454 const char* kNaClPluginMimeType = "application/x-nacl"; |
| 455 const char* kNaClPluginManifestAttribute = "nacl"; |
| 456 |
| 457 GURL manifest_url; |
| 458 if (actual_mime_type == kNaClPluginMimeType) { |
| 459 manifest_url = url; // Normal embedded NaCl plugin. |
| 460 } else { |
| 461 // This is a content type handling NaCl plugin; look for the .nexe URL |
| 462 // among the MIME type's additonal parameters. |
| 463 string16 nacl_attr = ASCIIToUTF16(kNaClPluginManifestAttribute); |
| 464 for (size_t i = 0; i < plugin.mime_types.size(); ++i) { |
| 465 if (plugin.mime_types[i].mime_type == actual_mime_type) { |
| 466 const webkit::WebPluginMimeType& content_type = |
| 467 plugin.mime_types[i]; |
| 468 for (size_t i = 0; |
| 469 i < content_type.additional_param_names.size(); ++i) { |
| 470 if (content_type.additional_param_names[i] == nacl_attr) { |
| 471 manifest_url = GURL(content_type.additional_param_values[i]); |
| 472 break; |
| 473 } |
| 474 } |
| 475 break; |
| 476 } |
| 477 } |
| 478 } |
| 479 |
| 480 // Determine if the manifest URL is part of an extension. |
| 481 const Extension* extension = |
| 482 extension_dispatcher_->extensions()->GetByURL(manifest_url); |
| 483 // Only component, unpacked, and Chrome Web Store extensions are allowed. |
| 484 bool allowed_extension = extension && |
| 485 (extension->from_webstore() || |
| 486 extension->location() == Extension::COMPONENT || |
| 487 extension->location() == Extension::LOAD); |
| 488 |
| 489 // Block any other use of NaCl plugin, unless --enable-nacl is set. |
| 490 if (!allowed_extension && !enable_nacl) |
| 491 return false; |
| 492 |
| 493 // Allow dev interfaces for non-extension apps. |
| 494 bool allow_dev_interfaces = true; |
| 495 if (allowed_extension) { |
| 496 // Allow dev interfaces for component and unpacked extensions. |
| 497 if (extension->location() != Extension::COMPONENT && |
| 498 extension->location() != Extension::LOAD) { |
| 499 // Whitelist all other allowed extensions. |
| 500 allow_dev_interfaces = |
| 501 // PDF Viewer plugin |
| 502 (manifest_url.scheme() == "chrome-extension" && |
| 503 manifest_url.host() == "acadkphlmlegjaadjagenfimbpphcgnh"); |
| 504 } |
| 505 } |
| 506 |
| 507 WebString dev_attribute = WebString::fromUTF8("@dev"); |
| 508 if (allow_dev_interfaces) { |
| 509 std::vector<string16> param_names; |
| 510 std::vector<string16> param_values; |
| 511 param_names.push_back(dev_attribute); |
| 512 param_values.push_back(WebString()); |
| 513 AppendParams( |
| 514 param_names, |
| 515 param_values, |
| 516 ¶ms.attributeNames, |
| 517 ¶ms.attributeValues); |
| 518 } else { |
| 519 // If the params somehow contain this special attribute, remove it. |
| 520 size_t attribute_count = params.attributeNames.size(); |
| 521 for (size_t i = 0; i < attribute_count; ++i) { |
| 522 if (params.attributeNames[i].equals(dev_attribute)) |
| 523 params.attributeNames[i] = WebString(); |
| 524 } |
| 525 } |
| 526 |
| 527 return true; |
| 528 } |
| 529 |
487 WebPlugin* ChromeContentRendererClient::CreatePluginPlaceholder( | 530 WebPlugin* ChromeContentRendererClient::CreatePluginPlaceholder( |
488 content::RenderView* render_view, | 531 content::RenderView* render_view, |
489 WebFrame* frame, | 532 WebFrame* frame, |
490 const webkit::WebPluginInfo& plugin, | 533 const webkit::WebPluginInfo& plugin, |
491 const WebPluginParams& params, | 534 const WebPluginParams& params, |
492 const webkit::npapi::PluginGroup* group, | 535 const webkit::npapi::PluginGroup* group, |
493 int resource_id, | 536 int resource_id, |
494 int message_id, | 537 int message_id, |
495 bool is_blocked_for_prerendering, | 538 bool is_blocked_for_prerendering, |
496 bool allow_loading) { | 539 bool allow_loading) { |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 it != extensions.end(); ++it) { | 856 it != extensions.end(); ++it) { |
814 if (it->second->HasAPIPermission(ExtensionAPIPermission::kExperimental) && | 857 if (it->second->HasAPIPermission(ExtensionAPIPermission::kExperimental) && |
815 it->second->name().find("Adblock") != std::string::npos && | 858 it->second->name().find("Adblock") != std::string::npos && |
816 it->second->name().find("Plus") != std::string::npos) | 859 it->second->name().find("Plus") != std::string::npos) |
817 return true; | 860 return true; |
818 } | 861 } |
819 return false; | 862 return false; |
820 } | 863 } |
821 | 864 |
822 } // namespace chrome | 865 } // namespace chrome |
OLD | NEW |