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