OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/network/onc/onc_utils.h" | 5 #include "chromeos/network/onc/onc_utils.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/metrics/histogram.h" |
10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
11 #include "base/values.h" | 12 #include "base/values.h" |
12 #include "chromeos/network/network_event_log.h" | 13 #include "chromeos/network/network_event_log.h" |
13 #include "chromeos/network/onc/onc_mapper.h" | 14 #include "chromeos/network/onc/onc_mapper.h" |
14 #include "chromeos/network/onc/onc_signature.h" | 15 #include "chromeos/network/onc/onc_signature.h" |
| 16 #include "chromeos/network/onc/onc_utils.h" |
| 17 #include "chromeos/network/onc/onc_validator.h" |
15 #include "crypto/encryptor.h" | 18 #include "crypto/encryptor.h" |
16 #include "crypto/hmac.h" | 19 #include "crypto/hmac.h" |
17 #include "crypto/symmetric_key.h" | 20 #include "crypto/symmetric_key.h" |
18 | 21 |
19 #define ONC_LOG_WARNING(message) NET_LOG_WARNING("ONC", message) | 22 #define ONC_LOG_WARNING(message) NET_LOG_WARNING("ONC", message) |
20 #define ONC_LOG_ERROR(message) NET_LOG_ERROR("ONC", message) | 23 #define ONC_LOG_ERROR(message) NET_LOG_ERROR("ONC", message) |
21 | 24 |
22 namespace chromeos { | 25 namespace chromeos { |
23 namespace onc { | 26 namespace onc { |
24 | 27 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 | 207 |
205 // Recurse into nested objects. | 208 // Recurse into nested objects. |
206 for (base::DictionaryValue::Iterator it(*onc_object); !it.IsAtEnd(); | 209 for (base::DictionaryValue::Iterator it(*onc_object); !it.IsAtEnd(); |
207 it.Advance()) { | 210 it.Advance()) { |
208 base::DictionaryValue* inner_object = NULL; | 211 base::DictionaryValue* inner_object = NULL; |
209 if (!onc_object->GetDictionaryWithoutPathExpansion(it.key(), &inner_object)) | 212 if (!onc_object->GetDictionaryWithoutPathExpansion(it.key(), &inner_object)) |
210 continue; | 213 continue; |
211 | 214 |
212 const OncFieldSignature* field_signature = | 215 const OncFieldSignature* field_signature = |
213 GetFieldSignature(signature, it.key()); | 216 GetFieldSignature(signature, it.key()); |
| 217 if (!field_signature) |
| 218 continue; |
214 | 219 |
215 ExpandStringsInOncObject(*field_signature->value_signature, | 220 ExpandStringsInOncObject(*field_signature->value_signature, |
216 substitution, inner_object); | 221 substitution, inner_object); |
217 } | 222 } |
218 } | 223 } |
219 | 224 |
220 namespace { | 225 namespace { |
221 | 226 |
222 class OncMaskValues : public onc::Mapper { | 227 class OncMaskValues : public onc::Mapper { |
223 public: | 228 public: |
(...skipping 24 matching lines...) Expand all Loading... |
248 found_unknown_field, error); | 253 found_unknown_field, error); |
249 } | 254 } |
250 } | 255 } |
251 | 256 |
252 // Mask to insert in place of the sensitive values. | 257 // Mask to insert in place of the sensitive values. |
253 std::string mask_; | 258 std::string mask_; |
254 }; | 259 }; |
255 | 260 |
256 } // namespace | 261 } // namespace |
257 | 262 |
258 CHROMEOS_EXPORT scoped_ptr<base::DictionaryValue> MaskCredentialsInOncObject( | 263 scoped_ptr<base::DictionaryValue> MaskCredentialsInOncObject( |
259 const onc::OncValueSignature& signature, | 264 const onc::OncValueSignature& signature, |
260 const base::DictionaryValue& onc_object, | 265 const base::DictionaryValue& onc_object, |
261 const std::string& mask) { | 266 const std::string& mask) { |
262 return OncMaskValues::Mask(signature, onc_object, mask); | 267 return OncMaskValues::Mask(signature, onc_object, mask); |
263 } | 268 } |
264 | 269 |
| 270 bool ParseAndValidateOncForImport( |
| 271 const std::string& onc_blob, |
| 272 chromeos::onc::ONCSource onc_source, |
| 273 const std::string& passphrase, |
| 274 base::ListValue* network_configs, |
| 275 base::ListValue* certificates) { |
| 276 certificates->Clear(); |
| 277 network_configs->Clear(); |
| 278 if (onc_blob.empty()) |
| 279 return true; |
| 280 |
| 281 scoped_ptr<base::DictionaryValue> toplevel_onc = |
| 282 onc::ReadDictionaryFromJson(onc_blob); |
| 283 if (toplevel_onc.get() == NULL) { |
| 284 LOG(ERROR) << "ONC loaded from " << onc::GetSourceAsString(onc_source) |
| 285 << " is not a valid JSON dictionary."; |
| 286 return false; |
| 287 } |
| 288 |
| 289 // Check and see if this is an encrypted ONC file. If so, decrypt it. |
| 290 std::string onc_type; |
| 291 toplevel_onc->GetStringWithoutPathExpansion(onc::toplevel_config::kType, |
| 292 &onc_type); |
| 293 if (onc_type == onc::toplevel_config::kEncryptedConfiguration) { |
| 294 toplevel_onc = onc::Decrypt(passphrase, *toplevel_onc); |
| 295 if (toplevel_onc.get() == NULL) { |
| 296 LOG(ERROR) << "Couldn't decrypt the ONC from " |
| 297 << onc::GetSourceAsString(onc_source); |
| 298 return false; |
| 299 } |
| 300 } |
| 301 |
| 302 bool from_policy = (onc_source == onc::ONC_SOURCE_USER_POLICY || |
| 303 onc_source == onc::ONC_SOURCE_DEVICE_POLICY); |
| 304 |
| 305 // Validate the ONC dictionary. We are liberal and ignore unknown field |
| 306 // names and ignore invalid field names in kRecommended arrays. |
| 307 onc::Validator validator(false, // Ignore unknown fields. |
| 308 false, // Ignore invalid recommended field names. |
| 309 true, // Fail on missing fields. |
| 310 from_policy); |
| 311 validator.SetOncSource(onc_source); |
| 312 |
| 313 onc::Validator::Result validation_result; |
| 314 toplevel_onc = validator.ValidateAndRepairObject( |
| 315 &onc::kToplevelConfigurationSignature, |
| 316 *toplevel_onc, |
| 317 &validation_result); |
| 318 |
| 319 if (from_policy) { |
| 320 UMA_HISTOGRAM_BOOLEAN("Enterprise.ONC.PolicyValidation", |
| 321 validation_result == onc::Validator::VALID); |
| 322 } |
| 323 |
| 324 bool success = true; |
| 325 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) { |
| 326 LOG(WARNING) << "ONC from " << onc::GetSourceAsString(onc_source) |
| 327 << " produced warnings."; |
| 328 success = false; |
| 329 } else if (validation_result == onc::Validator::INVALID || |
| 330 toplevel_onc == NULL) { |
| 331 LOG(ERROR) << "ONC from " << onc::GetSourceAsString(onc_source) |
| 332 << " is invalid and couldn't be repaired."; |
| 333 return false; |
| 334 } |
| 335 |
| 336 base::ListValue* validated_certs = NULL; |
| 337 if (toplevel_onc->GetListWithoutPathExpansion( |
| 338 onc::toplevel_config::kCertificates, &validated_certs)) { |
| 339 certificates->Swap(validated_certs); |
| 340 } |
| 341 |
| 342 base::ListValue* validated_networks = NULL; |
| 343 if (toplevel_onc->GetListWithoutPathExpansion( |
| 344 onc::toplevel_config::kNetworkConfigurations, &validated_networks)) { |
| 345 network_configs->Swap(validated_networks); |
| 346 } |
| 347 |
| 348 return success; |
| 349 } |
| 350 |
265 } // namespace onc | 351 } // namespace onc |
266 } // namespace chromeos | 352 } // namespace chromeos |
OLD | NEW |