configuration_policy_handler_chromeos.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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/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" 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 66} // namespace 67 68ExternalDataPolicyHandler::ExternalDataPolicyHandler(const char* policy_name) 69 : TypeCheckingPolicyHandler(policy_name, Value::TYPE_DICTIONARY) { 70} 71 72ExternalDataPolicyHandler::~ExternalDataPolicyHandler() { 73} 74 75bool ExternalDataPolicyHandler::CheckPolicySettings(const PolicyMap& policies, 76 PolicyErrorMap* errors) { 77 if (!TypeCheckingPolicyHandler::CheckPolicySettings(policies, errors)) 78 return false; 79 80 const std::string policy = policy_name(); 81 const base::Value* value = policies.GetValue(policy); 82 if (!value) 83 return true; 84 85 const DictionaryValue* dict = NULL; 86 value->GetAsDictionary(&dict); 87 if (!dict) { 88 NOTREACHED(); 89 return false; 90 } 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)) { 95 return false; 96 } 97 98 const GURL url(url_string); 99 if (!url.is_valid()) { 100 errors->AddError(policy, kSubkeyURL, IDS_POLICY_VALUE_FORMAT_ERROR); 101 return false; 102 } 103 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); 108 return false; 109 } 110 111 return true; 112} 113 114void ExternalDataPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 115 PrefValueMap* prefs) { 116} 117 118// static 119NetworkConfigurationPolicyHandler* 120NetworkConfigurationPolicyHandler::CreateForUserPolicy() { 121 return new NetworkConfigurationPolicyHandler( 122 key::kOpenNetworkConfiguration, 123 onc::ONC_SOURCE_USER_POLICY, 124 prefs::kOpenNetworkConfiguration); 125} 126 127// static 128NetworkConfigurationPolicyHandler* 129NetworkConfigurationPolicyHandler::CreateForDevicePolicy() { 130 return new NetworkConfigurationPolicyHandler( 131 key::kDeviceOpenNetworkConfiguration, 132 onc::ONC_SOURCE_DEVICE_POLICY, 133 prefs::kDeviceOpenNetworkConfiguration); 134} 135 136NetworkConfigurationPolicyHandler::~NetworkConfigurationPolicyHandler() {} 137 138bool NetworkConfigurationPolicyHandler::CheckPolicySettings( 139 const PolicyMap& policies, 140 PolicyErrorMap* errors) { 141 const base::Value* value; 142 if (!CheckAndGetValue(policies, errors, &value)) 143 return false; 144 145 if (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); 152 return false; 153 } 154 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_); 163 164 // ONC policies are always unencrypted. 165 chromeos::onc::Validator::Result validation_result; 166 root_dict = validator.ValidateAndRepairObject( 167 &chromeos::onc::kToplevelConfigurationSignature, *root_dict, 168 &validation_result); 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); 173 174 // In any case, don't reject the policy as some networks or certificates 175 // could still be applied. 176 } 177 178 return true; 179} 180 181void NetworkConfigurationPolicyHandler::ApplyPolicySettings( 182 const PolicyMap& policies, 183 PrefValueMap* prefs) { 184 const base::Value* value = policies.GetValue(policy_name()); 185 if (!value) 186 return; 187 188 std::string onc_blob; 189 value->GetAsString(&onc_blob); 190 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, 195 onc_source_, 196 "", 197 network_configs.get(), 198 &global_network_config, 199 &certificates); 200 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()); 204} 205 206void NetworkConfigurationPolicyHandler::PrepareForDisplaying( 207 PolicyMap* policies) const { 208 const PolicyMap::Entry* entry = policies->Get(policy_name()); 209 if (!entry) 210 return; 211 base::Value* sanitized_config = SanitizeNetworkConfig(entry->value); 212 if (!sanitized_config) 213 sanitized_config = base::Value::CreateNullValue(); 214 215 policies->Set(policy_name(), entry->level, entry->scope, 216 sanitized_config, NULL); 217} 218 219NetworkConfigurationPolicyHandler::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) { 226} 227 228// static 229base::Value* NetworkConfigurationPolicyHandler::SanitizeNetworkConfig( 230 const base::Value* config) { 231 std::string json_string; 232 if (!config->GetAsString(&json_string)) 233 return NULL; 234 235 scoped_ptr<base::DictionaryValue> toplevel_dict = 236 chromeos::onc::ReadDictionaryFromJson(json_string); 237 if (!toplevel_dict) 238 return NULL; 239 240 // Placeholder to insert in place of the filtered setting. 241 const char kPlaceholder[] = "********"; 242 243 toplevel_dict = chromeos::onc::MaskCredentialsInOncObject( 244 chromeos::onc::kToplevelConfigurationSignature, 245 *toplevel_dict, 246 kPlaceholder); 247 248 base::JSONWriter::WriteWithOptions(toplevel_dict.get(), 249 base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | 250 base::JSONWriter::OPTIONS_PRETTY_PRINT, 251 &json_string); 252 return base::Value::CreateStringValue(json_string); 253} 254 255PinnedLauncherAppsPolicyHandler::PinnedLauncherAppsPolicyHandler() 256 : ExtensionListPolicyHandler(key::kPinnedLauncherApps, 257 prefs::kPinnedLauncherApps, 258 false) {} 259 260PinnedLauncherAppsPolicyHandler::~PinnedLauncherAppsPolicyHandler() {} 261 262void PinnedLauncherAppsPolicyHandler::ApplyPolicySettings( 263 const PolicyMap& policies, 264 PrefValueMap* prefs) { 265 PolicyErrorMap errors; 266 const base::Value* policy_value = policies.GetValue(policy_name()); 267 const base::ListValue* policy_list = NULL; 268 if (policy_value && policy_value->GetAsList(&policy_list) && policy_list) { 269 base::ListValue* pinned_apps_list = new base::ListValue(); 270 for (base::ListValue::const_iterator entry(policy_list->begin()); 271 entry != policy_list->end(); ++entry) { 272 std::string id; 273 if ((*entry)->GetAsString(&id)) { 274 base::DictionaryValue* app_dict = new base::DictionaryValue(); 275 app_dict->SetString(ash::kPinnedAppsPrefAppIDPath, id); 276 pinned_apps_list->Append(app_dict); 277 } 278 } 279 prefs->SetValue(pref_path(), pinned_apps_list); 280 } 281} 282 283ScreenMagnifierPolicyHandler::ScreenMagnifierPolicyHandler() 284 : IntRangePolicyHandlerBase(key::kScreenMagnifierType, 285 0, ash::MAGNIFIER_FULL, false) { 286} 287 288ScreenMagnifierPolicyHandler::~ScreenMagnifierPolicyHandler() { 289} 290 291void ScreenMagnifierPolicyHandler::ApplyPolicySettings( 292 const PolicyMap& policies, 293 PrefValueMap* prefs) { 294 const base::Value* value = policies.GetValue(policy_name()); 295 int value_in_range; 296 if (value && EnsureInRange(value, &value_in_range, NULL)) { 297 prefs->SetValue(prefs::kScreenMagnifierEnabled, 298 base::Value::CreateBooleanValue(value_in_range != 0)); 299 prefs->SetValue(prefs::kScreenMagnifierType, 300 base::Value::CreateIntegerValue(value_in_range)); 301 } 302} 303 304LoginScreenPowerManagementPolicyHandler:: 305 LoginScreenPowerManagementPolicyHandler() 306 : TypeCheckingPolicyHandler(key::kDeviceLoginScreenPowerManagement, 307 base::Value::TYPE_STRING) { 308} 309 310LoginScreenPowerManagementPolicyHandler:: 311 ~LoginScreenPowerManagementPolicyHandler() { 312} 313 314bool LoginScreenPowerManagementPolicyHandler::CheckPolicySettings( 315 const PolicyMap& policies, 316 PolicyErrorMap* errors) { 317 const base::Value* value; 318 if (!CheckAndGetValue(policies, errors, &value)) 319 return false; 320 321 if (!value) 322 return true; 323 324 std::string json; 325 value->GetAsString(&json); 326 return LoginScreenPowerManagementPolicy().Init(json, errors); 327} 328 329void LoginScreenPowerManagementPolicyHandler::ApplyPolicySettings( 330 const PolicyMap& policies, 331 PrefValueMap* prefs) { 332} 333 334DeprecatedIdleActionHandler::DeprecatedIdleActionHandler() 335 : IntRangePolicyHandlerBase( 336 key::kIdleAction, 337 chromeos::PowerPolicyController::ACTION_SUSPEND, 338 chromeos::PowerPolicyController::ACTION_DO_NOTHING, 339 false) {} 340 341DeprecatedIdleActionHandler::~DeprecatedIdleActionHandler() {} 342 343void DeprecatedIdleActionHandler::ApplyPolicySettings(const PolicyMap& policies, 344 PrefValueMap* prefs) { 345 const base::Value* value = policies.GetValue(policy_name()); 346 if (value && EnsureInRange(value, NULL, NULL)) { 347 if (!prefs->GetValue(prefs::kPowerAcIdleAction, NULL)) 348 prefs->SetValue(prefs::kPowerAcIdleAction, value->DeepCopy()); 349 if (!prefs->GetValue(prefs::kPowerBatteryIdleAction, NULL)) 350 prefs->SetValue(prefs::kPowerBatteryIdleAction, value->DeepCopy()); 351 } 352} 353 354} // namespace policy 355