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

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

Issue 10944009: Implementation of ONC signature, validator and normalizer. (Closed) Base URL: http://git.chromium.org/chromium/src.git@gperffix
Patch Set: Addressed comments (formatting, sorting). Minor change in policy.onc. Created 8 years, 2 months 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/network_settings/onc_validator.h"
6
7 #include <string>
8
9 #include "base/logging.h"
10 #include "base/values.h"
11 #include "chrome/browser/chromeos/cros/onc_constants.h"
12 #include "chrome/browser/chromeos/network_settings/onc_signature.h"
13
14 namespace chromeos {
15 namespace onc {
16
17 Validator::Validator(
18 bool error_on_unknown_field,
19 bool error_on_wrong_recommended,
20 bool error_on_missing_field,
21 bool managed_onc)
22 : error_on_unknown_field_(error_on_unknown_field),
23 error_on_wrong_recommended_(error_on_wrong_recommended),
24 error_on_missing_field_(error_on_missing_field),
25 managed_onc_(managed_onc) {
26 }
27
28 // static
29 scoped_ptr<Validator> Validator::CreateStrictValidator(bool managed_onc) {
30 return make_scoped_ptr(new Validator(true, true, true, managed_onc));
31 }
32
33 // static
34 scoped_ptr<Validator> Validator::CreateLiberalValidator(bool managed_onc) {
35 return make_scoped_ptr(new Validator(false, false, false, managed_onc));
36 }
37
38 scoped_ptr<base::DictionaryValue> Validator::ValidateAndRepairObject(
39 const OncValueSignature* object_signature,
40 const base::DictionaryValue& onc_object) {
41 CHECK(object_signature != NULL);
42 scoped_ptr<base::Value> result_value =
43 MapValue(*object_signature, onc_object);
44 base::DictionaryValue* result_dict = NULL;
45 if (result_value.get()) {
46 result_value.release()->GetAsDictionary(&result_dict);
47 CHECK(result_dict != NULL);
48 }
49
50 return make_scoped_ptr(result_dict);
51 }
52
53 scoped_ptr<base::Value> Validator::MapValue(
54 const OncValueSignature& signature,
55 const base::Value& onc_value) {
56 if (onc_value.GetType() != signature.onc_type) {
57 LOG(WARNING) << "Wrong type. Expected " << signature.onc_type
58 << ", but found " << onc_value.GetType();
59 return scoped_ptr<base::Value>();
60 }
61
62 scoped_ptr<base::Value> repaired = Mapper::MapValue(signature, onc_value);
63 if (repaired.get())
64 CHECK_EQ(repaired->GetType(), signature.onc_type);
65 return repaired.Pass();
66 }
67
68 scoped_ptr<base::DictionaryValue> Validator::MapObject(
69 const OncValueSignature& signature,
70 const base::DictionaryValue& onc_object) {
71 scoped_ptr<base::DictionaryValue> repaired(new base::DictionaryValue);
72
73 bool valid;
74 if (&signature == &network_configuration_signature)
75 valid = ValidateNetworkConfiguration(onc_object, repaired.get());
76 else if (&signature == &vpn_signature)
77 valid = ValidateVpn(onc_object, repaired.get());
78 else if (&signature == &ipsec_signature)
79 valid = ValidateIpsec(onc_object, repaired.get());
80 else
81 valid = ValidateObjectDefault(signature, onc_object, repaired.get());
82
83 if (valid)
84 return repaired.Pass();
85 else
86 return scoped_ptr<base::DictionaryValue>();
87 }
88
89 bool Validator::ValidateObjectDefault(
90 const OncValueSignature& signature,
91 const base::DictionaryValue& onc_object,
92 base::DictionaryValue* result) {
93 bool found_unknown_fieldname = false;
94 if (!MapFields(signature, onc_object, &found_unknown_fieldname, result))
95 return false;
96
97 if (found_unknown_fieldname) {
98 if (error_on_unknown_field_) {
99 LOG(WARNING) << "Unknown field name. Aborting.";
100 return false;
101 } else {
stevenjb 2012/10/11 19:54:00 nit: else unnecessary after early exit
pneubeck (no reviews) 2012/10/15 13:57:44 Done.
102 LOG(WARNING) << "Unknown field name. Ignoring.";
103 }
104 }
105
106 return ValidateRecommendedField(signature, result);
107 }
108
109 bool Validator::ValidateRecommendedField(
110 const OncValueSignature& object_signature,
111 base::DictionaryValue* result) {
112 CHECK(result != NULL);
113
114 scoped_ptr<base::ListValue> recommended;
115 {
116 base::Value* recommended_value;
117 // This remove passes ownership to |recommended_value|.
118 if (!result->RemoveWithoutPathExpansion(onc::kRecommended,
119 &recommended_value)) {
120 return true;
121 }
122 base::ListValue* recommended_list;
123 if (!recommended_value->GetAsList(&recommended_list))
124 NOTREACHED();
125 recommended.reset(recommended_list);
126 }
127
128 if (!managed_onc_) {
129 LOG(WARNING) << "Found kRecommended field in unmanaged ONC."
130 << (error_on_wrong_recommended_ ? " Aborting." : " Ignoring.");
131 return !error_on_wrong_recommended_;
132 }
133
134 scoped_ptr<base::ListValue> repaired_recommended(new base::ListValue);
135 for (base::ListValue::iterator it = recommended->begin();
136 it != recommended->end(); ++it) {
137 std::string field_name;
138 if (!(*it)->GetAsString(&field_name))
139 NOTREACHED();
140
141 const OncFieldSignature* field_signature =
142 object_signature.GetFieldSignature(field_name);
143
144 bool found_error = false;
145 std::string error_cause = "";
stevenjb 2012/10/11 19:54:00 nit: = "" unnecessary
pneubeck (no reviews) 2012/10/15 13:57:44 Done.
146 if (!field_signature) {
147 found_error = true;
148 error_cause = "unknown";
149 } else if (field_signature->value_signature->onc_type ==
150 base::Value::TYPE_DICTIONARY) {
151 found_error = true;
152 error_cause = "dictionary-typed";
153 }
154
155 if (found_error) {
156 LOG(WARNING) << "Found " << error_cause << " field name '" << field_name
157 << "' in kRecommended array. "
158 << (error_on_wrong_recommended_ ? "Aborting." : "Ignoring.");
159 if (error_on_wrong_recommended_)
160 return false;
161 else
162 continue;
163 }
164
165 repaired_recommended->Append((*it)->DeepCopy());
166 }
167
168 result->Set(onc::kRecommended, repaired_recommended.release());
169 return true;
170 }
171
172 namespace {
173
174 template<class T>
175 bool IsAnyOf(const T &actual, const T &v1, const T &v2) {
176 if (actual == v1 || actual == v2)
177 return true;
178 LOG(WARNING) << "Found " << actual << ", but expected one of "
179 << v1 << ", " << v2;
180 return false;
181 }
stevenjb 2012/10/11 19:54:00 nit: empty line between templates / classes
pneubeck (no reviews) 2012/10/15 13:57:44 Done.
182 template<class T>
183 bool IsAnyOf(const T &actual, const T &v1, const T &v2, const T &v3) {
184 if (actual == v1 || actual == v2 || actual == v3)
185 return true;
186 LOG(WARNING) << "Found " << actual << ", but expected one of "
187 << v1 << ", " << v2 << ", " << v3;
188 return false;
189 }
190 bool RequiredField(const base::DictionaryValue& dict, std::string key) {
191 if (dict.HasKey(key))
192 return true;
193 LOG(WARNING) << "Required field " << key << " missing.";
194 return false;
195 }
196
197 } // namespace
198
199 bool Validator::ValidateNetworkConfiguration(
200 const base::DictionaryValue& onc_object,
201 base::DictionaryValue* result) {
202 if (!ValidateObjectDefault(network_configuration_signature,
203 onc_object, result)) {
204 return false;
205 }
206
207 std::string type = "";
stevenjb 2012/10/11 19:54:00 nit: = "" unnecessary
pneubeck (no reviews) 2012/10/15 13:57:44 Done.
208 if (result->GetStringWithoutPathExpansion(kType, &type) &&
209 !IsAnyOf<std::string>(type, "Ethernet", "VPN", "WiFi"))
stevenjb 2012/10/11 19:54:00 These should be consts declared somewhere
pneubeck (no reviews) 2012/10/15 13:57:44 Done.
210 return false;
211
212 bool allRequiredExist =
213 RequiredField(*result, kGUID) &&
214 RequiredField(*result, kName) &&
215 RequiredField(*result, kType) &&
216 (type != "Ethernet" || RequiredField(*result, kEthernet)) &&
217 (type != "VPN" || RequiredField(*result, kVPN)) &&
218 (type != "WiFi" || RequiredField(*result, kWiFi));
219 if (error_on_missing_field_ && !allRequiredExist)
220 return false;
221
222 return true;
223 }
224
225 bool Validator::ValidateVpn(
226 const base::DictionaryValue& onc_object,
227 base::DictionaryValue* result) {
228 return ValidateObjectDefault(vpn_signature, onc_object, result);
229 }
230
231 bool Validator::ValidateIpsec(
232 const base::DictionaryValue& onc_object,
233 base::DictionaryValue* result) {
234 return ValidateObjectDefault(ipsec_signature, onc_object, result);
235 }
236
237 } // namespace onc
238 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698