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

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: '' 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 const char* kPredefinedAllowedSocketOrigins[] = { 111 const char* kPredefinedAllowedSocketOrigins[] = {
110 "okddffdblfhhnmhodogpojmfkjmhinfp", // Test SSH Client 112 "okddffdblfhhnmhodogpojmfkjmhinfp", // Test SSH Client
111 "pnhechapfaindjhompbnflcldabbghjo" // HTerm App (SSH Client) 113 "pnhechapfaindjhompbnflcldabbghjo" // HTerm App (SSH Client)
112 }; 114 };
113 115
114 static void AppendParams(const std::vector<string16>& additional_names, 116 static void AppendParams(const std::vector<string16>& additional_names,
115 const std::vector<string16>& additional_values, 117 const std::vector<string16>& additional_values,
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 // Delay loading plugins if prerendering. 384 // Delay loading plugins if prerendering.
383 if (prerender::PrerenderHelper::IsPrerendering(render_view)) { 385 if (prerender::PrerenderHelper::IsPrerendering(render_view)) {
384 placeholder = PluginPlaceholder::CreateBlockedPlugin( 386 placeholder = PluginPlaceholder::CreateBlockedPlugin(
385 render_view, frame, params, plugin, name, 387 render_view, frame, params, plugin, name,
386 IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD); 388 IDR_CLICK_TO_PLAY_PLUGIN_HTML, IDS_PLUGIN_LOAD);
387 placeholder->set_blocked_for_prerendering(true); 389 placeholder->set_blocked_for_prerendering(true);
388 placeholder->set_allow_loading(true); 390 placeholder->set_allow_loading(true);
389 break; 391 break;
390 } 392 }
391 393
392 // Determine if NaCl is allowed for both the internal plugin and
393 // any external plugin that handles our MIME type. This is so NaCl
394 // tests will still pass.
395 const char* kNaClMimeType = "application/x-nacl"; 394 const char* kNaClMimeType = "application/x-nacl";
396 bool is_nacl_mime_type = actual_mime_type == kNaClMimeType; 395 bool is_nacl_mime_type = actual_mime_type == kNaClMimeType;
397 bool is_nacl_enabled; 396 bool is_nacl_unrestricted;
398 if (is_nacl_plugin) { 397 if (is_nacl_plugin) {
399 is_nacl_enabled = CommandLine::ForCurrentProcess()->HasSwitch( 398 is_nacl_unrestricted = CommandLine::ForCurrentProcess()->HasSwitch(
400 switches::kEnableNaCl); 399 switches::kEnableNaCl);
401 } else { 400 } else {
402 // If this is an external plugin that handles NaCl mime type, 401 // If this is an external plugin that handles the NaCl mime type, we
403 // we want to allow Native Client, because it's how 402 // allow Native Client, so Native Client's integration tests work.
404 // NaCl tests for the plugin work. 403 is_nacl_unrestricted = true;
405 is_nacl_enabled = true;
406 } 404 }
407 if (is_nacl_plugin || is_nacl_mime_type) { 405 if (is_nacl_plugin || is_nacl_mime_type) {
408 if (!IsNaClAllowed(plugin, 406 GURL manifest_url = is_nacl_mime_type ?
409 url, 407 url : GetNaClContentHandlerURL(actual_mime_type, plugin);
410 actual_mime_type, 408 const Extension* extension =
411 is_nacl_mime_type, 409 extension_dispatcher_->extensions()->GetExtensionOrAppByURL(
412 is_nacl_enabled, 410 ExtensionURLInfo(manifest_url));
413 params)) { 411 bool is_extension_from_webstore =
412 extension && extension->from_webstore();
413 // Allow built-in extensions and extensions under development.
414 bool is_extension_unrestricted = extension &&
415 (extension->location() == Extension::COMPONENT ||
416 extension->location() == Extension::LOAD);
417 GURL top_url = frame->top()->document().url();
418 if (IsNaClAllowed(manifest_url,
419 top_url,
420 is_nacl_unrestricted,
421 is_extension_unrestricted,
422 is_extension_from_webstore,
423 params)) {
424 return render_view->CreatePlugin(frame, plugin, params);
425 } else {
414 frame->addMessageToConsole( 426 frame->addMessageToConsole(
415 WebConsoleMessage( 427 WebConsoleMessage(
416 WebConsoleMessage::LevelError, 428 WebConsoleMessage::LevelError,
417 "Only unpacked extensions and apps installed from the " 429 "Only unpacked extensions and apps installed from the "
418 "Chrome Web Store can load NaCl modules without enabling " 430 "Chrome Web Store can load NaCl modules without enabling "
419 "Native Client in about:flags.")); 431 "Native Client in about:flags."));
420 placeholder = PluginPlaceholder::CreateBlockedPlugin( 432 placeholder = PluginPlaceholder::CreateBlockedPlugin(
421 render_view, frame, params, plugin, name, 433 render_view, frame, params, plugin, name,
422 IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED); 434 IDR_BLOCKED_PLUGIN_HTML, IDS_PLUGIN_BLOCKED);
423 break;
424 } 435 }
425 } 436 }
426 return render_view->CreatePlugin(frame, plugin, params); 437 break;
427 } 438 }
428 case ChromeViewHostMsg_GetPluginInfo_Status::kDisabled: { 439 case ChromeViewHostMsg_GetPluginInfo_Status::kDisabled: {
429 placeholder = PluginPlaceholder::CreateBlockedPlugin( 440 placeholder = PluginPlaceholder::CreateBlockedPlugin(
430 render_view, frame, params, plugin, name, 441 render_view, frame, params, plugin, name,
431 IDR_DISABLED_PLUGIN_HTML, IDS_PLUGIN_DISABLED); 442 IDR_DISABLED_PLUGIN_HTML, IDS_PLUGIN_DISABLED);
432 break; 443 break;
433 } 444 }
434 case ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked: { 445 case ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked: {
435 #if defined(ENABLE_PLUGIN_INSTALLATION) 446 #if defined(ENABLE_PLUGIN_INSTALLATION)
436 placeholder = PluginPlaceholder::CreateBlockedPlugin( 447 placeholder = PluginPlaceholder::CreateBlockedPlugin(
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 RenderThread::Get()->RecordUserMetrics("Plugin_Blocked"); 488 RenderThread::Get()->RecordUserMetrics("Plugin_Blocked");
478 observer->DidBlockContentType(content_type, group->identifier()); 489 observer->DidBlockContentType(content_type, group->identifier());
479 break; 490 break;
480 } 491 }
481 } 492 }
482 } 493 }
483 placeholder->SetStatus(status); 494 placeholder->SetStatus(status);
484 return placeholder->plugin(); 495 return placeholder->plugin();
485 } 496 }
486 497
498 // For NaCl content handling plugins, the NaCl manifest is stored in an
499 // additonal 'nacl' param associated with the MIME type.
500 GURL ChromeContentRendererClient::GetNaClContentHandlerURL(
Mihai Parparita -not on Chrome 2012/02/17 01:19:13 Nit: static functions usually have a "// static" c
bbudge 2012/02/17 19:25:04 Done.
501 const std::string& actual_mime_type,
502 const webkit::WebPluginInfo& plugin) {
503 // Look for the manifest URL among the MIME type's additonal parameters.
504 const char* kNaClPluginManifestAttribute = "nacl";
505 string16 nacl_attr = ASCIIToUTF16(kNaClPluginManifestAttribute);
506 for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
507 if (plugin.mime_types[i].mime_type == actual_mime_type) {
508 const WebPluginMimeType& content_type = plugin.mime_types[i];
509 for (size_t i = 0; i < content_type.additional_param_names.size(); ++i) {
510 if (content_type.additional_param_names[i] == nacl_attr)
511 return GURL(content_type.additional_param_values[i]);
512 }
513 break;
514 }
515 }
516 return GURL();
517 }
518
487 bool ChromeContentRendererClient::IsNaClAllowed( 519 bool ChromeContentRendererClient::IsNaClAllowed(
488 const webkit::WebPluginInfo& plugin, 520 const GURL& manifest_url,
489 const GURL& url, 521 const GURL& top_url,
490 const std::string& actual_mime_type, 522 bool is_nacl_unrestricted,
491 bool is_nacl_mime_type, 523 bool is_extension_unrestricted,
492 bool enable_nacl, 524 bool is_extension_from_webstore,
493 WebKit::WebPluginParams& params) { 525 WebPluginParams& params) {
494 GURL manifest_url; 526 // Temporarily allow these URLs to run NaCl apps. We should remove this
495 if (is_nacl_mime_type) { 527 // code when PNaCl ships.
496 manifest_url = url; // Normal embedded NaCl plugin. 528 bool is_whitelisted_url =
497 } else { 529 ((top_url.SchemeIs("http") || top_url.SchemeIs("https")) &&
498 // This is a content type handling NaCl plugin; look for the .nexe URL 530 (top_url.host() == "plus.google.com" ||
499 // among the MIME type's additonal parameters. 531 top_url.host() == "plus.sandbox.google.com") &&
500 const char* kNaClPluginManifestAttribute = "nacl"; 532 top_url.path().find("/games") == 0);
501 string16 nacl_attr = ASCIIToUTF16(kNaClPluginManifestAttribute); 533
502 for (size_t i = 0; i < plugin.mime_types.size(); ++i) { 534 // Allow Chrome Web Store extensions, built-in extensions, extensions
503 if (plugin.mime_types[i].mime_type == actual_mime_type) { 535 // under development, invocations from whitelisted URLs, and all invocations
504 const webkit::WebPluginMimeType& content_type = 536 // if --enable-nacl is set.
505 plugin.mime_types[i]; 537 bool is_nacl_allowed =
506 for (size_t i = 0; 538 is_extension_from_webstore ||
507 i < content_type.additional_param_names.size(); ++i) { 539 is_extension_unrestricted ||
508 if (content_type.additional_param_names[i] == nacl_attr) { 540 is_whitelisted_url ||
509 manifest_url = GURL(content_type.additional_param_values[i]); 541 is_nacl_unrestricted;
510 break; 542 if (is_nacl_allowed) {
511 } 543 bool app_can_use_dev_interfaces =
512 } 544 // NaCl PDF viewer extension
513 break; 545 (is_extension_from_webstore &&
546 manifest_url.SchemeIs("chrome-extension") &&
547 manifest_url.host() == "acadkphlmlegjaadjagenfimbpphcgnh");
548 // Make sure that PPAPI 'dev' interfaces aren't available for production
549 // apps unless they're whitelisted.
550 WebString dev_attribute = WebString::fromUTF8("@dev");
551 if ((!is_whitelisted_url && !is_extension_from_webstore) ||
552 app_can_use_dev_interfaces) {
553 // Add the special '@dev' attribute.
554 std::vector<string16> param_names;
555 std::vector<string16> param_values;
556 param_names.push_back(dev_attribute);
557 param_values.push_back(WebString());
558 AppendParams(
559 param_names,
560 param_values,
561 &params.attributeNames,
562 &params.attributeValues);
563 } else {
564 // If the params somehow contain '@dev', remove it.
565 size_t attribute_count = params.attributeNames.size();
566 for (size_t i = 0; i < attribute_count; ++i) {
567 if (params.attributeNames[i].equals(dev_attribute))
568 params.attributeNames[i] = WebString();
514 } 569 }
515 } 570 }
516 } 571 }
517 572 return is_nacl_allowed;
518 // Determine if the manifest URL is part of an extension.
519 const Extension* extension =
520 extension_dispatcher_->extensions()->GetExtensionOrAppByURL(
521 ExtensionURLInfo(manifest_url));
522 // Only component, unpacked, and Chrome Web Store extensions are allowed.
523 bool allowed_extension = extension &&
524 (extension->from_webstore() ||
525 extension->location() == Extension::COMPONENT ||
526 extension->location() == Extension::LOAD);
527
528 // Block any other use of NaCl plugin, unless --enable-nacl is set.
529 if (!allowed_extension && !enable_nacl)
530 return false;
531
532 // Allow dev interfaces for non-extension apps.
533 bool allow_dev_interfaces = true;
534 if (allowed_extension) {
535 // Allow dev interfaces for component and unpacked extensions.
536 if (extension->location() != Extension::COMPONENT &&
537 extension->location() != Extension::LOAD) {
538 // Whitelist all other allowed extensions.
539 allow_dev_interfaces =
540 // PDF Viewer plugin
541 (manifest_url.scheme() == "chrome-extension" &&
542 manifest_url.host() == "acadkphlmlegjaadjagenfimbpphcgnh");
543 }
544 }
545
546 WebString dev_attribute = WebString::fromUTF8("@dev");
547 if (allow_dev_interfaces) {
548 std::vector<string16> param_names;
549 std::vector<string16> param_values;
550 param_names.push_back(dev_attribute);
551 param_values.push_back(WebString());
552 AppendParams(
553 param_names,
554 param_values,
555 &params.attributeNames,
556 &params.attributeValues);
557 } else {
558 // If the params somehow contain this special attribute, remove it.
559 size_t attribute_count = params.attributeNames.size();
560 for (size_t i = 0; i < attribute_count; ++i) {
561 if (params.attributeNames[i].equals(dev_attribute))
562 params.attributeNames[i] = WebString();
563 }
564 }
565
566 return true;
567 } 573 }
568 574
569 bool ChromeContentRendererClient::HasErrorPage(int http_status_code, 575 bool ChromeContentRendererClient::HasErrorPage(int http_status_code,
570 std::string* error_domain) { 576 std::string* error_domain) {
571 // Use an internal error page, if we have one for the status code. 577 // Use an internal error page, if we have one for the status code.
572 if (!LocalizedError::HasStrings(LocalizedError::kHttpErrorDomain, 578 if (!LocalizedError::HasStrings(LocalizedError::kHttpErrorDomain,
573 http_status_code)) { 579 http_status_code)) {
574 return false; 580 return false;
575 } 581 }
576 582
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 webkit::ppapi::PpapiInterfaceFactoryManager* factory_manager) { 866 webkit::ppapi::PpapiInterfaceFactoryManager* factory_manager) {
861 factory_manager->RegisterFactory(ChromePPAPIInterfaceFactory); 867 factory_manager->RegisterFactory(ChromePPAPIInterfaceFactory);
862 } 868 }
863 869
864 bool ChromeContentRendererClient::AllowSocketAPI(const GURL& url) { 870 bool ChromeContentRendererClient::AllowSocketAPI(const GURL& url) {
865 return allowed_socket_origins_.find(url.host()) != 871 return allowed_socket_origins_.find(url.host()) !=
866 allowed_socket_origins_.end(); 872 allowed_socket_origins_.end();
867 } 873 }
868 874
869 } // namespace chrome 875 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698