1 // Copyright (c) 2012 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.
5 #include "chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h"
10 #include "ash/magnifier/magnifier_constants.h"
11 #include "base/callback.h"
12 #include "base/json/json_reader.h"
13 #include "base/json/json_writer.h"
14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/prefs/pref_value_map.h"
17 #include "base/sha1.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_util.h"
20 #include "base/values.h"
21 #include "chrome/browser/chromeos/policy/login_screen_power_management_policy.h"
22 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
23 #include "chrome/common/pref_names.h"
24 #include "chromeos/dbus/power_policy_controller.h"
25 #include "chromeos/network/onc/onc_signature.h"
26 #include "chromeos/network/onc/onc_utils.h"
27 #include "chromeos/network/onc/onc_validator.h"
28 #include "components/onc/onc_constants.h"
29 #include "components/policy/core/browser/policy_error_map.h"
30 #include "components/policy/core/common/external_data_fetcher.h"
31 #include "components/policy/core/common/policy_map.h"
32 #include "grit/component_strings.h"
33 #include "policy/policy_constants.h"
40 const char kSubkeyURL
[] = "url";
41 const char kSubkeyHash
[] = "hash";
43 bool GetSubkeyString(const base::DictionaryValue
& dict
,
44 policy::PolicyErrorMap
* errors
,
45 const std::string
& policy
,
46 const std::string
& subkey
,
48 const base::Value
* raw_value
= NULL
;
49 if (!dict
.GetWithoutPathExpansion(subkey
, &raw_value
)) {
50 errors
->AddError(policy
, subkey
, IDS_POLICY_NOT_SPECIFIED_ERROR
);
53 std::string string_value
;
54 if (!raw_value
->GetAsString(&string_value
)) {
55 errors
->AddError(policy
, subkey
, IDS_POLICY_TYPE_ERROR
, "string");
58 if (string_value
.empty()) {
59 errors
->AddError(policy
, subkey
, IDS_POLICY_NOT_SPECIFIED_ERROR
);
62 *value
= string_value
;
68 ExternalDataPolicyHandler::ExternalDataPolicyHandler(const char* policy_name
)
69 : TypeCheckingPolicyHandler(policy_name
, base::Value::TYPE_DICTIONARY
) {
72 ExternalDataPolicyHandler::~ExternalDataPolicyHandler() {
75 bool ExternalDataPolicyHandler::CheckPolicySettings(const PolicyMap
& policies
,
76 PolicyErrorMap
* errors
) {
77 if (!TypeCheckingPolicyHandler::CheckPolicySettings(policies
, errors
))
80 const std::string policy
= policy_name();
81 const base::Value
* value
= policies
.GetValue(policy
);
85 const base::DictionaryValue
* dict
= NULL
;
86 value
->GetAsDictionary(&dict
);
91 std::string url_string
;
92 std::string hash_string
;
93 if (!GetSubkeyString(*dict
, errors
, policy
, kSubkeyURL
, &url_string
) ||
94 !GetSubkeyString(*dict
, errors
, policy
, kSubkeyHash
, &hash_string
)) {
98 const GURL
url(url_string
);
99 if (!url
.is_valid()) {
100 errors
->AddError(policy
, kSubkeyURL
, IDS_POLICY_VALUE_FORMAT_ERROR
);
104 std::vector
<uint8
> hash
;
105 if (!base::HexStringToBytes(hash_string
, &hash
) ||
106 hash
.size() != base::kSHA1Length
) {
107 errors
->AddError(policy
, kSubkeyHash
, IDS_POLICY_VALUE_FORMAT_ERROR
);
114 void ExternalDataPolicyHandler::ApplyPolicySettings(const PolicyMap
& policies
,
115 PrefValueMap
* prefs
) {
119 NetworkConfigurationPolicyHandler
*
120 NetworkConfigurationPolicyHandler::CreateForUserPolicy() {
121 return new NetworkConfigurationPolicyHandler(
122 key::kOpenNetworkConfiguration
,
123 onc::ONC_SOURCE_USER_POLICY
,
124 prefs::kOpenNetworkConfiguration
);
128 NetworkConfigurationPolicyHandler
*
129 NetworkConfigurationPolicyHandler::CreateForDevicePolicy() {
130 return new NetworkConfigurationPolicyHandler(
131 key::kDeviceOpenNetworkConfiguration
,
132 onc::ONC_SOURCE_DEVICE_POLICY
,
133 prefs::kDeviceOpenNetworkConfiguration
);
136 NetworkConfigurationPolicyHandler::~NetworkConfigurationPolicyHandler() {}
138 bool NetworkConfigurationPolicyHandler::CheckPolicySettings(
139 const PolicyMap
& policies
,
140 PolicyErrorMap
* errors
) {
141 const base::Value
* value
;
142 if (!CheckAndGetValue(policies
, errors
, &value
))
146 std::string onc_blob
;
147 value
->GetAsString(&onc_blob
);
148 scoped_ptr
<base::DictionaryValue
> root_dict
=
149 chromeos::onc::ReadDictionaryFromJson(onc_blob
);
150 if (root_dict
.get() == NULL
) {
151 errors
->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_PARSE_FAILED
);
155 // Validate the ONC dictionary. We are liberal and ignore unknown field
156 // names and ignore invalid field names in kRecommended arrays.
157 chromeos::onc::Validator
validator(
158 false, // Ignore unknown fields.
159 false, // Ignore invalid recommended field names.
160 true, // Fail on missing fields.
161 true); // Validate for managed ONC
162 validator
.SetOncSource(onc_source_
);
164 // ONC policies are always unencrypted.
165 chromeos::onc::Validator::Result validation_result
;
166 root_dict
= validator
.ValidateAndRepairObject(
167 &chromeos::onc::kToplevelConfigurationSignature
, *root_dict
,
169 if (validation_result
== chromeos::onc::Validator::VALID_WITH_WARNINGS
)
170 errors
->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_IMPORT_PARTIAL
);
171 else if (validation_result
== chromeos::onc::Validator::INVALID
)
172 errors
->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_IMPORT_FAILED
);
174 // In any case, don't reject the policy as some networks or certificates
175 // could still be applied.
181 void NetworkConfigurationPolicyHandler::ApplyPolicySettings(
182 const PolicyMap
& policies
,
183 PrefValueMap
* prefs
) {
184 const base::Value
* value
= policies
.GetValue(policy_name());
188 std::string onc_blob
;
189 value
->GetAsString(&onc_blob
);
191 scoped_ptr
<base::ListValue
> network_configs(new base::ListValue
);
192 base::ListValue certificates
;
193 base::DictionaryValue global_network_config
;
194 chromeos::onc::ParseAndValidateOncForImport(onc_blob
,
197 network_configs
.get(),
198 &global_network_config
,
201 // Currently, only the per-network configuration is stored in a pref. Ignore
202 // |global_network_config| and |certificates|.
203 prefs
->SetValue(pref_path_
, network_configs
.release());
206 void NetworkConfigurationPolicyHandler::PrepareForDisplaying(
207 PolicyMap
* policies
) const {
208 const PolicyMap::Entry
* entry
= policies
->Get(policy_name());
211 base::Value
* sanitized_config
= SanitizeNetworkConfig(entry
->value
);
212 if (!sanitized_config
)
213 sanitized_config
= base::Value::CreateNullValue();
215 policies
->Set(policy_name(), entry
->level
, entry
->scope
,
216 sanitized_config
, NULL
);
219 NetworkConfigurationPolicyHandler::NetworkConfigurationPolicyHandler(
220 const char* policy_name
,
221 onc::ONCSource onc_source
,
222 const char* pref_path
)
223 : TypeCheckingPolicyHandler(policy_name
, base::Value::TYPE_STRING
),
224 onc_source_(onc_source
),
225 pref_path_(pref_path
) {
229 base::Value
* NetworkConfigurationPolicyHandler::SanitizeNetworkConfig(
230 const base::Value
* config
) {
231 std::string json_string
;
232 if (!config
->GetAsString(&json_string
))
235 scoped_ptr
<base::DictionaryValue
> toplevel_dict
=
236 chromeos::onc::ReadDictionaryFromJson(json_string
);
240 // Placeholder to insert in place of the filtered setting.
241 const char kPlaceholder
[] = "********";
243 toplevel_dict
= chromeos::onc::MaskCredentialsInOncObject(
244 chromeos::onc::kToplevelConfigurationSignature
,
248 base::JSONWriter::WriteWithOptions(toplevel_dict
.get(),
249 base::JSONWriter::OPTIONS_PRETTY_PRINT
,
251 return base::Value::CreateStringValue(json_string
);
254 PinnedLauncherAppsPolicyHandler::PinnedLauncherAppsPolicyHandler()
255 : ExtensionListPolicyHandler(key::kPinnedLauncherApps
,
256 prefs::kPinnedLauncherApps
,
259 PinnedLauncherAppsPolicyHandler::~PinnedLauncherAppsPolicyHandler() {}
261 void PinnedLauncherAppsPolicyHandler::ApplyPolicySettings(
262 const PolicyMap
& policies
,
263 PrefValueMap
* prefs
) {
264 PolicyErrorMap errors
;
265 const base::Value
* policy_value
= policies
.GetValue(policy_name());
266 const base::ListValue
* policy_list
= NULL
;
267 if (policy_value
&& policy_value
->GetAsList(&policy_list
) && policy_list
) {
268 base::ListValue
* pinned_apps_list
= new base::ListValue();
269 for (base::ListValue::const_iterator
entry(policy_list
->begin());
270 entry
!= policy_list
->end(); ++entry
) {
272 if ((*entry
)->GetAsString(&id
)) {
273 base::DictionaryValue
* app_dict
= new base::DictionaryValue();
274 app_dict
->SetString(ash::kPinnedAppsPrefAppIDPath
, id
);
275 pinned_apps_list
->Append(app_dict
);
278 prefs
->SetValue(pref_path(), pinned_apps_list
);
282 ScreenMagnifierPolicyHandler::ScreenMagnifierPolicyHandler()
283 : IntRangePolicyHandlerBase(key::kScreenMagnifierType
,
284 0, ash::MAGNIFIER_FULL
, false) {
287 ScreenMagnifierPolicyHandler::~ScreenMagnifierPolicyHandler() {
290 void ScreenMagnifierPolicyHandler::ApplyPolicySettings(
291 const PolicyMap
& policies
,
292 PrefValueMap
* prefs
) {
293 const base::Value
* value
= policies
.GetValue(policy_name());
295 if (value
&& EnsureInRange(value
, &value_in_range
, NULL
)) {
296 prefs
->SetValue(prefs::kScreenMagnifierEnabled
,
297 base::Value::CreateBooleanValue(value_in_range
!= 0));
298 prefs
->SetValue(prefs::kScreenMagnifierType
,
299 base::Value::CreateIntegerValue(value_in_range
));
303 LoginScreenPowerManagementPolicyHandler::
304 LoginScreenPowerManagementPolicyHandler()
305 : TypeCheckingPolicyHandler(key::kDeviceLoginScreenPowerManagement
,
306 base::Value::TYPE_STRING
) {
309 LoginScreenPowerManagementPolicyHandler::
310 ~LoginScreenPowerManagementPolicyHandler() {
313 bool LoginScreenPowerManagementPolicyHandler::CheckPolicySettings(
314 const PolicyMap
& policies
,
315 PolicyErrorMap
* errors
) {
316 const base::Value
* value
;
317 if (!CheckAndGetValue(policies
, errors
, &value
))
324 value
->GetAsString(&json
);
325 return LoginScreenPowerManagementPolicy().Init(json
, errors
);
328 void LoginScreenPowerManagementPolicyHandler::ApplyPolicySettings(
329 const PolicyMap
& policies
,
330 PrefValueMap
* prefs
) {
333 DeprecatedIdleActionHandler::DeprecatedIdleActionHandler()
334 : IntRangePolicyHandlerBase(
336 chromeos::PowerPolicyController::ACTION_SUSPEND
,
337 chromeos::PowerPolicyController::ACTION_DO_NOTHING
,
340 DeprecatedIdleActionHandler::~DeprecatedIdleActionHandler() {}
342 void DeprecatedIdleActionHandler::ApplyPolicySettings(const PolicyMap
& policies
,
343 PrefValueMap
* prefs
) {
344 const base::Value
* value
= policies
.GetValue(policy_name());
345 if (value
&& EnsureInRange(value
, NULL
, NULL
)) {
346 if (!prefs
->GetValue(prefs::kPowerAcIdleAction
, NULL
))
347 prefs
->SetValue(prefs::kPowerAcIdleAction
, value
->DeepCopy());
348 if (!prefs
->GetValue(prefs::kPowerBatteryIdleAction
, NULL
))
349 prefs
->SetValue(prefs::kPowerBatteryIdleAction
, value
->DeepCopy());
353 } // namespace policy