Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(655)

Side by Side Diff: chrome/renderer/chrome_content_renderer_client.cc

Issue 9368046: Allow NaCl for non web store apps if their top level URL is whitelisted. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Allow NaCl for non web store apps if their top level URL is whitelisted. Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 using WebKit::WebSecurityPolicy; 96 using WebKit::WebSecurityPolicy;
97 using WebKit::WebString; 97 using WebKit::WebString;
98 using WebKit::WebURL; 98 using WebKit::WebURL;
99 using WebKit::WebURLError; 99 using WebKit::WebURLError;
100 using WebKit::WebURLRequest; 100 using WebKit::WebURLRequest;
101 using WebKit::WebURLResponse; 101 using WebKit::WebURLResponse;
102 using WebKit::WebVector; 102 using WebKit::WebVector;
103 using autofill::AutofillAgent; 103 using autofill::AutofillAgent;
104 using autofill::PasswordAutofillManager; 104 using autofill::PasswordAutofillManager;
105 using content::RenderThread; 105 using content::RenderThread;
106 using webkit::WebPluginInfo;
107 using webkit::WebPluginMimeType;
106 108
107 namespace { 109 namespace {
108 110
109 static void AppendParams(const std::vector<string16>& additional_names, 111 static void AppendParams(const std::vector<string16>& additional_names,
110 const std::vector<string16>& additional_values, 112 const std::vector<string16>& additional_values,
111 WebVector<WebString>* existing_names, 113 WebVector<WebString>* existing_names,
112 WebVector<WebString>* existing_values) { 114 WebVector<WebString>* existing_values) {
113 DCHECK(additional_names.size() == additional_values.size()); 115 DCHECK(additional_names.size() == additional_values.size());
114 DCHECK(existing_names->size() == existing_values->size()); 116 DCHECK(existing_names->size() == existing_values->size());
115 117
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 // Delay loading plugins if prerendering. 367 // Delay loading plugins if prerendering.
366 if (prerender::PrerenderHelper::IsPrerendering(render_view)) { 368 if (prerender::PrerenderHelper::IsPrerendering(render_view)) {
367 placeholder = PluginPlaceholder::CreateBlockedPlugin( 369 placeholder = PluginPlaceholder::CreateBlockedPlugin(
368 render_view, frame, params, plugin, name, 370 render_view, frame, params, plugin, name,
369 IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD); 371 IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD);
370 placeholder->set_blocked_for_prerendering(true); 372 placeholder->set_blocked_for_prerendering(true);
371 placeholder->set_allow_loading(true); 373 placeholder->set_allow_loading(true);
372 break; 374 break;
373 } 375 }
374 376
375 // Determine if NaCl is allowed for both the internal plugin and
376 // any external plugin that handles our MIME type. This is so NaCl
377 // tests will still pass.
378 const char* kNaClMimeType = "application/x-nacl"; 377 const char* kNaClMimeType = "application/x-nacl";
379 bool is_nacl_mime_type = actual_mime_type == kNaClMimeType; 378 bool is_nacl_mime_type = actual_mime_type == kNaClMimeType;
380 bool is_nacl_enabled; 379 bool is_nacl_unrestricted;
381 if (is_nacl_plugin) { 380 if (is_nacl_plugin) {
382 is_nacl_enabled = CommandLine::ForCurrentProcess()->HasSwitch( 381 is_nacl_unrestricted = CommandLine::ForCurrentProcess()->HasSwitch(
383 switches::kEnableNaCl); 382 switches::kEnableNaCl);
384 } else { 383 } else {
385 // If this is an external plugin that handles NaCl mime type, 384 // If this is an external plugin that handles the NaCl mime type, we
386 // we want to allow Native Client, because it's how 385 // allow Native Client, so Native Client's integration tests work.
387 // NaCl tests for the plugin work. 386 is_nacl_unrestricted = true;
388 is_nacl_enabled = true;
389 } 387 }
390 if (is_nacl_plugin || is_nacl_mime_type) { 388 if (is_nacl_plugin || is_nacl_mime_type) {
391 if (!IsNaClAllowed(plugin, 389 GURL manifest_url = is_nacl_mime_type ?
392 url, 390 url : GetNaClContentHandlerURL(actual_mime_type, plugin);
393 actual_mime_type, 391 const Extension* extension =
394 is_nacl_mime_type, 392 extension_dispatcher_->extensions()->GetExtensionOrAppByURL(
395 is_nacl_enabled, 393 ExtensionURLInfo(manifest_url));
396 params)) { 394 bool is_extension_from_webstore =
395 extension && extension->from_webstore();
396 // Allow built-in extensions and extensions under development.
397 bool is_extension_unrestricted = extension &&
398 (extension->location() == Extension::COMPONENT ||
399 extension->location() == Extension::LOAD);
400 GURL top_url = frame->top()->document().url();
401 if (!IsNaClAllowed(manifest_url,
402 top_url,
403 is_nacl_unrestricted,
404 is_extension_unrestricted,
405 is_extension_from_webstore,
406 &params)) {
397 frame->addMessageToConsole( 407 frame->addMessageToConsole(
398 WebConsoleMessage( 408 WebConsoleMessage(
399 WebConsoleMessage::LevelError, 409 WebConsoleMessage::LevelError,
400 "Only unpacked extensions and apps installed from the " 410 "Only unpacked extensions and apps installed from the "
401 "Chrome Web Store can load NaCl modules without enabling " 411 "Chrome Web Store can load NaCl modules without enabling "
402 "Native Client in about:flags.")); 412 "Native Client in about:flags."));
403 placeholder = PluginPlaceholder::CreateBlockedPlugin( 413 placeholder = PluginPlaceholder::CreateBlockedPlugin(
404 render_view, frame, params, plugin, name, 414 render_view, frame, params, plugin, name,
405 IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED); 415 IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED);
406 break; 416 break;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 RenderThread::Get()->RecordUserMetrics("Plugin_Blocked"); 470 RenderThread::Get()->RecordUserMetrics("Plugin_Blocked");
461 observer->DidBlockContentType(content_type, group->identifier()); 471 observer->DidBlockContentType(content_type, group->identifier());
462 break; 472 break;
463 } 473 }
464 } 474 }
465 } 475 }
466 placeholder->SetStatus(status); 476 placeholder->SetStatus(status);
467 return placeholder->plugin(); 477 return placeholder->plugin();
468 } 478 }
469 479
480 // For NaCl content handling plugins, the NaCl manifest is stored in an
481 // additonal 'nacl' param associated with the MIME type.
482 // static
483 GURL ChromeContentRendererClient::GetNaClContentHandlerURL(
484 const std::string& actual_mime_type,
485 const webkit::WebPluginInfo& plugin) {
486 // Look for the manifest URL among the MIME type's additonal parameters.
487 const char* kNaClPluginManifestAttribute = "nacl";
488 string16 nacl_attr = ASCIIToUTF16(kNaClPluginManifestAttribute);
489 for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
490 if (plugin.mime_types[i].mime_type == actual_mime_type) {
491 const WebPluginMimeType& content_type = plugin.mime_types[i];
492 for (size_t i = 0; i < content_type.additional_param_names.size(); ++i) {
493 if (content_type.additional_param_names[i] == nacl_attr)
494 return GURL(content_type.additional_param_values[i]);
495 }
496 break;
497 }
498 }
499 return GURL();
500 }
501
502 // static
470 bool ChromeContentRendererClient::IsNaClAllowed( 503 bool ChromeContentRendererClient::IsNaClAllowed(
471 const webkit::WebPluginInfo& plugin, 504 const GURL& manifest_url,
472 const GURL& url, 505 const GURL& top_url,
473 const std::string& actual_mime_type, 506 bool is_nacl_unrestricted,
474 bool is_nacl_mime_type, 507 bool is_extension_unrestricted,
475 bool enable_nacl, 508 bool is_extension_from_webstore,
476 WebKit::WebPluginParams& params) { 509 WebPluginParams* params) {
477 GURL manifest_url; 510 // Temporarily allow these URLs to run NaCl apps. We should remove this
478 if (is_nacl_mime_type) { 511 // code when PNaCl ships.
479 manifest_url = url; // Normal embedded NaCl plugin. 512 bool is_whitelisted_url =
480 } else { 513 ((top_url.SchemeIs("http") || top_url.SchemeIs("https")) &&
481 // This is a content type handling NaCl plugin; look for the .nexe URL 514 (top_url.host() == "plus.google.com" ||
482 // among the MIME type's additonal parameters. 515 top_url.host() == "plus.sandbox.google.com") &&
483 const char* kNaClPluginManifestAttribute = "nacl"; 516 top_url.path().find("/games") == 0);
484 string16 nacl_attr = ASCIIToUTF16(kNaClPluginManifestAttribute); 517
485 for (size_t i = 0; i < plugin.mime_types.size(); ++i) { 518 // Allow Chrome Web Store extensions, built-in extensions, extensions
486 if (plugin.mime_types[i].mime_type == actual_mime_type) { 519 // under development, invocations from whitelisted URLs, and all invocations
487 const webkit::WebPluginMimeType& content_type = 520 // if --enable-nacl is set.
488 plugin.mime_types[i]; 521 bool is_nacl_allowed =
489 for (size_t i = 0; 522 is_extension_from_webstore ||
490 i < content_type.additional_param_names.size(); ++i) { 523 is_extension_unrestricted ||
491 if (content_type.additional_param_names[i] == nacl_attr) { 524 is_whitelisted_url ||
492 manifest_url = GURL(content_type.additional_param_values[i]); 525 is_nacl_unrestricted;
493 break; 526 if (is_nacl_allowed) {
494 } 527 bool app_can_use_dev_interfaces =
495 } 528 // NaCl PDF viewer extension
496 break; 529 (is_extension_from_webstore &&
530 manifest_url.SchemeIs("chrome-extension") &&
531 manifest_url.host() == "acadkphlmlegjaadjagenfimbpphcgnh");
532 // Make sure that PPAPI 'dev' interfaces aren't available for production
533 // apps unless they're whitelisted.
534 WebString dev_attribute = WebString::fromUTF8("@dev");
535 if ((!is_whitelisted_url && !is_extension_from_webstore) ||
536 app_can_use_dev_interfaces) {
537 // Add the special '@dev' attribute.
538 std::vector<string16> param_names;
539 std::vector<string16> param_values;
540 param_names.push_back(dev_attribute);
541 param_values.push_back(WebString());
542 AppendParams(
543 param_names,
544 param_values,
545 &params->attributeNames,
546 &params->attributeValues);
547 } else {
548 // If the params somehow contain '@dev', remove it.
549 size_t attribute_count = params->attributeNames.size();
550 for (size_t i = 0; i < attribute_count; ++i) {
551 if (params->attributeNames[i].equals(dev_attribute))
552 params->attributeNames[i] = WebString();
497 } 553 }
498 } 554 }
499 } 555 }
500 556 return is_nacl_allowed;
501 // Determine if the manifest URL is part of an extension.
502 const Extension* extension =
503 extension_dispatcher_->extensions()->GetExtensionOrAppByURL(
504 ExtensionURLInfo(manifest_url));
505 // Only component, unpacked, and Chrome Web Store extensions are allowed.
506 bool allowed_extension = extension &&
507 (extension->from_webstore() ||
508 extension->location() == Extension::COMPONENT ||
509 extension->location() == Extension::LOAD);
510
511 // Block any other use of NaCl plugin, unless --enable-nacl is set.
512 if (!allowed_extension && !enable_nacl)
513 return false;
514
515 // Allow dev interfaces for non-extension apps.
516 bool allow_dev_interfaces = true;
517 if (allowed_extension) {
518 // Allow dev interfaces for component and unpacked extensions.
519 if (extension->location() != Extension::COMPONENT &&
520 extension->location() != Extension::LOAD) {
521 // Whitelist all other allowed extensions.
522 allow_dev_interfaces =
523 // PDF Viewer plugin
524 (manifest_url.scheme() == "chrome-extension" &&
525 manifest_url.host() == "acadkphlmlegjaadjagenfimbpphcgnh");
526 }
527 }
528
529 WebString dev_attribute = WebString::fromUTF8("@dev");
530 if (allow_dev_interfaces) {
531 std::vector<string16> param_names;
532 std::vector<string16> param_values;
533 param_names.push_back(dev_attribute);
534 param_values.push_back(WebString());
535 AppendParams(
536 param_names,
537 param_values,
538 &params.attributeNames,
539 &params.attributeValues);
540 } else {
541 // If the params somehow contain this special attribute, remove it.
542 size_t attribute_count = params.attributeNames.size();
543 for (size_t i = 0; i < attribute_count; ++i) {
544 if (params.attributeNames[i].equals(dev_attribute))
545 params.attributeNames[i] = WebString();
546 }
547 }
548
549 return true;
550 } 557 }
551 558
552 bool ChromeContentRendererClient::HasErrorPage(int http_status_code, 559 bool ChromeContentRendererClient::HasErrorPage(int http_status_code,
553 std::string* error_domain) { 560 std::string* error_domain) {
554 // Use an internal error page, if we have one for the status code. 561 // Use an internal error page, if we have one for the status code.
555 if (!LocalizedError::HasStrings(LocalizedError::kHttpErrorDomain, 562 if (!LocalizedError::HasStrings(LocalizedError::kHttpErrorDomain,
556 http_status_code)) { 563 http_status_code)) {
557 return false; 564 return false;
558 } 565 }
559 566
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 bool ChromeContentRendererClient::IsOtherExtensionWithWebRequestInstalled() { 845 bool ChromeContentRendererClient::IsOtherExtensionWithWebRequestInstalled() {
839 return extension_dispatcher_->IsOtherExtensionWithWebRequestInstalled(); 846 return extension_dispatcher_->IsOtherExtensionWithWebRequestInstalled();
840 } 847 }
841 848
842 void ChromeContentRendererClient::RegisterPPAPIInterfaceFactories( 849 void ChromeContentRendererClient::RegisterPPAPIInterfaceFactories(
843 webkit::ppapi::PpapiInterfaceFactoryManager* factory_manager) { 850 webkit::ppapi::PpapiInterfaceFactoryManager* factory_manager) {
844 factory_manager->RegisterFactory(ChromePPAPIInterfaceFactory); 851 factory_manager->RegisterFactory(ChromePPAPIInterfaceFactory);
845 } 852 }
846 853
847 } // namespace chrome 854 } // namespace chrome
OLDNEW
« no previous file with comments | « chrome/renderer/chrome_content_renderer_client.h ('k') | chrome/renderer/chrome_content_renderer_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698