Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: chromeos/network/onc/onc_validator.cc

Issue 13957012: Adding a NetworkProfileHandler used by ManagedNetworkConfigurationHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 } 85 }
86 86
87 return make_scoped_ptr(result_dict); 87 return make_scoped_ptr(result_dict);
88 } 88 }
89 89
90 scoped_ptr<base::Value> Validator::MapValue( 90 scoped_ptr<base::Value> Validator::MapValue(
91 const OncValueSignature& signature, 91 const OncValueSignature& signature,
92 const base::Value& onc_value, 92 const base::Value& onc_value,
93 bool* error) { 93 bool* error) {
94 if (onc_value.GetType() != signature.onc_type) { 94 if (onc_value.GetType() != signature.onc_type) {
95 LOG(ERROR) << ErrorHeader() << "Found value '" << onc_value 95 LOG(ERROR) << MessageHeader() << "Found value '" << onc_value
96 << "' of type '" << ValueTypeToString(onc_value.GetType()) 96 << "' of type '" << ValueTypeToString(onc_value.GetType())
97 << "', but type '" << ValueTypeToString(signature.onc_type) 97 << "', but type '" << ValueTypeToString(signature.onc_type)
98 << "' is required."; 98 << "' is required.";
99 error_or_warning_found_ = *error = true; 99 error_or_warning_found_ = *error = true;
100 return scoped_ptr<base::Value>(); 100 return scoped_ptr<base::Value>();
101 } 101 }
102 102
103 scoped_ptr<base::Value> repaired = 103 scoped_ptr<base::Value> repaired =
104 Mapper::MapValue(signature, onc_value, error); 104 Mapper::MapValue(signature, onc_value, error);
105 if (repaired.get() != NULL) 105 if (repaired.get() != NULL)
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 path_.push_back(field_name); 161 path_.push_back(field_name);
162 bool current_field_unknown = false; 162 bool current_field_unknown = false;
163 scoped_ptr<base::Value> result = Mapper::MapField( 163 scoped_ptr<base::Value> result = Mapper::MapField(
164 field_name, object_signature, onc_value, &current_field_unknown, error); 164 field_name, object_signature, onc_value, &current_field_unknown, error);
165 165
166 DCHECK_EQ(field_name, path_.back()); 166 DCHECK_EQ(field_name, path_.back());
167 path_.pop_back(); 167 path_.pop_back();
168 168
169 if (current_field_unknown) { 169 if (current_field_unknown) {
170 error_or_warning_found_ = *found_unknown_field = true; 170 error_or_warning_found_ = *found_unknown_field = true;
171 std::string message = MessageHeader(error_on_unknown_field_) 171 std::string message = MessageHeader() + "Field name '" + field_name +
172 + "Field name '" + field_name + "' is unknown."; 172 "' is unknown.";
173 if (error_on_unknown_field_) 173 if (error_on_unknown_field_)
174 LOG(ERROR) << message; 174 LOG(ERROR) << message;
175 else 175 else
176 LOG(WARNING) << message; 176 LOG(WARNING) << message;
177 } 177 }
178 178
179 return result.Pass(); 179 return result.Pass();
180 } 180 }
181 181
182 scoped_ptr<base::ListValue> Validator::MapArray( 182 scoped_ptr<base::ListValue> Validator::MapArray(
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 return true; 243 return true;
244 } 244 }
245 base::ListValue* recommended_list = NULL; 245 base::ListValue* recommended_list = NULL;
246 recommended_value->GetAsList(&recommended_list); 246 recommended_value->GetAsList(&recommended_list);
247 CHECK(recommended_list != NULL); 247 CHECK(recommended_list != NULL);
248 248
249 recommended.reset(recommended_list); 249 recommended.reset(recommended_list);
250 250
251 if (!managed_onc_) { 251 if (!managed_onc_) {
252 error_or_warning_found_ = true; 252 error_or_warning_found_ = true;
253 LOG(WARNING) << WarningHeader() << "Found the field '" << onc::kRecommended 253 LOG(WARNING) << MessageHeader() << "Found the field '" << onc::kRecommended
254 << "' in an unmanaged ONC. Removing it."; 254 << "' in an unmanaged ONC. Removing it.";
255 return true; 255 return true;
256 } 256 }
257 257
258 scoped_ptr<base::ListValue> repaired_recommended(new base::ListValue); 258 scoped_ptr<base::ListValue> repaired_recommended(new base::ListValue);
259 for (base::ListValue::iterator it = recommended->begin(); 259 for (base::ListValue::iterator it = recommended->begin();
260 it != recommended->end(); ++it) { 260 it != recommended->end(); ++it) {
261 std::string field_name; 261 std::string field_name;
262 if (!(*it)->GetAsString(&field_name)) { 262 if (!(*it)->GetAsString(&field_name)) {
263 NOTREACHED(); 263 NOTREACHED();
(...skipping 10 matching lines...) Expand all
274 error_cause = "unknown"; 274 error_cause = "unknown";
275 } else if (field_signature->value_signature->onc_type == 275 } else if (field_signature->value_signature->onc_type ==
276 base::Value::TYPE_DICTIONARY) { 276 base::Value::TYPE_DICTIONARY) {
277 found_error = true; 277 found_error = true;
278 error_cause = "dictionary-typed"; 278 error_cause = "dictionary-typed";
279 } 279 }
280 280
281 if (found_error) { 281 if (found_error) {
282 error_or_warning_found_ = true; 282 error_or_warning_found_ = true;
283 path_.push_back(onc::kRecommended); 283 path_.push_back(onc::kRecommended);
284 std::string message = MessageHeader(error_on_wrong_recommended_) + 284 std::string message = MessageHeader() + "The " + error_cause +
285 "The " + error_cause + " field '" + field_name + 285 " field '" + field_name + "' cannot be recommended.";
286 "' cannot be recommended.";
287 path_.pop_back(); 286 path_.pop_back();
288 if (error_on_wrong_recommended_) { 287 if (error_on_wrong_recommended_) {
289 LOG(ERROR) << message; 288 LOG(ERROR) << message;
290 return false; 289 return false;
291 } else { 290 } else {
292 LOG(WARNING) << message; 291 LOG(WARNING) << message;
293 continue; 292 continue;
294 } 293 }
295 } 294 }
296 295
(...skipping 26 matching lines...) Expand all
323 322
324 const char** it = valid_values; 323 const char** it = valid_values;
325 for (; *it != NULL; ++it) { 324 for (; *it != NULL; ++it) {
326 if (actual_value == *it) 325 if (actual_value == *it)
327 return false; 326 return false;
328 } 327 }
329 error_or_warning_found_ = true; 328 error_or_warning_found_ = true;
330 std::string valid_values_str = 329 std::string valid_values_str =
331 "[" + JoinStringRange(valid_values, it, ", ") + "]"; 330 "[" + JoinStringRange(valid_values, it, ", ") + "]";
332 path_.push_back(field_name); 331 path_.push_back(field_name);
333 LOG(ERROR) << ErrorHeader() << "Found value '" << actual_value << 332 LOG(ERROR) << MessageHeader() << "Found value '" << actual_value <<
334 "', but expected one of the values " << valid_values_str; 333 "', but expected one of the values " << valid_values_str;
335 path_.pop_back(); 334 path_.pop_back();
336 return true; 335 return true;
337 } 336 }
338 337
339 bool Validator::FieldExistsAndIsNotInRange(const base::DictionaryValue& object, 338 bool Validator::FieldExistsAndIsNotInRange(const base::DictionaryValue& object,
340 const std::string &field_name, 339 const std::string &field_name,
341 int lower_bound, 340 int lower_bound,
342 int upper_bound) { 341 int upper_bound) {
343 int actual_value; 342 int actual_value;
344 if (!object.GetIntegerWithoutPathExpansion(field_name, &actual_value) || 343 if (!object.GetIntegerWithoutPathExpansion(field_name, &actual_value) ||
345 (lower_bound <= actual_value && actual_value <= upper_bound)) { 344 (lower_bound <= actual_value && actual_value <= upper_bound)) {
346 return false; 345 return false;
347 } 346 }
348 error_or_warning_found_ = true; 347 error_or_warning_found_ = true;
349 path_.push_back(field_name); 348 path_.push_back(field_name);
350 LOG(ERROR) << ErrorHeader() << "Found value '" << actual_value 349 LOG(ERROR) << MessageHeader() << "Found value '" << actual_value
351 << "', but expected a value in the range [" << lower_bound 350 << "', but expected a value in the range [" << lower_bound
352 << ", " << upper_bound << "] (boundaries inclusive)"; 351 << ", " << upper_bound << "] (boundaries inclusive)";
353 path_.pop_back(); 352 path_.pop_back();
354 return true; 353 return true;
355 } 354 }
356 355
357 bool Validator::FieldExistsAndIsEmpty(const base::DictionaryValue& object, 356 bool Validator::FieldExistsAndIsEmpty(const base::DictionaryValue& object,
358 const std::string& field_name) { 357 const std::string& field_name) {
359 std::string value; 358 std::string value;
360 if (!object.GetStringWithoutPathExpansion(field_name, &value) || 359 if (!object.GetStringWithoutPathExpansion(field_name, &value) ||
361 !value.empty()) { 360 !value.empty()) {
362 return false; 361 return false;
363 } 362 }
364 363
365 error_or_warning_found_ = true; 364 error_or_warning_found_ = true;
366 path_.push_back(field_name); 365 path_.push_back(field_name);
367 LOG(ERROR) << ErrorHeader() << "Found an empty string, but expected a " 366 LOG(ERROR) << MessageHeader() << "Found an empty string, but expected a "
368 << "non-empty string."; 367 << "non-empty string.";
369 path_.pop_back(); 368 path_.pop_back();
370 return true; 369 return true;
371 } 370 }
372 371
373 bool Validator::RequireField(const base::DictionaryValue& dict, 372 bool Validator::RequireField(const base::DictionaryValue& dict,
374 const std::string& field_name) { 373 const std::string& field_name) {
375 if (dict.HasKey(field_name)) 374 if (dict.HasKey(field_name))
376 return true; 375 return true;
377 error_or_warning_found_ = true; 376 error_or_warning_found_ = true;
378 LOG(ERROR) << ErrorHeader() << "The required field '" << field_name 377 std::string message = MessageHeader() + "The required field '" + field_name +
379 << "' is missing."; 378 "' is missing.";
379 if (error_on_missing_field_)
380 LOG(ERROR) << message;
381 else
382 LOG(WARNING) << message;
380 return false; 383 return false;
381 } 384 }
382 385
383 // Prohibit certificate patterns for device policy ONC so that an unmanaged user 386 // Prohibit certificate patterns for device policy ONC so that an unmanaged user
384 // won't have a certificate presented for them involuntarily. 387 // won't have a certificate presented for them involuntarily.
385 bool Validator::CertPatternInDevicePolicy(const std::string& cert_type) { 388 bool Validator::CertPatternInDevicePolicy(const std::string& cert_type) {
386 if (cert_type == certificate::kPattern && 389 if (cert_type == certificate::kPattern &&
387 onc_source_ == ONC_SOURCE_DEVICE_POLICY) { 390 onc_source_ == ONC_SOURCE_DEVICE_POLICY) {
388 error_or_warning_found_ = true; 391 error_or_warning_found_ = true;
389 LOG(ERROR) << ErrorHeader() << "Client certificate patterns are " 392 LOG(ERROR) << MessageHeader() << "Client certificate patterns are "
390 << "prohibited in ONC device policies."; 393 << "prohibited in ONC device policies.";
391 return true; 394 return true;
392 } 395 }
393 return false; 396 return false;
394 } 397 }
395 398
396 bool Validator::ValidateToplevelConfiguration( 399 bool Validator::ValidateToplevelConfiguration(
397 const base::DictionaryValue& onc_object, 400 const base::DictionaryValue& onc_object,
398 base::DictionaryValue* result) { 401 base::DictionaryValue* result) {
399 using namespace onc::toplevel_config; 402 using namespace onc::toplevel_config;
400 403
401 static const char* kValidTypes[] = { kUnencryptedConfiguration, 404 static const char* kValidTypes[] = { kUnencryptedConfiguration,
402 kEncryptedConfiguration, 405 kEncryptedConfiguration,
403 NULL }; 406 NULL };
404 if (FieldExistsAndHasNoValidValue(*result, kType, kValidTypes)) 407 if (FieldExistsAndHasNoValidValue(*result, kType, kValidTypes))
405 return false; 408 return false;
406 409
407 bool allRequiredExist = true; 410 bool allRequiredExist = true;
408 411
409 // Not part of the ONC spec yet: 412 // Not part of the ONC spec yet:
410 // We don't require the type field and default to UnencryptedConfiguration. 413 // We don't require the type field and default to UnencryptedConfiguration.
411 std::string type = kUnencryptedConfiguration; 414 std::string type = kUnencryptedConfiguration;
412 result->GetStringWithoutPathExpansion(kType, &type); 415 result->GetStringWithoutPathExpansion(kType, &type);
413 if (type == kUnencryptedConfiguration && 416 if (type == kUnencryptedConfiguration &&
414 !result->HasKey(kNetworkConfigurations) && 417 !result->HasKey(kNetworkConfigurations) &&
415 !result->HasKey(kCertificates)) { 418 !result->HasKey(kCertificates)) {
416 error_or_warning_found_ = true; 419 error_or_warning_found_ = true;
417 std::string message = MessageHeader(error_on_missing_field_) + 420 std::string message = MessageHeader() + "Neither the field '" +
418 "Neither the field '" + kNetworkConfigurations + "' nor '" + 421 kNetworkConfigurations + "' nor '" + kCertificates +
419 kCertificates + "is present, but at least one is required."; 422 "is present, but at least one is required.";
420 if (error_on_missing_field_) 423 if (error_on_missing_field_)
421 LOG(ERROR) << message; 424 LOG(ERROR) << message;
422 else 425 else
423 LOG(WARNING) << message; 426 LOG(WARNING) << message;
424 allRequiredExist = false; 427 allRequiredExist = false;
425 } 428 }
426 429
427 return !error_on_missing_field_ || allRequiredExist; 430 return !error_on_missing_field_ || allRequiredExist;
428 } 431 }
429 432
(...skipping 22 matching lines...) Expand all
452 455
453 std::string type; 456 std::string type;
454 result->GetStringWithoutPathExpansion(kType, &type); 457 result->GetStringWithoutPathExpansion(kType, &type);
455 458
456 // Prohibit anything but WiFi and Ethernet for device-level policy (which 459 // Prohibit anything but WiFi and Ethernet for device-level policy (which
457 // corresponds to shared networks). See also http://crosbug.com/28741. 460 // corresponds to shared networks). See also http://crosbug.com/28741.
458 if (onc_source_ == ONC_SOURCE_DEVICE_POLICY && 461 if (onc_source_ == ONC_SOURCE_DEVICE_POLICY &&
459 type != network_type::kWiFi && 462 type != network_type::kWiFi &&
460 type != network_type::kEthernet) { 463 type != network_type::kEthernet) {
461 error_or_warning_found_ = true; 464 error_or_warning_found_ = true;
462 LOG(ERROR) << ErrorHeader() << "Networks of type '" 465 LOG(ERROR) << MessageHeader() << "Networks of type '"
463 << type << "' are prohibited in ONC device policies."; 466 << type << "' are prohibited in ONC device policies.";
464 return false; 467 return false;
465 } 468 }
466 469
467 if (type == network_type::kWiFi) 470 if (type == network_type::kWiFi)
468 allRequiredExist &= RequireField(*result, network_config::kWiFi); 471 allRequiredExist &= RequireField(*result, network_config::kWiFi);
469 else if (type == network_type::kEthernet) 472 else if (type == network_type::kEthernet)
470 allRequiredExist &= RequireField(*result, network_config::kEthernet); 473 allRequiredExist &= RequireField(*result, network_config::kEthernet);
471 else if (type == network_type::kCellular) 474 else if (type == network_type::kCellular)
472 allRequiredExist &= RequireField(*result, network_config::kCellular); 475 allRequiredExist &= RequireField(*result, network_config::kCellular);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 bool Validator::ValidateCertificatePattern( 655 bool Validator::ValidateCertificatePattern(
653 const base::DictionaryValue& onc_object, 656 const base::DictionaryValue& onc_object,
654 base::DictionaryValue* result) { 657 base::DictionaryValue* result) {
655 using namespace onc::certificate; 658 using namespace onc::certificate;
656 659
657 bool allRequiredExist = true; 660 bool allRequiredExist = true;
658 if (!result->HasKey(kSubject) && !result->HasKey(kIssuer) && 661 if (!result->HasKey(kSubject) && !result->HasKey(kIssuer) &&
659 !result->HasKey(kIssuerCARef)) { 662 !result->HasKey(kIssuerCARef)) {
660 error_or_warning_found_ = true; 663 error_or_warning_found_ = true;
661 allRequiredExist = false; 664 allRequiredExist = false;
662 std::string message = MessageHeader(error_on_missing_field_) + 665 std::string message = MessageHeader() + "None of the fields '" + kSubject +
663 "None of the fields '" + kSubject + "', '" + kIssuer + "', and '" + 666 "', '" + kIssuer + "', and '" + kIssuerCARef +
664 kIssuerCARef + "' is present, but at least one is required."; 667 "' is present, but at least one is required.";
665 if (error_on_missing_field_) 668 if (error_on_missing_field_)
666 LOG(ERROR) << message; 669 LOG(ERROR) << message;
667 else 670 else
668 LOG(WARNING) << message; 671 LOG(WARNING) << message;
669 } 672 }
670 673
671 return !error_on_missing_field_ || allRequiredExist; 674 return !error_on_missing_field_ || allRequiredExist;
672 } 675 }
673 676
674 bool Validator::ValidateProxySettings(const base::DictionaryValue& onc_object, 677 bool Validator::ValidateProxySettings(const base::DictionaryValue& onc_object,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 if (FieldExistsAndHasNoValidValue(*result, kType, kValidTypes) || 747 if (FieldExistsAndHasNoValidValue(*result, kType, kValidTypes) ||
745 FieldExistsAndIsEmpty(*result, kGUID)) { 748 FieldExistsAndIsEmpty(*result, kGUID)) {
746 return false; 749 return false;
747 } 750 }
748 751
749 std::string type; 752 std::string type;
750 result->GetStringWithoutPathExpansion(kType, &type); 753 result->GetStringWithoutPathExpansion(kType, &type);
751 if (onc_source_ == ONC_SOURCE_DEVICE_POLICY && 754 if (onc_source_ == ONC_SOURCE_DEVICE_POLICY &&
752 (type == kServer || type == kAuthority)) { 755 (type == kServer || type == kAuthority)) {
753 error_or_warning_found_ = true; 756 error_or_warning_found_ = true;
754 LOG(ERROR) << ErrorHeader() << "Server and authority certificates are " 757 LOG(ERROR) << MessageHeader() << "Server and authority certificates are "
755 << "prohibited in ONC device policies."; 758 << "prohibited in ONC device policies.";
756 return false; 759 return false;
757 } 760 }
758 761
759 bool allRequiredExist = RequireField(*result, kGUID); 762 bool allRequiredExist = RequireField(*result, kGUID);
760 763
761 bool remove = false; 764 bool remove = false;
762 result->GetBooleanWithoutPathExpansion(kRemove, &remove); 765 result->GetBooleanWithoutPathExpansion(kRemove, &remove);
763 if (!remove) { 766 if (!remove) {
764 allRequiredExist &= RequireField(*result, kType); 767 allRequiredExist &= RequireField(*result, kType);
765 768
766 if (type == kClient) 769 if (type == kClient)
767 allRequiredExist &= RequireField(*result, kPKCS12); 770 allRequiredExist &= RequireField(*result, kPKCS12);
768 else if (type == kServer || type == kAuthority) 771 else if (type == kServer || type == kAuthority)
769 allRequiredExist &= RequireField(*result, kX509); 772 allRequiredExist &= RequireField(*result, kX509);
770 } 773 }
771 774
772 return !error_on_missing_field_ || allRequiredExist; 775 return !error_on_missing_field_ || allRequiredExist;
773 } 776 }
774 777
775 std::string Validator::WarningHeader() { 778 std::string Validator::MessageHeader() {
776 return MessageHeader(false);
777 }
778
779 std::string Validator::ErrorHeader() {
780 return MessageHeader(true);
781 }
782
783 std::string Validator::MessageHeader(bool is_error) {
784 std::string path = path_.empty() ? "toplevel" : JoinString(path_, "."); 779 std::string path = path_.empty() ? "toplevel" : JoinString(path_, ".");
785 std::string message = "At " + path + ": "; 780 std::string message = "At " + path + ": ";
786 return message; 781 return message;
787 } 782 }
788 783
789 } // namespace onc 784 } // namespace onc
790 } // namespace chromeos 785 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/network/onc/onc_validator.h ('k') | chromeos/test/data/network/policy/shill_policy_on_unconfigured_wifi1.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698