Home | History | Annotate | Download | only in browser
      1 // Copyright 2013 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 "extensions/browser/admin_policy.h"
      6 
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "extensions/common/extension.h"
      9 #include "extensions/common/manifest.h"
     10 #include "grit/extensions_strings.h"
     11 #include "ui/base/l10n/l10n_util.h"
     12 
     13 namespace {
     14 
     15 bool ManagementPolicyImpl(const extensions::Extension* extension,
     16                           base::string16* error,
     17                           bool modifiable_value) {
     18   // Note that COMPONENT and EXTERNAL_COMPONENT are treated differently
     19   // below. EXTERNAL_COMPONENT extensions can be modified including
     20   // enabled, disabled, uninstalled while COMPONENT extensions cannot.
     21   // However, those options are only available for EXTERNAL_COMPONENT
     22   // extensions when the proper command line flag is passed.
     23   bool modifiable =
     24       extension->location() != extensions::Manifest::COMPONENT &&
     25       !extensions::Manifest::IsPolicyLocation(extension->location());
     26   // Some callers equate "no restriction" to true, others to false.
     27   if (modifiable)
     28     return modifiable_value;
     29 
     30   if (error) {
     31     *error = l10n_util::GetStringFUTF16(
     32         IDS_EXTENSION_CANT_MODIFY_POLICY_REQUIRED,
     33         base::UTF8ToUTF16(extension->name()));
     34   }
     35   return !modifiable_value;
     36 }
     37 
     38 bool ReturnLoadError(const extensions::Extension* extension,
     39                      base::string16* error) {
     40   if (error) {
     41     *error = l10n_util::GetStringFUTF16(
     42           IDS_EXTENSION_CANT_INSTALL_POLICY_BLOCKED,
     43           base::UTF8ToUTF16(extension->name()),
     44           base::UTF8ToUTF16(extension->id()));
     45   }
     46   return false;
     47 }
     48 
     49 }  // namespace
     50 
     51 namespace extensions {
     52 namespace admin_policy {
     53 
     54 bool BlacklistedByDefault(const base::ListValue* blacklist) {
     55   base::StringValue wildcard("*");
     56   return blacklist && blacklist->Find(wildcard) != blacklist->end();
     57 }
     58 
     59 bool UserMayLoad(const base::ListValue* blacklist,
     60                  const base::ListValue* whitelist,
     61                  const base::DictionaryValue* forcelist,
     62                  const base::ListValue* allowed_types,
     63                  const Extension* extension,
     64                  base::string16* error) {
     65   // Component extensions are always allowed.
     66   if (extension->location() == Manifest::COMPONENT)
     67     return true;
     68 
     69   // Forced installed extensions cannot be overwritten manually.
     70   if (extension->location() != Manifest::EXTERNAL_POLICY &&
     71       extension->location() != Manifest::EXTERNAL_POLICY_DOWNLOAD &&
     72       forcelist && forcelist->HasKey(extension->id())) {
     73     return ReturnLoadError(extension, error);
     74   }
     75 
     76   // Early exit for the common case of no policy restrictions.
     77   if ((!blacklist || blacklist->empty()) && (!allowed_types))
     78     return true;
     79 
     80   // Check whether the extension type is allowed.
     81   //
     82   // If you get a compile error here saying that the type you added is not
     83   // handled by the switch statement below, please consider whether enterprise
     84   // policy should be able to disallow extensions of the new type. If so, add a
     85   // branch to the second block and add a line to the definition of
     86   // kExtensionAllowedTypesMap in configuration_policy_handler_list.cc.
     87   switch (extension->GetType()) {
     88     case Manifest::TYPE_UNKNOWN:
     89       break;
     90     case Manifest::TYPE_EXTENSION:
     91     case Manifest::TYPE_THEME:
     92     case Manifest::TYPE_USER_SCRIPT:
     93     case Manifest::TYPE_HOSTED_APP:
     94     case Manifest::TYPE_LEGACY_PACKAGED_APP:
     95     case Manifest::TYPE_PLATFORM_APP:
     96     case Manifest::TYPE_SHARED_MODULE: {
     97       base::FundamentalValue type_value(extension->GetType());
     98       if (allowed_types &&
     99           allowed_types->Find(type_value) == allowed_types->end())
    100         return ReturnLoadError(extension, error);
    101       break;
    102     }
    103     case Manifest::NUM_LOAD_TYPES:
    104       NOTREACHED();
    105   }
    106 
    107   // Check the whitelist/forcelist first.
    108   base::StringValue id_value(extension->id());
    109   if ((whitelist && whitelist->Find(id_value) != whitelist->end()) ||
    110       (forcelist && forcelist->HasKey(extension->id())))
    111     return true;
    112 
    113   // Then check the admin blacklist.
    114   if ((blacklist && blacklist->Find(id_value) != blacklist->end()) ||
    115       BlacklistedByDefault(blacklist))
    116     return ReturnLoadError(extension, error);
    117 
    118   return true;
    119 }
    120 
    121 bool UserMayModifySettings(const Extension* extension, base::string16* error) {
    122   return ManagementPolicyImpl(extension, error, true);
    123 }
    124 
    125 bool MustRemainEnabled(const Extension* extension, base::string16* error) {
    126   return ManagementPolicyImpl(extension, error, false);
    127 }
    128 
    129 }  // namespace admin_policy
    130 }  // namespace extensions
    131