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

Side by Side Diff: chrome/browser/chromeos/network_settings/onc_validator.cc

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

Powered by Google App Engine
This is Rietveld 408576698