| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/network/onc/onc_validator.h" | 5 #include "chromeos/network/onc/onc_validator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chromeos/network/onc/onc_signature.h" | 15 #include "chromeos/network/onc/onc_signature.h" |
| 16 #include "components/onc/onc_constants.h" | 16 #include "components/onc/onc_constants.h" |
| 17 | 17 |
| 18 namespace chromeos { | 18 namespace chromeos { |
| 19 namespace onc { | 19 namespace onc { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 // According to the IEEE 802.11 standard the SSID is a series of 0 to 32 octets. |
| 24 const int kMaximumSSIDLengthInBytes = 32; |
| 25 |
| 23 template <typename T, size_t N> | 26 template <typename T, size_t N> |
| 24 std::vector<T> toVector(T const (&array)[N]) { | 27 std::vector<T> toVector(T const (&array)[N]) { |
| 25 return std::vector<T>(array, array + N); | 28 return std::vector<T>(array, array + N); |
| 26 } | 29 } |
| 27 | 30 |
| 28 // Copied from policy/configuration_policy_handler.cc. | 31 // Copied from policy/configuration_policy_handler.cc. |
| 29 // TODO(pneubeck): move to a common place like base/. | 32 // TODO(pneubeck): move to a common place like base/. |
| 30 std::string ValueTypeToString(base::Value::Type type) { | 33 std::string ValueTypeToString(base::Value::Type type) { |
| 31 const char* const strings[] = {"null", "boolean", "integer", "double", | 34 const char* const strings[] = {"null", "boolean", "integer", "double", |
| 32 "string", "binary", "dictionary", "list"}; | 35 "string", "binary", "dictionary", "list"}; |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 } | 392 } |
| 390 | 393 |
| 391 error_or_warning_found_ = true; | 394 error_or_warning_found_ = true; |
| 392 path_.push_back(field_name); | 395 path_.push_back(field_name); |
| 393 LOG(ERROR) << MessageHeader() << "Found an empty string, but expected a " | 396 LOG(ERROR) << MessageHeader() << "Found an empty string, but expected a " |
| 394 << "non-empty string."; | 397 << "non-empty string."; |
| 395 path_.pop_back(); | 398 path_.pop_back(); |
| 396 return true; | 399 return true; |
| 397 } | 400 } |
| 398 | 401 |
| 402 bool Validator::IsSSIDOrHexSSIDValid(const base::DictionaryValue& object) { |
| 403 // Check SSID validity. |
| 404 std::string ssid_string; |
| 405 if (object.GetStringWithoutPathExpansion(::onc::wifi::kSSID, &ssid_string)) { |
| 406 if (ssid_string.size() <= 0 || |
| 407 ssid_string.size() > kMaximumSSIDLengthInBytes) { |
| 408 LOG(ERROR) << MessageHeader() << ::onc::wifi::kSSID |
| 409 << " has an invalid length."; |
| 410 error_or_warning_found_ = true; |
| 411 return false; |
| 412 } |
| 413 } |
| 414 |
| 415 // Check HexSSID validity. |
| 416 std::string hex_ssid_string; |
| 417 if (object.GetStringWithoutPathExpansion(::onc::wifi::kHexSSID, |
| 418 &hex_ssid_string)) { |
| 419 std::vector<uint8> bytes; |
| 420 if (!base::HexStringToBytes(hex_ssid_string, &bytes)) { |
| 421 LOG(ERROR) << MessageHeader() << "Field " << ::onc::wifi::kHexSSID |
| 422 << " is not a valid hex representation: \"" << hex_ssid_string |
| 423 << "\""; |
| 424 error_or_warning_found_ = true; |
| 425 return false; |
| 426 } |
| 427 if (bytes.size() <= 0 || bytes.size() > kMaximumSSIDLengthInBytes) { |
| 428 LOG(ERROR) << MessageHeader() << ::onc::wifi::kHexSSID |
| 429 << " has an invalid length."; |
| 430 error_or_warning_found_ = true; |
| 431 return false; |
| 432 } |
| 433 } |
| 434 // If both SSID and HexSSID are set, ensure that they are consistent. |
| 435 if (ssid_string.length() > 0 && hex_ssid_string.length() > 0) { |
| 436 std::string hexified = |
| 437 base::HexEncode(ssid_string.c_str(), ssid_string.size()); |
| 438 if (hexified != hex_ssid_string) { |
| 439 LOG(ERROR) << MessageHeader() << "Fields " << ::onc::wifi::kSSID |
| 440 << " and " << ::onc::wifi::kHexSSID |
| 441 << " contain inconsistent values."; |
| 442 error_or_warning_found_ = true; |
| 443 return false; |
| 444 } |
| 445 } |
| 446 |
| 447 return true; |
| 448 } |
| 449 |
| 399 bool Validator::RequireField(const base::DictionaryValue& dict, | 450 bool Validator::RequireField(const base::DictionaryValue& dict, |
| 400 const std::string& field_name) { | 451 const std::string& field_name) { |
| 401 if (dict.HasKey(field_name)) | 452 if (dict.HasKey(field_name)) |
| 402 return true; | 453 return true; |
| 403 std::string message = MessageHeader() + "The required field '" + field_name + | 454 std::string message = MessageHeader() + "The required field '" + field_name + |
| 404 "' is missing."; | 455 "' is missing."; |
| 405 if (error_on_missing_field_) { | 456 if (error_on_missing_field_) { |
| 406 error_or_warning_found_ = true; | 457 error_or_warning_found_ = true; |
| 407 LOG(ERROR) << message; | 458 LOG(ERROR) << message; |
| 408 } else { | 459 } else { |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 | 616 |
| 566 bool Validator::ValidateWiFi(base::DictionaryValue* result) { | 617 bool Validator::ValidateWiFi(base::DictionaryValue* result) { |
| 567 using namespace ::onc::wifi; | 618 using namespace ::onc::wifi; |
| 568 | 619 |
| 569 const char* const kValidSecurities[] = {kSecurityNone, kWEP_PSK, kWEP_8021X, | 620 const char* const kValidSecurities[] = {kSecurityNone, kWEP_PSK, kWEP_8021X, |
| 570 kWPA_PSK, kWPA_EAP}; | 621 kWPA_PSK, kWPA_EAP}; |
| 571 const std::vector<const char*> valid_securities(toVector(kValidSecurities)); | 622 const std::vector<const char*> valid_securities(toVector(kValidSecurities)); |
| 572 if (FieldExistsAndHasNoValidValue(*result, kSecurity, valid_securities)) | 623 if (FieldExistsAndHasNoValidValue(*result, kSecurity, valid_securities)) |
| 573 return false; | 624 return false; |
| 574 | 625 |
| 575 bool all_required_exist = | 626 // Validate SSID and HexSSID fields, if present. |
| 576 RequireField(*result, kSecurity) && RequireField(*result, kSSID); | 627 if (!IsSSIDOrHexSSIDValid(*result)) |
| 628 return false; |
| 629 |
| 630 bool all_required_exist = RequireField(*result, kSecurity); |
| 631 |
| 632 // One of {kSSID, kHexSSID} must be present. |
| 633 if (!result->HasKey(kSSID)) |
| 634 all_required_exist &= RequireField(*result, kHexSSID); |
| 635 if (!result->HasKey(kHexSSID)) |
| 636 all_required_exist &= RequireField(*result, kSSID); |
| 577 | 637 |
| 578 std::string security; | 638 std::string security; |
| 579 result->GetStringWithoutPathExpansion(kSecurity, &security); | 639 result->GetStringWithoutPathExpansion(kSecurity, &security); |
| 580 if (security == kWEP_8021X || security == kWPA_EAP) | 640 if (security == kWEP_8021X || security == kWPA_EAP) |
| 581 all_required_exist &= RequireField(*result, kEAP); | 641 all_required_exist &= RequireField(*result, kEAP); |
| 582 else if (security == kWEP_PSK || security == kWPA_PSK) | 642 else if (security == kWEP_PSK || security == kWPA_PSK) |
| 583 all_required_exist &= RequireField(*result, kPassphrase); | 643 all_required_exist &= RequireField(*result, kPassphrase); |
| 584 | 644 |
| 585 return !error_on_missing_field_ || all_required_exist; | 645 return !error_on_missing_field_ || all_required_exist; |
| 586 } | 646 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 } | 904 } |
| 845 | 905 |
| 846 std::string Validator::MessageHeader() { | 906 std::string Validator::MessageHeader() { |
| 847 std::string path = path_.empty() ? "toplevel" : JoinString(path_, "."); | 907 std::string path = path_.empty() ? "toplevel" : JoinString(path_, "."); |
| 848 std::string message = "At " + path + ": "; | 908 std::string message = "At " + path + ": "; |
| 849 return message; | 909 return message; |
| 850 } | 910 } |
| 851 | 911 |
| 852 } // namespace onc | 912 } // namespace onc |
| 853 } // namespace chromeos | 913 } // namespace chromeos |
| OLD | NEW |