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 "base/callback.h"
11 #include "base/json/json_reader.h"
12 #include "base/json/json_writer.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/prefs/pref_value_map.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h"
18 #include "base/values.h"
19 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
20 #include "chrome/common/pref_names.h"
21 #include "chromeos/dbus/power_policy_controller.h"
22 #include "chromeos/network/onc/onc_signature.h"
23 #include "chromeos/network/onc/onc_utils.h"
24 #include "chromeos/network/onc/onc_validator.h"
25 #include "components/onc/onc_constants.h"
26 #include "components/policy/core/browser/policy_error_map.h"
27 #include "components/policy/core/common/external_data_fetcher.h"
28 #include "components/policy/core/common/policy_map.h"
29 #include "components/policy/core/common/schema.h"
30 #include "crypto/sha2.h"
31 #include "grit/components_strings.h"
32 #include "policy/policy_constants.h"
33 #include "ui/chromeos/accessibility_types.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
;
66 const char kScreenDimDelayAC
[] = "AC.Delays.ScreenDim";
67 const char kScreenOffDelayAC
[] = "AC.Delays.ScreenOff";
68 const char kIdleWarningDelayAC
[] = "AC.Delays.IdleWarning";
69 const char kIdleDelayAC
[] = "AC.Delays.Idle";
70 const char kIdleActionAC
[] = "AC.IdleAction";
72 const char kScreenDimDelayBattery
[] = "Battery.Delays.ScreenDim";
73 const char kScreenOffDelayBattery
[] = "Battery.Delays.ScreenOff";
74 const char kIdleWarningDelayBattery
[] = "Battery.Delays.IdleWarning";
75 const char kIdleDelayBattery
[] = "Battery.Delays.Idle";
76 const char kIdleActionBattery
[] = "Battery.IdleAction";
78 const char kScreenLockDelayAC
[] = "AC";
79 const char kScreenLockDelayBattery
[] = "Battery";
81 const char kActionSuspend
[] = "Suspend";
82 const char kActionLogout
[] = "Logout";
83 const char kActionShutdown
[] = "Shutdown";
84 const char kActionDoNothing
[] = "DoNothing";
86 scoped_ptr
<base::Value
> GetValue(const base::DictionaryValue
* dict
,
88 const base::Value
* value
= NULL
;
89 if (!dict
->Get(key
, &value
))
90 return scoped_ptr
<base::Value
>();
91 return scoped_ptr
<base::Value
>(value
->DeepCopy());
94 scoped_ptr
<base::Value
> GetAction(const base::DictionaryValue
* dict
,
96 scoped_ptr
<base::Value
> value
= GetValue(dict
, key
);
98 if (!value
|| !value
->GetAsString(&action
))
99 return scoped_ptr
<base::Value
>();
100 if (action
== kActionSuspend
) {
101 return scoped_ptr
<base::Value
>(new base::FundamentalValue(
102 chromeos::PowerPolicyController::ACTION_SUSPEND
));
104 if (action
== kActionLogout
) {
105 return scoped_ptr
<base::Value
>(new base::FundamentalValue(
106 chromeos::PowerPolicyController::ACTION_STOP_SESSION
));
108 if (action
== kActionShutdown
) {
109 return scoped_ptr
<base::Value
>(new base::FundamentalValue(
110 chromeos::PowerPolicyController::ACTION_SHUT_DOWN
));
112 if (action
== kActionDoNothing
) {
113 return scoped_ptr
<base::Value
>(new base::FundamentalValue(
114 chromeos::PowerPolicyController::ACTION_DO_NOTHING
));
116 return scoped_ptr
<base::Value
>();
121 ExternalDataPolicyHandler::ExternalDataPolicyHandler(const char* policy_name
)
122 : TypeCheckingPolicyHandler(policy_name
, base::Value::TYPE_DICTIONARY
) {
125 ExternalDataPolicyHandler::~ExternalDataPolicyHandler() {
128 bool ExternalDataPolicyHandler::CheckPolicySettings(const PolicyMap
& policies
,
129 PolicyErrorMap
* errors
) {
130 if (!TypeCheckingPolicyHandler::CheckPolicySettings(policies
, errors
))
133 const std::string policy
= policy_name();
134 const base::Value
* value
= policies
.GetValue(policy
);
138 const base::DictionaryValue
* dict
= NULL
;
139 value
->GetAsDictionary(&dict
);
144 std::string url_string
;
145 std::string hash_string
;
146 if (!GetSubkeyString(*dict
, errors
, policy
, kSubkeyURL
, &url_string
) ||
147 !GetSubkeyString(*dict
, errors
, policy
, kSubkeyHash
, &hash_string
)) {
151 const GURL
url(url_string
);
152 if (!url
.is_valid()) {
153 errors
->AddError(policy
, kSubkeyURL
, IDS_POLICY_VALUE_FORMAT_ERROR
);
157 std::vector
<uint8
> hash
;
158 if (!base::HexStringToBytes(hash_string
, &hash
) ||
159 hash
.size() != crypto::kSHA256Length
) {
160 errors
->AddError(policy
, kSubkeyHash
, IDS_POLICY_VALUE_FORMAT_ERROR
);
167 void ExternalDataPolicyHandler::ApplyPolicySettings(const PolicyMap
& policies
,
168 PrefValueMap
* prefs
) {
172 NetworkConfigurationPolicyHandler
*
173 NetworkConfigurationPolicyHandler::CreateForUserPolicy() {
174 return new NetworkConfigurationPolicyHandler(
175 key::kOpenNetworkConfiguration
,
176 onc::ONC_SOURCE_USER_POLICY
,
177 prefs::kOpenNetworkConfiguration
);
181 NetworkConfigurationPolicyHandler
*
182 NetworkConfigurationPolicyHandler::CreateForDevicePolicy() {
183 return new NetworkConfigurationPolicyHandler(
184 key::kDeviceOpenNetworkConfiguration
,
185 onc::ONC_SOURCE_DEVICE_POLICY
,
186 prefs::kDeviceOpenNetworkConfiguration
);
189 NetworkConfigurationPolicyHandler::~NetworkConfigurationPolicyHandler() {}
191 bool NetworkConfigurationPolicyHandler::CheckPolicySettings(
192 const PolicyMap
& policies
,
193 PolicyErrorMap
* errors
) {
194 const base::Value
* value
;
195 if (!CheckAndGetValue(policies
, errors
, &value
))
199 std::string onc_blob
;
200 value
->GetAsString(&onc_blob
);
201 scoped_ptr
<base::DictionaryValue
> root_dict
=
202 chromeos::onc::ReadDictionaryFromJson(onc_blob
);
203 if (root_dict
.get() == NULL
) {
204 errors
->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_PARSE_FAILED
);
208 // Validate the ONC dictionary. We are liberal and ignore unknown field
209 // names and ignore invalid field names in kRecommended arrays.
210 chromeos::onc::Validator
validator(
211 false, // Ignore unknown fields.
212 false, // Ignore invalid recommended field names.
213 true, // Fail on missing fields.
214 true); // Validate for managed ONC
215 validator
.SetOncSource(onc_source_
);
217 // ONC policies are always unencrypted.
218 chromeos::onc::Validator::Result validation_result
;
219 root_dict
= validator
.ValidateAndRepairObject(
220 &chromeos::onc::kToplevelConfigurationSignature
, *root_dict
,
222 if (validation_result
== chromeos::onc::Validator::VALID_WITH_WARNINGS
)
223 errors
->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_IMPORT_PARTIAL
);
224 else if (validation_result
== chromeos::onc::Validator::INVALID
)
225 errors
->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_IMPORT_FAILED
);
227 // In any case, don't reject the policy as some networks or certificates
228 // could still be applied.
234 void NetworkConfigurationPolicyHandler::ApplyPolicySettings(
235 const PolicyMap
& policies
,
236 PrefValueMap
* prefs
) {
237 const base::Value
* value
= policies
.GetValue(policy_name());
241 std::string onc_blob
;
242 value
->GetAsString(&onc_blob
);
244 scoped_ptr
<base::ListValue
> network_configs(new base::ListValue
);
245 base::ListValue certificates
;
246 base::DictionaryValue global_network_config
;
247 chromeos::onc::ParseAndValidateOncForImport(onc_blob
,
250 network_configs
.get(),
251 &global_network_config
,
254 // Currently, only the per-network configuration is stored in a pref. Ignore
255 // |global_network_config| and |certificates|.
256 prefs
->SetValue(pref_path_
, network_configs
.release());
259 void NetworkConfigurationPolicyHandler::PrepareForDisplaying(
260 PolicyMap
* policies
) const {
261 const PolicyMap::Entry
* entry
= policies
->Get(policy_name());
264 base::Value
* sanitized_config
= SanitizeNetworkConfig(entry
->value
);
265 if (!sanitized_config
)
266 sanitized_config
= base::Value::CreateNullValue();
268 policies
->Set(policy_name(), entry
->level
, entry
->scope
,
269 sanitized_config
, NULL
);
272 NetworkConfigurationPolicyHandler::NetworkConfigurationPolicyHandler(
273 const char* policy_name
,
274 onc::ONCSource onc_source
,
275 const char* pref_path
)
276 : TypeCheckingPolicyHandler(policy_name
, base::Value::TYPE_STRING
),
277 onc_source_(onc_source
),
278 pref_path_(pref_path
) {
282 base::Value
* NetworkConfigurationPolicyHandler::SanitizeNetworkConfig(
283 const base::Value
* config
) {
284 std::string json_string
;
285 if (!config
->GetAsString(&json_string
))
288 scoped_ptr
<base::DictionaryValue
> toplevel_dict
=
289 chromeos::onc::ReadDictionaryFromJson(json_string
);
293 // Placeholder to insert in place of the filtered setting.
294 const char kPlaceholder
[] = "********";
296 toplevel_dict
= chromeos::onc::MaskCredentialsInOncObject(
297 chromeos::onc::kToplevelConfigurationSignature
,
301 base::JSONWriter::WriteWithOptions(toplevel_dict
.get(),
302 base::JSONWriter::OPTIONS_PRETTY_PRINT
,
304 return new base::StringValue(json_string
);
307 PinnedLauncherAppsPolicyHandler::PinnedLauncherAppsPolicyHandler()
308 : ExtensionListPolicyHandler(key::kPinnedLauncherApps
,
309 prefs::kPinnedLauncherApps
,
312 PinnedLauncherAppsPolicyHandler::~PinnedLauncherAppsPolicyHandler() {}
314 void PinnedLauncherAppsPolicyHandler::ApplyPolicySettings(
315 const PolicyMap
& policies
,
316 PrefValueMap
* prefs
) {
317 PolicyErrorMap errors
;
318 const base::Value
* policy_value
= policies
.GetValue(policy_name());
319 const base::ListValue
* policy_list
= NULL
;
320 if (policy_value
&& policy_value
->GetAsList(&policy_list
) && policy_list
) {
321 base::ListValue
* pinned_apps_list
= new base::ListValue();
322 for (base::ListValue::const_iterator
entry(policy_list
->begin());
323 entry
!= policy_list
->end(); ++entry
) {
325 if ((*entry
)->GetAsString(&id
)) {
326 base::DictionaryValue
* app_dict
= new base::DictionaryValue();
327 app_dict
->SetString(ash::kPinnedAppsPrefAppIDPath
, id
);
328 pinned_apps_list
->Append(app_dict
);
331 prefs
->SetValue(pref_path(), pinned_apps_list
);
335 ScreenMagnifierPolicyHandler::ScreenMagnifierPolicyHandler()
336 : IntRangePolicyHandlerBase(key::kScreenMagnifierType
,
337 0, ui::MAGNIFIER_FULL
, false) {
340 ScreenMagnifierPolicyHandler::~ScreenMagnifierPolicyHandler() {
343 void ScreenMagnifierPolicyHandler::ApplyPolicySettings(
344 const PolicyMap
& policies
,
345 PrefValueMap
* prefs
) {
346 const base::Value
* value
= policies
.GetValue(policy_name());
348 if (value
&& EnsureInRange(value
, &value_in_range
, NULL
)) {
349 prefs
->SetValue(prefs::kAccessibilityScreenMagnifierEnabled
,
350 new base::FundamentalValue(value_in_range
!= 0));
351 prefs
->SetValue(prefs::kAccessibilityScreenMagnifierType
,
352 new base::FundamentalValue(value_in_range
));
356 LoginScreenPowerManagementPolicyHandler::
357 LoginScreenPowerManagementPolicyHandler(const Schema
& chrome_schema
)
358 : SchemaValidatingPolicyHandler(key::kDeviceLoginScreenPowerManagement
,
359 chrome_schema
.GetKnownProperty(
360 key::kDeviceLoginScreenPowerManagement
),
361 SCHEMA_ALLOW_UNKNOWN
) {
364 LoginScreenPowerManagementPolicyHandler::
365 ~LoginScreenPowerManagementPolicyHandler() {
368 void LoginScreenPowerManagementPolicyHandler::ApplyPolicySettings(
369 const PolicyMap
& policies
,
370 PrefValueMap
* prefs
) {
373 DeprecatedIdleActionHandler::DeprecatedIdleActionHandler()
374 : IntRangePolicyHandlerBase(
376 chromeos::PowerPolicyController::ACTION_SUSPEND
,
377 chromeos::PowerPolicyController::ACTION_DO_NOTHING
,
380 DeprecatedIdleActionHandler::~DeprecatedIdleActionHandler() {}
382 void DeprecatedIdleActionHandler::ApplyPolicySettings(const PolicyMap
& policies
,
383 PrefValueMap
* prefs
) {
384 const base::Value
* value
= policies
.GetValue(policy_name());
385 if (value
&& EnsureInRange(value
, NULL
, NULL
)) {
386 if (!prefs
->GetValue(prefs::kPowerAcIdleAction
, NULL
))
387 prefs
->SetValue(prefs::kPowerAcIdleAction
, value
->DeepCopy());
388 if (!prefs
->GetValue(prefs::kPowerBatteryIdleAction
, NULL
))
389 prefs
->SetValue(prefs::kPowerBatteryIdleAction
, value
->DeepCopy());
393 PowerManagementIdleSettingsPolicyHandler::
394 PowerManagementIdleSettingsPolicyHandler(const Schema
& chrome_schema
)
395 : SchemaValidatingPolicyHandler(
396 key::kPowerManagementIdleSettings
,
397 chrome_schema
.GetKnownProperty(key::kPowerManagementIdleSettings
),
398 SCHEMA_ALLOW_UNKNOWN
) {
401 PowerManagementIdleSettingsPolicyHandler::
402 ~PowerManagementIdleSettingsPolicyHandler() {
405 void PowerManagementIdleSettingsPolicyHandler::ApplyPolicySettings(
406 const PolicyMap
& policies
,
407 PrefValueMap
* prefs
) {
408 scoped_ptr
<base::Value
> policy_value
;
409 if (!CheckAndGetValue(policies
, NULL
, &policy_value
))
411 const base::DictionaryValue
* dict
= NULL
;
412 if (!policy_value
->GetAsDictionary(&dict
)) {
416 scoped_ptr
<base::Value
> value
;
418 value
= GetValue(dict
, kScreenDimDelayAC
);
420 prefs
->SetValue(prefs::kPowerAcScreenDimDelayMs
, value
.release());
421 value
= GetValue(dict
, kScreenOffDelayAC
);
423 prefs
->SetValue(prefs::kPowerAcScreenOffDelayMs
, value
.release());
424 value
= GetValue(dict
, kIdleWarningDelayAC
);
426 prefs
->SetValue(prefs::kPowerAcIdleWarningDelayMs
, value
.release());
427 value
= GetValue(dict
, kIdleDelayAC
);
429 prefs
->SetValue(prefs::kPowerAcIdleDelayMs
, value
.release());
430 value
= GetAction(dict
, kIdleActionAC
);
432 prefs
->SetValue(prefs::kPowerAcIdleAction
, value
.release());
434 value
= GetValue(dict
, kScreenDimDelayBattery
);
436 prefs
->SetValue(prefs::kPowerBatteryScreenDimDelayMs
, value
.release());
437 value
= GetValue(dict
, kScreenOffDelayBattery
);
439 prefs
->SetValue(prefs::kPowerBatteryScreenOffDelayMs
, value
.release());
440 value
= GetValue(dict
, kIdleWarningDelayBattery
);
442 prefs
->SetValue(prefs::kPowerBatteryIdleWarningDelayMs
, value
.release());
443 value
= GetValue(dict
, kIdleDelayBattery
);
445 prefs
->SetValue(prefs::kPowerBatteryIdleDelayMs
, value
.release());
446 value
= GetAction(dict
, kIdleActionBattery
);
448 prefs
->SetValue(prefs::kPowerBatteryIdleAction
, value
.release());
451 ScreenLockDelayPolicyHandler::ScreenLockDelayPolicyHandler(
452 const Schema
& chrome_schema
)
453 : SchemaValidatingPolicyHandler(
454 key::kScreenLockDelays
,
455 chrome_schema
.GetKnownProperty(key::kScreenLockDelays
),
456 SCHEMA_ALLOW_UNKNOWN
) {
459 ScreenLockDelayPolicyHandler::~ScreenLockDelayPolicyHandler() {
462 void ScreenLockDelayPolicyHandler::ApplyPolicySettings(
463 const PolicyMap
& policies
,
464 PrefValueMap
* prefs
) {
465 scoped_ptr
<base::Value
> policy_value
;
466 if (!CheckAndGetValue(policies
, NULL
, &policy_value
))
468 const base::DictionaryValue
* dict
= NULL
;
469 if (!policy_value
->GetAsDictionary(&dict
)) {
473 scoped_ptr
<base::Value
> value
;
475 value
= GetValue(dict
, kScreenLockDelayAC
);
477 prefs
->SetValue(prefs::kPowerAcScreenLockDelayMs
, value
.release());
478 value
= GetValue(dict
, kScreenLockDelayBattery
);
480 prefs
->SetValue(prefs::kPowerBatteryScreenLockDelayMs
, value
.release());
483 } // namespace policy