onc_validator.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/onc/onc_validator.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_writer.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/onc/onc_signature.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "components/onc/onc_constants.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace onc { 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <typename T, size_t N> 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstd::vector<T> toVector(T const (&array)[N]) { 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return std::vector<T>(array, array + N); 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copied from policy/configuration_policy_handler.cc. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(pneubeck): move to a common place like base/. 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string ValueTypeToString(base::Value::Type type) { 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const strings[] = {"null", "boolean", "integer", "double", 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "string", "binary", "dictionary", "list"}; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(static_cast<size_t>(type) < arraysize(strings)); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return strings[type]; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Validator::Validator(bool error_on_unknown_field, 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool error_on_wrong_recommended, 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool error_on_missing_field, 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool managed_onc) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : error_on_unknown_field_(error_on_unknown_field), 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_on_wrong_recommended_(error_on_wrong_recommended), 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_on_missing_field_(error_on_missing_field), 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) managed_onc_(managed_onc), 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) onc_source_(::onc::ONC_SOURCE_NONE) {} 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Validator::~Validator() {} 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<base::DictionaryValue> Validator::ValidateAndRepairObject( 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OncValueSignature* object_signature, 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& onc_object, 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Result* result) { 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(object_signature); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *result = VALID; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = false; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool error = false; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> result_value = 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MapValue(*object_signature, onc_object, &error); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error) { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *result = INVALID; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result_value.reset(); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (error_or_warning_found_) { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *result = VALID_WITH_WARNINGS; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The return value should be NULL if, and only if, |result| equals INVALID. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(result_value.get() == NULL, *result == INVALID); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* result_dict = NULL; 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (result_value) { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result_value.release()->GetAsDictionary(&result_dict); 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(result_dict); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return make_scoped_ptr(result_dict); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<base::Value> Validator::MapValue(const OncValueSignature& signature, 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Value& onc_value, 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool* error) { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (onc_value.GetType() != signature.onc_type) { 83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(ERROR) << MessageHeader() << "Found value '" << onc_value 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "' of type '" << ValueTypeToString(onc_value.GetType()) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "', but type '" << ValueTypeToString(signature.onc_type) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "' is required."; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = *error = true; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scoped_ptr<base::Value>(); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> repaired = 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mapper::MapValue(signature, onc_value, error); 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (repaired) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_EQ(repaired->GetType(), signature.onc_type); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return repaired.Pass(); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<base::DictionaryValue> Validator::MapObject( 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OncValueSignature& signature, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& onc_object, 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* error) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> repaired(new base::DictionaryValue); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool valid = ValidateObjectDefault(signature, onc_object, repaired.get()); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (valid) { 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (&signature == &kToplevelConfigurationSignature) { 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateToplevelConfiguration(repaired.get()); 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kNetworkConfigurationSignature) { 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateNetworkConfiguration(repaired.get()); 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kEthernetSignature) { 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateEthernet(repaired.get()); 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kIPConfigSignature || 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &signature == &kSavedIPConfigSignature || 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &signature == &kStaticIPConfigSignature) { 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateIPConfig(repaired.get()); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kWiFiSignature) { 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateWiFi(repaired.get()); 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kVPNSignature) { 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateVPN(repaired.get()); 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kIPsecSignature) { 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateIPsec(repaired.get()); 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kOpenVPNSignature) { 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateOpenVPN(repaired.get()); 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kVerifyX509Signature) { 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateVerifyX509(repaired.get()); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kCertificatePatternSignature) { 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateCertificatePattern(repaired.get()); 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kProxySettingsSignature) { 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateProxySettings(repaired.get()); 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kProxyLocationSignature) { 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateProxyLocation(repaired.get()); 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kEAPSignature) { 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateEAP(repaired.get()); 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (&signature == &kCertificateSignature) { 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid = ValidateCertificate(repaired.get()); 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (valid) { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return repaired.Pass(); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(error_or_warning_found_); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = *error = true; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scoped_ptr<base::DictionaryValue>(); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<base::Value> Validator::MapField( 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& field_name, 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OncValueSignature& object_signature, 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Value& onc_value, 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* found_unknown_field, 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* error) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.push_back(field_name); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool current_field_unknown = false; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> result = Mapper::MapField( 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) field_name, object_signature, onc_value, ¤t_field_unknown, error); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(field_name, path_.back()); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.pop_back(); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (current_field_unknown) { 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = *found_unknown_field = true; 164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::string message = MessageHeader() + "Field name '" + field_name + 165b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "' is unknown."; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error_on_unknown_field_) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << message; 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << message; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result.Pass(); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<base::ListValue> Validator::MapArray( 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OncValueSignature& array_signature, 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& onc_array, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* nested_error) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool nested_error_in_current_array = false; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> result = Mapper::MapArray( 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) array_signature, onc_array, &nested_error_in_current_array); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Drop individual networks and certificates instead of rejecting all of 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the configuration. 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (nested_error_in_current_array && 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &array_signature != &kNetworkConfigurationListSignature && 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &array_signature != &kCertificateListSignature) { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *nested_error = nested_error_in_current_array; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result.Pass(); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<base::Value> Validator::MapEntry(int index, 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OncValueSignature& signature, 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Value& onc_value, 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* error) { 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string str = base::IntToString(index); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.push_back(str); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> result = 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mapper::MapEntry(index, signature, onc_value, error); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(str, path_.back()); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.pop_back(); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result.Pass(); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateObjectDefault(const OncValueSignature& signature, 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue& onc_object, 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* result) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool found_unknown_field = false; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool nested_error_occured = false; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MapFields(signature, onc_object, &found_unknown_field, &nested_error_occured, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (found_unknown_field && error_on_unknown_field_) { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Unknown field names are errors: Aborting."; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (nested_error_occured) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ValidateRecommendedField(signature, result); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Validator::ValidateRecommendedField( 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OncValueSignature& object_signature, 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* result) { 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK(result); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> recommended; 2313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch scoped_ptr<base::Value> recommended_value; 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This remove passes ownership to |recommended_value|. 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!result->RemoveWithoutPathExpansion(::onc::kRecommended, 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &recommended_value)) { 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* recommended_list = NULL; 2383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch recommended_value.release()->GetAsList(&recommended_list); 2393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch CHECK(recommended_list); 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recommended.reset(recommended_list); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!managed_onc_) { 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(WARNING) << MessageHeader() << "Found the field '" 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << ::onc::kRecommended 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "' in an unmanaged ONC. Removing it."; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> repaired_recommended(new base::ListValue); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (base::ListValue::iterator it = recommended->begin(); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != recommended->end(); ++it) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string field_name; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!(*it)->GetAsString(&field_name)) { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OncFieldSignature* field_signature = 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetFieldSignature(object_signature, field_name); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool found_error = false; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string error_cause; 265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!field_signature) { 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found_error = true; 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_cause = "unknown"; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (field_signature->value_signature->onc_type == 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value::TYPE_DICTIONARY) { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found_error = true; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_cause = "dictionary-typed"; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (found_error) { 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) path_.push_back(::onc::kRecommended); 277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::string message = MessageHeader() + "The " + error_cause + 278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) " field '" + field_name + "' cannot be recommended."; 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.pop_back(); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error_on_wrong_recommended_) { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << message; 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << message; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) repaired_recommended->Append((*it)->DeepCopy()); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result->Set(::onc::kRecommended, repaired_recommended.release()); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool Validator::ValidateClientCertFields(bool allow_cert_type_none, 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::DictionaryValue* result) { 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch using namespace ::onc::client_cert; 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidCertTypes[] = {kRef, kPattern}; 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<const char*> valid_cert_types(toVector(kValidCertTypes)); 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (allow_cert_type_none) 302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch valid_cert_types.push_back(kClientCertTypeNone); 303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (FieldExistsAndHasNoValidValue(*result, kClientCertType, valid_cert_types)) 304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string cert_type; 307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result->GetStringWithoutPathExpansion(kClientCertType, &cert_type); 308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (IsCertPatternInDevicePolicy(cert_type)) 310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool all_required_exist = true; 313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (cert_type == kPattern) 315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch all_required_exist &= RequireField(*result, kClientCertPattern); 316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else if (cert_type == kRef) 317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch all_required_exist &= RequireField(*result, kClientCertRef); 318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return !error_on_missing_field_ || all_required_exist; 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstd::string JoinStringRange(const std::vector<const char*>& strings, 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& separator) { 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> string_vector; 327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::copy(strings.begin(), strings.end(), std::back_inserter(string_vector)); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return JoinString(string_vector, separator); 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Validator::FieldExistsAndHasNoValidValue( 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& object, 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& field_name, 336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*>& valid_values) { 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string actual_value; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!object.GetStringWithoutPathExpansion(field_name, &actual_value)) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (std::vector<const char*>::const_iterator it = valid_values.begin(); 342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it != valid_values.end(); 343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++it) { 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (actual_value == *it) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string valid_values_str = 349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "[" + JoinStringRange(valid_values, ", ") + "]"; 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.push_back(field_name); 351b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(ERROR) << MessageHeader() << "Found value '" << actual_value << 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "', but expected one of the values " << valid_values_str; 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.pop_back(); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Validator::FieldExistsAndIsNotInRange(const base::DictionaryValue& object, 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& field_name, 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int lower_bound, 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int upper_bound) { 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int actual_value; 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!object.GetIntegerWithoutPathExpansion(field_name, &actual_value) || 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (lower_bound <= actual_value && actual_value <= upper_bound)) { 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.push_back(field_name); 368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(ERROR) << MessageHeader() << "Found value '" << actual_value 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "', but expected a value in the range [" << lower_bound 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ", " << upper_bound << "] (boundaries inclusive)"; 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.pop_back(); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Validator::FieldExistsAndIsEmpty(const base::DictionaryValue& object, 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& field_name) { 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Value* value = NULL; 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!object.GetWithoutPathExpansion(field_name, &value)) 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string str; 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* list = NULL; 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (value->GetAsString(&str)) { 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!str.empty()) 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (value->GetAsList(&list)) { 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!list->empty()) 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.push_back(field_name); 396b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(ERROR) << MessageHeader() << "Found an empty string, but expected a " 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "non-empty string."; 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path_.pop_back(); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Validator::RequireField(const base::DictionaryValue& dict, 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& field_name) { 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dict.HasKey(field_name)) 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 407b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::string message = MessageHeader() + "The required field '" + field_name + 408b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "' is missing."; 409b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (error_on_missing_field_) 410b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(ERROR) << message; 411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) else 412b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(WARNING) << message; 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::CheckGuidIsUniqueAndAddToSet(const base::DictionaryValue& dict, 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& key_guid, 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string> *guids) { 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string guid; 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (dict.GetStringWithoutPathExpansion(key_guid, &guid)) { 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (guids->count(guid) != 0) { 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_or_warning_found_ = true; 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << MessageHeader() << "Found a duplicate GUID " << guid << "."; 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) guids->insert(guid); 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool Validator::IsCertPatternInDevicePolicy(const std::string& cert_type) { 432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (cert_type == ::onc::client_cert::kPattern && 4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) onc_source_ == ::onc::ONC_SOURCE_DEVICE_POLICY) { 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 435b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(ERROR) << MessageHeader() << "Client certificate patterns are " 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "prohibited in ONC device policies."; 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool Validator::IsGlobalNetworkConfigInUserImport( 4438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const base::DictionaryValue& onc_object) { 4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (onc_source_ == ::onc::ONC_SOURCE_USER_IMPORT && 4458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) onc_object.HasKey(::onc::toplevel_config::kGlobalNetworkConfiguration)) { 4468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) error_or_warning_found_ = true; 4478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LOG(ERROR) << MessageHeader() << "GlobalNetworkConfiguration is prohibited " 4488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) << "in ONC user imports"; 4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return true; 4508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 4528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateToplevelConfiguration(base::DictionaryValue* result) { 4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::toplevel_config; 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidTypes[] = {kUnencryptedConfiguration, 458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kEncryptedConfiguration}; 459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_types(toVector(kValidTypes)); 460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (FieldExistsAndHasNoValidValue(*result, kType, valid_types)) 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (IsGlobalNetworkConfigInUserImport(*result)) 4648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 4658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateNetworkConfiguration(base::DictionaryValue* result) { 4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::network_config; 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidTypes[] = { 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ::onc::network_type::kEthernet, ::onc::network_type::kVPN, 474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ::onc::network_type::kWiFi, ::onc::network_type::kCellular}; 475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_types(toVector(kValidTypes)); 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (FieldExistsAndHasNoValidValue(*result, kType, valid_types) || 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FieldExistsAndIsEmpty(*result, kGUID)) { 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!CheckGuidIsUniqueAndAddToSet(*result, kGUID, &network_guids_)) 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = RequireField(*result, kGUID); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool remove = false; 4874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result->GetBooleanWithoutPathExpansion(::onc::kRemove, &remove); 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!remove) { 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RequireField(*result, kName) && RequireField(*result, kType); 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->GetStringWithoutPathExpansion(kType, &type); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Prohibit anything but WiFi and Ethernet for device-level policy (which 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // corresponds to shared networks). See also http://crosbug.com/28741. 4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (onc_source_ == ::onc::ONC_SOURCE_DEVICE_POLICY && 4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) type != ::onc::network_type::kWiFi && 4994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) type != ::onc::network_type::kEthernet) { 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 501b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(ERROR) << MessageHeader() << "Networks of type '" 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << type << "' are prohibited in ONC device policies."; 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type == ::onc::network_type::kWiFi) { 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, ::onc::network_config::kWiFi); 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (type == ::onc::network_type::kEthernet) { 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RequireField(*result, ::onc::network_config::kEthernet); 511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (type == ::onc::network_type::kCellular) { 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RequireField(*result, ::onc::network_config::kCellular); 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (type == ::onc::network_type::kVPN) { 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, ::onc::network_config::kVPN); 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (!type.empty()) { 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateEthernet(base::DictionaryValue* result) { 5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::ethernet; 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidAuthentications[] = {kAuthenticationNone, k8021X}; 528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_authentications( 529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch toVector(kValidAuthentications)); 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (FieldExistsAndHasNoValidValue( 531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *result, kAuthentication, valid_authentications)) { 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = true; 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string auth; 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->GetStringWithoutPathExpansion(kAuthentication, &auth); 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (auth == k8021X) 539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kEAP); 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateIPConfig(base::DictionaryValue* result) { 5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::ipconfig; 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 547116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidTypes[] = {kIPv4, kIPv6}; 548116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_types(toVector(kValidTypes)); 549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (FieldExistsAndHasNoValidValue( 550116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *result, ::onc::ipconfig::kType, valid_types)) 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result->GetStringWithoutPathExpansion(::onc::ipconfig::kType, &type); 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int lower_bound = 1; 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In case of missing type, choose higher upper_bound. 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int upper_bound = (type == kIPv4) ? 32 : 128; 558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (FieldExistsAndIsNotInRange( 559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *result, kRoutingPrefix, lower_bound, upper_bound)) { 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = RequireField(*result, kIPAddress) && 564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RequireField(*result, kRoutingPrefix) && 565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RequireField(*result, ::onc::ipconfig::kType); 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateWiFi(base::DictionaryValue* result) { 5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::wifi; 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidSecurities[] = {kSecurityNone, kWEP_PSK, kWEP_8021X, 574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kWPA_PSK, kWPA_EAP}; 575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_securities(toVector(kValidSecurities)); 576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (FieldExistsAndHasNoValidValue(*result, kSecurity, valid_securities)) 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RequireField(*result, kSecurity) && RequireField(*result, kSSID); 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string security; 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->GetStringWithoutPathExpansion(kSecurity, &security); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (security == kWEP_8021X || security == kWPA_EAP) 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kEAP); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (security == kWEP_PSK || security == kWPA_PSK) 587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kPassphrase); 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateVPN(base::DictionaryValue* result) { 5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::vpn; 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 595116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidTypes[] = {kIPsec, kTypeL2TP_IPsec, kOpenVPN}; 596116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_types(toVector(kValidTypes)); 597116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (FieldExistsAndHasNoValidValue(*result, ::onc::vpn::kType, valid_types)) 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = RequireField(*result, ::onc::vpn::kType); 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result->GetStringWithoutPathExpansion(::onc::vpn::kType, &type); 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == kOpenVPN) { 604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kOpenVPN); 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (type == kIPsec) { 606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kIPsec); 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (type == kTypeL2TP_IPsec) { 608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= 609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RequireField(*result, kIPsec) && RequireField(*result, kL2TP); 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateIPsec(base::DictionaryValue* result) { 6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::ipsec; 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 618116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidAuthentications[] = {kPSK, kCert}; 619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_authentications( 620116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch toVector(kValidAuthentications)); 621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (FieldExistsAndHasNoValidValue( 622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *result, kAuthenticationType, valid_authentications) || 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FieldExistsAndIsEmpty(*result, kServerCARefs)) { 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result->HasKey(kServerCARefs) && result->HasKey(kServerCARef)) { 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_or_warning_found_ = true; 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << MessageHeader() << "At most one of " << kServerCARefs 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " and " << kServerCARef << " can be set."; 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ValidateClientCertFields(false, // don't allow ClientCertType None 635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result)) { 636116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 637116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = RequireField(*result, kAuthenticationType) && 640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RequireField(*result, kIKEVersion); 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string auth; 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->GetStringWithoutPathExpansion(kAuthenticationType, &auth); 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool has_server_ca_cert = 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result->HasKey(kServerCARefs) || result->HasKey(kServerCARef); 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (auth == kCert) { 646116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch all_required_exist &= 647116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RequireField(*result, ::onc::client_cert::kClientCertType); 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!has_server_ca_cert) { 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) all_required_exist = false; 6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_or_warning_found_ = true; 6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string message = MessageHeader() + "The required field '" + 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kServerCARefs + "' is missing."; 6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error_on_missing_field_) 6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << message; 6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(WARNING) << message; 6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (has_server_ca_cert) { 6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_or_warning_found_ = true; 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << MessageHeader() << kServerCARefs << " (or " << kServerCARef 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << ") can only be set if " << kAuthenticationType 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " is set to " << kCert << "."; 6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateOpenVPN(base::DictionaryValue* result) { 6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::openvpn; 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidAuthRetryValues[] = {::onc::openvpn::kNone, kInteract, 673116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kNoInteract}; 674116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_auth_retry_values( 675116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch toVector(kValidAuthRetryValues)); 676116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidCertTlsValues[] = {::onc::openvpn::kNone, 677116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ::onc::openvpn::kServer}; 678116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_cert_tls_values( 679116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch toVector(kValidCertTlsValues)); 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (FieldExistsAndHasNoValidValue( 682116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *result, kAuthRetry, valid_auth_retry_values) || 683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FieldExistsAndHasNoValidValue( 684116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *result, kRemoteCertTLS, valid_cert_tls_values) || 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FieldExistsAndIsEmpty(*result, kServerCARefs)) { 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result->HasKey(kServerCARefs) && result->HasKey(kServerCARef)) { 6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_or_warning_found_ = true; 6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << MessageHeader() << "At most one of " << kServerCARefs 6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " and " << kServerCARef << " can be set."; 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 696116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ValidateClientCertFields(true /* allow ClientCertType None */, result)) 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 699116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool all_required_exist = 700116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RequireField(*result, ::onc::client_cert::kClientCertType); 701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateVerifyX509(base::DictionaryValue* result) { 706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) using namespace ::onc::verify_x509; 707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 708116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidTypes[] = {types::kName, types::kNamePrefix, 709116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch types::kSubject}; 710116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_types(toVector(kValidTypes)); 711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 712116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (FieldExistsAndHasNoValidValue(*result, kType, valid_types)) 713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = RequireField(*result, kName); 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateCertificatePattern(base::DictionaryValue* result) { 721116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch using namespace ::onc::client_cert; 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = true; 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->HasKey(kSubject) && !result->HasKey(kIssuer) && 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !result->HasKey(kIssuerCARef)) { 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist = false; 728b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::string message = MessageHeader() + "None of the fields '" + kSubject + 729b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "', '" + kIssuer + "', and '" + kIssuerCARef + 730b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "' is present, but at least one is required."; 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error_on_missing_field_) 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << message; 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << message; 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateProxySettings(base::DictionaryValue* result) { 7414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::proxy; 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 743116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidTypes[] = {kDirect, kManual, kPAC, kWPAD}; 744116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_types(toVector(kValidTypes)); 745116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (FieldExistsAndHasNoValidValue(*result, ::onc::proxy::kType, valid_types)) 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = RequireField(*result, ::onc::proxy::kType); 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 7504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result->GetStringWithoutPathExpansion(::onc::proxy::kType, &type); 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == kManual) 752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kManual); 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (type == kPAC) 754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kPAC); 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateProxyLocation(base::DictionaryValue* result) { 7604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::proxy; 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = 763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RequireField(*result, kHost) && RequireField(*result, kPort); 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateEAP(base::DictionaryValue* result) { 7694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::eap; 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 771116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidInnerValues[] = {kAutomatic, kMD5, kMSCHAPv2, kPAP}; 772116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_inner_values( 773116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch toVector(kValidInnerValues)); 774116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidOuterValues[] = { 775116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kPEAP, kEAP_TLS, kEAP_TTLS, kLEAP, kEAP_SIM, kEAP_FAST, kEAP_AKA}; 776116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_outer_values( 777116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch toVector(kValidOuterValues)); 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 779116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (FieldExistsAndHasNoValidValue(*result, kInner, valid_inner_values) || 780116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FieldExistsAndHasNoValidValue(*result, kOuter, valid_outer_values) || 7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FieldExistsAndIsEmpty(*result, kServerCARefs)) { 7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result->HasKey(kServerCARefs) && result->HasKey(kServerCARef)) { 7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_or_warning_found_ = true; 7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << MessageHeader() << "At most one of " << kServerCARefs 7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " and " << kServerCARef << " can be set."; 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 792116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ValidateClientCertFields(false, // don't allow ClientCertType None 793116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result)) { 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 795116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 797116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool all_required_exist = RequireField(*result, kOuter); 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 799f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Validator::ValidateCertificate(base::DictionaryValue* result) { 8034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) using namespace ::onc::certificate; 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 805116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* const kValidTypes[] = {kClient, kServer, kAuthority}; 806116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<const char*> valid_types(toVector(kValidTypes)); 807116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (FieldExistsAndHasNoValidValue(*result, kType, valid_types) || 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FieldExistsAndIsEmpty(*result, kGUID)) { 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->GetStringWithoutPathExpansion(kType, &type); 8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (onc_source_ == ::onc::ONC_SOURCE_DEVICE_POLICY && 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (type == kServer || type == kAuthority)) { 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_or_warning_found_ = true; 817b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(ERROR) << MessageHeader() << "Server and authority certificates are " 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "prohibited in ONC device policies."; 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!CheckGuidIsUniqueAndAddToSet(*result, kGUID, &certificate_guids_)) 8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool all_required_exist = RequireField(*result, kGUID); 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool remove = false; 8284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) result->GetBooleanWithoutPathExpansion(::onc::kRemove, &remove); 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!remove) { 830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kType); 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == kClient) 833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kPKCS12); 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (type == kServer || type == kAuthority) 835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_required_exist &= RequireField(*result, kX509); 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !error_on_missing_field_ || all_required_exist; 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 841b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)std::string Validator::MessageHeader() { 8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string path = path_.empty() ? "toplevel" : JoinString(path_, "."); 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message = "At " + path + ": "; 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return message; 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace onc 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace chromeos 849