[email protected] | 1ff3fac | 2013-11-08 09:39:47 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors. All rights reserved. |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 1ff3fac | 2013-11-08 09:39:47 | [diff] [blame] | 5 | #include "extensions/browser/admin_policy.h" |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 6 | |
[email protected] | 135cb80 | 2013-06-09 16:44:20 | [diff] [blame] | 7 | #include "base/strings/utf_string_conversions.h" |
[email protected] | e4452d3 | 2013-11-15 23:07:41 | [diff] [blame] | 8 | #include "extensions/common/extension.h" |
[email protected] | d42c1115 | 2013-08-22 19:36:32 | [diff] [blame] | 9 | #include "extensions/common/manifest.h" |
[email protected] | 99c0125b | 2014-04-17 05:21:57 | [diff] [blame] | 10 | #include "grit/extensions_strings.h" |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 11 | #include "ui/base/l10n/l10n_util.h" |
| 12 | |
| 13 | namespace { |
| 14 | |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 15 | bool ManagementPolicyImpl(const extensions::Extension* extension, |
[email protected] | 0d163dc | 2013-12-20 23:48:36 | [diff] [blame] | 16 | base::string16* error, |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 17 | bool modifiable_value) { |
[email protected] | 75181f6 | 2014-03-19 21:41:12 | [diff] [blame] | 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. |
[email protected] | 366a3b9 | 2012-12-14 14:25:10 | [diff] [blame] | 23 | bool modifiable = |
[email protected] | 75181f6 | 2014-03-19 21:41:12 | [diff] [blame] | 24 | extension->location() != extensions::Manifest::COMPONENT && |
[email protected] | 9bb69163 | 2013-09-26 18:50:12 | [diff] [blame] | 25 | !extensions::Manifest::IsPolicyLocation(extension->location()); |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 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, |
[email protected] | ad65a3e | 2013-12-25 18:18:01 | [diff] [blame] | 33 | base::UTF8ToUTF16(extension->name())); |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 34 | } |
| 35 | return !modifiable_value; |
| 36 | } |
| 37 | |
[email protected] | 0d163dc | 2013-12-20 23:48:36 | [diff] [blame] | 38 | bool ReturnLoadError(const extensions::Extension* extension, |
| 39 | base::string16* error) { |
[email protected] | ce4e5d7a | 2012-12-11 20:59:26 | [diff] [blame] | 40 | if (error) { |
| 41 | *error = l10n_util::GetStringFUTF16( |
| 42 | IDS_EXTENSION_CANT_INSTALL_POLICY_BLOCKED, |
[email protected] | ad65a3e | 2013-12-25 18:18:01 | [diff] [blame] | 43 | base::UTF8ToUTF16(extension->name()), |
| 44 | base::UTF8ToUTF16(extension->id())); |
[email protected] | ce4e5d7a | 2012-12-11 20:59:26 | [diff] [blame] | 45 | } |
| 46 | return false; |
| 47 | } |
| 48 | |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 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 | |
[email protected] | 695b571 | 2012-12-06 23:55:28 | [diff] [blame] | 59 | bool UserMayLoad(const base::ListValue* blacklist, |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 60 | const base::ListValue* whitelist, |
[email protected] | e410b5f | 2012-12-14 14:02:24 | [diff] [blame] | 61 | const base::DictionaryValue* forcelist, |
[email protected] | ce4e5d7a | 2012-12-11 20:59:26 | [diff] [blame] | 62 | const base::ListValue* allowed_types, |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 63 | const Extension* extension, |
[email protected] | 0d163dc | 2013-12-20 23:48:36 | [diff] [blame] | 64 | base::string16* error) { |
[email protected] | 366a3b9 | 2012-12-14 14:25:10 | [diff] [blame] | 65 | // Component extensions are always allowed. |
[email protected] | 1d5e58b | 2013-01-31 08:41:40 | [diff] [blame] | 66 | if (extension->location() == Manifest::COMPONENT) |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 67 | return true; |
| 68 | |
[email protected] | ec1b3e71 | 2013-05-25 14:29:16 | [diff] [blame] | 69 | // Forced installed extensions cannot be overwritten manually. |
[email protected] | 9bb69163 | 2013-09-26 18:50:12 | [diff] [blame] | 70 | if (extension->location() != Manifest::EXTERNAL_POLICY && |
| 71 | extension->location() != Manifest::EXTERNAL_POLICY_DOWNLOAD && |
[email protected] | ec1b3e71 | 2013-05-25 14:29:16 | [diff] [blame] | 72 | forcelist && forcelist->HasKey(extension->id())) { |
| 73 | return ReturnLoadError(extension, error); |
| 74 | } |
| 75 | |
[email protected] | ce4e5d7a | 2012-12-11 20:59:26 | [diff] [blame] | 76 | // Early exit for the common case of no policy restrictions. |
| 77 | if ((!blacklist || blacklist->empty()) && (!allowed_types)) |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 78 | return true; |
| 79 | |
[email protected] | ce4e5d7a | 2012-12-11 20:59:26 | [diff] [blame] | 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()) { |
[email protected] | 1d5e58b | 2013-01-31 08:41:40 | [diff] [blame] | 88 | case Manifest::TYPE_UNKNOWN: |
[email protected] | ce4e5d7a | 2012-12-11 20:59:26 | [diff] [blame] | 89 | break; |
[email protected] | 1d5e58b | 2013-01-31 08:41:40 | [diff] [blame] | 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: |
[email protected] | 180d4e9 | 2014-05-22 15:35:16 | [diff] [blame] | 96 | case Manifest::TYPE_SHARED_MODULE: { |
[email protected] | ce4e5d7a | 2012-12-11 20:59:26 | [diff] [blame] | 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; |
[email protected] | 180d4e9 | 2014-05-22 15:35:16 | [diff] [blame] | 102 | } |
| 103 | case Manifest::NUM_LOAD_TYPES: |
| 104 | NOTREACHED(); |
[email protected] | ce4e5d7a | 2012-12-11 20:59:26 | [diff] [blame] | 105 | } |
| 106 | |
[email protected] | 695b571 | 2012-12-06 23:55:28 | [diff] [blame] | 107 | // Check the whitelist/forcelist first. |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 108 | base::StringValue id_value(extension->id()); |
[email protected] | 4ee07c6 | 2012-08-21 12:40:42 | [diff] [blame] | 109 | if ((whitelist && whitelist->Find(id_value) != whitelist->end()) || |
[email protected] | e410b5f | 2012-12-14 14:02:24 | [diff] [blame] | 110 | (forcelist && forcelist->HasKey(extension->id()))) |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 111 | return true; |
| 112 | |
[email protected] | 695b571 | 2012-12-06 23:55:28 | [diff] [blame] | 113 | // Then check the admin blacklist. |
[email protected] | ce4e5d7a | 2012-12-11 20:59:26 | [diff] [blame] | 114 | if ((blacklist && blacklist->Find(id_value) != blacklist->end()) || |
| 115 | BlacklistedByDefault(blacklist)) |
| 116 | return ReturnLoadError(extension, error); |
| 117 | |
| 118 | return true; |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 119 | } |
| 120 | |
[email protected] | 0d163dc | 2013-12-20 23:48:36 | [diff] [blame] | 121 | bool UserMayModifySettings(const Extension* extension, base::string16* error) { |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 122 | return ManagementPolicyImpl(extension, error, true); |
| 123 | } |
| 124 | |
[email protected] | 0d163dc | 2013-12-20 23:48:36 | [diff] [blame] | 125 | bool MustRemainEnabled(const Extension* extension, base::string16* error) { |
[email protected] | 013724b | 2012-06-05 19:40:39 | [diff] [blame] | 126 | return ManagementPolicyImpl(extension, error, false); |
| 127 | } |
| 128 | |
[email protected] | d42c1115 | 2013-08-22 19:36:32 | [diff] [blame] | 129 | } // namespace admin_policy |
| 130 | } // namespace extensions |