Home | History | Annotate | Download | only in extensions
      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 
     27 using content::PluginService;
     28 using content::WebContents;
     29 using extensions::Extension;
     30 using extensions::Manifest;
     31 
     32 namespace {
     33 
     34 const 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.
     38 class 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
    151 IN_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
    161 IN_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
    171 IN_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
    182 IN_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
    194 IN_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.
    205 IN_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