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

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 (don't reject policies by onc::Validator). 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
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::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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698