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/policy/configuration_policy_handler.h" 6 7 #include <algorithm> 8 9 #include "base/callback.h" 10 #include "base/files/file_path.h" 11 #include "base/json/json_writer.h" 12 #include "base/logging.h" 13 #include "base/prefs/pref_value_map.h" 14 #include "base/stl_util.h" 15 #include "base/strings/string16.h" 16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_util.h" 18 #include "chrome/browser/chrome_notification_types.h" 19 #include "chrome/browser/download/download_util.h" 20 #include "chrome/browser/extensions/external_policy_loader.h" 21 #include "chrome/browser/policy/configuration_policy_pref_store.h" 22 #include "chrome/browser/policy/external_data_fetcher.h" 23 #include "chrome/browser/policy/policy_error_map.h" 24 #include "chrome/browser/policy/policy_map.h" 25 #include "chrome/browser/prefs/proxy_config_dictionary.h" 26 #include "chrome/browser/prefs/proxy_prefs.h" 27 #include "chrome/browser/prefs/session_startup_pref.h" 28 #include "chrome/browser/search_engines/search_terms_data.h" 29 #include "chrome/browser/search_engines/template_url.h" 30 #include "chrome/common/extensions/extension.h" 31 #include "chrome/common/pref_names.h" 32 #include "content/public/browser/notification_service.h" 33 #include "grit/generated_resources.h" 34 #include "policy/policy_constants.h" 35 #include "url/gurl.h" 36 37 #if !defined(OS_ANDROID) 38 #include "chrome/browser/policy/policy_path_parser.h" 39 #endif 40 41 namespace policy { 42 43 namespace { 44 45 // Helper classes -------------------------------------------------------------- 46 47 // This is used to check whether for a given ProxyMode value, the ProxyPacUrl, 48 // the ProxyBypassList and the ProxyServer policies are allowed to be specified. 49 // |error_message_id| is the message id of the localized error message to show 50 // when the policies are not specified as allowed. Each value of ProxyMode 51 // has a ProxyModeValidationEntry in the |kProxyModeValidationMap| below. 52 struct ProxyModeValidationEntry { 53 const char* mode_value; 54 bool pac_url_allowed; 55 bool bypass_list_allowed; 56 bool server_allowed; 57 int error_message_id; 58 }; 59 60 // Maps a policy type to a preference path, and to the expected value type. 61 struct DefaultSearchSimplePolicyHandlerEntry { 62 const char* policy_name; 63 const char* preference_path; 64 base::Value::Type value_type; 65 }; 66 67 68 // Static data ----------------------------------------------------------------- 69 70 // List of policy types to preference names, for policies affecting the default 71 // search provider. 72 const DefaultSearchSimplePolicyHandlerEntry kDefaultSearchPolicyMap[] = { 73 { key::kDefaultSearchProviderEnabled, 74 prefs::kDefaultSearchProviderEnabled, 75 Value::TYPE_BOOLEAN }, 76 { key::kDefaultSearchProviderName, 77 prefs::kDefaultSearchProviderName, 78 Value::TYPE_STRING }, 79 { key::kDefaultSearchProviderKeyword, 80 prefs::kDefaultSearchProviderKeyword, 81 Value::TYPE_STRING }, 82 { key::kDefaultSearchProviderSearchURL, 83 prefs::kDefaultSearchProviderSearchURL, 84 Value::TYPE_STRING }, 85 { key::kDefaultSearchProviderSuggestURL, 86 prefs::kDefaultSearchProviderSuggestURL, 87 Value::TYPE_STRING }, 88 { key::kDefaultSearchProviderInstantURL, 89 prefs::kDefaultSearchProviderInstantURL, 90 Value::TYPE_STRING }, 91 { key::kDefaultSearchProviderIconURL, 92 prefs::kDefaultSearchProviderIconURL, 93 Value::TYPE_STRING }, 94 { key::kDefaultSearchProviderEncodings, 95 prefs::kDefaultSearchProviderEncodings, 96 Value::TYPE_LIST }, 97 { key::kDefaultSearchProviderAlternateURLs, 98 prefs::kDefaultSearchProviderAlternateURLs, 99 Value::TYPE_LIST }, 100 { key::kDefaultSearchProviderSearchTermsReplacementKey, 101 prefs::kDefaultSearchProviderSearchTermsReplacementKey, 102 Value::TYPE_STRING }, 103 { key::kDefaultSearchProviderImageURL, 104 prefs::kDefaultSearchProviderImageURL, 105 Value::TYPE_STRING }, 106 { key::kDefaultSearchProviderSearchURLPostParams, 107 prefs::kDefaultSearchProviderSearchURLPostParams, 108 Value::TYPE_STRING }, 109 { key::kDefaultSearchProviderSuggestURLPostParams, 110 prefs::kDefaultSearchProviderSuggestURLPostParams, 111 Value::TYPE_STRING }, 112 { key::kDefaultSearchProviderInstantURLPostParams, 113 prefs::kDefaultSearchProviderInstantURLPostParams, 114 Value::TYPE_STRING }, 115 { key::kDefaultSearchProviderImageURLPostParams, 116 prefs::kDefaultSearchProviderImageURLPostParams, 117 Value::TYPE_STRING }, 118 }; 119 120 // List of entries determining which proxy policies can be specified, depending 121 // on the ProxyMode. 122 const ProxyModeValidationEntry kProxyModeValidationMap[] = { 123 { ProxyPrefs::kDirectProxyModeName, 124 false, false, false, IDS_POLICY_PROXY_MODE_DISABLED_ERROR }, 125 { ProxyPrefs::kAutoDetectProxyModeName, 126 false, false, false, IDS_POLICY_PROXY_MODE_AUTO_DETECT_ERROR }, 127 { ProxyPrefs::kPacScriptProxyModeName, 128 true, false, false, IDS_POLICY_PROXY_MODE_PAC_URL_ERROR }, 129 { ProxyPrefs::kFixedServersProxyModeName, 130 false, true, true, IDS_POLICY_PROXY_MODE_FIXED_SERVERS_ERROR }, 131 { ProxyPrefs::kSystemProxyModeName, 132 false, false, false, IDS_POLICY_PROXY_MODE_SYSTEM_ERROR }, 133 }; 134 135 136 // Helper function ------------------------------------------------------------- 137 138 // Utility function that returns a JSON representation of the given |dict| as 139 // a StringValue. The caller owns the returned object. 140 base::StringValue* DictionaryToJSONString(const base::DictionaryValue* dict) { 141 std::string json_string; 142 base::JSONWriter::WriteWithOptions( 143 dict, 144 base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | 145 base::JSONWriter::OPTIONS_PRETTY_PRINT, 146 &json_string); 147 return Value::CreateStringValue(json_string); 148 } 149 150 151 } // namespace 152 153 154 // ConfigurationPolicyHandler implementation ----------------------------------- 155 156 // static 157 std::string ConfigurationPolicyHandler::ValueTypeToString(Value::Type type) { 158 static const char* strings[] = { 159 "null", 160 "boolean", 161 "integer", 162 "double", 163 "string", 164 "binary", 165 "dictionary", 166 "list" 167 }; 168 CHECK(static_cast<size_t>(type) < arraysize(strings)); 169 return std::string(strings[type]); 170 } 171 172 ConfigurationPolicyHandler::ConfigurationPolicyHandler() { 173 } 174 175 ConfigurationPolicyHandler::~ConfigurationPolicyHandler() { 176 } 177 178 void ConfigurationPolicyHandler::PrepareForDisplaying( 179 PolicyMap* policies) const { 180 // jstemplate can't render DictionaryValues/objects. Convert those values to 181 // a string representation. 182 base::DictionaryValue* dict; 183 base::ListValue* list; 184 for (PolicyMap::const_iterator it = policies->begin(); 185 it != policies->end(); ++it) { 186 const PolicyMap::Entry& entry = it->second; 187 if (entry.value->GetAsDictionary(&dict)) { 188 base::StringValue* value = DictionaryToJSONString(dict); 189 policies->Set(it->first, entry.level, entry.scope, 190 value, entry.external_data_fetcher ? 191 new ExternalDataFetcher(*entry.external_data_fetcher) : 192 NULL); 193 } else if (entry.value->GetAsList(&list)) { 194 for (size_t i = 0; i < list->GetSize(); ++i) { 195 if (list->GetDictionary(i, &dict)) { 196 list->Set(i, DictionaryToJSONString(dict)); 197 } 198 } 199 } 200 } 201 } 202 203 204 // TypeCheckingPolicyHandler implementation ------------------------------------ 205 206 TypeCheckingPolicyHandler::TypeCheckingPolicyHandler( 207 const char* policy_name, 208 Value::Type value_type) 209 : policy_name_(policy_name), 210 value_type_(value_type) { 211 } 212 213 TypeCheckingPolicyHandler::~TypeCheckingPolicyHandler() { 214 } 215 216 const char* TypeCheckingPolicyHandler::policy_name() const { 217 return policy_name_; 218 } 219 220 bool TypeCheckingPolicyHandler::CheckPolicySettings(const PolicyMap& policies, 221 PolicyErrorMap* errors) { 222 const Value* value = NULL; 223 return CheckAndGetValue(policies, errors, &value); 224 } 225 226 bool TypeCheckingPolicyHandler::CheckAndGetValue(const PolicyMap& policies, 227 PolicyErrorMap* errors, 228 const Value** value) { 229 *value = policies.GetValue(policy_name_); 230 if (*value && !(*value)->IsType(value_type_)) { 231 errors->AddError(policy_name_, 232 IDS_POLICY_TYPE_ERROR, 233 ValueTypeToString(value_type_)); 234 return false; 235 } 236 return true; 237 } 238 239 // IntRangePolicyHandlerBase implementation ------------------------------------ 240 241 IntRangePolicyHandlerBase::IntRangePolicyHandlerBase( 242 const char* policy_name, 243 int min, 244 int max, 245 bool clamp) 246 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_INTEGER), 247 min_(min), 248 max_(max), 249 clamp_(clamp) { 250 } 251 252 bool IntRangePolicyHandlerBase::CheckPolicySettings(const PolicyMap& policies, 253 PolicyErrorMap* errors) { 254 const base::Value* value; 255 return CheckAndGetValue(policies, errors, &value) && 256 EnsureInRange(value, NULL, errors); 257 } 258 259 IntRangePolicyHandlerBase::~IntRangePolicyHandlerBase() { 260 } 261 262 bool IntRangePolicyHandlerBase::EnsureInRange(const base::Value* input, 263 int* output, 264 PolicyErrorMap* errors) { 265 if (!input) 266 return true; 267 268 int value; 269 if (!input->GetAsInteger(&value)) { 270 NOTREACHED(); 271 return false; 272 } 273 274 if (value < min_ || value > max_) { 275 if (errors) { 276 errors->AddError(policy_name(), 277 IDS_POLICY_OUT_OF_RANGE_ERROR, 278 base::IntToString(value)); 279 } 280 281 if (!clamp_) 282 return false; 283 284 value = std::min(std::max(value, min_), max_); 285 } 286 287 if (output) 288 *output = value; 289 return true; 290 } 291 292 // StringToIntEnumListPolicyHandler implementation ----------------------------- 293 294 StringToIntEnumListPolicyHandler::StringToIntEnumListPolicyHandler( 295 const char* policy_name, 296 const char* pref_path, 297 const MappingEntry* mapping_begin, 298 const MappingEntry* mapping_end) 299 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST), 300 pref_path_(pref_path), 301 mapping_begin_(mapping_begin), 302 mapping_end_(mapping_end) {} 303 304 bool StringToIntEnumListPolicyHandler::CheckPolicySettings( 305 const PolicyMap& policies, 306 PolicyErrorMap* errors) { 307 const base::Value* value; 308 return CheckAndGetValue(policies, errors, &value) && 309 Convert(value, NULL, errors); 310 } 311 312 void StringToIntEnumListPolicyHandler::ApplyPolicySettings( 313 const PolicyMap& policies, 314 PrefValueMap* prefs) { 315 if (!pref_path_) 316 return; 317 const base::Value* value = policies.GetValue(policy_name()); 318 scoped_ptr<base::ListValue> list(new base::ListValue()); 319 if (value && Convert(value, list.get(), NULL)) 320 prefs->SetValue(pref_path_, list.release()); 321 } 322 323 bool StringToIntEnumListPolicyHandler::Convert(const base::Value* input, 324 base::ListValue* output, 325 PolicyErrorMap* errors) { 326 if (!input) 327 return true; 328 329 const base::ListValue* list_value = NULL; 330 if (!input->GetAsList(&list_value)) { 331 NOTREACHED(); 332 return false; 333 } 334 335 for (base::ListValue::const_iterator entry(list_value->begin()); 336 entry != list_value->end(); ++entry) { 337 std::string entry_value; 338 if (!(*entry)->GetAsString(&entry_value)) { 339 if (errors) { 340 errors->AddError(policy_name(), 341 entry - list_value->begin(), 342 IDS_POLICY_TYPE_ERROR, 343 ValueTypeToString(base::Value::TYPE_STRING)); 344 } 345 continue; 346 } 347 bool found = false; 348 for (const MappingEntry* mapping_entry(mapping_begin_); 349 mapping_entry != mapping_end_; ++mapping_entry) { 350 if (mapping_entry->enum_value == entry_value) { 351 found = true; 352 if (output) 353 output->AppendInteger(mapping_entry->int_value); 354 break; 355 } 356 } 357 if (!found) { 358 if (errors) { 359 errors->AddError(policy_name(), 360 entry - list_value->begin(), 361 IDS_POLICY_OUT_OF_RANGE_ERROR); 362 } 363 } 364 } 365 366 return true; 367 } 368 369 // IntRangePolicyHandler implementation ---------------------------------------- 370 371 IntRangePolicyHandler::IntRangePolicyHandler(const char* policy_name, 372 const char* pref_path, 373 int min, 374 int max, 375 bool clamp) 376 : IntRangePolicyHandlerBase(policy_name, min, max, clamp), 377 pref_path_(pref_path) { 378 } 379 380 IntRangePolicyHandler::~IntRangePolicyHandler() { 381 } 382 383 void IntRangePolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 384 PrefValueMap* prefs) { 385 if (!pref_path_) 386 return; 387 const base::Value* value = policies.GetValue(policy_name()); 388 int value_in_range; 389 if (value && EnsureInRange(value, &value_in_range, NULL)) { 390 prefs->SetValue(pref_path_, 391 base::Value::CreateIntegerValue(value_in_range)); 392 } 393 } 394 395 // IntPercentageToDoublePolicyHandler implementation --------------------------- 396 397 IntPercentageToDoublePolicyHandler::IntPercentageToDoublePolicyHandler( 398 const char* policy_name, 399 const char* pref_path, 400 int min, 401 int max, 402 bool clamp) 403 : IntRangePolicyHandlerBase(policy_name, min, max, clamp), 404 pref_path_(pref_path) { 405 } 406 407 IntPercentageToDoublePolicyHandler::~IntPercentageToDoublePolicyHandler() { 408 } 409 410 void IntPercentageToDoublePolicyHandler::ApplyPolicySettings( 411 const PolicyMap& policies, 412 PrefValueMap* prefs) { 413 if (!pref_path_) 414 return; 415 const base::Value* value = policies.GetValue(policy_name()); 416 int percentage; 417 if (value && EnsureInRange(value, &percentage, NULL)) { 418 prefs->SetValue(pref_path_, base::Value::CreateDoubleValue( 419 static_cast<double>(percentage) / 100.)); 420 } 421 } 422 423 // ExtensionListPolicyHandler implementation ----------------------------------- 424 425 ExtensionListPolicyHandler::ExtensionListPolicyHandler(const char* policy_name, 426 const char* pref_path, 427 bool allow_wildcards) 428 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST), 429 pref_path_(pref_path), 430 allow_wildcards_(allow_wildcards) {} 431 432 ExtensionListPolicyHandler::~ExtensionListPolicyHandler() {} 433 434 bool ExtensionListPolicyHandler::CheckPolicySettings( 435 const PolicyMap& policies, 436 PolicyErrorMap* errors) { 437 return CheckAndGetList(policies, errors, NULL); 438 } 439 440 void ExtensionListPolicyHandler::ApplyPolicySettings( 441 const PolicyMap& policies, 442 PrefValueMap* prefs) { 443 scoped_ptr<base::ListValue> list; 444 PolicyErrorMap errors; 445 if (CheckAndGetList(policies, &errors, &list) && list) 446 prefs->SetValue(pref_path(), list.release()); 447 } 448 449 const char* ExtensionListPolicyHandler::pref_path() const { 450 return pref_path_; 451 } 452 453 bool ExtensionListPolicyHandler::CheckAndGetList( 454 const PolicyMap& policies, 455 PolicyErrorMap* errors, 456 scoped_ptr<base::ListValue>* extension_ids) { 457 if (extension_ids) 458 extension_ids->reset(); 459 460 const base::Value* value = NULL; 461 if (!CheckAndGetValue(policies, errors, &value)) 462 return false; 463 464 if (!value) 465 return true; 466 467 const base::ListValue* list_value = NULL; 468 if (!value->GetAsList(&list_value)) { 469 NOTREACHED(); 470 return false; 471 } 472 473 // Filter the list, rejecting any invalid extension IDs. 474 scoped_ptr<base::ListValue> filtered_list(new base::ListValue()); 475 for (base::ListValue::const_iterator entry(list_value->begin()); 476 entry != list_value->end(); ++entry) { 477 std::string id; 478 if (!(*entry)->GetAsString(&id)) { 479 errors->AddError(policy_name(), 480 entry - list_value->begin(), 481 IDS_POLICY_TYPE_ERROR, 482 ValueTypeToString(base::Value::TYPE_STRING)); 483 continue; 484 } 485 if (!(allow_wildcards_ && id == "*") && 486 !extensions::Extension::IdIsValid(id)) { 487 errors->AddError(policy_name(), 488 entry - list_value->begin(), 489 IDS_POLICY_VALUE_FORMAT_ERROR); 490 continue; 491 } 492 filtered_list->Append(base::Value::CreateStringValue(id)); 493 } 494 495 if (extension_ids) 496 *extension_ids = filtered_list.Pass(); 497 498 return true; 499 } 500 501 // ExtensionInstallForcelistPolicyHandler implementation ----------------------- 502 503 ExtensionInstallForcelistPolicyHandler:: 504 ExtensionInstallForcelistPolicyHandler() 505 : TypeCheckingPolicyHandler(key::kExtensionInstallForcelist, 506 base::Value::TYPE_LIST) {} 507 508 ExtensionInstallForcelistPolicyHandler:: 509 ~ExtensionInstallForcelistPolicyHandler() {} 510 511 bool ExtensionInstallForcelistPolicyHandler::CheckPolicySettings( 512 const PolicyMap& policies, 513 PolicyErrorMap* errors) { 514 const base::Value* value; 515 return CheckAndGetValue(policies, errors, &value) && 516 ParseList(value, NULL, errors); 517 } 518 519 void ExtensionInstallForcelistPolicyHandler::ApplyPolicySettings( 520 const PolicyMap& policies, 521 PrefValueMap* prefs) { 522 const base::Value* value = NULL; 523 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 524 if (CheckAndGetValue(policies, NULL, &value) && 525 value && 526 ParseList(value, dict.get(), NULL)) { 527 prefs->SetValue(prefs::kExtensionInstallForceList, dict.release()); 528 } 529 } 530 531 bool ExtensionInstallForcelistPolicyHandler::ParseList( 532 const base::Value* policy_value, 533 base::DictionaryValue* extension_dict, 534 PolicyErrorMap* errors) { 535 if (!policy_value) 536 return true; 537 538 const base::ListValue* policy_list_value = NULL; 539 if (!policy_value->GetAsList(&policy_list_value)) { 540 // This should have been caught in CheckPolicySettings. 541 NOTREACHED(); 542 return false; 543 } 544 545 for (base::ListValue::const_iterator entry(policy_list_value->begin()); 546 entry != policy_list_value->end(); ++entry) { 547 std::string entry_string; 548 if (!(*entry)->GetAsString(&entry_string)) { 549 if (errors) { 550 errors->AddError(policy_name(), 551 entry - policy_list_value->begin(), 552 IDS_POLICY_TYPE_ERROR, 553 ValueTypeToString(base::Value::TYPE_STRING)); 554 } 555 continue; 556 } 557 558 // Each string item of the list has the following form: 559 // <extension_id>;<update_url> 560 // Note: The update URL might also contain semicolons. 561 size_t pos = entry_string.find(';'); 562 if (pos == std::string::npos) { 563 if (errors) { 564 errors->AddError(policy_name(), 565 entry - policy_list_value->begin(), 566 IDS_POLICY_VALUE_FORMAT_ERROR); 567 } 568 continue; 569 } 570 571 std::string extension_id = entry_string.substr(0, pos); 572 std::string update_url = entry_string.substr(pos+1); 573 if (!extensions::Extension::IdIsValid(extension_id) || 574 !GURL(update_url).is_valid()) { 575 if (errors) { 576 errors->AddError(policy_name(), 577 entry - policy_list_value->begin(), 578 IDS_POLICY_VALUE_FORMAT_ERROR); 579 } 580 continue; 581 } 582 583 if (extension_dict) { 584 extensions::ExternalPolicyLoader::AddExtension( 585 extension_dict, extension_id, update_url); 586 } 587 } 588 589 return true; 590 } 591 592 // ExtensionURLPatternListPolicyHandler implementation ------------------------- 593 594 ExtensionURLPatternListPolicyHandler::ExtensionURLPatternListPolicyHandler( 595 const char* policy_name, 596 const char* pref_path) 597 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_LIST), 598 pref_path_(pref_path) {} 599 600 ExtensionURLPatternListPolicyHandler::~ExtensionURLPatternListPolicyHandler() {} 601 602 bool ExtensionURLPatternListPolicyHandler::CheckPolicySettings( 603 const PolicyMap& policies, 604 PolicyErrorMap* errors) { 605 const base::Value* value = NULL; 606 if (!CheckAndGetValue(policies, errors, &value)) 607 return false; 608 609 if (!value) 610 return true; 611 612 const base::ListValue* list_value = NULL; 613 if (!value->GetAsList(&list_value)) { 614 NOTREACHED(); 615 return false; 616 } 617 618 // Check that the list contains valid URLPattern strings only. 619 for (base::ListValue::const_iterator entry(list_value->begin()); 620 entry != list_value->end(); ++entry) { 621 std::string url_pattern_string; 622 if (!(*entry)->GetAsString(&url_pattern_string)) { 623 errors->AddError(policy_name(), 624 entry - list_value->begin(), 625 IDS_POLICY_TYPE_ERROR, 626 ValueTypeToString(base::Value::TYPE_STRING)); 627 return false; 628 } 629 630 URLPattern pattern(URLPattern::SCHEME_ALL); 631 if (pattern.Parse(url_pattern_string) != URLPattern::PARSE_SUCCESS) { 632 errors->AddError(policy_name(), 633 entry - list_value->begin(), 634 IDS_POLICY_VALUE_FORMAT_ERROR); 635 return false; 636 } 637 } 638 639 return true; 640 } 641 642 void ExtensionURLPatternListPolicyHandler::ApplyPolicySettings( 643 const PolicyMap& policies, 644 PrefValueMap* prefs) { 645 if (!pref_path_) 646 return; 647 const Value* value = policies.GetValue(policy_name()); 648 if (value) 649 prefs->SetValue(pref_path_, value->DeepCopy()); 650 } 651 652 // SimplePolicyHandler implementation ------------------------------------------ 653 654 SimplePolicyHandler::SimplePolicyHandler( 655 const char* policy_name, 656 const char* pref_path, 657 Value::Type value_type) 658 : TypeCheckingPolicyHandler(policy_name, value_type), 659 pref_path_(pref_path) { 660 } 661 662 SimplePolicyHandler::~SimplePolicyHandler() { 663 } 664 665 void SimplePolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 666 PrefValueMap* prefs) { 667 if (!pref_path_) 668 return; 669 const Value* value = policies.GetValue(policy_name()); 670 if (value) 671 prefs->SetValue(pref_path_, value->DeepCopy()); 672 } 673 674 675 // SyncPolicyHandler implementation -------------------------------------------- 676 677 SyncPolicyHandler::SyncPolicyHandler() 678 : TypeCheckingPolicyHandler(key::kSyncDisabled, 679 Value::TYPE_BOOLEAN) { 680 } 681 682 SyncPolicyHandler::~SyncPolicyHandler() { 683 } 684 685 void SyncPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 686 PrefValueMap* prefs) { 687 const Value* value = policies.GetValue(policy_name()); 688 bool disable_sync; 689 if (value && value->GetAsBoolean(&disable_sync) && disable_sync) 690 prefs->SetValue(prefs::kSyncManaged, value->DeepCopy()); 691 } 692 693 694 // AutofillPolicyHandler implementation ---------------------------------------- 695 696 AutofillPolicyHandler::AutofillPolicyHandler() 697 : TypeCheckingPolicyHandler(key::kAutoFillEnabled, 698 Value::TYPE_BOOLEAN) { 699 } 700 701 AutofillPolicyHandler::~AutofillPolicyHandler() { 702 } 703 704 void AutofillPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 705 PrefValueMap* prefs) { 706 const Value* value = policies.GetValue(policy_name()); 707 bool auto_fill_enabled; 708 if (value && value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled) { 709 prefs->SetValue(autofill::prefs::kAutofillEnabled, 710 Value::CreateBooleanValue(false)); 711 } 712 } 713 714 // Android doesn't support these policies, and doesn't have a policy_path_parser 715 // implementation. 716 #if !defined(OS_ANDROID) 717 718 // DownloadDirPolicyHandler implementation ------------------------------------- 719 720 DownloadDirPolicyHandler::DownloadDirPolicyHandler() 721 : TypeCheckingPolicyHandler(key::kDownloadDirectory, 722 Value::TYPE_STRING) { 723 } 724 725 DownloadDirPolicyHandler::~DownloadDirPolicyHandler() { 726 } 727 728 void DownloadDirPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 729 PrefValueMap* prefs) { 730 const Value* value = policies.GetValue(policy_name()); 731 base::FilePath::StringType string_value; 732 if (!value || !value->GetAsString(&string_value)) 733 return; 734 735 base::FilePath::StringType expanded_value = 736 policy::path_parser::ExpandPathVariables(string_value); 737 // Make sure the path isn't empty, since that will point to an undefined 738 // location; the default location is used instead in that case. 739 // This is checked after path expansion because a non-empty policy value can 740 // lead to an empty path value after expansion (e.g. "\"\""). 741 if (expanded_value.empty()) 742 expanded_value = download_util::GetDefaultDownloadDirectory().value(); 743 prefs->SetValue(prefs::kDownloadDefaultDirectory, 744 Value::CreateStringValue(expanded_value)); 745 prefs->SetValue(prefs::kPromptForDownload, 746 Value::CreateBooleanValue(false)); 747 } 748 749 750 // DiskCacheDirPolicyHandler implementation ------------------------------------ 751 752 DiskCacheDirPolicyHandler::DiskCacheDirPolicyHandler() 753 : TypeCheckingPolicyHandler(key::kDiskCacheDir, 754 Value::TYPE_STRING) { 755 } 756 757 DiskCacheDirPolicyHandler::~DiskCacheDirPolicyHandler() { 758 } 759 760 void DiskCacheDirPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 761 PrefValueMap* prefs) { 762 const Value* value = policies.GetValue(policy_name()); 763 base::FilePath::StringType string_value; 764 if (value && value->GetAsString(&string_value)) { 765 base::FilePath::StringType expanded_value = 766 policy::path_parser::ExpandPathVariables(string_value); 767 prefs->SetValue(prefs::kDiskCacheDir, 768 Value::CreateStringValue(expanded_value)); 769 } 770 } 771 772 #endif // !defined(OS_ANDROID) 773 774 // FileSelectionDialogsHandler implementation ---------------------------------- 775 776 FileSelectionDialogsHandler::FileSelectionDialogsHandler() 777 : TypeCheckingPolicyHandler(key::kAllowFileSelectionDialogs, 778 Value::TYPE_BOOLEAN) { 779 } 780 781 FileSelectionDialogsHandler::~FileSelectionDialogsHandler() { 782 } 783 784 void FileSelectionDialogsHandler::ApplyPolicySettings(const PolicyMap& policies, 785 PrefValueMap* prefs) { 786 bool allow_dialogs; 787 const Value* value = policies.GetValue(policy_name()); 788 if (value && value->GetAsBoolean(&allow_dialogs)) { 789 prefs->SetValue(prefs::kAllowFileSelectionDialogs, 790 Value::CreateBooleanValue(allow_dialogs)); 791 // Disallow selecting the download location if file dialogs are disabled. 792 if (!allow_dialogs) { 793 prefs->SetValue(prefs::kPromptForDownload, 794 Value::CreateBooleanValue(false)); 795 } 796 } 797 } 798 799 800 // IncognitoModePolicyHandler implementation ----------------------------------- 801 802 IncognitoModePolicyHandler::IncognitoModePolicyHandler() { 803 } 804 805 IncognitoModePolicyHandler::~IncognitoModePolicyHandler() { 806 } 807 808 bool IncognitoModePolicyHandler::CheckPolicySettings(const PolicyMap& policies, 809 PolicyErrorMap* errors) { 810 int int_value = IncognitoModePrefs::ENABLED; 811 const Value* availability = 812 policies.GetValue(key::kIncognitoModeAvailability); 813 814 if (availability) { 815 if (availability->GetAsInteger(&int_value)) { 816 IncognitoModePrefs::Availability availability_enum_value; 817 if (!IncognitoModePrefs::IntToAvailability(int_value, 818 &availability_enum_value)) { 819 errors->AddError(key::kIncognitoModeAvailability, 820 IDS_POLICY_OUT_OF_RANGE_ERROR, 821 base::IntToString(int_value)); 822 return false; 823 } 824 } else { 825 errors->AddError(key::kIncognitoModeAvailability, 826 IDS_POLICY_TYPE_ERROR, 827 ValueTypeToString(Value::TYPE_INTEGER)); 828 return false; 829 } 830 } else { 831 const Value* deprecated_enabled = policies.GetValue(key::kIncognitoEnabled); 832 if (deprecated_enabled && 833 !deprecated_enabled->IsType(Value::TYPE_BOOLEAN)) { 834 errors->AddError(key::kIncognitoEnabled, 835 IDS_POLICY_TYPE_ERROR, 836 ValueTypeToString(Value::TYPE_BOOLEAN)); 837 return false; 838 } 839 } 840 return true; 841 } 842 843 void IncognitoModePolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 844 PrefValueMap* prefs) { 845 const Value* availability = 846 policies.GetValue(key::kIncognitoModeAvailability); 847 const Value* deprecated_enabled = policies.GetValue(key::kIncognitoEnabled); 848 if (availability) { 849 int int_value = IncognitoModePrefs::ENABLED; 850 IncognitoModePrefs::Availability availability_enum_value; 851 if (availability->GetAsInteger(&int_value) && 852 IncognitoModePrefs::IntToAvailability(int_value, 853 &availability_enum_value)) { 854 prefs->SetValue(prefs::kIncognitoModeAvailability, 855 Value::CreateIntegerValue(availability_enum_value)); 856 } else { 857 NOTREACHED(); 858 } 859 } else if (deprecated_enabled) { 860 // If kIncognitoModeAvailability is not specified, check the obsolete 861 // kIncognitoEnabled. 862 bool enabled = true; 863 if (deprecated_enabled->GetAsBoolean(&enabled)) { 864 prefs->SetInteger(prefs::kIncognitoModeAvailability, 865 enabled ? IncognitoModePrefs::ENABLED : 866 IncognitoModePrefs::DISABLED); 867 } else { 868 NOTREACHED(); 869 } 870 } 871 } 872 873 874 // DefaultSearchEncodingsPolicyHandler implementation -------------------------- 875 876 DefaultSearchEncodingsPolicyHandler::DefaultSearchEncodingsPolicyHandler() 877 : TypeCheckingPolicyHandler(key::kDefaultSearchProviderEncodings, 878 Value::TYPE_LIST) { 879 } 880 881 DefaultSearchEncodingsPolicyHandler::~DefaultSearchEncodingsPolicyHandler() { 882 } 883 884 void DefaultSearchEncodingsPolicyHandler::ApplyPolicySettings( 885 const PolicyMap& policies, PrefValueMap* prefs) { 886 // The DefaultSearchProviderEncodings policy has type list, but the related 887 // preference has type string. Convert one into the other here, using 888 // ';' as a separator. 889 const Value* value = policies.GetValue(policy_name()); 890 const ListValue* list; 891 if (!value || !value->GetAsList(&list)) 892 return; 893 894 ListValue::const_iterator iter(list->begin()); 895 ListValue::const_iterator end(list->end()); 896 std::vector<std::string> string_parts; 897 for (; iter != end; ++iter) { 898 std::string s; 899 if ((*iter)->GetAsString(&s)) { 900 string_parts.push_back(s); 901 } 902 } 903 std::string encodings = JoinString(string_parts, ';'); 904 prefs->SetValue(prefs::kDefaultSearchProviderEncodings, 905 Value::CreateStringValue(encodings)); 906 } 907 908 909 // DefaultSearchPolicyHandler implementation ----------------------------------- 910 911 DefaultSearchPolicyHandler::DefaultSearchPolicyHandler() { 912 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) { 913 const char* policy_name = kDefaultSearchPolicyMap[i].policy_name; 914 if (policy_name == key::kDefaultSearchProviderEncodings) { 915 handlers_.push_back(new DefaultSearchEncodingsPolicyHandler()); 916 } else { 917 handlers_.push_back( 918 new SimplePolicyHandler(policy_name, 919 kDefaultSearchPolicyMap[i].preference_path, 920 kDefaultSearchPolicyMap[i].value_type)); 921 } 922 } 923 } 924 925 DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() { 926 STLDeleteElements(&handlers_); 927 } 928 929 bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap& policies, 930 PolicyErrorMap* errors) { 931 if (!CheckIndividualPolicies(policies, errors)) 932 return false; 933 934 if (DefaultSearchProviderIsDisabled(policies)) { 935 // Add an error for all specified default search policies except 936 // DefaultSearchProviderEnabled. 937 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) { 938 const char* policy_name = kDefaultSearchPolicyMap[i].policy_name; 939 if (policy_name != key::kDefaultSearchProviderEnabled && 940 HasDefaultSearchPolicy(policies, policy_name)) { 941 errors->AddError(policy_name, IDS_POLICY_DEFAULT_SEARCH_DISABLED); 942 } 943 } 944 return true; 945 } 946 947 const Value* url; 948 std::string dummy; 949 if (DefaultSearchURLIsValid(policies, &url, &dummy) || 950 !AnyDefaultSearchPoliciesSpecified(policies)) 951 return true; 952 errors->AddError(key::kDefaultSearchProviderSearchURL, url ? 953 IDS_POLICY_INVALID_SEARCH_URL_ERROR : IDS_POLICY_NOT_SPECIFIED_ERROR); 954 return false; 955 } 956 957 void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 958 PrefValueMap* prefs) { 959 if (DefaultSearchProviderIsDisabled(policies)) { 960 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, false); 961 962 // If default search is disabled, the other fields are ignored. 963 prefs->SetString(prefs::kDefaultSearchProviderName, std::string()); 964 prefs->SetString(prefs::kDefaultSearchProviderSearchURL, std::string()); 965 prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, std::string()); 966 prefs->SetString(prefs::kDefaultSearchProviderIconURL, std::string()); 967 prefs->SetString(prefs::kDefaultSearchProviderEncodings, std::string()); 968 prefs->SetString(prefs::kDefaultSearchProviderKeyword, std::string()); 969 prefs->SetString(prefs::kDefaultSearchProviderInstantURL, std::string()); 970 prefs->SetValue(prefs::kDefaultSearchProviderAlternateURLs, 971 new ListValue()); 972 prefs->SetString(prefs::kDefaultSearchProviderSearchTermsReplacementKey, 973 std::string()); 974 prefs->SetString(prefs::kDefaultSearchProviderImageURL, std::string()); 975 prefs->SetString(prefs::kDefaultSearchProviderSearchURLPostParams, 976 std::string()); 977 prefs->SetString(prefs::kDefaultSearchProviderSuggestURLPostParams, 978 std::string()); 979 prefs->SetString(prefs::kDefaultSearchProviderInstantURLPostParams, 980 std::string()); 981 prefs->SetString(prefs::kDefaultSearchProviderImageURLPostParams, 982 std::string()); 983 } else { 984 // The search URL is required. The other entries are optional. Just make 985 // sure that they are all specified via policy, so that the regular prefs 986 // aren't used. 987 const Value* dummy; 988 std::string url; 989 if (DefaultSearchURLIsValid(policies, &dummy, &url)) { 990 for (std::vector<ConfigurationPolicyHandler*>::const_iterator handler = 991 handlers_.begin(); handler != handlers_.end(); ++handler) 992 (*handler)->ApplyPolicySettings(policies, prefs); 993 994 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderSuggestURL); 995 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderIconURL); 996 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderEncodings); 997 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderKeyword); 998 EnsureStringPrefExists(prefs, prefs::kDefaultSearchProviderInstantURL); 999 EnsureListPrefExists(prefs, prefs::kDefaultSearchProviderAlternateURLs); 1000 EnsureStringPrefExists(prefs, 1001 prefs::kDefaultSearchProviderSearchTermsReplacementKey); 1002 EnsureStringPrefExists(prefs, 1003 prefs::kDefaultSearchProviderImageURL); 1004 EnsureStringPrefExists(prefs, 1005 prefs::kDefaultSearchProviderSearchURLPostParams); 1006 EnsureStringPrefExists(prefs, 1007 prefs::kDefaultSearchProviderSuggestURLPostParams); 1008 EnsureStringPrefExists(prefs, 1009 prefs::kDefaultSearchProviderInstantURLPostParams); 1010 EnsureStringPrefExists(prefs, 1011 prefs::kDefaultSearchProviderImageURLPostParams); 1012 1013 // For the name and keyword, default to the host if not specified. If 1014 // there is no host (file: URLs? Not sure), use "_" to guarantee that the 1015 // keyword is non-empty. 1016 std::string name, keyword; 1017 std::string host(GURL(url).host()); 1018 if (host.empty()) 1019 host = "_"; 1020 if (!prefs->GetString(prefs::kDefaultSearchProviderName, &name) || 1021 name.empty()) 1022 prefs->SetString(prefs::kDefaultSearchProviderName, host); 1023 if (!prefs->GetString(prefs::kDefaultSearchProviderKeyword, &keyword) || 1024 keyword.empty()) 1025 prefs->SetString(prefs::kDefaultSearchProviderKeyword, host); 1026 1027 // And clear the IDs since these are not specified via policy. 1028 prefs->SetString(prefs::kDefaultSearchProviderID, std::string()); 1029 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID, 1030 std::string()); 1031 } 1032 } 1033 content::NotificationService::current()->Notify( 1034 chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED, 1035 content::NotificationService::AllSources(), 1036 content::NotificationService::NoDetails()); 1037 } 1038 1039 bool DefaultSearchPolicyHandler::CheckIndividualPolicies( 1040 const PolicyMap& policies, 1041 PolicyErrorMap* errors) { 1042 std::vector<ConfigurationPolicyHandler*>::const_iterator handler; 1043 for (handler = handlers_.begin() ; handler != handlers_.end(); ++handler) { 1044 if (!(*handler)->CheckPolicySettings(policies, errors)) 1045 return false; 1046 } 1047 return true; 1048 } 1049 1050 bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy( 1051 const PolicyMap& policies, 1052 const char* policy_name) { 1053 return policies.Get(policy_name) != NULL; 1054 } 1055 1056 bool DefaultSearchPolicyHandler::AnyDefaultSearchPoliciesSpecified( 1057 const PolicyMap& policies) { 1058 for (size_t i = 0; i < arraysize(kDefaultSearchPolicyMap); ++i) { 1059 if (policies.Get(kDefaultSearchPolicyMap[i].policy_name)) 1060 return true; 1061 } 1062 return false; 1063 } 1064 1065 bool DefaultSearchPolicyHandler::DefaultSearchProviderIsDisabled( 1066 const PolicyMap& policies) { 1067 const Value* provider_enabled = 1068 policies.GetValue(key::kDefaultSearchProviderEnabled); 1069 bool enabled = true; 1070 return provider_enabled && provider_enabled->GetAsBoolean(&enabled) && 1071 !enabled; 1072 } 1073 1074 bool DefaultSearchPolicyHandler::DefaultSearchURLIsValid( 1075 const PolicyMap& policies, 1076 const Value** url_value, 1077 std::string* url_string) { 1078 *url_value = policies.GetValue(key::kDefaultSearchProviderSearchURL); 1079 if (!*url_value || !(*url_value)->GetAsString(url_string) || 1080 url_string->empty()) 1081 return false; 1082 TemplateURLData data; 1083 data.SetURL(*url_string); 1084 SearchTermsData search_terms_data; 1085 return TemplateURL(NULL, data).SupportsReplacementUsingTermsData( 1086 search_terms_data); 1087 } 1088 1089 void DefaultSearchPolicyHandler::EnsureStringPrefExists( 1090 PrefValueMap* prefs, 1091 const std::string& path) { 1092 std::string value; 1093 if (!prefs->GetString(path, &value)) 1094 prefs->SetString(path, value); 1095 } 1096 1097 void DefaultSearchPolicyHandler::EnsureListPrefExists( 1098 PrefValueMap* prefs, 1099 const std::string& path) { 1100 base::Value* value; 1101 base::ListValue* list_value; 1102 if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value)) 1103 prefs->SetValue(path, new ListValue()); 1104 } 1105 1106 1107 // ProxyPolicyHandler implementation ------------------------------------------- 1108 1109 // The proxy policies have the peculiarity that they are loaded from individual 1110 // policies, but the providers then expose them through a unified 1111 // DictionaryValue. Once Dictionary policies are fully supported, the individual 1112 // proxy policies will be deprecated. http://crbug.com/108996 1113 1114 ProxyPolicyHandler::ProxyPolicyHandler() { 1115 } 1116 1117 ProxyPolicyHandler::~ProxyPolicyHandler() { 1118 } 1119 1120 bool ProxyPolicyHandler::CheckPolicySettings(const PolicyMap& policies, 1121 PolicyErrorMap* errors) { 1122 const Value* mode = GetProxyPolicyValue(policies, key::kProxyMode); 1123 const Value* server = GetProxyPolicyValue(policies, key::kProxyServer); 1124 const Value* server_mode = 1125 GetProxyPolicyValue(policies, key::kProxyServerMode); 1126 const Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl); 1127 const Value* bypass_list = 1128 GetProxyPolicyValue(policies, key::kProxyBypassList); 1129 1130 if ((server || pac_url || bypass_list) && !(mode || server_mode)) { 1131 errors->AddError(key::kProxySettings, 1132 key::kProxyMode, 1133 IDS_POLICY_NOT_SPECIFIED_ERROR); 1134 return false; 1135 } 1136 1137 std::string mode_value; 1138 if (!CheckProxyModeAndServerMode(policies, errors, &mode_value)) 1139 return false; 1140 1141 // If neither ProxyMode nor ProxyServerMode are specified, mode_value will be 1142 // empty and the proxy shouldn't be configured at all. 1143 if (mode_value.empty()) 1144 return true; 1145 1146 bool is_valid_mode = false; 1147 for (size_t i = 0; i != arraysize(kProxyModeValidationMap); ++i) { 1148 const ProxyModeValidationEntry& entry = kProxyModeValidationMap[i]; 1149 if (entry.mode_value != mode_value) 1150 continue; 1151 1152 is_valid_mode = true; 1153 1154 if (!entry.pac_url_allowed && pac_url) { 1155 errors->AddError(key::kProxySettings, 1156 key::kProxyPacUrl, 1157 entry.error_message_id); 1158 } 1159 if (!entry.bypass_list_allowed && bypass_list) { 1160 errors->AddError(key::kProxySettings, 1161 key::kProxyBypassList, 1162 entry.error_message_id); 1163 } 1164 if (!entry.server_allowed && server) { 1165 errors->AddError(key::kProxySettings, 1166 key::kProxyServer, 1167 entry.error_message_id); 1168 } 1169 1170 if ((!entry.pac_url_allowed && pac_url) || 1171 (!entry.bypass_list_allowed && bypass_list) || 1172 (!entry.server_allowed && server)) { 1173 return false; 1174 } 1175 } 1176 1177 if (!is_valid_mode) { 1178 errors->AddError(key::kProxySettings, 1179 mode ? key::kProxyMode : key::kProxyServerMode, 1180 IDS_POLICY_OUT_OF_RANGE_ERROR, 1181 mode_value); 1182 return false; 1183 } 1184 return true; 1185 } 1186 1187 void ProxyPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 1188 PrefValueMap* prefs) { 1189 const Value* mode = GetProxyPolicyValue(policies, key::kProxyMode); 1190 const Value* server = GetProxyPolicyValue(policies, key::kProxyServer); 1191 const Value* server_mode = 1192 GetProxyPolicyValue(policies, key::kProxyServerMode); 1193 const Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl); 1194 const Value* bypass_list = 1195 GetProxyPolicyValue(policies, key::kProxyBypassList); 1196 1197 ProxyPrefs::ProxyMode proxy_mode; 1198 if (mode) { 1199 std::string string_mode; 1200 CHECK(mode->GetAsString(&string_mode)); 1201 CHECK(ProxyPrefs::StringToProxyMode(string_mode, &proxy_mode)); 1202 } else if (server_mode) { 1203 int int_mode = 0; 1204 CHECK(server_mode->GetAsInteger(&int_mode)); 1205 1206 switch (int_mode) { 1207 case PROXY_SERVER_MODE: 1208 proxy_mode = ProxyPrefs::MODE_DIRECT; 1209 break; 1210 case PROXY_AUTO_DETECT_PROXY_SERVER_MODE: 1211 proxy_mode = ProxyPrefs::MODE_AUTO_DETECT; 1212 break; 1213 case PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE: 1214 proxy_mode = ProxyPrefs::MODE_FIXED_SERVERS; 1215 if (pac_url) 1216 proxy_mode = ProxyPrefs::MODE_PAC_SCRIPT; 1217 break; 1218 case PROXY_USE_SYSTEM_PROXY_SERVER_MODE: 1219 proxy_mode = ProxyPrefs::MODE_SYSTEM; 1220 break; 1221 default: 1222 proxy_mode = ProxyPrefs::MODE_DIRECT; 1223 NOTREACHED(); 1224 } 1225 } else { 1226 return; 1227 } 1228 1229 switch (proxy_mode) { 1230 case ProxyPrefs::MODE_DIRECT: 1231 prefs->SetValue(prefs::kProxy, ProxyConfigDictionary::CreateDirect()); 1232 break; 1233 case ProxyPrefs::MODE_AUTO_DETECT: 1234 prefs->SetValue(prefs::kProxy, ProxyConfigDictionary::CreateAutoDetect()); 1235 break; 1236 case ProxyPrefs::MODE_PAC_SCRIPT: { 1237 std::string pac_url_string; 1238 if (pac_url && pac_url->GetAsString(&pac_url_string)) { 1239 prefs->SetValue(prefs::kProxy, 1240 ProxyConfigDictionary::CreatePacScript(pac_url_string, false)); 1241 } else { 1242 NOTREACHED(); 1243 } 1244 break; 1245 } 1246 case ProxyPrefs::MODE_FIXED_SERVERS: { 1247 std::string proxy_server; 1248 std::string bypass_list_string; 1249 if (server->GetAsString(&proxy_server)) { 1250 if (bypass_list) 1251 bypass_list->GetAsString(&bypass_list_string); 1252 prefs->SetValue(prefs::kProxy, 1253 ProxyConfigDictionary::CreateFixedServers( 1254 proxy_server, bypass_list_string)); 1255 } 1256 break; 1257 } 1258 case ProxyPrefs::MODE_SYSTEM: 1259 prefs->SetValue(prefs::kProxy, 1260 ProxyConfigDictionary::CreateSystem()); 1261 break; 1262 case ProxyPrefs::kModeCount: 1263 NOTREACHED(); 1264 } 1265 } 1266 1267 const Value* ProxyPolicyHandler::GetProxyPolicyValue( 1268 const PolicyMap& policies, const char* policy_name) { 1269 // See note on the ProxyPolicyHandler implementation above. 1270 const Value* value = policies.GetValue(key::kProxySettings); 1271 const DictionaryValue* settings; 1272 if (!value || !value->GetAsDictionary(&settings)) 1273 return NULL; 1274 1275 const Value* policy_value = NULL; 1276 std::string tmp; 1277 if (!settings->Get(policy_name, &policy_value) || 1278 policy_value->IsType(Value::TYPE_NULL) || 1279 (policy_value->IsType(Value::TYPE_STRING) && 1280 policy_value->GetAsString(&tmp) && 1281 tmp.empty())) { 1282 return NULL; 1283 } 1284 return policy_value; 1285 } 1286 1287 bool ProxyPolicyHandler::CheckProxyModeAndServerMode(const PolicyMap& policies, 1288 PolicyErrorMap* errors, 1289 std::string* mode_value) { 1290 const Value* mode = GetProxyPolicyValue(policies, key::kProxyMode); 1291 const Value* server = GetProxyPolicyValue(policies, key::kProxyServer); 1292 const Value* server_mode = 1293 GetProxyPolicyValue(policies, key::kProxyServerMode); 1294 const Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl); 1295 1296 // If there's a server mode, convert it into a mode. 1297 // When both are specified, the mode takes precedence. 1298 if (mode) { 1299 if (server_mode) { 1300 errors->AddError(key::kProxySettings, 1301 key::kProxyServerMode, 1302 IDS_POLICY_OVERRIDDEN, 1303 key::kProxyMode); 1304 } 1305 if (!mode->GetAsString(mode_value)) { 1306 errors->AddError(key::kProxySettings, 1307 key::kProxyMode, 1308 IDS_POLICY_TYPE_ERROR, 1309 ValueTypeToString(Value::TYPE_BOOLEAN)); 1310 return false; 1311 } 1312 1313 ProxyPrefs::ProxyMode mode; 1314 if (!ProxyPrefs::StringToProxyMode(*mode_value, &mode)) { 1315 errors->AddError(key::kProxySettings, 1316 key::kProxyMode, 1317 IDS_POLICY_INVALID_PROXY_MODE_ERROR); 1318 return false; 1319 } 1320 1321 if (mode == ProxyPrefs::MODE_PAC_SCRIPT && !pac_url) { 1322 errors->AddError(key::kProxySettings, 1323 key::kProxyPacUrl, 1324 IDS_POLICY_NOT_SPECIFIED_ERROR); 1325 return false; 1326 } else if (mode == ProxyPrefs::MODE_FIXED_SERVERS && !server) { 1327 errors->AddError(key::kProxySettings, 1328 key::kProxyServer, 1329 IDS_POLICY_NOT_SPECIFIED_ERROR); 1330 return false; 1331 } 1332 } else if (server_mode) { 1333 int server_mode_value; 1334 if (!server_mode->GetAsInteger(&server_mode_value)) { 1335 errors->AddError(key::kProxySettings, 1336 key::kProxyServerMode, 1337 IDS_POLICY_TYPE_ERROR, 1338 ValueTypeToString(Value::TYPE_INTEGER)); 1339 return false; 1340 } 1341 1342 switch (server_mode_value) { 1343 case PROXY_SERVER_MODE: 1344 *mode_value = ProxyPrefs::kDirectProxyModeName; 1345 break; 1346 case PROXY_AUTO_DETECT_PROXY_SERVER_MODE: 1347 *mode_value = ProxyPrefs::kAutoDetectProxyModeName; 1348 break; 1349 case PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE: 1350 if (server && pac_url) { 1351 int message_id = IDS_POLICY_PROXY_BOTH_SPECIFIED_ERROR; 1352 errors->AddError(key::kProxySettings, 1353 key::kProxyServer, 1354 message_id); 1355 errors->AddError(key::kProxySettings, 1356 key::kProxyPacUrl, 1357 message_id); 1358 return false; 1359 } 1360 if (!server && !pac_url) { 1361 int message_id = IDS_POLICY_PROXY_NEITHER_SPECIFIED_ERROR; 1362 errors->AddError(key::kProxySettings, 1363 key::kProxyServer, 1364 message_id); 1365 errors->AddError(key::kProxySettings, 1366 key::kProxyPacUrl, 1367 message_id); 1368 return false; 1369 } 1370 if (pac_url) 1371 *mode_value = ProxyPrefs::kPacScriptProxyModeName; 1372 else 1373 *mode_value = ProxyPrefs::kFixedServersProxyModeName; 1374 break; 1375 case PROXY_USE_SYSTEM_PROXY_SERVER_MODE: 1376 *mode_value = ProxyPrefs::kSystemProxyModeName; 1377 break; 1378 default: 1379 errors->AddError(key::kProxySettings, 1380 key::kProxyServerMode, 1381 IDS_POLICY_OUT_OF_RANGE_ERROR, 1382 base::IntToString(server_mode_value)); 1383 return false; 1384 } 1385 } 1386 return true; 1387 } 1388 1389 1390 // JavascriptPolicyHandler implementation -------------------------------------- 1391 1392 JavascriptPolicyHandler::JavascriptPolicyHandler() { 1393 } 1394 1395 JavascriptPolicyHandler::~JavascriptPolicyHandler() { 1396 } 1397 1398 bool JavascriptPolicyHandler::CheckPolicySettings(const PolicyMap& policies, 1399 PolicyErrorMap* errors) { 1400 const Value* javascript_enabled = policies.GetValue(key::kJavascriptEnabled); 1401 const Value* default_setting = 1402 policies.GetValue(key::kDefaultJavaScriptSetting); 1403 1404 if (javascript_enabled && !javascript_enabled->IsType(Value::TYPE_BOOLEAN)) { 1405 errors->AddError(key::kJavascriptEnabled, 1406 IDS_POLICY_TYPE_ERROR, 1407 ValueTypeToString(Value::TYPE_BOOLEAN)); 1408 } 1409 1410 if (default_setting && !default_setting->IsType(Value::TYPE_INTEGER)) { 1411 errors->AddError(key::kDefaultJavaScriptSetting, 1412 IDS_POLICY_TYPE_ERROR, 1413 ValueTypeToString(Value::TYPE_INTEGER)); 1414 } 1415 1416 if (javascript_enabled && default_setting) { 1417 errors->AddError(key::kJavascriptEnabled, 1418 IDS_POLICY_OVERRIDDEN, 1419 key::kDefaultJavaScriptSetting); 1420 } 1421 1422 return true; 1423 } 1424 1425 void JavascriptPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 1426 PrefValueMap* prefs) { 1427 int setting = CONTENT_SETTING_DEFAULT; 1428 const Value* default_setting = 1429 policies.GetValue(key::kDefaultJavaScriptSetting); 1430 1431 if (default_setting) { 1432 default_setting->GetAsInteger(&setting); 1433 } else { 1434 const Value* javascript_enabled = 1435 policies.GetValue(key::kJavascriptEnabled); 1436 bool enabled = true; 1437 if (javascript_enabled && 1438 javascript_enabled->GetAsBoolean(&enabled) && 1439 !enabled) { 1440 setting = CONTENT_SETTING_BLOCK; 1441 } 1442 } 1443 1444 if (setting != CONTENT_SETTING_DEFAULT) { 1445 prefs->SetValue(prefs::kManagedDefaultJavaScriptSetting, 1446 Value::CreateIntegerValue(setting)); 1447 } 1448 } 1449 1450 // URLBlacklistPolicyHandler implementation ------------------------------------ 1451 1452 URLBlacklistPolicyHandler::URLBlacklistPolicyHandler() { 1453 } 1454 1455 URLBlacklistPolicyHandler::~URLBlacklistPolicyHandler() { 1456 } 1457 1458 bool URLBlacklistPolicyHandler::CheckPolicySettings(const PolicyMap& policies, 1459 PolicyErrorMap* errors) { 1460 const Value* disabled_schemes = policies.GetValue(key::kDisabledSchemes); 1461 const Value* url_blacklist = policies.GetValue(key::kURLBlacklist); 1462 1463 if (disabled_schemes && !disabled_schemes->IsType(Value::TYPE_LIST)) { 1464 errors->AddError(key::kDisabledSchemes, 1465 IDS_POLICY_TYPE_ERROR, 1466 ValueTypeToString(Value::TYPE_LIST)); 1467 } 1468 1469 if (url_blacklist && !url_blacklist->IsType(Value::TYPE_LIST)) { 1470 errors->AddError(key::kURLBlacklist, 1471 IDS_POLICY_TYPE_ERROR, 1472 ValueTypeToString(Value::TYPE_LIST)); 1473 } 1474 1475 return true; 1476 } 1477 1478 void URLBlacklistPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, 1479 PrefValueMap* prefs) { 1480 const base::Value* url_blacklist_policy = 1481 policies.GetValue(key::kURLBlacklist); 1482 const base::ListValue* url_blacklist = NULL; 1483 if (url_blacklist_policy) 1484 url_blacklist_policy->GetAsList(&url_blacklist); 1485 const base::Value* disabled_schemes_policy = 1486 policies.GetValue(key::kDisabledSchemes); 1487 const base::ListValue* disabled_schemes = NULL; 1488 if (disabled_schemes_policy) 1489 disabled_schemes_policy->GetAsList(&disabled_schemes); 1490 1491 scoped_ptr<base::ListValue> merged_url_blacklist(new base::ListValue()); 1492 1493 // We start with the DisabledSchemes because we have size limit when 1494 // handling URLBacklists. 1495 if (disabled_schemes_policy) { 1496 for (base::ListValue::const_iterator entry(disabled_schemes->begin()); 1497 entry != disabled_schemes->end(); ++entry) { 1498 std::string entry_value; 1499 if ((*entry)->GetAsString(&entry_value)) { 1500 entry_value.append("://*"); 1501 merged_url_blacklist->AppendString(entry_value); 1502 } 1503 } 1504 } 1505 1506 if (url_blacklist_policy) { 1507 for (base::ListValue::const_iterator entry(url_blacklist->begin()); 1508 entry != url_blacklist->end(); ++entry) { 1509 if ((*entry)->IsType(Value::TYPE_STRING)) 1510 merged_url_blacklist->Append((*entry)->DeepCopy()); 1511 } 1512 } 1513 1514 if (disabled_schemes_policy || url_blacklist_policy) 1515 prefs->SetValue(prefs::kUrlBlacklist, merged_url_blacklist.release()); 1516 } 1517 1518 // RestoreOnStartupPolicyHandler implementation -------------------------------- 1519 1520 RestoreOnStartupPolicyHandler::RestoreOnStartupPolicyHandler() 1521 : TypeCheckingPolicyHandler(key::kRestoreOnStartup, 1522 Value::TYPE_INTEGER) { 1523 } 1524 1525 RestoreOnStartupPolicyHandler::~RestoreOnStartupPolicyHandler() { 1526 } 1527 1528 void RestoreOnStartupPolicyHandler::ApplyPolicySettings( 1529 const PolicyMap& policies, 1530 PrefValueMap* prefs) { 1531 const Value* restore_on_startup_value = policies.GetValue(policy_name()); 1532 if (restore_on_startup_value) { 1533 int restore_on_startup; 1534 if (!restore_on_startup_value->GetAsInteger(&restore_on_startup)) 1535 return; 1536 1537 if (restore_on_startup == SessionStartupPref::kPrefValueHomePage) 1538 ApplyPolicySettingsFromHomePage(policies, prefs); 1539 else 1540 prefs->SetInteger(prefs::kRestoreOnStartup, restore_on_startup); 1541 } 1542 } 1543 1544 void RestoreOnStartupPolicyHandler::ApplyPolicySettingsFromHomePage( 1545 const PolicyMap& policies, 1546 PrefValueMap* prefs) { 1547 const base::Value* homepage_is_new_tab_page_value = 1548 policies.GetValue(key::kHomepageIsNewTabPage); 1549 if (!homepage_is_new_tab_page_value) { 1550 // The policy is enforcing 'open the homepage on startup' but not 1551 // enforcing what the homepage should be. Don't set any prefs. 1552 return; 1553 } 1554 1555 bool homepage_is_new_tab_page; 1556 if (!homepage_is_new_tab_page_value->GetAsBoolean(&homepage_is_new_tab_page)) 1557 return; 1558 1559 if (homepage_is_new_tab_page) { 1560 prefs->SetInteger(prefs::kRestoreOnStartup, 1561 SessionStartupPref::kPrefValueNewTab); 1562 } else { 1563 const base::Value* homepage_value = 1564 policies.GetValue(key::kHomepageLocation); 1565 if (!homepage_value || !homepage_value->IsType(base::Value::TYPE_STRING)) { 1566 // The policy is enforcing 'open the homepage on startup' but not 1567 // enforcing what the homepage should be. Don't set any prefs. 1568 return; 1569 } 1570 ListValue* url_list = new ListValue(); 1571 url_list->Append(homepage_value->DeepCopy()); 1572 prefs->SetInteger(prefs::kRestoreOnStartup, 1573 SessionStartupPref::kPrefValueURLs); 1574 prefs->SetValue(prefs::kURLsToRestoreOnStartup, url_list); 1575 } 1576 } 1577 1578 bool RestoreOnStartupPolicyHandler::CheckPolicySettings( 1579 const PolicyMap& policies, 1580 PolicyErrorMap* errors) { 1581 if (!TypeCheckingPolicyHandler::CheckPolicySettings(policies, errors)) 1582 return false; 1583 1584 const base::Value* restore_policy = policies.GetValue(key::kRestoreOnStartup); 1585 1586 if (restore_policy) { 1587 int restore_value; 1588 if (restore_policy->GetAsInteger(&restore_value)) { 1589 switch (restore_value) { 1590 case SessionStartupPref::kPrefValueHomePage: 1591 errors->AddError(policy_name(), IDS_POLICY_VALUE_DEPRECATED); 1592 break; 1593 case SessionStartupPref::kPrefValueLast: { 1594 // If the "restore last session" policy is set, session cookies are 1595 // treated as permanent cookies and site data needed to restore the 1596 // session is not cleared so we have to warn the user in that case. 1597 const base::Value* cookies_policy = 1598 policies.GetValue(key::kCookiesSessionOnlyForUrls); 1599 const base::ListValue *cookies_value; 1600 if (cookies_policy && cookies_policy->GetAsList(&cookies_value) && 1601 !cookies_value->empty()) { 1602 errors->AddError(key::kCookiesSessionOnlyForUrls, 1603 IDS_POLICY_OVERRIDDEN, 1604 key::kRestoreOnStartup); 1605 } 1606 1607 const base::Value* exit_policy = 1608 policies.GetValue(key::kClearSiteDataOnExit); 1609 bool exit_value; 1610 if (exit_policy && 1611 exit_policy->GetAsBoolean(&exit_value) && exit_value) { 1612 errors->AddError(key::kClearSiteDataOnExit, 1613 IDS_POLICY_OVERRIDDEN, 1614 key::kRestoreOnStartup); 1615 } 1616 break; 1617 } 1618 case SessionStartupPref::kPrefValueURLs: 1619 case SessionStartupPref::kPrefValueNewTab: 1620 // No error 1621 break; 1622 default: 1623 errors->AddError(policy_name(), 1624 IDS_POLICY_OUT_OF_RANGE_ERROR, 1625 base::IntToString(restore_value)); 1626 } 1627 } 1628 } 1629 return true; 1630 } 1631 1632 } // namespace policy 1633