普通文本  |  222行  |  7.76 KB

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test_utils.h"
#include "extensions/browser/extension_system.h"
#include "net/dns/mock_host_resolver.h"

using content::PluginService;
using content::WebContents;
using extensions::Extension;
using extensions::Manifest;

namespace {

const char* kExtensionId = "bjjcibdiodkkeanflmiijlcfieiemced";

// This class tests that the Native Client plugin is blocked unless the
// .nexe is part of an extension from the Chrome Webstore.
class NaClExtensionTest : public ExtensionBrowserTest {
 public:
  NaClExtensionTest() {}

 protected:
  enum InstallType {
    INSTALL_TYPE_COMPONENT,
    INSTALL_TYPE_UNPACKED,
    INSTALL_TYPE_FROM_WEBSTORE,
    INSTALL_TYPE_NON_WEBSTORE,
  };
  enum PluginType {
    PLUGIN_TYPE_NONE = 0,
    PLUGIN_TYPE_EMBED = 1,
    PLUGIN_TYPE_CONTENT_HANDLER = 2,
    PLUGIN_TYPE_ALL = PLUGIN_TYPE_EMBED |
                      PLUGIN_TYPE_CONTENT_HANDLER,
  };


  const Extension* InstallExtension(const base::FilePath& file_path,
                                    InstallType install_type) {
    ExtensionService* service = extensions::ExtensionSystem::Get(
        browser()->profile())->extension_service();
    const Extension* extension = NULL;
    switch (install_type) {
      case INSTALL_TYPE_COMPONENT:
        if (LoadExtensionAsComponent(file_path)) {
          extension = service->GetExtensionById(kExtensionId, false);
        }
        break;

      case INSTALL_TYPE_UNPACKED:
        // Install the extension from a folder so it's unpacked.
        if (LoadExtension(file_path)) {
          extension = service->GetExtensionById(kExtensionId, false);
        }
        break;

      case INSTALL_TYPE_FROM_WEBSTORE:
        // Install native_client.crx from the webstore.
        if (InstallExtensionFromWebstore(file_path, 1)) {
          extension = service->GetExtensionById(last_loaded_extension_id(),
                                                false);
        }
        break;

      case INSTALL_TYPE_NON_WEBSTORE:
        // Install native_client.crx but not from the webstore.
        if (ExtensionBrowserTest::InstallExtension(file_path, 1)) {
          extension = service->GetExtensionById(last_loaded_extension_id(),
                                                false);
        }
        break;
    }
    return extension;
  }

  const Extension* InstallExtension(InstallType install_type) {
    base::FilePath file_path = test_data_dir_.AppendASCII("native_client");
    return InstallExtension(file_path, install_type);
  }

  const Extension* InstallHostedApp() {
    base::FilePath file_path = test_data_dir_.AppendASCII(
        "native_client_hosted_app");
    return InstallExtension(file_path, INSTALL_TYPE_FROM_WEBSTORE);
  }

  bool IsNaClPluginLoaded() {
    base::FilePath path;
    if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) {
      content::WebPluginInfo info;
      return PluginService::GetInstance()->GetPluginInfoByPath(path, &info);
    }
    return false;
  }

  void CheckPluginsCreated(const GURL& url, PluginType expected_to_succeed) {
    ui_test_utils::NavigateToURL(browser(), url);
    // Don't run tests if the NaCl plugin isn't loaded.
    if (!IsNaClPluginLoaded())
      return;

    bool embedded_plugin_created = false;
    bool content_handler_plugin_created = false;
    WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
        web_contents,
        "window.domAutomationController.send(EmbeddedPluginCreated());",
        &embedded_plugin_created));
    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
        web_contents,
        "window.domAutomationController.send(ContentHandlerPluginCreated());",
        &content_handler_plugin_created));

    EXPECT_EQ(embedded_plugin_created,
              (expected_to_succeed & PLUGIN_TYPE_EMBED) != 0);
    EXPECT_EQ(content_handler_plugin_created,
              (expected_to_succeed & PLUGIN_TYPE_CONTENT_HANDLER) != 0);
  }

  void CheckPluginsCreated(const Extension* extension,
                           PluginType expected_to_succeed) {
    CheckPluginsCreated(extension->GetResourceURL("test.html"),
                        expected_to_succeed);
  }

};

// Test that the NaCl plugin isn't blocked for Webstore extensions.
// Disabled: http://crbug.com/319892
IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_WebStoreExtension) {
  ASSERT_TRUE(test_server()->Start());

  const Extension* extension = InstallExtension(INSTALL_TYPE_FROM_WEBSTORE);
  ASSERT_TRUE(extension);
  CheckPluginsCreated(extension, PLUGIN_TYPE_ALL);
}

// Test that the NaCl plugin is blocked for non-Webstore extensions.
// Disabled: http://crbug.com/319892
IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_NonWebStoreExtension) {
  ASSERT_TRUE(test_server()->Start());

  const Extension* extension = InstallExtension(INSTALL_TYPE_NON_WEBSTORE);
  ASSERT_TRUE(extension);
  CheckPluginsCreated(extension, PLUGIN_TYPE_NONE);
}

// Test that the NaCl plugin isn't blocked for component extensions.
// Disabled: http://crbug.com/319892
IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_ComponentExtension) {
  ASSERT_TRUE(test_server()->Start());

  const Extension* extension = InstallExtension(INSTALL_TYPE_COMPONENT);
  ASSERT_TRUE(extension);
  ASSERT_EQ(extension->location(), Manifest::COMPONENT);
  CheckPluginsCreated(extension, PLUGIN_TYPE_ALL);
}

// Test that the NaCl plugin isn't blocked for unpacked extensions.
// Disabled: http://crbug.com/319892
IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_UnpackedExtension) {
  ASSERT_TRUE(test_server()->Start());

  const Extension* extension = InstallExtension(INSTALL_TYPE_UNPACKED);
  ASSERT_TRUE(extension);
  ASSERT_EQ(extension->location(), Manifest::UNPACKED);
  CheckPluginsCreated(extension, PLUGIN_TYPE_ALL);
}

// Test that the NaCl plugin is blocked for non chrome-extension urls, except
// if it's a content (MIME type) handler.
// Disabled: http://crbug.com/319892
IN_PROC_BROWSER_TEST_F(NaClExtensionTest, DISABLED_NonExtensionScheme) {
  ASSERT_TRUE(test_server()->Start());

  const Extension* extension = InstallExtension(INSTALL_TYPE_FROM_WEBSTORE);
  ASSERT_TRUE(extension);
  CheckPluginsCreated(
      test_server()->GetURL("files/extensions/native_client/test.html"),
      PLUGIN_TYPE_CONTENT_HANDLER);
}

// Test that NaCl plugin isn't blocked for hosted app URLs.
IN_PROC_BROWSER_TEST_F(NaClExtensionTest, HostedApp) {
  host_resolver()->AddRule("*", "127.0.0.1");
  ASSERT_TRUE(test_server()->Start());

  GURL url = test_server()->GetURL("files/extensions/native_client/test.html");
  GURL::Replacements replace_host;
  std::string host_str("localhost");
  replace_host.SetHostStr(host_str);
  replace_host.ClearPort();
  url = url.ReplaceComponents(replace_host);

  const Extension* extension = InstallHostedApp();
  ASSERT_TRUE(extension);
  CheckPluginsCreated(url, PLUGIN_TYPE_ALL);
}

}  // namespace