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 3// found in the LICENSE file. 4 5#include "base/command_line.h" 6#include "base/files/file_path.h" 7#include "base/path_service.h" 8#include "base/prefs/pref_service.h" 9#include "base/strings/utf_string_conversions.h" 10#include "chrome/browser/extensions/crx_installer.h" 11#include "chrome/browser/extensions/extension_browsertest.h" 12#include "chrome/browser/extensions/extension_service.h" 13#include "chrome/browser/profiles/profile.h" 14#include "chrome/browser/ui/browser.h" 15#include "chrome/browser/ui/tabs/tab_strip_model.h" 16#include "chrome/common/chrome_paths.h" 17#include "chrome/common/chrome_switches.h" 18#include "chrome/common/pref_names.h" 19#include "chrome/test/base/ui_test_utils.h" 20#include "content/public/browser/plugin_service.h" 21#include "content/public/browser/web_contents.h" 22#include "content/public/common/webplugininfo.h" 23#include "content/public/test/browser_test_utils.h" 24#include "extensions/browser/extension_system.h" 25#include "net/dns/mock_host_resolver.h" 26 27using content::PluginService; 28using content::WebContents; 29using extensions::Extension; 30using extensions::Manifest; 31 32namespace { 33 34const char* kExtensionId = "bjjcibdiodkkeanflmiijlcfieiemced"; 35 36// This class tests that the Native Client plugin is blocked unless the 37// .nexe is part of an extension from the Chrome Webstore. 38class NaClExtensionTest : public ExtensionBrowserTest { 39 public: 40 NaClExtensionTest() {} 41 42 protected: 43 enum InstallType { 44 INSTALL_TYPE_COMPONENT, 45 INSTALL_TYPE_UNPACKED, 46 INSTALL_TYPE_FROM_WEBSTORE, 47 INSTALL_TYPE_NON_WEBSTORE, 48 }; 49 enum PluginType { 50 PLUGIN_TYPE_NONE = 0, 51 PLUGIN_TYPE_EMBED = 1, 52 PLUGIN_TYPE_CONTENT_HANDLER = 2, 53 PLUGIN_TYPE_ALL = PLUGIN_TYPE_EMBED | 54 PLUGIN_TYPE_CONTENT_HANDLER, 55 }; 56 57 58 const Extension* InstallExtension(const base::FilePath& file_path, 59 InstallType install_type) { 60 ExtensionService* service = extensions::ExtensionSystem::Get( 61 browser()->profile())->extension_service(); 62 const Extension* extension = NULL; 63 switch (install_type) { 64 case INSTALL_TYPE_COMPONENT: 65 if (LoadExtensionAsComponent(file_path)) { 66 extension = service->GetExtensionById(kExtensionId, false); 67 } 68 break; 69 70 case INSTALL_TYPE_UNPACKED: 71 // Install the extension from a folder so it's unpacked. 72 if (LoadExtension(file_path)) { 73 extension = service->GetExtensionById(kExtensionId, false); 74 } 75 break; 76 77 case INSTALL_TYPE_FROM_WEBSTORE: 78 // Install native_client.crx from the webstore. 79 if (InstallExtensionFromWebstore(file_path, 1)) { 80 extension = service->GetExtensionById(last_loaded_extension_id(), 81 false); 82 } 83 break; 84 85 case INSTALL_TYPE_NON_WEBSTORE: 86 // Install native_client.crx but not from the webstore. 87 if (ExtensionBrowserTest::InstallExtension(file_path, 1)) { 88 extension = service->GetExtensionById(last_loaded_extension_id(), 89 false); 90 } 91 break; 92 } 93 return extension; 94 } 95 96 const Extension* InstallExtension(InstallType install_type) { 97 base::FilePath file_path = test_data_dir_.AppendASCII("native_client"); 98 return InstallExtension(file_path, install_type); 99 } 100 101 const Extension* InstallHostedApp() { 102 base::FilePath file_path = test_data_dir_.AppendASCII( 103 "native_client_hosted_app"); 104 return InstallExtension(file_path, INSTALL_TYPE_FROM_WEBSTORE); 105 } 106 107 bool IsNaClPluginLoaded() { 108 base::FilePath path; 109 if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) { 110 content::WebPluginInfo info; 111 return PluginService::GetInstance()->GetPluginInfoByPath(path, &info); 112 } 113 return false; 114 } 115 116 void CheckPluginsCreated(const GURL& url, PluginType expected_to_succeed) { 117 ui_test_utils::NavigateToURL(browser(), url); 118 // Don't run tests if the NaCl plugin isn't loaded. 119 if (!IsNaClPluginLoaded()) 120 return; 121 122 bool embedded_plugin_created = false; 123 bool content_handler_plugin_created = false; 124 WebContents* web_contents = 125 browser()->tab_strip_model()->GetActiveWebContents(); 126 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 127 web_contents, 128 "window.domAutomationController.send(EmbeddedPluginCreated());", 129 &embedded_plugin_created)); 130 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 131 web_contents, 132 "window.domAutomationController.send(ContentHandlerPluginCreated());", 133 &content_handler_plugin_created)); 134 135 EXPECT_EQ(embedded_plugin_created, 136 (expected_to_succeed & PLUGIN_TYPE_EMBED) != 0); 137 EXPECT_EQ(content_handler_plugin_created, 138 (expected_to_succeed & PLUGIN_TYPE_CONTENT_HANDLER) != 0); 139 } 140 141 void CheckPluginsCreated(const Extension* extension, 142 PluginType expected_to_succeed) { 143 CheckPluginsCreated(extension->GetResourceURL("test.html"), 144 expected_to_succeed); 145 } 146 147}; 148 149// Test that the NaCl plugin isn't blocked for Webstore extensions. 150// Disabled: http://crbug.com/319892 151IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_WebStoreExtension) { 152 ASSERT_TRUE(test_server()->Start()); 153 154 const Extension* extension = InstallExtension(INSTALL_TYPE_FROM_WEBSTORE); 155 ASSERT_TRUE(extension); 156 CheckPluginsCreated(extension, PLUGIN_TYPE_ALL); 157} 158 159// Test that the NaCl plugin is blocked for non-Webstore extensions. 160// Disabled: http://crbug.com/319892 161IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_NonWebStoreExtension) { 162 ASSERT_TRUE(test_server()->Start()); 163 164 const Extension* extension = InstallExtension(INSTALL_TYPE_NON_WEBSTORE); 165 ASSERT_TRUE(extension); 166 CheckPluginsCreated(extension, PLUGIN_TYPE_NONE); 167} 168 169// Test that the NaCl plugin isn't blocked for component extensions. 170// Disabled: http://crbug.com/319892 171IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_ComponentExtension) { 172 ASSERT_TRUE(test_server()->Start()); 173 174 const Extension* extension = InstallExtension(INSTALL_TYPE_COMPONENT); 175 ASSERT_TRUE(extension); 176 ASSERT_EQ(extension->location(), Manifest::COMPONENT); 177 CheckPluginsCreated(extension, PLUGIN_TYPE_ALL); 178} 179 180// Test that the NaCl plugin isn't blocked for unpacked extensions. 181// Disabled: http://crbug.com/319892 182IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_UnpackedExtension) { 183 ASSERT_TRUE(test_server()->Start()); 184 185 const Extension* extension = InstallExtension(INSTALL_TYPE_UNPACKED); 186 ASSERT_TRUE(extension); 187 ASSERT_EQ(extension->location(), Manifest::UNPACKED); 188 CheckPluginsCreated(extension, PLUGIN_TYPE_ALL); 189} 190 191// Test that the NaCl plugin is blocked for non chrome-extension urls, except 192// if it's a content (MIME type) handler. 193// Disabled: http://crbug.com/319892 194IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_NonExtensionScheme) { 195 ASSERT_TRUE(test_server()->Start()); 196 197 const Extension* extension = InstallExtension(INSTALL_TYPE_FROM_WEBSTORE); 198 ASSERT_TRUE(extension); 199 CheckPluginsCreated( 200 test_server()->GetURL("files/extensions/native_client/test.html"), 201 PLUGIN_TYPE_CONTENT_HANDLER); 202} 203 204// Test that NaCl plugin isn't blocked for hosted app URLs. 205IN_PROC_BROWSER_TEST_F(NaClExtensionTest, HostedApp) { 206 host_resolver()->AddRule("*", "127.0.0.1"); 207 ASSERT_TRUE(test_server()->Start()); 208 209 GURL url = test_server()->GetURL("files/extensions/native_client/test.html"); 210 GURL::Replacements replace_host; 211 std::string host_str("localhost"); 212 replace_host.SetHostStr(host_str); 213 replace_host.ClearPort(); 214 url = url.ReplaceComponents(replace_host); 215 216 const Extension* extension = InstallHostedApp(); 217 ASSERT_TRUE(extension); 218 CheckPluginsCreated(url, PLUGIN_TYPE_ALL); 219} 220 221} // namespace 222