configuration_policy_handler_chromeos.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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. 4 5#include "chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h" 6 7#include <string> 8#include <vector> 9 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/strings/string_number_conversions.h" 18#include "base/strings/string_util.h" 19#include "base/values.h" 20#include "chrome/browser/ui/ash/chrome_launcher_prefs.h" 21#include "chrome/common/pref_names.h" 22#include "chromeos/dbus/power_policy_controller.h" 23#include "chromeos/network/onc/onc_signature.h" 24#include "chromeos/network/onc/onc_utils.h" 25#include "chromeos/network/onc/onc_validator.h" 26#include "components/onc/onc_constants.h" 27#include "components/policy/core/browser/policy_error_map.h" 28#include "components/policy/core/common/external_data_fetcher.h" 29#include "components/policy/core/common/policy_map.h" 30#include "components/policy/core/common/schema.h" 31#include "crypto/sha2.h" 32#include "grit/components_strings.h" 33#include "policy/policy_constants.h" 34#include "url/gurl.h" 35 36namespace policy { 37 38namespace { 39 40const char kSubkeyURL[] = "url"; 41const char kSubkeyHash[] = "hash"; 42 43bool GetSubkeyString(const base::DictionaryValue& dict, 44 policy::PolicyErrorMap* errors, 45 const std::string& policy, 46 const std::string& subkey, 47 std::string* value) { 48 const base::Value* raw_value = NULL; 49 if (!dict.GetWithoutPathExpansion(subkey, &raw_value)) { 50 errors->AddError(policy, subkey, IDS_POLICY_NOT_SPECIFIED_ERROR); 51 return false; 52 } 53 std::string string_value; 54 if (!raw_value->GetAsString(&string_value)) { 55 errors->AddError(policy, subkey, IDS_POLICY_TYPE_ERROR, "string"); 56 return false; 57 } 58 if (string_value.empty()) { 59 errors->AddError(policy, subkey, IDS_POLICY_NOT_SPECIFIED_ERROR); 60 return false; 61 } 62 *value = string_value; 63 return true; 64} 65 66const char kScreenDimDelayAC[] = "AC.Delays.ScreenDim"; 67const char kScreenOffDelayAC[] = "AC.Delays.ScreenOff"; 68const char kIdleWarningDelayAC[] = "AC.Delays.IdleWarning"; 69const char kIdleDelayAC[] = "AC.Delays.Idle"; 70const char kIdleActionAC[] = "AC.IdleAction"; 71 72const char kScreenDimDelayBattery[] = "Battery.Delays.ScreenDim"; 73const char kScreenOffDelayBattery[] = "Battery.Delays.ScreenOff"; 74const char kIdleWarningDelayBattery[] = "Battery.Delays.IdleWarning"; 75const char kIdleDelayBattery[] = "Battery.Delays.Idle"; 76const char kIdleActionBattery[] = "Battery.IdleAction"; 77 78const char kScreenLockDelayAC[] = "AC"; 79const char kScreenLockDelayBattery[] = "Battery"; 80 81const char kActionSuspend[] = "Suspend"; 82const char kActionLogout[] = "Logout"; 83const char kActionShutdown[] = "Shutdown"; 84const char kActionDoNothing[] = "DoNothing"; 85 86scoped_ptr<base::Value> GetValue(const base::DictionaryValue* dict, 87 const char* key) { 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()); 92} 93 94scoped_ptr<base::Value> GetAction(const base::DictionaryValue* dict, 95 const char* key) { 96 scoped_ptr<base::Value> value = GetValue(dict, key); 97 std::string action; 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)); 103 } 104 if (action == kActionLogout) { 105 return scoped_ptr<base::Value>(new base::FundamentalValue( 106 chromeos::PowerPolicyController::ACTION_STOP_SESSION)); 107 } 108 if (action == kActionShutdown) { 109 return scoped_ptr<base::Value>(new base::FundamentalValue( 110 chromeos::PowerPolicyController::ACTION_SHUT_DOWN)); 111 } 112 if (action == kActionDoNothing) { 113 return scoped_ptr<base::Value>(new base::FundamentalValue( 114 chromeos::PowerPolicyController::ACTION_DO_NOTHING)); 115 } 116 return scoped_ptr<base::Value>(); 117} 118 119} // namespace 120 121ExternalDataPolicyHandler::ExternalDataPolicyHandler(const char* policy_name) 122 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_DICTIONARY) { 123} 124 125ExternalDataPolicyHandler::~ExternalDataPolicyHandler() { 126} 127 128bool ExternalDataPolicyHandler::CheckPolicySettings(const PolicyMap& policies, 129 PolicyErrorMap* errors) { 130 if (!TypeCheckingPolicyHandler::CheckPolicySettings(policies, errors)) 131 return false; 132 133 const std::string policy = policy_name(); 134 const base::Value* value = policies.GetValue(policy); 135 if (!value) 136 return true; 137 138 const base::DictionaryValue* dict = NULL; 139 value->GetAsDictionary(&dict); 140 if (!dict) { 141 NOTREACHED(); 142 return false; 143 } 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)) { 148 return false; 149 } 150 151 const GURL url(url_string); 152 if (!url.is_valid()) { 153 errors->AddError(policy, kSubkeyURL, IDS_POLICY_VALUE_FORMAT_ERROR); 154 return false; 155 } 156 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); 161 return false; 162 } 163 164 return true; 165} 166 167void ExternalDataPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 168 PrefValueMap* prefs) { 169} 170 171// static 172NetworkConfigurationPolicyHandler* 173NetworkConfigurationPolicyHandler::CreateForUserPolicy() { 174 return new NetworkConfigurationPolicyHandler( 175 key::kOpenNetworkConfiguration, 176 onc::ONC_SOURCE_USER_POLICY, 177 prefs::kOpenNetworkConfiguration); 178} 179 180// static 181NetworkConfigurationPolicyHandler* 182NetworkConfigurationPolicyHandler::CreateForDevicePolicy() { 183 return new NetworkConfigurationPolicyHandler( 184 key::kDeviceOpenNetworkConfiguration, 185 onc::ONC_SOURCE_DEVICE_POLICY, 186 prefs::kDeviceOpenNetworkConfiguration); 187} 188 189NetworkConfigurationPolicyHandler::~NetworkConfigurationPolicyHandler() {} 190 191bool NetworkConfigurationPolicyHandler::CheckPolicySettings( 192 const PolicyMap& policies, 193 PolicyErrorMap* errors) { 194 const base::Value* value; 195 if (!CheckAndGetValue(policies, errors, &value)) 196 return false; 197 198 if (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); 205 return false; 206 } 207 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_); 216 217 // ONC policies are always unencrypted. 218 chromeos::onc::Validator::Result validation_result; 219 root_dict = validator.ValidateAndRepairObject( 220 &chromeos::onc::kToplevelConfigurationSignature, *root_dict, 221 &validation_result); 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); 226 227 // In any case, don't reject the policy as some networks or certificates 228 // could still be applied. 229 } 230 231 return true; 232} 233 234void NetworkConfigurationPolicyHandler::ApplyPolicySettings( 235 const PolicyMap& policies, 236 PrefValueMap* prefs) { 237 const base::Value* value = policies.GetValue(policy_name()); 238 if (!value) 239 return; 240 241 std::string onc_blob; 242 value->GetAsString(&onc_blob); 243 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, 248 onc_source_, 249 "", 250 network_configs.get(), 251 &global_network_config, 252 &certificates); 253 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()); 257} 258 259void NetworkConfigurationPolicyHandler::PrepareForDisplaying( 260 PolicyMap* policies) const { 261 const PolicyMap::Entry* entry = policies->Get(policy_name()); 262 if (!entry) 263 return; 264 base::Value* sanitized_config = SanitizeNetworkConfig(entry->value); 265 if (!sanitized_config) 266 sanitized_config = base::Value::CreateNullValue(); 267 268 policies->Set(policy_name(), entry->level, entry->scope, 269 sanitized_config, NULL); 270} 271 272NetworkConfigurationPolicyHandler::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) { 279} 280 281// static 282base::Value* NetworkConfigurationPolicyHandler::SanitizeNetworkConfig( 283 const base::Value* config) { 284 std::string json_string; 285 if (!config->GetAsString(&json_string)) 286 return NULL; 287 288 scoped_ptr<base::DictionaryValue> toplevel_dict = 289 chromeos::onc::ReadDictionaryFromJson(json_string); 290 if (!toplevel_dict) 291 return NULL; 292 293 // Placeholder to insert in place of the filtered setting. 294 const char kPlaceholder[] = "********"; 295 296 toplevel_dict = chromeos::onc::MaskCredentialsInOncObject( 297 chromeos::onc::kToplevelConfigurationSignature, 298 *toplevel_dict, 299 kPlaceholder); 300 301 base::JSONWriter::WriteWithOptions(toplevel_dict.get(), 302 base::JSONWriter::OPTIONS_PRETTY_PRINT, 303 &json_string); 304 return new base::StringValue(json_string); 305} 306 307PinnedLauncherAppsPolicyHandler::PinnedLauncherAppsPolicyHandler() 308 : ExtensionListPolicyHandler(key::kPinnedLauncherApps, 309 prefs::kPinnedLauncherApps, 310 false) {} 311 312PinnedLauncherAppsPolicyHandler::~PinnedLauncherAppsPolicyHandler() {} 313 314void 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) { 324 std::string id; 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); 329 } 330 } 331 prefs->SetValue(pref_path(), pinned_apps_list); 332 } 333} 334 335ScreenMagnifierPolicyHandler::ScreenMagnifierPolicyHandler() 336 : IntRangePolicyHandlerBase(key::kScreenMagnifierType, 337 0, ash::MAGNIFIER_FULL, false) { 338} 339 340ScreenMagnifierPolicyHandler::~ScreenMagnifierPolicyHandler() { 341} 342 343void ScreenMagnifierPolicyHandler::ApplyPolicySettings( 344 const PolicyMap& policies, 345 PrefValueMap* prefs) { 346 const base::Value* value = policies.GetValue(policy_name()); 347 int value_in_range; 348 if (value && EnsureInRange(value, &value_in_range, NULL)) { 349 prefs->SetValue(prefs::kScreenMagnifierEnabled, 350 new base::FundamentalValue(value_in_range != 0)); 351 prefs->SetValue(prefs::kScreenMagnifierType, 352 new base::FundamentalValue(value_in_range)); 353 } 354} 355 356LoginScreenPowerManagementPolicyHandler:: 357 LoginScreenPowerManagementPolicyHandler(const Schema& chrome_schema) 358 : SchemaValidatingPolicyHandler(key::kDeviceLoginScreenPowerManagement, 359 chrome_schema.GetKnownProperty( 360 key::kDeviceLoginScreenPowerManagement), 361 SCHEMA_ALLOW_UNKNOWN) { 362} 363 364LoginScreenPowerManagementPolicyHandler:: 365 ~LoginScreenPowerManagementPolicyHandler() { 366} 367 368void LoginScreenPowerManagementPolicyHandler::ApplyPolicySettings( 369 const PolicyMap& policies, 370 PrefValueMap* prefs) { 371} 372 373DeprecatedIdleActionHandler::DeprecatedIdleActionHandler() 374 : IntRangePolicyHandlerBase( 375 key::kIdleAction, 376 chromeos::PowerPolicyController::ACTION_SUSPEND, 377 chromeos::PowerPolicyController::ACTION_DO_NOTHING, 378 false) {} 379 380DeprecatedIdleActionHandler::~DeprecatedIdleActionHandler() {} 381 382void 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()); 390 } 391} 392 393PowerManagementIdleSettingsPolicyHandler:: 394 PowerManagementIdleSettingsPolicyHandler(const Schema& chrome_schema) 395 : SchemaValidatingPolicyHandler( 396 key::kPowerManagementIdleSettings, 397 chrome_schema.GetKnownProperty(key::kPowerManagementIdleSettings), 398 SCHEMA_ALLOW_UNKNOWN) { 399} 400 401PowerManagementIdleSettingsPolicyHandler:: 402 ~PowerManagementIdleSettingsPolicyHandler() { 403} 404 405void PowerManagementIdleSettingsPolicyHandler::ApplyPolicySettings( 406 const PolicyMap& policies, 407 PrefValueMap* prefs) { 408 scoped_ptr<base::Value> policy_value; 409 if (!CheckAndGetValue(policies, NULL, &policy_value)) 410 return; 411 const base::DictionaryValue* dict = NULL; 412 if (!policy_value->GetAsDictionary(&dict)) { 413 NOTREACHED(); 414 return; 415 } 416 scoped_ptr<base::Value> value; 417 418 value = GetValue(dict, kScreenDimDelayAC); 419 if (value) 420 prefs->SetValue(prefs::kPowerAcScreenDimDelayMs, value.release()); 421 value = GetValue(dict, kScreenOffDelayAC); 422 if (value) 423 prefs->SetValue(prefs::kPowerAcScreenOffDelayMs, value.release()); 424 value = GetValue(dict, kIdleWarningDelayAC); 425 if (value) 426 prefs->SetValue(prefs::kPowerAcIdleWarningDelayMs, value.release()); 427 value = GetValue(dict, kIdleDelayAC); 428 if (value) 429 prefs->SetValue(prefs::kPowerAcIdleDelayMs, value.release()); 430 value = GetAction(dict, kIdleActionAC); 431 if (value) 432 prefs->SetValue(prefs::kPowerAcIdleAction, value.release()); 433 434 value = GetValue(dict, kScreenDimDelayBattery); 435 if (value) 436 prefs->SetValue(prefs::kPowerBatteryScreenDimDelayMs, value.release()); 437 value = GetValue(dict, kScreenOffDelayBattery); 438 if (value) 439 prefs->SetValue(prefs::kPowerBatteryScreenOffDelayMs, value.release()); 440 value = GetValue(dict, kIdleWarningDelayBattery); 441 if (value) 442 prefs->SetValue(prefs::kPowerBatteryIdleWarningDelayMs, value.release()); 443 value = GetValue(dict, kIdleDelayBattery); 444 if (value) 445 prefs->SetValue(prefs::kPowerBatteryIdleDelayMs, value.release()); 446 value = GetAction(dict, kIdleActionBattery); 447 if (value) 448 prefs->SetValue(prefs::kPowerBatteryIdleAction, value.release()); 449} 450 451ScreenLockDelayPolicyHandler::ScreenLockDelayPolicyHandler( 452 const Schema& chrome_schema) 453 : SchemaValidatingPolicyHandler( 454 key::kScreenLockDelays, 455 chrome_schema.GetKnownProperty(key::kScreenLockDelays), 456 SCHEMA_ALLOW_UNKNOWN) { 457} 458 459ScreenLockDelayPolicyHandler::~ScreenLockDelayPolicyHandler() { 460} 461 462void ScreenLockDelayPolicyHandler::ApplyPolicySettings( 463 const PolicyMap& policies, 464 PrefValueMap* prefs) { 465 scoped_ptr<base::Value> policy_value; 466 if (!CheckAndGetValue(policies, NULL, &policy_value)) 467 return; 468 const base::DictionaryValue* dict = NULL; 469 if (!policy_value->GetAsDictionary(&dict)) { 470 NOTREACHED(); 471 return; 472 } 473 scoped_ptr<base::Value> value; 474 475 value = GetValue(dict, kScreenLockDelayAC); 476 if (value) 477 prefs->SetValue(prefs::kPowerAcScreenLockDelayMs, value.release()); 478 value = GetValue(dict, kScreenLockDelayBattery); 479 if (value) 480 prefs->SetValue(prefs::kPowerBatteryScreenLockDelayMs, value.release()); 481} 482 483} // namespace policy 484