Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/network/onc/onc_validator.h" | 5 #include "chromeos/network/onc/onc_validator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/json/json_writer.h" | |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/string_number_conversions.h" | |
| 11 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 12 #include "base/values.h" | 14 #include "base/values.h" |
| 13 #include "chromeos/network/onc/onc_constants.h" | 15 #include "chromeos/network/onc/onc_constants.h" |
| 14 #include "chromeos/network/onc/onc_signature.h" | 16 #include "chromeos/network/onc/onc_signature.h" |
| 15 | 17 |
| 16 namespace chromeos { | 18 namespace chromeos { |
| 17 namespace onc { | 19 namespace onc { |
| 18 | 20 |
| 21 namespace { | |
| 22 | |
| 23 std::string ValueToString(const base::Value& value) { | |
| 24 std::string json; | |
| 25 base::JSONWriter::Write(&value, &json); | |
| 26 return json; | |
| 27 } | |
| 28 | |
| 29 // Copied from policy/configuration_policy_handler.cc. | |
| 30 // TODO(pneubeck): move to a common place like base/. | |
| 31 std::string ValueTypeToString(Value::Type type) { | |
| 32 static const char* strings[] = { | |
| 33 "null", | |
| 34 "boolean", | |
| 35 "integer", | |
| 36 "double", | |
| 37 "string", | |
| 38 "binary", | |
| 39 "dictionary", | |
| 40 "list" | |
| 41 }; | |
| 42 CHECK(static_cast<size_t>(type) < arraysize(strings)); | |
| 43 return strings[type]; | |
| 44 } | |
| 45 | |
| 46 } // namespace | |
| 47 | |
| 19 Validator::Validator( | 48 Validator::Validator( |
| 20 bool error_on_unknown_field, | 49 bool error_on_unknown_field, |
| 21 bool error_on_wrong_recommended, | 50 bool error_on_wrong_recommended, |
| 22 bool error_on_missing_field, | 51 bool error_on_missing_field, |
| 23 bool managed_onc) | 52 bool managed_onc) |
| 24 : error_on_unknown_field_(error_on_unknown_field), | 53 : error_on_unknown_field_(error_on_unknown_field), |
| 25 error_on_wrong_recommended_(error_on_wrong_recommended), | 54 error_on_wrong_recommended_(error_on_wrong_recommended), |
| 26 error_on_missing_field_(error_on_missing_field), | 55 error_on_missing_field_(error_on_missing_field), |
| 27 managed_onc_(managed_onc) { | 56 managed_onc_(managed_onc) { |
| 28 } | 57 } |
| 29 | 58 |
| 30 Validator::~Validator() { | 59 Validator::~Validator() { |
| 31 } | 60 } |
| 32 | 61 |
| 33 scoped_ptr<base::DictionaryValue> Validator::ValidateAndRepairObject( | 62 scoped_ptr<base::DictionaryValue> Validator::ValidateAndRepairObject( |
| 34 const OncValueSignature* object_signature, | 63 const OncValueSignature* object_signature, |
| 35 const base::DictionaryValue& onc_object) { | 64 const base::DictionaryValue& onc_object, |
| 65 Result* result) { | |
| 36 CHECK(object_signature != NULL); | 66 CHECK(object_signature != NULL); |
| 67 *result = VALID; | |
| 68 error_or_warning_found_ = false; | |
| 69 bool error = false; | |
| 37 scoped_ptr<base::Value> result_value = | 70 scoped_ptr<base::Value> result_value = |
| 38 MapValue(*object_signature, onc_object); | 71 MapValue(*object_signature, onc_object, &error); |
| 72 if (error) { | |
| 73 *result = INVALID; | |
| 74 result_value.reset(); | |
| 75 } else if (error_or_warning_found_) { | |
| 76 *result = VALID_WITH_WARNINGS; | |
| 77 } | |
| 78 // The return value should be NULL if, and only if, |result| equals INVALID. | |
| 79 DCHECK_EQ(result_value.get() == NULL, *result == INVALID); | |
| 80 | |
| 39 base::DictionaryValue* result_dict = NULL; | 81 base::DictionaryValue* result_dict = NULL; |
| 40 if (result_value.get() != NULL) { | 82 if (result_value.get() != NULL) { |
| 41 result_value.release()->GetAsDictionary(&result_dict); | 83 result_value.release()->GetAsDictionary(&result_dict); |
| 42 CHECK(result_dict != NULL); | 84 CHECK(result_dict != NULL); |
| 43 } | 85 } |
| 44 | 86 |
| 45 return make_scoped_ptr(result_dict); | 87 return make_scoped_ptr(result_dict); |
| 46 } | 88 } |
| 47 | 89 |
| 48 scoped_ptr<base::Value> Validator::MapValue( | 90 scoped_ptr<base::Value> Validator::MapValue( |
| 49 const OncValueSignature& signature, | 91 const OncValueSignature& signature, |
| 50 const base::Value& onc_value) { | 92 const base::Value& onc_value, |
| 93 bool* error) { | |
| 51 if (onc_value.GetType() != signature.onc_type) { | 94 if (onc_value.GetType() != signature.onc_type) { |
| 52 DVLOG(1) << "Wrong type. Expected " << signature.onc_type | 95 LOG(ERROR) << ErrorHeader() << "Found value '" << onc_value |
| 53 << ", but found " << onc_value.GetType(); | 96 << "' of type '" << ValueTypeToString(onc_value.GetType()) |
| 97 << "', but type '" << ValueTypeToString(signature.onc_type) | |
| 98 << "' is required."; | |
| 99 error_or_warning_found_ = *error = true; | |
| 54 return scoped_ptr<base::Value>(); | 100 return scoped_ptr<base::Value>(); |
| 55 } | 101 } |
| 56 | 102 |
| 57 scoped_ptr<base::Value> repaired = Mapper::MapValue(signature, onc_value); | 103 scoped_ptr<base::Value> repaired = |
| 104 Mapper::MapValue(signature, onc_value, error); | |
| 58 if (repaired.get() != NULL) | 105 if (repaired.get() != NULL) |
| 59 CHECK_EQ(repaired->GetType(), signature.onc_type); | 106 CHECK_EQ(repaired->GetType(), signature.onc_type); |
| 60 return repaired.Pass(); | 107 return repaired.Pass(); |
| 61 } | 108 } |
| 62 | 109 |
| 63 scoped_ptr<base::DictionaryValue> Validator::MapObject( | 110 scoped_ptr<base::DictionaryValue> Validator::MapObject( |
| 64 const OncValueSignature& signature, | 111 const OncValueSignature& signature, |
| 65 const base::DictionaryValue& onc_object) { | 112 const base::DictionaryValue& onc_object, |
| 113 bool* error) { | |
| 66 scoped_ptr<base::DictionaryValue> repaired(new base::DictionaryValue); | 114 scoped_ptr<base::DictionaryValue> repaired(new base::DictionaryValue); |
| 67 | 115 |
| 68 bool valid; | 116 bool valid; |
| 69 if (&signature == &kNetworkConfigurationSignature) | 117 if (&signature == &kToplevelConfigurationSignature) |
| 118 valid = ValidateToplevelConfiguration(onc_object, repaired.get()); | |
| 119 else if (&signature == &kNetworkConfigurationSignature) | |
| 70 valid = ValidateNetworkConfiguration(onc_object, repaired.get()); | 120 valid = ValidateNetworkConfiguration(onc_object, repaired.get()); |
| 71 else if (&signature == &kEthernetSignature) | 121 else if (&signature == &kEthernetSignature) |
| 72 valid = ValidateEthernet(onc_object, repaired.get()); | 122 valid = ValidateEthernet(onc_object, repaired.get()); |
| 73 else if (&signature == &kIPConfigSignature) | 123 else if (&signature == &kIPConfigSignature) |
| 74 valid = ValidateIPConfig(onc_object, repaired.get()); | 124 valid = ValidateIPConfig(onc_object, repaired.get()); |
| 75 else if (&signature == &kWiFiSignature) | 125 else if (&signature == &kWiFiSignature) |
| 76 valid = ValidateWiFi(onc_object, repaired.get()); | 126 valid = ValidateWiFi(onc_object, repaired.get()); |
| 77 else if (&signature == &kVPNSignature) | 127 else if (&signature == &kVPNSignature) |
| 78 valid = ValidateVPN(onc_object, repaired.get()); | 128 valid = ValidateVPN(onc_object, repaired.get()); |
| 79 else if (&signature == &kIPsecSignature) | 129 else if (&signature == &kIPsecSignature) |
| 80 valid = ValidateIPsec(onc_object, repaired.get()); | 130 valid = ValidateIPsec(onc_object, repaired.get()); |
| 81 else if (&signature == &kOpenVPNSignature) | 131 else if (&signature == &kOpenVPNSignature) |
| 82 valid = ValidateOpenVPN(onc_object, repaired.get()); | 132 valid = ValidateOpenVPN(onc_object, repaired.get()); |
| 83 else if (&signature == &kCertificatePatternSignature) | 133 else if (&signature == &kCertificatePatternSignature) |
| 84 valid = ValidateCertificatePattern(onc_object, repaired.get()); | 134 valid = ValidateCertificatePattern(onc_object, repaired.get()); |
| 85 else if (&signature == &kProxySettingsSignature) | 135 else if (&signature == &kProxySettingsSignature) |
| 86 valid = ValidateProxySettings(onc_object, repaired.get()); | 136 valid = ValidateProxySettings(onc_object, repaired.get()); |
| 87 else if (&signature == &kProxyLocationSignature) | 137 else if (&signature == &kProxyLocationSignature) |
| 88 valid = ValidateProxyLocation(onc_object, repaired.get()); | 138 valid = ValidateProxyLocation(onc_object, repaired.get()); |
| 89 else if (&signature == &kEAPSignature) | 139 else if (&signature == &kEAPSignature) |
| 90 valid = ValidateEAP(onc_object, repaired.get()); | 140 valid = ValidateEAP(onc_object, repaired.get()); |
| 91 else if (&signature == &kCertificateSignature) | 141 else if (&signature == &kCertificateSignature) |
| 92 valid = ValidateCertificate(onc_object, repaired.get()); | 142 valid = ValidateCertificate(onc_object, repaired.get()); |
| 93 else | 143 else |
| 94 valid = ValidateObjectDefault(signature, onc_object, repaired.get()); | 144 valid = ValidateObjectDefault(signature, onc_object, repaired.get()); |
| 95 | 145 |
| 96 if (valid) | 146 if (valid) { |
| 97 return repaired.Pass(); | 147 return repaired.Pass(); |
| 98 else | 148 } else { |
| 149 error_or_warning_found_ = *error = true; | |
| 99 return scoped_ptr<base::DictionaryValue>(); | 150 return scoped_ptr<base::DictionaryValue>(); |
| 151 } | |
| 152 } | |
| 153 | |
| 154 scoped_ptr<base::Value> Validator::MapField( | |
| 155 const std::string& field_name, | |
| 156 const OncValueSignature& object_signature, | |
| 157 const base::Value& onc_value, | |
| 158 bool* found_unknown_field, | |
| 159 bool* error) { | |
| 160 path_.push_back(field_name); | |
| 161 bool current_field_unknown = false; | |
| 162 scoped_ptr<base::Value> result = Mapper::MapField( | |
| 163 field_name, object_signature, onc_value, ¤t_field_unknown, error); | |
| 164 | |
| 165 DCHECK_EQ(field_name, path_.back()); | |
| 166 path_.pop_back(); | |
| 167 | |
| 168 if (current_field_unknown) { | |
| 169 error_or_warning_found_ = *found_unknown_field = true; | |
| 170 std::string message = MessageHeader(error_on_unknown_field_) | |
| 171 + "Field name '" + field_name + "' is unknown."; | |
| 172 if (error_on_unknown_field_) | |
| 173 LOG(ERROR) << message; | |
| 174 else | |
| 175 LOG(WARNING) << message; | |
| 176 } | |
| 177 | |
| 178 return result.Pass(); | |
| 179 } | |
| 180 | |
| 181 scoped_ptr<base::Value> Validator::MapEntry(int index, | |
| 182 const OncValueSignature& signature, | |
| 183 const base::Value& onc_value, | |
| 184 bool* error) { | |
| 185 std::string str = base::IntToString(index); | |
| 186 path_.push_back(str); | |
| 187 scoped_ptr<base::Value> result = | |
| 188 Mapper::MapEntry(index, signature, onc_value, error); | |
| 189 DCHECK_EQ(str, path_.back()); | |
| 190 path_.pop_back(); | |
| 191 return result.Pass(); | |
| 100 } | 192 } |
| 101 | 193 |
| 102 bool Validator::ValidateObjectDefault( | 194 bool Validator::ValidateObjectDefault( |
| 103 const OncValueSignature& signature, | 195 const OncValueSignature& signature, |
| 104 const base::DictionaryValue& onc_object, | 196 const base::DictionaryValue& onc_object, |
| 105 base::DictionaryValue* result) { | 197 base::DictionaryValue* result) { |
| 106 bool found_unknown_field = false; | 198 bool found_unknown_field = false; |
| 107 bool nested_error_occured = false; | 199 bool nested_error_occured = false; |
| 108 MapFields(signature, onc_object, &found_unknown_field, &nested_error_occured, | 200 MapFields(signature, onc_object, &found_unknown_field, &nested_error_occured, |
| 109 result); | 201 result); |
| 202 | |
| 203 if (found_unknown_field && error_on_unknown_field_) { | |
| 204 DVLOG(1) << "Unknown field names are errors: Aborting."; | |
| 205 return false; | |
| 206 } | |
| 207 | |
| 110 if (nested_error_occured) | 208 if (nested_error_occured) |
| 111 return false; | 209 return false; |
| 112 | 210 |
| 113 if (found_unknown_field) { | |
| 114 if (error_on_unknown_field_) { | |
| 115 DVLOG(1) << "Unknown field name. Aborting."; | |
| 116 return false; | |
| 117 } | |
| 118 DVLOG(1) << "Unknown field name. Ignoring."; | |
| 119 } | |
| 120 | |
| 121 return ValidateRecommendedField(signature, result); | 211 return ValidateRecommendedField(signature, result); |
| 122 } | 212 } |
| 123 | 213 |
| 124 bool Validator::ValidateRecommendedField( | 214 bool Validator::ValidateRecommendedField( |
| 125 const OncValueSignature& object_signature, | 215 const OncValueSignature& object_signature, |
| 126 base::DictionaryValue* result) { | 216 base::DictionaryValue* result) { |
| 127 CHECK(result != NULL); | 217 CHECK(result != NULL); |
| 128 | 218 |
| 129 scoped_ptr<base::ListValue> recommended; | 219 scoped_ptr<base::ListValue> recommended; |
| 130 base::Value* recommended_value; | 220 base::Value* recommended_value; |
| 131 // This remove passes ownership to |recommended_value|. | 221 // This remove passes ownership to |recommended_value|. |
| 132 if (!result->RemoveWithoutPathExpansion(onc::kRecommended, | 222 if (!result->RemoveWithoutPathExpansion(onc::kRecommended, |
| 133 &recommended_value)) { | 223 &recommended_value)) { |
| 134 return true; | 224 return true; |
| 135 } | 225 } |
| 136 base::ListValue* recommended_list; | 226 base::ListValue* recommended_list; |
| 137 recommended_value->GetAsList(&recommended_list); | 227 recommended_value->GetAsList(&recommended_list); |
| 138 CHECK(recommended_list != NULL); | 228 CHECK(recommended_list != NULL); |
| 139 | 229 |
| 140 recommended.reset(recommended_list); | 230 recommended.reset(recommended_list); |
| 141 | 231 |
| 142 if (!managed_onc_) { | 232 if (!managed_onc_) { |
| 143 DVLOG(1) << "Found a " << onc::kRecommended | 233 LOG(WARNING) << WarningHeader() << "Found the field '" << onc::kRecommended |
| 144 << " field in unmanaged ONC. Removing it."; | 234 << "' in an unmanaged ONC. Removing it."; |
| 145 return true; | 235 return true; |
| 146 } | 236 } |
| 147 | 237 |
| 148 scoped_ptr<base::ListValue> repaired_recommended(new base::ListValue); | 238 scoped_ptr<base::ListValue> repaired_recommended(new base::ListValue); |
| 149 for (base::ListValue::iterator it = recommended->begin(); | 239 for (base::ListValue::iterator it = recommended->begin(); |
| 150 it != recommended->end(); ++it) { | 240 it != recommended->end(); ++it) { |
| 151 std::string field_name; | 241 std::string field_name; |
| 152 if (!(*it)->GetAsString(&field_name)) { | 242 if (!(*it)->GetAsString(&field_name)) { |
| 153 NOTREACHED(); | 243 NOTREACHED(); |
| 154 continue; | 244 continue; |
| 155 } | 245 } |
| 156 | 246 |
| 157 const OncFieldSignature* field_signature = | 247 const OncFieldSignature* field_signature = |
| 158 GetFieldSignature(object_signature, field_name); | 248 GetFieldSignature(object_signature, field_name); |
| 159 | 249 |
| 160 bool found_error = false; | 250 bool found_error = false; |
| 161 std::string error_cause; | 251 std::string error_cause; |
| 162 if (field_signature == NULL) { | 252 if (field_signature == NULL) { |
| 163 found_error = true; | 253 found_error = true; |
| 164 error_cause = "unknown"; | 254 error_cause = "unknown"; |
| 165 } else if (field_signature->value_signature->onc_type == | 255 } else if (field_signature->value_signature->onc_type == |
| 166 base::Value::TYPE_DICTIONARY) { | 256 base::Value::TYPE_DICTIONARY) { |
| 167 found_error = true; | 257 found_error = true; |
| 168 error_cause = "dictionary-typed"; | 258 error_cause = "dictionary-typed"; |
| 169 } | 259 } |
| 170 | 260 |
| 171 if (found_error) { | 261 if (found_error) { |
| 172 DVLOG(1) << "Found " << error_cause << " field name '" << field_name | 262 error_or_warning_found_ = true; |
| 173 << "' in kRecommended array. " | 263 path_.push_back(onc::kRecommended); |
| 174 << (error_on_wrong_recommended_ ? "Aborting." : "Ignoring."); | 264 std::string message = MessageHeader(error_on_wrong_recommended_) + |
| 175 if (error_on_wrong_recommended_) | 265 "The " + error_cause + " field '" + field_name + |
| 266 "' cannot be recommended."; | |
| 267 path_.pop_back(); | |
| 268 if (error_on_wrong_recommended_) { | |
| 269 LOG(ERROR) << message; | |
| 176 return false; | 270 return false; |
| 177 else | 271 } else { |
| 272 LOG(WARNING) << message; | |
| 178 continue; | 273 continue; |
| 274 } | |
| 179 } | 275 } |
| 180 | 276 |
| 181 repaired_recommended->Append((*it)->DeepCopy()); | 277 repaired_recommended->Append((*it)->DeepCopy()); |
| 182 } | 278 } |
| 183 | 279 |
| 184 result->Set(onc::kRecommended, repaired_recommended.release()); | 280 result->Set(onc::kRecommended, repaired_recommended.release()); |
| 185 return true; | 281 return true; |
| 186 } | 282 } |
| 187 | 283 |
| 188 namespace { | 284 namespace { |
| 189 | 285 |
| 190 std::string JoinStringRange(const char** range_begin, | 286 std::string JoinStringRange(const char** range_begin, |
| 191 const char** range_end, | 287 const char** range_end, |
| 192 const std::string& separator) { | 288 const std::string& separator) { |
| 193 std::vector<std::string> string_vector; | 289 std::vector<std::string> string_vector; |
| 194 std::copy(range_begin, range_end, std::back_inserter(string_vector)); | 290 std::copy(range_begin, range_end, std::back_inserter(string_vector)); |
| 195 return JoinString(string_vector, separator); | 291 return JoinString(string_vector, separator); |
| 196 } | 292 } |
| 197 | 293 |
| 198 bool RequireAnyOf(const std::string &actual, const char** valid_values) { | |
| 199 const char** it = valid_values; | |
| 200 for (; *it != NULL; ++it) { | |
| 201 if (actual == *it) | |
| 202 return true; | |
| 203 } | |
| 204 DVLOG(1) << "Found " << actual << ", but expected one of " | |
| 205 << JoinStringRange(valid_values, it, ", "); | |
| 206 return false; | |
| 207 } | |
| 208 | |
| 209 bool IsInRange(int actual, int lower_bound, int upper_bound) { | |
| 210 if (lower_bound <= actual && actual <= upper_bound) | |
| 211 return true; | |
| 212 DVLOG(1) << "Found " << actual << ", which is out of range [" << lower_bound | |
| 213 << ", " << upper_bound << "]"; | |
| 214 return false; | |
| 215 } | |
| 216 | |
| 217 bool RequireField(const base::DictionaryValue& dict, std::string key) { | |
| 218 if (dict.HasKey(key)) | |
| 219 return true; | |
| 220 DVLOG(1) << "Required field " << key << " missing."; | |
| 221 return false; | |
| 222 } | |
| 223 | |
| 224 } // namespace | 294 } // namespace |
| 225 | 295 |
| 296 bool Validator::FieldExistsAndHasNoValueOf(const base::DictionaryValue& object, | |
|
Greg Spencer (Chromium)
2012/12/14 18:28:43
Maybe "FieldExistsAndHasNoValidValue"?
pneubeck (no reviews)
2012/12/14 19:44:45
Done.
| |
| 297 const std::string &field_name, | |
| 298 const char** valid_values) { | |
| 299 std::string actual_value; | |
| 300 if (!object.GetStringWithoutPathExpansion(field_name, &actual_value)) | |
| 301 return false; | |
| 302 | |
| 303 const char** it = valid_values; | |
| 304 for (; *it != NULL; ++it) { | |
| 305 if (actual_value == *it) | |
| 306 return false; | |
| 307 } | |
| 308 error_or_warning_found_ = true; | |
| 309 std::string valid_values_str = | |
| 310 "[" + JoinStringRange(valid_values, it, ", ") + "]"; | |
| 311 path_.push_back(field_name); | |
| 312 LOG(ERROR) << ErrorHeader() << "Found value '" << actual_value << | |
| 313 "', but expected one of the values " << valid_values_str; | |
| 314 path_.pop_back(); | |
| 315 return true; | |
| 316 } | |
| 317 | |
| 318 bool Validator::FieldExistsAndIsNotInRange(const base::DictionaryValue& object, | |
| 319 const std::string &field_name, | |
| 320 int lower_bound, | |
| 321 int upper_bound) { | |
| 322 int actual_value; | |
| 323 if (!object.GetIntegerWithoutPathExpansion(field_name, &actual_value) || | |
| 324 (lower_bound <= actual_value && actual_value <= upper_bound)) { | |
| 325 return false; | |
| 326 } | |
| 327 error_or_warning_found_ = true; | |
| 328 path_.push_back(field_name); | |
| 329 LOG(ERROR) << ErrorHeader() << "Found value '" << actual_value | |
| 330 << "', but expected a value in the range [" << lower_bound | |
| 331 << ", " << upper_bound << "] (boundaries inclusive)"; | |
| 332 path_.pop_back(); | |
| 333 return true; | |
| 334 } | |
| 335 | |
| 336 bool Validator::RequireField(const base::DictionaryValue& dict, | |
| 337 const std::string& field_name) { | |
| 338 if (dict.HasKey(field_name)) | |
| 339 return true; | |
| 340 error_or_warning_found_ = true; | |
| 341 LOG(ERROR) << ErrorHeader() << "The required field '" << field_name | |
| 342 << "' is missing."; | |
| 343 return false; | |
| 344 } | |
| 345 | |
| 346 bool Validator::ValidateToplevelConfiguration( | |
| 347 const base::DictionaryValue& onc_object, | |
| 348 base::DictionaryValue* result) { | |
| 349 if (!ValidateObjectDefault(kToplevelConfigurationSignature, | |
| 350 onc_object, result)) { | |
| 351 return false; | |
| 352 } | |
| 353 | |
| 354 static const char* kValidTypes[] = | |
| 355 { kUnencryptedConfiguration, kEncryptedConfiguration, NULL }; | |
| 356 if (FieldExistsAndHasNoValueOf(*result, kType, kValidTypes)) | |
| 357 return false; | |
| 358 | |
| 359 bool allRequiredExist = true; | |
| 360 | |
| 361 // Not part of the ONC spec yet: | |
| 362 // We don't require the type field and default to UnencryptedConfiguration. | |
| 363 std::string type = kUnencryptedConfiguration; | |
| 364 result->GetStringWithoutPathExpansion(kType, &type); | |
| 365 if (type == kUnencryptedConfiguration && | |
| 366 !result->HasKey(kNetworkConfigurations) && | |
| 367 !result->HasKey(kCertificates)) { | |
| 368 error_or_warning_found_ = true; | |
| 369 std::string message = MessageHeader(error_on_missing_field_) + | |
| 370 "Neither the field '" + kNetworkConfigurations + "' nor '" + | |
| 371 kCertificates + "is present, but at least one is required."; | |
| 372 if (error_on_missing_field_) | |
| 373 LOG(ERROR) << message; | |
| 374 else | |
| 375 LOG(WARNING) << message; | |
| 376 allRequiredExist = false; | |
| 377 } | |
| 378 | |
| 379 return !error_on_missing_field_ || allRequiredExist; | |
| 380 } | |
| 381 | |
| 226 bool Validator::ValidateNetworkConfiguration( | 382 bool Validator::ValidateNetworkConfiguration( |
| 227 const base::DictionaryValue& onc_object, | 383 const base::DictionaryValue& onc_object, |
| 228 base::DictionaryValue* result) { | 384 base::DictionaryValue* result) { |
| 229 if (!ValidateObjectDefault(kNetworkConfigurationSignature, | 385 if (!ValidateObjectDefault(kNetworkConfigurationSignature, |
| 230 onc_object, result)) { | 386 onc_object, result)) { |
| 231 return false; | 387 return false; |
| 232 } | 388 } |
| 233 | 389 |
| 234 std::string type; | |
| 235 static const char* kValidTypes[] = { kEthernet, kVPN, kWiFi, NULL }; | 390 static const char* kValidTypes[] = { kEthernet, kVPN, kWiFi, NULL }; |
| 236 if (result->GetStringWithoutPathExpansion(kType, &type) && | 391 if (FieldExistsAndHasNoValueOf(*result, kType, kValidTypes)) |
| 237 !RequireAnyOf(type, kValidTypes)) { | |
| 238 return false; | 392 return false; |
| 239 } | |
| 240 | 393 |
| 241 bool allRequiredExist = RequireField(*result, kGUID); | 394 bool allRequiredExist = RequireField(*result, kGUID); |
| 242 | 395 |
| 243 bool remove = false; | 396 bool remove = false; |
| 244 result->GetBooleanWithoutPathExpansion(kRemove, &remove); | 397 result->GetBooleanWithoutPathExpansion(kRemove, &remove); |
| 245 if (!remove) { | 398 if (!remove) { |
| 246 allRequiredExist &= RequireField(*result, kName); | 399 allRequiredExist &= RequireField(*result, kName); |
| 247 allRequiredExist &= RequireField(*result, kType); | 400 allRequiredExist &= RequireField(*result, kType); |
| 401 | |
| 402 std::string type; | |
| 403 result->GetStringWithoutPathExpansion(kType, &type); | |
| 248 allRequiredExist &= type.empty() || RequireField(*result, type); | 404 allRequiredExist &= type.empty() || RequireField(*result, type); |
| 249 } | 405 } |
| 250 | 406 |
| 251 return !error_on_missing_field_ || allRequiredExist; | 407 return !error_on_missing_field_ || allRequiredExist; |
| 252 } | 408 } |
| 253 | 409 |
| 254 bool Validator::ValidateEthernet( | 410 bool Validator::ValidateEthernet( |
| 255 const base::DictionaryValue& onc_object, | 411 const base::DictionaryValue& onc_object, |
| 256 base::DictionaryValue* result) { | 412 base::DictionaryValue* result) { |
| 257 using namespace onc::ethernet; | 413 using namespace onc::ethernet; |
| 258 if (!ValidateObjectDefault(kEthernetSignature, onc_object, result)) | 414 if (!ValidateObjectDefault(kEthernetSignature, onc_object, result)) |
| 259 return false; | 415 return false; |
| 260 | 416 |
| 261 std::string auth; | |
| 262 static const char* kValidAuthentications[] = { kNone, k8021X, NULL }; | 417 static const char* kValidAuthentications[] = { kNone, k8021X, NULL }; |
| 263 if (result->GetStringWithoutPathExpansion(kAuthentication, &auth) && | 418 if (FieldExistsAndHasNoValueOf(*result, kAuthentication, |
| 264 !RequireAnyOf(auth, kValidAuthentications)) { | 419 kValidAuthentications)) { |
| 265 return false; | 420 return false; |
| 266 } | 421 } |
| 267 | 422 |
| 268 bool allRequiredExist = true; | 423 bool allRequiredExist = true; |
| 424 std::string auth; | |
| 425 result->GetStringWithoutPathExpansion(kAuthentication, &auth); | |
| 269 if (auth == k8021X) | 426 if (auth == k8021X) |
| 270 allRequiredExist &= RequireField(*result, kEAP); | 427 allRequiredExist &= RequireField(*result, kEAP); |
| 271 | 428 |
| 272 return !error_on_missing_field_ || allRequiredExist; | 429 return !error_on_missing_field_ || allRequiredExist; |
| 273 } | 430 } |
| 274 | 431 |
| 275 bool Validator::ValidateIPConfig( | 432 bool Validator::ValidateIPConfig( |
| 276 const base::DictionaryValue& onc_object, | 433 const base::DictionaryValue& onc_object, |
| 277 base::DictionaryValue* result) { | 434 base::DictionaryValue* result) { |
| 278 using namespace onc::ipconfig; | 435 using namespace onc::ipconfig; |
| 279 if (!ValidateObjectDefault(kIPConfigSignature, onc_object, result)) | 436 if (!ValidateObjectDefault(kIPConfigSignature, onc_object, result)) |
| 280 return false; | 437 return false; |
| 281 | 438 |
| 439 static const char* kValidTypes[] = { kIPv4, kIPv6, NULL }; | |
| 440 if (FieldExistsAndHasNoValueOf(*result, ipconfig::kType, kValidTypes)) | |
| 441 return false; | |
| 442 | |
| 282 std::string type; | 443 std::string type; |
| 283 static const char* kValidTypes[] = { kIPv4, kIPv6, NULL }; | 444 result->GetStringWithoutPathExpansion(ipconfig::kType, &type); |
| 284 if (result->GetStringWithoutPathExpansion(ipconfig::kType, &type) && | 445 int lower_bound = 1; |
| 285 !RequireAnyOf(type, kValidTypes)) { | 446 // In case of missing type, choose higher upper_bound. |
| 447 int upper_bound = (type == kIPv4) ? 32 : 128; | |
| 448 if (FieldExistsAndIsNotInRange(*result, kRoutingPrefix, | |
| 449 lower_bound, upper_bound)) { | |
| 286 return false; | 450 return false; |
| 287 } | 451 } |
| 288 | 452 |
| 289 int routing_prefix; | |
| 290 int lower_bound = 1; | |
| 291 // In case of missing type, choose higher upper_bound. | |
| 292 int upper_bound = (type == kIPv4) ? 32 : 128; | |
| 293 if (result->GetIntegerWithoutPathExpansion(kRoutingPrefix, &routing_prefix) && | |
| 294 !IsInRange(routing_prefix, lower_bound, upper_bound)) { | |
| 295 return false; | |
| 296 } | |
| 297 | |
| 298 bool allRequiredExist = RequireField(*result, kIPAddress) & | 453 bool allRequiredExist = RequireField(*result, kIPAddress) & |
| 299 RequireField(*result, kRoutingPrefix) & | 454 RequireField(*result, kRoutingPrefix) & |
| 300 RequireField(*result, ipconfig::kType); | 455 RequireField(*result, ipconfig::kType); |
| 301 | 456 |
| 302 return !error_on_missing_field_ || allRequiredExist; | 457 return !error_on_missing_field_ || allRequiredExist; |
| 303 } | 458 } |
| 304 | 459 |
| 305 bool Validator::ValidateWiFi( | 460 bool Validator::ValidateWiFi( |
| 306 const base::DictionaryValue& onc_object, | 461 const base::DictionaryValue& onc_object, |
| 307 base::DictionaryValue* result) { | 462 base::DictionaryValue* result) { |
| 308 using namespace onc::wifi; | 463 using namespace onc::wifi; |
| 309 if (!ValidateObjectDefault(kWiFiSignature, onc_object, result)) | 464 if (!ValidateObjectDefault(kWiFiSignature, onc_object, result)) |
| 310 return false; | 465 return false; |
| 311 | 466 |
| 312 std::string security; | |
| 313 static const char* kValidSecurities[] = | 467 static const char* kValidSecurities[] = |
| 314 { kNone, kWEP_PSK, kWEP_8021X, kWPA_PSK, kWPA_EAP, NULL }; | 468 { kNone, kWEP_PSK, kWEP_8021X, kWPA_PSK, kWPA_EAP, NULL }; |
| 315 if (result->GetStringWithoutPathExpansion(kSecurity, &security) && | 469 if (FieldExistsAndHasNoValueOf(*result, kSecurity, kValidSecurities)) |
| 316 !RequireAnyOf(security, kValidSecurities)) { | |
| 317 return false; | 470 return false; |
| 318 } | |
| 319 | 471 |
| 320 bool allRequiredExist = RequireField(*result, kSecurity) & | 472 bool allRequiredExist = RequireField(*result, kSecurity) & |
| 321 RequireField(*result, kSSID); | 473 RequireField(*result, kSSID); |
| 474 | |
| 475 std::string security; | |
| 476 result->GetStringWithoutPathExpansion(kSecurity, &security); | |
| 322 if (security == kWEP_8021X || security == kWPA_EAP) | 477 if (security == kWEP_8021X || security == kWPA_EAP) |
| 323 allRequiredExist &= RequireField(*result, kEAP); | 478 allRequiredExist &= RequireField(*result, kEAP); |
| 324 else if (security == kWEP_PSK || security == kWPA_PSK) | 479 else if (security == kWEP_PSK || security == kWPA_PSK) |
| 325 allRequiredExist &= RequireField(*result, kPassphrase); | 480 allRequiredExist &= RequireField(*result, kPassphrase); |
| 326 | 481 |
| 327 return !error_on_missing_field_ || allRequiredExist; | 482 return !error_on_missing_field_ || allRequiredExist; |
| 328 } | 483 } |
| 329 | 484 |
| 330 bool Validator::ValidateVPN( | 485 bool Validator::ValidateVPN( |
| 331 const base::DictionaryValue& onc_object, | 486 const base::DictionaryValue& onc_object, |
| 332 base::DictionaryValue* result) { | 487 base::DictionaryValue* result) { |
| 333 using namespace vpn; | 488 using namespace vpn; |
| 334 if (!ValidateObjectDefault(kVPNSignature, onc_object, result)) | 489 if (!ValidateObjectDefault(kVPNSignature, onc_object, result)) |
| 335 return false; | 490 return false; |
| 336 | 491 |
| 337 std::string type; | |
| 338 static const char* kValidTypes[] = | 492 static const char* kValidTypes[] = |
| 339 { kIPsec, kTypeL2TP_IPsec, kOpenVPN, NULL }; | 493 { kIPsec, kTypeL2TP_IPsec, kOpenVPN, NULL }; |
| 340 if (result->GetStringWithoutPathExpansion(vpn::kType, &type) && | 494 if (FieldExistsAndHasNoValueOf(*result, vpn::kType, kValidTypes)) |
| 341 !RequireAnyOf(type, kValidTypes)) { | |
| 342 return false; | 495 return false; |
| 343 } | |
| 344 | 496 |
| 345 bool allRequiredExist = RequireField(*result, vpn::kType); | 497 bool allRequiredExist = RequireField(*result, vpn::kType); |
| 346 | 498 std::string type; |
| 499 result->GetStringWithoutPathExpansion(vpn::kType, &type); | |
| 347 if (type == kOpenVPN) { | 500 if (type == kOpenVPN) { |
| 348 allRequiredExist &= RequireField(*result, kOpenVPN); | 501 allRequiredExist &= RequireField(*result, kOpenVPN); |
| 349 } else if (type == kIPsec) { | 502 } else if (type == kIPsec) { |
| 350 allRequiredExist &= RequireField(*result, kIPsec); | 503 allRequiredExist &= RequireField(*result, kIPsec); |
| 351 } else if (type == kTypeL2TP_IPsec) { | 504 } else if (type == kTypeL2TP_IPsec) { |
| 352 allRequiredExist &= RequireField(*result, kIPsec) & | 505 allRequiredExist &= RequireField(*result, kIPsec) & |
| 353 RequireField(*result, kL2TP); | 506 RequireField(*result, kL2TP); |
| 354 } | 507 } |
| 355 | 508 |
| 356 return !error_on_missing_field_ || allRequiredExist; | 509 return !error_on_missing_field_ || allRequiredExist; |
| 357 } | 510 } |
| 358 | 511 |
| 359 bool Validator::ValidateIPsec( | 512 bool Validator::ValidateIPsec( |
| 360 const base::DictionaryValue& onc_object, | 513 const base::DictionaryValue& onc_object, |
| 361 base::DictionaryValue* result) { | 514 base::DictionaryValue* result) { |
| 362 using namespace onc::vpn; | 515 using namespace onc::vpn; |
| 363 using namespace onc::certificate; | 516 using namespace onc::certificate; |
| 364 if (!ValidateObjectDefault(kIPsecSignature, onc_object, result)) | 517 if (!ValidateObjectDefault(kIPsecSignature, onc_object, result)) |
| 365 return false; | 518 return false; |
| 366 | 519 |
| 367 std::string auth; | |
| 368 static const char* kValidAuthentications[] = { kPSK, kCert, NULL }; | 520 static const char* kValidAuthentications[] = { kPSK, kCert, NULL }; |
| 369 if (result->GetStringWithoutPathExpansion(kAuthenticationType, &auth) && | |
| 370 !RequireAnyOf(auth, kValidAuthentications)) { | |
| 371 return false; | |
| 372 } | |
| 373 | |
| 374 std::string cert_type; | |
| 375 static const char* kValidCertTypes[] = { kRef, kPattern, NULL }; | 521 static const char* kValidCertTypes[] = { kRef, kPattern, NULL }; |
| 376 if (result->GetStringWithoutPathExpansion(kClientCertType, &cert_type) && | 522 // Using strict bit-wise OR to check all conditions. |
| 377 !RequireAnyOf(cert_type, kValidCertTypes)) { | 523 if (FieldExistsAndHasNoValueOf(*result, kAuthenticationType, |
| 524 kValidAuthentications) | | |
| 525 FieldExistsAndHasNoValueOf(*result, kClientCertType, kValidCertTypes)) { | |
| 378 return false; | 526 return false; |
| 379 } | 527 } |
| 380 | 528 |
| 381 bool allRequiredExist = RequireField(*result, kAuthenticationType) & | 529 bool allRequiredExist = RequireField(*result, kAuthenticationType) & |
| 382 RequireField(*result, kIKEVersion); | 530 RequireField(*result, kIKEVersion); |
| 531 std::string auth; | |
| 532 result->GetStringWithoutPathExpansion(kAuthenticationType, &auth); | |
| 383 if (auth == kCert) { | 533 if (auth == kCert) { |
| 384 allRequiredExist &= RequireField(*result, kClientCertType) & | 534 allRequiredExist &= RequireField(*result, kClientCertType) & |
| 385 RequireField(*result, kServerCARef); | 535 RequireField(*result, kServerCARef); |
| 386 } | 536 } |
| 537 std::string cert_type; | |
| 538 result->GetStringWithoutPathExpansion(kClientCertType, &cert_type); | |
| 387 if (cert_type == kPattern) | 539 if (cert_type == kPattern) |
| 388 allRequiredExist &= RequireField(*result, kClientCertPattern); | 540 allRequiredExist &= RequireField(*result, kClientCertPattern); |
| 389 else if (cert_type == kRef) | 541 else if (cert_type == kRef) |
| 390 allRequiredExist &= RequireField(*result, kClientCertRef); | 542 allRequiredExist &= RequireField(*result, kClientCertRef); |
| 391 | 543 |
| 392 return !error_on_missing_field_ || allRequiredExist; | 544 return !error_on_missing_field_ || allRequiredExist; |
| 393 } | 545 } |
| 394 | 546 |
| 395 bool Validator::ValidateOpenVPN( | 547 bool Validator::ValidateOpenVPN( |
| 396 const base::DictionaryValue& onc_object, | 548 const base::DictionaryValue& onc_object, |
| 397 base::DictionaryValue* result) { | 549 base::DictionaryValue* result) { |
| 398 using namespace onc::vpn; | 550 using namespace onc::vpn; |
| 399 using namespace onc::openvpn; | 551 using namespace onc::openvpn; |
| 400 using namespace onc::certificate; | 552 using namespace onc::certificate; |
| 401 if (!ValidateObjectDefault(kOpenVPNSignature, onc_object, result)) | 553 if (!ValidateObjectDefault(kOpenVPNSignature, onc_object, result)) |
| 402 return false; | 554 return false; |
| 403 | 555 |
| 404 std::string auth_retry; | |
| 405 static const char* kValidAuthRetryValues[] = | 556 static const char* kValidAuthRetryValues[] = |
| 406 { openvpn::kNone, kInteract, kNoInteract, NULL }; | 557 { openvpn::kNone, kInteract, kNoInteract, NULL }; |
| 407 if (result->GetStringWithoutPathExpansion(kAuthRetry, &auth_retry) && | |
| 408 !RequireAnyOf(auth_retry, kValidAuthRetryValues)) { | |
| 409 return false; | |
| 410 } | |
| 411 | |
| 412 std::string cert_type; | |
| 413 static const char* kValidCertTypes[] = | 558 static const char* kValidCertTypes[] = |
| 414 { certificate::kNone, kRef, kPattern, NULL }; | 559 { certificate::kNone, kRef, kPattern, NULL }; |
| 415 if (result->GetStringWithoutPathExpansion(kClientCertType, &cert_type) && | |
| 416 !RequireAnyOf(cert_type, kValidCertTypes)) { | |
| 417 return false; | |
| 418 } | |
| 419 | |
| 420 std::string cert_tls; | |
| 421 static const char* kValidCertTlsValues[] = | 560 static const char* kValidCertTlsValues[] = |
| 422 { openvpn::kNone, openvpn::kServer, NULL }; | 561 { openvpn::kNone, openvpn::kServer, NULL }; |
| 423 if (result->GetStringWithoutPathExpansion(kRemoteCertTLS, &cert_tls) && | 562 |
| 424 !RequireAnyOf(cert_tls, kValidCertTlsValues)) { | 563 // Using strict bit-wise OR to check all conditions. |
| 564 if (FieldExistsAndHasNoValueOf(*result, kAuthRetry, kValidAuthRetryValues) | | |
| 565 FieldExistsAndHasNoValueOf(*result, kClientCertType, kValidCertTypes) | | |
| 566 FieldExistsAndHasNoValueOf(*result, kRemoteCertTLS, | |
| 567 kValidCertTlsValues)) { | |
| 425 return false; | 568 return false; |
| 426 } | 569 } |
| 427 | 570 |
| 428 bool allRequiredExist = RequireField(*result, kClientCertType); | 571 bool allRequiredExist = RequireField(*result, kClientCertType); |
| 572 std::string cert_type; | |
| 573 result->GetStringWithoutPathExpansion(kClientCertType, &cert_type); | |
| 429 if (cert_type == kPattern) | 574 if (cert_type == kPattern) |
| 430 allRequiredExist &= RequireField(*result, kClientCertPattern); | 575 allRequiredExist &= RequireField(*result, kClientCertPattern); |
| 431 else if (cert_type == kRef) | 576 else if (cert_type == kRef) |
| 432 allRequiredExist &= RequireField(*result, kClientCertRef); | 577 allRequiredExist &= RequireField(*result, kClientCertRef); |
| 433 | 578 |
| 434 return !error_on_missing_field_ || allRequiredExist; | 579 return !error_on_missing_field_ || allRequiredExist; |
| 435 } | 580 } |
| 436 | 581 |
| 437 bool Validator::ValidateCertificatePattern( | 582 bool Validator::ValidateCertificatePattern( |
| 438 const base::DictionaryValue& onc_object, | 583 const base::DictionaryValue& onc_object, |
| 439 base::DictionaryValue* result) { | 584 base::DictionaryValue* result) { |
| 440 using namespace onc::certificate; | 585 using namespace onc::certificate; |
| 441 if (!ValidateObjectDefault(kCertificatePatternSignature, onc_object, result)) | 586 if (!ValidateObjectDefault(kCertificatePatternSignature, onc_object, result)) |
| 442 return false; | 587 return false; |
| 443 | 588 |
| 444 bool allRequiredExist = true; | 589 bool allRequiredExist = true; |
| 445 if (!result->HasKey(kSubject) && !result->HasKey(kIssuer) && | 590 if (!result->HasKey(kSubject) && !result->HasKey(kIssuer) && |
| 446 !result->HasKey(kIssuerCARef)) { | 591 !result->HasKey(kIssuerCARef)) { |
| 592 error_or_warning_found_ = true; | |
| 447 allRequiredExist = false; | 593 allRequiredExist = false; |
| 448 DVLOG(1) << "None of the fields " << kSubject << ", " << kIssuer << ", and " | 594 std::string message = MessageHeader(error_on_missing_field_) + |
| 449 << kIssuerCARef << " exists, but at least one is required."; | 595 "None of the fields '" + kSubject + "', '" + kIssuer + "', and '" + |
| 596 kIssuerCARef + "' is present, but at least one is required."; | |
| 597 if (error_on_missing_field_) | |
| 598 LOG(ERROR) << message; | |
| 599 else | |
| 600 LOG(WARNING) << message; | |
| 450 } | 601 } |
| 451 | 602 |
| 452 return !error_on_missing_field_ || allRequiredExist; | 603 return !error_on_missing_field_ || allRequiredExist; |
| 453 } | 604 } |
| 454 | 605 |
| 455 bool Validator::ValidateProxySettings(const base::DictionaryValue& onc_object, | 606 bool Validator::ValidateProxySettings(const base::DictionaryValue& onc_object, |
| 456 base::DictionaryValue* result) { | 607 base::DictionaryValue* result) { |
| 457 using namespace onc::proxy; | 608 using namespace onc::proxy; |
| 458 if (!ValidateObjectDefault(kProxySettingsSignature, onc_object, result)) | 609 if (!ValidateObjectDefault(kProxySettingsSignature, onc_object, result)) |
| 459 return false; | 610 return false; |
| 460 | 611 |
| 461 std::string type; | |
| 462 static const char* kValidTypes[] = { kDirect, kManual, kPAC, kWPAD, NULL }; | 612 static const char* kValidTypes[] = { kDirect, kManual, kPAC, kWPAD, NULL }; |
| 463 if (result->GetStringWithoutPathExpansion(proxy::kType, &type) && | 613 if (FieldExistsAndHasNoValueOf(*result, proxy::kType, kValidTypes)) |
| 464 !RequireAnyOf(type, kValidTypes)) { | |
| 465 return false; | 614 return false; |
| 466 } | |
| 467 | 615 |
| 468 bool allRequiredExist = RequireField(*result, proxy::kType); | 616 bool allRequiredExist = RequireField(*result, proxy::kType); |
| 469 | 617 std::string type; |
| 618 result->GetStringWithoutPathExpansion(proxy::kType, &type); | |
| 470 if (type == kManual) | 619 if (type == kManual) |
| 471 allRequiredExist &= RequireField(*result, kManual); | 620 allRequiredExist &= RequireField(*result, kManual); |
| 472 else if (type == kPAC) | 621 else if (type == kPAC) |
| 473 allRequiredExist &= RequireField(*result, kPAC); | 622 allRequiredExist &= RequireField(*result, kPAC); |
| 474 | 623 |
| 475 return !error_on_missing_field_ || allRequiredExist; | 624 return !error_on_missing_field_ || allRequiredExist; |
| 476 } | 625 } |
| 477 | 626 |
| 478 bool Validator::ValidateProxyLocation(const base::DictionaryValue& onc_object, | 627 bool Validator::ValidateProxyLocation(const base::DictionaryValue& onc_object, |
| 479 base::DictionaryValue* result) { | 628 base::DictionaryValue* result) { |
| 480 using namespace onc::proxy; | 629 using namespace onc::proxy; |
| 481 if (!ValidateObjectDefault(kProxyLocationSignature, onc_object, result)) | 630 if (!ValidateObjectDefault(kProxyLocationSignature, onc_object, result)) |
| 482 return false; | 631 return false; |
| 483 | 632 |
| 484 bool allRequiredExist = RequireField(*result, kHost) & | 633 bool allRequiredExist = RequireField(*result, kHost) & |
| 485 RequireField(*result, kPort); | 634 RequireField(*result, kPort); |
| 486 | 635 |
| 487 return !error_on_missing_field_ || allRequiredExist; | 636 return !error_on_missing_field_ || allRequiredExist; |
| 488 } | 637 } |
| 489 | 638 |
| 490 bool Validator::ValidateEAP(const base::DictionaryValue& onc_object, | 639 bool Validator::ValidateEAP(const base::DictionaryValue& onc_object, |
| 491 base::DictionaryValue* result) { | 640 base::DictionaryValue* result) { |
| 492 using namespace onc::eap; | 641 using namespace onc::eap; |
| 493 using namespace onc::certificate; | 642 using namespace onc::certificate; |
| 494 if (!ValidateObjectDefault(kEAPSignature, onc_object, result)) | 643 if (!ValidateObjectDefault(kEAPSignature, onc_object, result)) |
| 495 return false; | 644 return false; |
| 496 | 645 |
| 497 std::string inner; | |
| 498 static const char* kValidInnerValues[] = | 646 static const char* kValidInnerValues[] = |
| 499 { kAutomatic, kMD5, kMSCHAPv2, kPAP, NULL }; | 647 { kAutomatic, kMD5, kMSCHAPv2, kPAP, NULL }; |
| 500 if (result->GetStringWithoutPathExpansion(kInner, &inner) && | |
| 501 !RequireAnyOf(inner, kValidInnerValues)) { | |
| 502 return false; | |
| 503 } | |
| 504 | |
| 505 std::string outer; | |
| 506 static const char* kValidOuterValues[] = | 648 static const char* kValidOuterValues[] = |
| 507 { kPEAP, kEAP_TLS, kEAP_TTLS, kLEAP, kEAP_SIM, kEAP_FAST, kEAP_AKA, | 649 { kPEAP, kEAP_TLS, kEAP_TTLS, kLEAP, kEAP_SIM, kEAP_FAST, kEAP_AKA, |
| 508 NULL }; | 650 NULL }; |
| 509 if (result->GetStringWithoutPathExpansion(kOuter, &outer) && | 651 static const char* kValidCertTypes[] = { kRef, kPattern, NULL }; |
| 510 !RequireAnyOf(outer, kValidOuterValues)) { | |
| 511 return false; | |
| 512 } | |
| 513 | 652 |
| 514 std::string cert_type; | 653 // Using strict bit-wise OR to check all conditions. |
| 515 static const char* kValidCertTypes[] = { kRef, kPattern, NULL }; | 654 if (FieldExistsAndHasNoValueOf(*result, kInner, kValidInnerValues) | |
| 516 if (result->GetStringWithoutPathExpansion(kClientCertType, &cert_type) && | 655 FieldExistsAndHasNoValueOf(*result, kOuter, kValidOuterValues) | |
| 517 !RequireAnyOf(cert_type, kValidCertTypes )) { | 656 FieldExistsAndHasNoValueOf(*result, kClientCertType, kValidCertTypes)) { |
| 518 return false; | 657 return false; |
| 519 } | 658 } |
| 520 | 659 |
| 521 bool allRequiredExist = RequireField(*result, kOuter); | 660 bool allRequiredExist = RequireField(*result, kOuter); |
| 522 | 661 std::string cert_type; |
| 662 result->GetStringWithoutPathExpansion(kClientCertType, &cert_type); | |
| 523 if (cert_type == kPattern) | 663 if (cert_type == kPattern) |
| 524 allRequiredExist &= RequireField(*result, kClientCertPattern); | 664 allRequiredExist &= RequireField(*result, kClientCertPattern); |
| 525 else if (cert_type == kRef) | 665 else if (cert_type == kRef) |
| 526 allRequiredExist &= RequireField(*result, kClientCertRef); | 666 allRequiredExist &= RequireField(*result, kClientCertRef); |
| 527 | 667 |
| 528 return !error_on_missing_field_ || allRequiredExist; | 668 return !error_on_missing_field_ || allRequiredExist; |
| 529 } | 669 } |
| 530 | 670 |
| 531 bool Validator::ValidateCertificate( | 671 bool Validator::ValidateCertificate( |
| 532 const base::DictionaryValue& onc_object, | 672 const base::DictionaryValue& onc_object, |
| 533 base::DictionaryValue* result) { | 673 base::DictionaryValue* result) { |
| 534 using namespace onc::certificate; | 674 using namespace onc::certificate; |
| 535 if (!ValidateObjectDefault(kCertificateSignature, onc_object, result)) | 675 if (!ValidateObjectDefault(kCertificateSignature, onc_object, result)) |
| 536 return false; | 676 return false; |
| 537 | 677 |
| 538 std::string type; | |
| 539 static const char* kValidTypes[] = { kClient, kServer, kAuthority, NULL }; | 678 static const char* kValidTypes[] = { kClient, kServer, kAuthority, NULL }; |
| 540 if (result->GetStringWithoutPathExpansion(certificate::kType, &type) && | 679 if (FieldExistsAndHasNoValueOf(*result, certificate::kType, kValidTypes)) |
| 541 !RequireAnyOf(type, kValidTypes)) { | |
| 542 return false; | 680 return false; |
| 543 } | |
| 544 | 681 |
| 545 bool allRequiredExist = RequireField(*result, kGUID); | 682 bool allRequiredExist = RequireField(*result, kGUID); |
| 546 | 683 |
| 547 bool remove = false; | 684 bool remove = false; |
| 548 result->GetBooleanWithoutPathExpansion(kRemove, &remove); | 685 result->GetBooleanWithoutPathExpansion(kRemove, &remove); |
| 549 if (!remove) { | 686 if (!remove) { |
| 550 allRequiredExist &= RequireField(*result, certificate::kType); | 687 allRequiredExist &= RequireField(*result, certificate::kType); |
| 551 | 688 |
| 689 std::string type; | |
| 690 result->GetStringWithoutPathExpansion(certificate::kType, &type); | |
| 552 if (type == kClient) | 691 if (type == kClient) |
| 553 allRequiredExist &= RequireField(*result, kPKCS12); | 692 allRequiredExist &= RequireField(*result, kPKCS12); |
| 554 else if (type == kServer || type == kAuthority) | 693 else if (type == kServer || type == kAuthority) |
| 555 allRequiredExist &= RequireField(*result, kX509); | 694 allRequiredExist &= RequireField(*result, kX509); |
| 556 } | 695 } |
| 557 | 696 |
| 558 return !error_on_missing_field_ || allRequiredExist; | 697 return !error_on_missing_field_ || allRequiredExist; |
| 559 } | 698 } |
| 560 | 699 |
| 700 std::string Validator::WarningHeader() { | |
| 701 return MessageHeader(false); | |
| 702 } | |
| 703 | |
| 704 std::string Validator::ErrorHeader() { | |
| 705 return MessageHeader(true); | |
| 706 } | |
| 707 | |
| 708 std::string Validator::MessageHeader(bool is_error) { | |
| 709 std::string path = path_.empty() ? "toplevel" : JoinString(path_, "."); | |
| 710 std::string message = "At " + path + ": "; | |
| 711 return message; | |
| 712 } | |
| 713 | |
| 561 } // namespace onc | 714 } // namespace onc |
| 562 } // namespace chromeos | 715 } // namespace chromeos |
| OLD | NEW |