Home | History | Annotate | Download | only in common
      1 // Copyright 2014 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 "chrome/common/pepper_permission_util.h"
      6 
      7 #include <set>
      8 #include <string>
      9 
     10 #include "chrome/common/extensions/features/feature_channel.h"
     11 #include "components/crx_file/id_util.h"
     12 #include "extensions/common/extension_builder.h"
     13 #include "extensions/common/extension_set.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 using chrome::IsExtensionOrSharedModuleWhitelisted;
     17 
     18 namespace extensions {
     19 
     20 namespace {
     21 
     22 // Return an extension with |id| which imports a module with the given
     23 // |import_id|.
     24 scoped_refptr<Extension> CreateExtensionImportingModule(
     25     const std::string& import_id,
     26     const std::string& id) {
     27   scoped_ptr<base::DictionaryValue> manifest =
     28       DictionaryBuilder()
     29           .Set("name", "Has Dependent Modules")
     30           .Set("version", "1.0")
     31           .Set("manifest_version", 2)
     32           .Set("import",
     33                ListBuilder().Append(DictionaryBuilder().Set("id", import_id)))
     34           .Build();
     35 
     36   return ExtensionBuilder()
     37       .SetManifest(manifest.Pass())
     38       .AddFlags(Extension::FROM_WEBSTORE)
     39       .SetID(id)
     40       .Build();
     41 }
     42 
     43 }  // namespace
     44 
     45 TEST(PepperPermissionUtilTest, ExtensionWhitelisting) {
     46   ScopedCurrentChannel current_channel(chrome::VersionInfo::CHANNEL_UNKNOWN);
     47   ExtensionSet extensions;
     48   std::string whitelisted_id =
     49       crx_file::id_util::GenerateId("whitelisted_extension");
     50   scoped_ptr<base::DictionaryValue> manifest =
     51       DictionaryBuilder()
     52           .Set("name", "Whitelisted Extension")
     53           .Set("version", "1.0")
     54           .Set("manifest_version", 2)
     55           .Build();
     56   scoped_refptr<Extension> ext = ExtensionBuilder()
     57                                      .SetManifest(manifest.Pass())
     58                                      .SetID(whitelisted_id)
     59                                      .Build();
     60   extensions.Insert(ext);
     61   std::set<std::string> whitelist;
     62   std::string url = std::string("chrome-extension://") + whitelisted_id +
     63                     std::string("/manifest.nmf");
     64   std::string bad_scheme_url =
     65       std::string("http://") + whitelisted_id + std::string("/manifest.nmf");
     66   std::string bad_host_url = std::string("chrome-extension://") +
     67                              crx_file::id_util::GenerateId("bad_host");
     68   std::string("/manifest.nmf");
     69 
     70   EXPECT_FALSE(
     71       IsExtensionOrSharedModuleWhitelisted(GURL(url), &extensions, whitelist));
     72   whitelist.insert(whitelisted_id);
     73   EXPECT_TRUE(
     74       IsExtensionOrSharedModuleWhitelisted(GURL(url), &extensions, whitelist));
     75   EXPECT_FALSE(IsExtensionOrSharedModuleWhitelisted(
     76       GURL(bad_scheme_url), &extensions, whitelist));
     77   EXPECT_FALSE(IsExtensionOrSharedModuleWhitelisted(
     78       GURL(bad_host_url), &extensions, whitelist));
     79 }
     80 
     81 TEST(PepperPermissionUtilTest, SharedModuleWhitelisting) {
     82   ScopedCurrentChannel current_channel(chrome::VersionInfo::CHANNEL_UNKNOWN);
     83   ExtensionSet extensions;
     84   std::string whitelisted_id = crx_file::id_util::GenerateId("extension_id");
     85   std::string bad_id = crx_file::id_util::GenerateId("bad_id");
     86 
     87   scoped_ptr<base::DictionaryValue> shared_module_manifest =
     88       DictionaryBuilder()
     89           .Set("name", "Whitelisted Shared Module")
     90           .Set("version", "1.0")
     91           .Set("manifest_version", 2)
     92           .Set("export",
     93                DictionaryBuilder()
     94                    .Set("resources", ListBuilder().Append("*"))
     95                    // Add the extension to the whitelist.  This
     96                    // restricts import to |whitelisted_id| only.
     97                    .Set("whitelist", ListBuilder().Append(whitelisted_id)))
     98           .Build();
     99   scoped_refptr<Extension> shared_module =
    100       ExtensionBuilder().SetManifest(shared_module_manifest.Pass()).Build();
    101 
    102   scoped_refptr<Extension> ext =
    103       CreateExtensionImportingModule(shared_module->id(), whitelisted_id);
    104   std::string extension_url =
    105       std::string("chrome-extension://") + ext->id() + std::string("/foo.html");
    106 
    107   std::set<std::string> whitelist;
    108   // Important: whitelist *only* the shared module.
    109   whitelist.insert(shared_module->id());
    110 
    111   extensions.Insert(ext);
    112   // This should fail because shared_module is not in the set of extensions.
    113   EXPECT_FALSE(IsExtensionOrSharedModuleWhitelisted(
    114       GURL(extension_url), &extensions, whitelist));
    115   extensions.Insert(shared_module);
    116   EXPECT_TRUE(IsExtensionOrSharedModuleWhitelisted(
    117       GURL(extension_url), &extensions, whitelist));
    118   scoped_refptr<Extension> not_in_sm_whitelist =
    119       CreateExtensionImportingModule(shared_module->id(), bad_id);
    120   std::string not_in_sm_whitelist_url = std::string("chrome-extension://") +
    121                                         not_in_sm_whitelist->id() +
    122                                         std::string("/foo.html");
    123 
    124   extensions.Insert(not_in_sm_whitelist);
    125   // This should succeed, even though |not_in_sm_whitelist| is not whitelisted
    126   // to use shared_module, because the pepper permission utility does not care
    127   // about that whitelist.  It is possible to install against the whitelist as
    128   // an unpacked extension.
    129   EXPECT_TRUE(IsExtensionOrSharedModuleWhitelisted(
    130       GURL(not_in_sm_whitelist_url), &extensions, whitelist));
    131 
    132   // Note that the whitelist should be empty after this call, so tests checking
    133   // for failure to import will fail because of this.
    134   whitelist.erase(shared_module->id());
    135   EXPECT_FALSE(IsExtensionOrSharedModuleWhitelisted(
    136       GURL(extension_url), &extensions, whitelist));
    137 }
    138 
    139 }  // namespace extensions
    140