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

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

Issue 11469026: Extending ONC validator's logging. Completing toplevel validation. (Closed) Base URL: http://git.chromium.org/chromium/src.git@add_error_handling_to_validator
Patch Set: Rebased. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chromeos/network/onc/onc_validator.h ('k') | chromeos/network/onc/onc_validator_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromeos/network/onc/onc_validator.h" 5 #include "chromeos/network/onc/onc_validator.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/json/json_writer.h"
10 #include "base/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, &current_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::FieldExistsAndHasNoValidValue(
297 const base::DictionaryValue& object,
298 const std::string &field_name,
299 const char** valid_values) {
300 std::string actual_value;
301 if (!object.GetStringWithoutPathExpansion(field_name, &actual_value))
302 return false;
303
304 const char** it = valid_values;
305 for (; *it != NULL; ++it) {
306 if (actual_value == *it)
307 return false;
308 }
309 error_or_warning_found_ = true;
310 std::string valid_values_str =
311 "[" + JoinStringRange(valid_values, it, ", ") + "]";
312 path_.push_back(field_name);
313 LOG(ERROR) << ErrorHeader() << "Found value '" << actual_value <<
314 "', but expected one of the values " << valid_values_str;
315 path_.pop_back();
316 return true;
317 }
318
319 bool Validator::FieldExistsAndIsNotInRange(const base::DictionaryValue& object,
320 const std::string &field_name,
321 int lower_bound,
322 int upper_bound) {
323 int actual_value;
324 if (!object.GetIntegerWithoutPathExpansion(field_name, &actual_value) ||
325 (lower_bound <= actual_value && actual_value <= upper_bound)) {
326 return false;
327 }
328 error_or_warning_found_ = true;
329 path_.push_back(field_name);
330 LOG(ERROR) << ErrorHeader() << "Found value '" << actual_value
331 << "', but expected a value in the range [" << lower_bound
332 << ", " << upper_bound << "] (boundaries inclusive)";
333 path_.pop_back();
334 return true;
335 }
336
337 bool Validator::RequireField(const base::DictionaryValue& dict,
338 const std::string& field_name) {
339 if (dict.HasKey(field_name))
340 return true;
341 error_or_warning_found_ = true;
342 LOG(ERROR) << ErrorHeader() << "The required field '" << field_name
343 << "' is missing.";
344 return false;
345 }
346
347 bool Validator::ValidateToplevelConfiguration(
348 const base::DictionaryValue& onc_object,
349 base::DictionaryValue* result) {
350 if (!ValidateObjectDefault(kToplevelConfigurationSignature,
351 onc_object, result)) {
352 return false;
353 }
354
355 static const char* kValidTypes[] =
356 { kUnencryptedConfiguration, kEncryptedConfiguration, NULL };
357 if (FieldExistsAndHasNoValidValue(*result, kType, kValidTypes))
358 return false;
359
360 bool allRequiredExist = true;
361
362 // Not part of the ONC spec yet:
363 // We don't require the type field and default to UnencryptedConfiguration.
364 std::string type = kUnencryptedConfiguration;
365 result->GetStringWithoutPathExpansion(kType, &type);
366 if (type == kUnencryptedConfiguration &&
367 !result->HasKey(kNetworkConfigurations) &&
368 !result->HasKey(kCertificates)) {
369 error_or_warning_found_ = true;
370 std::string message = MessageHeader(error_on_missing_field_) +
371 "Neither the field '" + kNetworkConfigurations + "' nor '" +
372 kCertificates + "is present, but at least one is required.";
373 if (error_on_missing_field_)
374 LOG(ERROR) << message;
375 else
376 LOG(WARNING) << message;
377 allRequiredExist = false;
378 }
379
380 return !error_on_missing_field_ || allRequiredExist;
381 }
382
226 bool Validator::ValidateNetworkConfiguration( 383 bool Validator::ValidateNetworkConfiguration(
227 const base::DictionaryValue& onc_object, 384 const base::DictionaryValue& onc_object,
228 base::DictionaryValue* result) { 385 base::DictionaryValue* result) {
229 if (!ValidateObjectDefault(kNetworkConfigurationSignature, 386 if (!ValidateObjectDefault(kNetworkConfigurationSignature,
230 onc_object, result)) { 387 onc_object, result)) {
231 return false; 388 return false;
232 } 389 }
233 390
234 std::string type;
235 static const char* kValidTypes[] = { kEthernet, kVPN, kWiFi, NULL }; 391 static const char* kValidTypes[] = { kEthernet, kVPN, kWiFi, NULL };
236 if (result->GetStringWithoutPathExpansion(kType, &type) && 392 if (FieldExistsAndHasNoValidValue(*result, kType, kValidTypes))
237 !RequireAnyOf(type, kValidTypes)) {
238 return false; 393 return false;
239 }
240 394
241 bool allRequiredExist = RequireField(*result, kGUID); 395 bool allRequiredExist = RequireField(*result, kGUID);
242 396
243 bool remove = false; 397 bool remove = false;
244 result->GetBooleanWithoutPathExpansion(kRemove, &remove); 398 result->GetBooleanWithoutPathExpansion(kRemove, &remove);
245 if (!remove) { 399 if (!remove) {
246 allRequiredExist &= RequireField(*result, kName); 400 allRequiredExist &= RequireField(*result, kName);
247 allRequiredExist &= RequireField(*result, kType); 401 allRequiredExist &= RequireField(*result, kType);
402
403 std::string type;
404 result->GetStringWithoutPathExpansion(kType, &type);
248 allRequiredExist &= type.empty() || RequireField(*result, type); 405 allRequiredExist &= type.empty() || RequireField(*result, type);
249 } 406 }
250 407
251 return !error_on_missing_field_ || allRequiredExist; 408 return !error_on_missing_field_ || allRequiredExist;
252 } 409 }
253 410
254 bool Validator::ValidateEthernet( 411 bool Validator::ValidateEthernet(
255 const base::DictionaryValue& onc_object, 412 const base::DictionaryValue& onc_object,
256 base::DictionaryValue* result) { 413 base::DictionaryValue* result) {
257 using namespace onc::ethernet; 414 using namespace onc::ethernet;
258 if (!ValidateObjectDefault(kEthernetSignature, onc_object, result)) 415 if (!ValidateObjectDefault(kEthernetSignature, onc_object, result))
259 return false; 416 return false;
260 417
261 std::string auth;
262 static const char* kValidAuthentications[] = { kNone, k8021X, NULL }; 418 static const char* kValidAuthentications[] = { kNone, k8021X, NULL };
263 if (result->GetStringWithoutPathExpansion(kAuthentication, &auth) && 419 if (FieldExistsAndHasNoValidValue(*result, kAuthentication,
264 !RequireAnyOf(auth, kValidAuthentications)) { 420 kValidAuthentications)) {
265 return false; 421 return false;
266 } 422 }
267 423
268 bool allRequiredExist = true; 424 bool allRequiredExist = true;
425 std::string auth;
426 result->GetStringWithoutPathExpansion(kAuthentication, &auth);
269 if (auth == k8021X) 427 if (auth == k8021X)
270 allRequiredExist &= RequireField(*result, kEAP); 428 allRequiredExist &= RequireField(*result, kEAP);
271 429
272 return !error_on_missing_field_ || allRequiredExist; 430 return !error_on_missing_field_ || allRequiredExist;
273 } 431 }
274 432
275 bool Validator::ValidateIPConfig( 433 bool Validator::ValidateIPConfig(
276 const base::DictionaryValue& onc_object, 434 const base::DictionaryValue& onc_object,
277 base::DictionaryValue* result) { 435 base::DictionaryValue* result) {
278 using namespace onc::ipconfig; 436 using namespace onc::ipconfig;
279 if (!ValidateObjectDefault(kIPConfigSignature, onc_object, result)) 437 if (!ValidateObjectDefault(kIPConfigSignature, onc_object, result))
280 return false; 438 return false;
281 439
440 static const char* kValidTypes[] = { kIPv4, kIPv6, NULL };
441 if (FieldExistsAndHasNoValidValue(*result, ipconfig::kType, kValidTypes))
442 return false;
443
282 std::string type; 444 std::string type;
283 static const char* kValidTypes[] = { kIPv4, kIPv6, NULL }; 445 result->GetStringWithoutPathExpansion(ipconfig::kType, &type);
284 if (result->GetStringWithoutPathExpansion(ipconfig::kType, &type) && 446 int lower_bound = 1;
285 !RequireAnyOf(type, kValidTypes)) { 447 // In case of missing type, choose higher upper_bound.
448 int upper_bound = (type == kIPv4) ? 32 : 128;
449 if (FieldExistsAndIsNotInRange(*result, kRoutingPrefix,
450 lower_bound, upper_bound)) {
286 return false; 451 return false;
287 } 452 }
288 453
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) & 454 bool allRequiredExist = RequireField(*result, kIPAddress) &
299 RequireField(*result, kRoutingPrefix) & 455 RequireField(*result, kRoutingPrefix) &
300 RequireField(*result, ipconfig::kType); 456 RequireField(*result, ipconfig::kType);
301 457
302 return !error_on_missing_field_ || allRequiredExist; 458 return !error_on_missing_field_ || allRequiredExist;
303 } 459 }
304 460
305 bool Validator::ValidateWiFi( 461 bool Validator::ValidateWiFi(
306 const base::DictionaryValue& onc_object, 462 const base::DictionaryValue& onc_object,
307 base::DictionaryValue* result) { 463 base::DictionaryValue* result) {
308 using namespace onc::wifi; 464 using namespace onc::wifi;
309 if (!ValidateObjectDefault(kWiFiSignature, onc_object, result)) 465 if (!ValidateObjectDefault(kWiFiSignature, onc_object, result))
310 return false; 466 return false;
311 467
312 std::string security;
313 static const char* kValidSecurities[] = 468 static const char* kValidSecurities[] =
314 { kNone, kWEP_PSK, kWEP_8021X, kWPA_PSK, kWPA_EAP, NULL }; 469 { kNone, kWEP_PSK, kWEP_8021X, kWPA_PSK, kWPA_EAP, NULL };
315 if (result->GetStringWithoutPathExpansion(kSecurity, &security) && 470 if (FieldExistsAndHasNoValidValue(*result, kSecurity, kValidSecurities))
316 !RequireAnyOf(security, kValidSecurities)) {
317 return false; 471 return false;
318 }
319 472
320 bool allRequiredExist = RequireField(*result, kSecurity) & 473 bool allRequiredExist = RequireField(*result, kSecurity) &
321 RequireField(*result, kSSID); 474 RequireField(*result, kSSID);
475
476 std::string security;
477 result->GetStringWithoutPathExpansion(kSecurity, &security);
322 if (security == kWEP_8021X || security == kWPA_EAP) 478 if (security == kWEP_8021X || security == kWPA_EAP)
323 allRequiredExist &= RequireField(*result, kEAP); 479 allRequiredExist &= RequireField(*result, kEAP);
324 else if (security == kWEP_PSK || security == kWPA_PSK) 480 else if (security == kWEP_PSK || security == kWPA_PSK)
325 allRequiredExist &= RequireField(*result, kPassphrase); 481 allRequiredExist &= RequireField(*result, kPassphrase);
326 482
327 return !error_on_missing_field_ || allRequiredExist; 483 return !error_on_missing_field_ || allRequiredExist;
328 } 484 }
329 485
330 bool Validator::ValidateVPN( 486 bool Validator::ValidateVPN(
331 const base::DictionaryValue& onc_object, 487 const base::DictionaryValue& onc_object,
332 base::DictionaryValue* result) { 488 base::DictionaryValue* result) {
333 using namespace vpn; 489 using namespace vpn;
334 if (!ValidateObjectDefault(kVPNSignature, onc_object, result)) 490 if (!ValidateObjectDefault(kVPNSignature, onc_object, result))
335 return false; 491 return false;
336 492
337 std::string type;
338 static const char* kValidTypes[] = 493 static const char* kValidTypes[] =
339 { kIPsec, kTypeL2TP_IPsec, kOpenVPN, NULL }; 494 { kIPsec, kTypeL2TP_IPsec, kOpenVPN, NULL };
340 if (result->GetStringWithoutPathExpansion(vpn::kType, &type) && 495 if (FieldExistsAndHasNoValidValue(*result, vpn::kType, kValidTypes))
341 !RequireAnyOf(type, kValidTypes)) {
342 return false; 496 return false;
343 }
344 497
345 bool allRequiredExist = RequireField(*result, vpn::kType); 498 bool allRequiredExist = RequireField(*result, vpn::kType);
346 499 std::string type;
500 result->GetStringWithoutPathExpansion(vpn::kType, &type);
347 if (type == kOpenVPN) { 501 if (type == kOpenVPN) {
348 allRequiredExist &= RequireField(*result, kOpenVPN); 502 allRequiredExist &= RequireField(*result, kOpenVPN);
349 } else if (type == kIPsec) { 503 } else if (type == kIPsec) {
350 allRequiredExist &= RequireField(*result, kIPsec); 504 allRequiredExist &= RequireField(*result, kIPsec);
351 } else if (type == kTypeL2TP_IPsec) { 505 } else if (type == kTypeL2TP_IPsec) {
352 allRequiredExist &= RequireField(*result, kIPsec) & 506 allRequiredExist &= RequireField(*result, kIPsec) &
353 RequireField(*result, kL2TP); 507 RequireField(*result, kL2TP);
354 } 508 }
355 509
356 return !error_on_missing_field_ || allRequiredExist; 510 return !error_on_missing_field_ || allRequiredExist;
357 } 511 }
358 512
359 bool Validator::ValidateIPsec( 513 bool Validator::ValidateIPsec(
360 const base::DictionaryValue& onc_object, 514 const base::DictionaryValue& onc_object,
361 base::DictionaryValue* result) { 515 base::DictionaryValue* result) {
362 using namespace onc::vpn; 516 using namespace onc::vpn;
363 using namespace onc::certificate; 517 using namespace onc::certificate;
364 if (!ValidateObjectDefault(kIPsecSignature, onc_object, result)) 518 if (!ValidateObjectDefault(kIPsecSignature, onc_object, result))
365 return false; 519 return false;
366 520
367 std::string auth;
368 static const char* kValidAuthentications[] = { kPSK, kCert, NULL }; 521 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 }; 522 static const char* kValidCertTypes[] = { kRef, kPattern, NULL };
376 if (result->GetStringWithoutPathExpansion(kClientCertType, &cert_type) && 523 // Using strict bit-wise OR to check all conditions.
377 !RequireAnyOf(cert_type, kValidCertTypes)) { 524 if (FieldExistsAndHasNoValidValue(*result, kAuthenticationType,
525 kValidAuthentications) |
526 FieldExistsAndHasNoValidValue(*result, kClientCertType,
527 kValidCertTypes)) {
378 return false; 528 return false;
379 } 529 }
380 530
381 bool allRequiredExist = RequireField(*result, kAuthenticationType) & 531 bool allRequiredExist = RequireField(*result, kAuthenticationType) &
382 RequireField(*result, kIKEVersion); 532 RequireField(*result, kIKEVersion);
533 std::string auth;
534 result->GetStringWithoutPathExpansion(kAuthenticationType, &auth);
383 if (auth == kCert) { 535 if (auth == kCert) {
384 allRequiredExist &= RequireField(*result, kClientCertType) & 536 allRequiredExist &= RequireField(*result, kClientCertType) &
385 RequireField(*result, kServerCARef); 537 RequireField(*result, kServerCARef);
386 } 538 }
539 std::string cert_type;
540 result->GetStringWithoutPathExpansion(kClientCertType, &cert_type);
387 if (cert_type == kPattern) 541 if (cert_type == kPattern)
388 allRequiredExist &= RequireField(*result, kClientCertPattern); 542 allRequiredExist &= RequireField(*result, kClientCertPattern);
389 else if (cert_type == kRef) 543 else if (cert_type == kRef)
390 allRequiredExist &= RequireField(*result, kClientCertRef); 544 allRequiredExist &= RequireField(*result, kClientCertRef);
391 545
392 return !error_on_missing_field_ || allRequiredExist; 546 return !error_on_missing_field_ || allRequiredExist;
393 } 547 }
394 548
395 bool Validator::ValidateOpenVPN( 549 bool Validator::ValidateOpenVPN(
396 const base::DictionaryValue& onc_object, 550 const base::DictionaryValue& onc_object,
397 base::DictionaryValue* result) { 551 base::DictionaryValue* result) {
398 using namespace onc::vpn; 552 using namespace onc::vpn;
399 using namespace onc::openvpn; 553 using namespace onc::openvpn;
400 using namespace onc::certificate; 554 using namespace onc::certificate;
401 if (!ValidateObjectDefault(kOpenVPNSignature, onc_object, result)) 555 if (!ValidateObjectDefault(kOpenVPNSignature, onc_object, result))
402 return false; 556 return false;
403 557
404 std::string auth_retry;
405 static const char* kValidAuthRetryValues[] = 558 static const char* kValidAuthRetryValues[] =
406 { openvpn::kNone, kInteract, kNoInteract, NULL }; 559 { 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[] = 560 static const char* kValidCertTypes[] =
414 { certificate::kNone, kRef, kPattern, NULL }; 561 { 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[] = 562 static const char* kValidCertTlsValues[] =
422 { openvpn::kNone, openvpn::kServer, NULL }; 563 { openvpn::kNone, openvpn::kServer, NULL };
423 if (result->GetStringWithoutPathExpansion(kRemoteCertTLS, &cert_tls) && 564
424 !RequireAnyOf(cert_tls, kValidCertTlsValues)) { 565 // Using strict bit-wise OR to check all conditions.
566 if (FieldExistsAndHasNoValidValue(*result, kAuthRetry,
567 kValidAuthRetryValues) |
568 FieldExistsAndHasNoValidValue(*result, kClientCertType, kValidCertTypes) |
569 FieldExistsAndHasNoValidValue(*result, kRemoteCertTLS,
570 kValidCertTlsValues)) {
425 return false; 571 return false;
426 } 572 }
427 573
428 bool allRequiredExist = RequireField(*result, kClientCertType); 574 bool allRequiredExist = RequireField(*result, kClientCertType);
575 std::string cert_type;
576 result->GetStringWithoutPathExpansion(kClientCertType, &cert_type);
429 if (cert_type == kPattern) 577 if (cert_type == kPattern)
430 allRequiredExist &= RequireField(*result, kClientCertPattern); 578 allRequiredExist &= RequireField(*result, kClientCertPattern);
431 else if (cert_type == kRef) 579 else if (cert_type == kRef)
432 allRequiredExist &= RequireField(*result, kClientCertRef); 580 allRequiredExist &= RequireField(*result, kClientCertRef);
433 581
434 return !error_on_missing_field_ || allRequiredExist; 582 return !error_on_missing_field_ || allRequiredExist;
435 } 583 }
436 584
437 bool Validator::ValidateCertificatePattern( 585 bool Validator::ValidateCertificatePattern(
438 const base::DictionaryValue& onc_object, 586 const base::DictionaryValue& onc_object,
439 base::DictionaryValue* result) { 587 base::DictionaryValue* result) {
440 using namespace onc::certificate; 588 using namespace onc::certificate;
441 if (!ValidateObjectDefault(kCertificatePatternSignature, onc_object, result)) 589 if (!ValidateObjectDefault(kCertificatePatternSignature, onc_object, result))
442 return false; 590 return false;
443 591
444 bool allRequiredExist = true; 592 bool allRequiredExist = true;
445 if (!result->HasKey(kSubject) && !result->HasKey(kIssuer) && 593 if (!result->HasKey(kSubject) && !result->HasKey(kIssuer) &&
446 !result->HasKey(kIssuerCARef)) { 594 !result->HasKey(kIssuerCARef)) {
595 error_or_warning_found_ = true;
447 allRequiredExist = false; 596 allRequiredExist = false;
448 DVLOG(1) << "None of the fields " << kSubject << ", " << kIssuer << ", and " 597 std::string message = MessageHeader(error_on_missing_field_) +
449 << kIssuerCARef << " exists, but at least one is required."; 598 "None of the fields '" + kSubject + "', '" + kIssuer + "', and '" +
599 kIssuerCARef + "' is present, but at least one is required.";
600 if (error_on_missing_field_)
601 LOG(ERROR) << message;
602 else
603 LOG(WARNING) << message;
450 } 604 }
451 605
452 return !error_on_missing_field_ || allRequiredExist; 606 return !error_on_missing_field_ || allRequiredExist;
453 } 607 }
454 608
455 bool Validator::ValidateProxySettings(const base::DictionaryValue& onc_object, 609 bool Validator::ValidateProxySettings(const base::DictionaryValue& onc_object,
456 base::DictionaryValue* result) { 610 base::DictionaryValue* result) {
457 using namespace onc::proxy; 611 using namespace onc::proxy;
458 if (!ValidateObjectDefault(kProxySettingsSignature, onc_object, result)) 612 if (!ValidateObjectDefault(kProxySettingsSignature, onc_object, result))
459 return false; 613 return false;
460 614
461 std::string type;
462 static const char* kValidTypes[] = { kDirect, kManual, kPAC, kWPAD, NULL }; 615 static const char* kValidTypes[] = { kDirect, kManual, kPAC, kWPAD, NULL };
463 if (result->GetStringWithoutPathExpansion(proxy::kType, &type) && 616 if (FieldExistsAndHasNoValidValue(*result, proxy::kType, kValidTypes))
464 !RequireAnyOf(type, kValidTypes)) {
465 return false; 617 return false;
466 }
467 618
468 bool allRequiredExist = RequireField(*result, proxy::kType); 619 bool allRequiredExist = RequireField(*result, proxy::kType);
469 620 std::string type;
621 result->GetStringWithoutPathExpansion(proxy::kType, &type);
470 if (type == kManual) 622 if (type == kManual)
471 allRequiredExist &= RequireField(*result, kManual); 623 allRequiredExist &= RequireField(*result, kManual);
472 else if (type == kPAC) 624 else if (type == kPAC)
473 allRequiredExist &= RequireField(*result, kPAC); 625 allRequiredExist &= RequireField(*result, kPAC);
474 626
475 return !error_on_missing_field_ || allRequiredExist; 627 return !error_on_missing_field_ || allRequiredExist;
476 } 628 }
477 629
478 bool Validator::ValidateProxyLocation(const base::DictionaryValue& onc_object, 630 bool Validator::ValidateProxyLocation(const base::DictionaryValue& onc_object,
479 base::DictionaryValue* result) { 631 base::DictionaryValue* result) {
480 using namespace onc::proxy; 632 using namespace onc::proxy;
481 if (!ValidateObjectDefault(kProxyLocationSignature, onc_object, result)) 633 if (!ValidateObjectDefault(kProxyLocationSignature, onc_object, result))
482 return false; 634 return false;
483 635
484 bool allRequiredExist = RequireField(*result, kHost) & 636 bool allRequiredExist = RequireField(*result, kHost) &
485 RequireField(*result, kPort); 637 RequireField(*result, kPort);
486 638
487 return !error_on_missing_field_ || allRequiredExist; 639 return !error_on_missing_field_ || allRequiredExist;
488 } 640 }
489 641
490 bool Validator::ValidateEAP(const base::DictionaryValue& onc_object, 642 bool Validator::ValidateEAP(const base::DictionaryValue& onc_object,
491 base::DictionaryValue* result) { 643 base::DictionaryValue* result) {
492 using namespace onc::eap; 644 using namespace onc::eap;
493 using namespace onc::certificate; 645 using namespace onc::certificate;
494 if (!ValidateObjectDefault(kEAPSignature, onc_object, result)) 646 if (!ValidateObjectDefault(kEAPSignature, onc_object, result))
495 return false; 647 return false;
496 648
497 std::string inner;
498 static const char* kValidInnerValues[] = 649 static const char* kValidInnerValues[] =
499 { kAutomatic, kMD5, kMSCHAPv2, kPAP, NULL }; 650 { 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[] = 651 static const char* kValidOuterValues[] =
507 { kPEAP, kEAP_TLS, kEAP_TTLS, kLEAP, kEAP_SIM, kEAP_FAST, kEAP_AKA, 652 { kPEAP, kEAP_TLS, kEAP_TTLS, kLEAP, kEAP_SIM, kEAP_FAST, kEAP_AKA,
508 NULL }; 653 NULL };
509 if (result->GetStringWithoutPathExpansion(kOuter, &outer) && 654 static const char* kValidCertTypes[] = { kRef, kPattern, NULL };
510 !RequireAnyOf(outer, kValidOuterValues)) {
511 return false;
512 }
513 655
514 std::string cert_type; 656 // Using strict bit-wise OR to check all conditions.
515 static const char* kValidCertTypes[] = { kRef, kPattern, NULL }; 657 if (FieldExistsAndHasNoValidValue(*result, kInner, kValidInnerValues) |
516 if (result->GetStringWithoutPathExpansion(kClientCertType, &cert_type) && 658 FieldExistsAndHasNoValidValue(*result, kOuter, kValidOuterValues) |
517 !RequireAnyOf(cert_type, kValidCertTypes )) { 659 FieldExistsAndHasNoValidValue(*result, kClientCertType,
660 kValidCertTypes)) {
518 return false; 661 return false;
519 } 662 }
520 663
521 bool allRequiredExist = RequireField(*result, kOuter); 664 bool allRequiredExist = RequireField(*result, kOuter);
522 665 std::string cert_type;
666 result->GetStringWithoutPathExpansion(kClientCertType, &cert_type);
523 if (cert_type == kPattern) 667 if (cert_type == kPattern)
524 allRequiredExist &= RequireField(*result, kClientCertPattern); 668 allRequiredExist &= RequireField(*result, kClientCertPattern);
525 else if (cert_type == kRef) 669 else if (cert_type == kRef)
526 allRequiredExist &= RequireField(*result, kClientCertRef); 670 allRequiredExist &= RequireField(*result, kClientCertRef);
527 671
528 return !error_on_missing_field_ || allRequiredExist; 672 return !error_on_missing_field_ || allRequiredExist;
529 } 673 }
530 674
531 bool Validator::ValidateCertificate( 675 bool Validator::ValidateCertificate(
532 const base::DictionaryValue& onc_object, 676 const base::DictionaryValue& onc_object,
533 base::DictionaryValue* result) { 677 base::DictionaryValue* result) {
534 using namespace onc::certificate; 678 using namespace onc::certificate;
535 if (!ValidateObjectDefault(kCertificateSignature, onc_object, result)) 679 if (!ValidateObjectDefault(kCertificateSignature, onc_object, result))
536 return false; 680 return false;
537 681
538 std::string type;
539 static const char* kValidTypes[] = { kClient, kServer, kAuthority, NULL }; 682 static const char* kValidTypes[] = { kClient, kServer, kAuthority, NULL };
540 if (result->GetStringWithoutPathExpansion(certificate::kType, &type) && 683 if (FieldExistsAndHasNoValidValue(*result, certificate::kType, kValidTypes))
541 !RequireAnyOf(type, kValidTypes)) {
542 return false; 684 return false;
543 }
544 685
545 bool allRequiredExist = RequireField(*result, kGUID); 686 bool allRequiredExist = RequireField(*result, kGUID);
546 687
547 bool remove = false; 688 bool remove = false;
548 result->GetBooleanWithoutPathExpansion(kRemove, &remove); 689 result->GetBooleanWithoutPathExpansion(kRemove, &remove);
549 if (!remove) { 690 if (!remove) {
550 allRequiredExist &= RequireField(*result, certificate::kType); 691 allRequiredExist &= RequireField(*result, certificate::kType);
551 692
693 std::string type;
694 result->GetStringWithoutPathExpansion(certificate::kType, &type);
552 if (type == kClient) 695 if (type == kClient)
553 allRequiredExist &= RequireField(*result, kPKCS12); 696 allRequiredExist &= RequireField(*result, kPKCS12);
554 else if (type == kServer || type == kAuthority) 697 else if (type == kServer || type == kAuthority)
555 allRequiredExist &= RequireField(*result, kX509); 698 allRequiredExist &= RequireField(*result, kX509);
556 } 699 }
557 700
558 return !error_on_missing_field_ || allRequiredExist; 701 return !error_on_missing_field_ || allRequiredExist;
559 } 702 }
560 703
704 std::string Validator::WarningHeader() {
705 return MessageHeader(false);
706 }
707
708 std::string Validator::ErrorHeader() {
709 return MessageHeader(true);
710 }
711
712 std::string Validator::MessageHeader(bool is_error) {
713 std::string path = path_.empty() ? "toplevel" : JoinString(path_, ".");
714 std::string message = "At " + path + ": ";
715 return message;
716 }
717
561 } // namespace onc 718 } // namespace onc
562 } // namespace chromeos 719 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/network/onc/onc_validator.h ('k') | chromeos/network/onc/onc_validator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698