OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/cros/onc_network_parser.h" | 5 #include "chrome/browser/chromeos/cros/onc_network_parser.h" |
6 | 6 |
| 7 #include <keyhi.h> |
7 #include <pk11pub.h> | 8 #include <pk11pub.h> |
8 #include <keyhi.h> | |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
11 #include "base/json/json_value_serializer.h" | 11 #include "base/json/json_value_serializer.h" |
12 #include "base/json/json_writer.h" // for debug output only. | 12 #include "base/json/json_writer.h" // for debug output only. |
13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "chrome/browser/chromeos/cros/native_network_constants.h" | 15 #include "chrome/browser/chromeos/cros/native_network_constants.h" |
16 #include "chrome/browser/chromeos/cros/native_network_parser.h" | 16 #include "chrome/browser/chromeos/cros/native_network_parser.h" |
17 #include "chrome/browser/chromeos/cros/network_library.h" | 17 #include "chrome/browser/chromeos/cros/network_library.h" |
18 #include "chrome/common/net/x509_certificate_model.h" | 18 #include "chrome/common/net/x509_certificate_model.h" |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 std::string ConvertValueToString(const base::Value& value) { | 179 std::string ConvertValueToString(const base::Value& value) { |
180 std::string value_json; | 180 std::string value_json; |
181 base::JSONWriter::Write(&value, false, &value_json); | 181 base::JSONWriter::Write(&value, false, &value_json); |
182 return value_json; | 182 return value_json; |
183 } | 183 } |
184 | 184 |
185 } // namespace | 185 } // namespace |
186 | 186 |
187 // -------------------- OncNetworkParser -------------------- | 187 // -------------------- OncNetworkParser -------------------- |
188 | 188 |
189 OncNetworkParser::OncNetworkParser(const std::string& onc_blob) | 189 OncNetworkParser::OncNetworkParser(const std::string& onc_blob, |
| 190 NetworkUIData::ONCSource onc_source) |
190 : NetworkParser(get_onc_mapper()), | 191 : NetworkParser(get_onc_mapper()), |
| 192 onc_source_(onc_source), |
191 network_configs_(NULL), | 193 network_configs_(NULL), |
192 certificates_(NULL) { | 194 certificates_(NULL) { |
193 VLOG(2) << __func__ << ": OncNetworkParser called on " << onc_blob; | 195 VLOG(2) << __func__ << ": OncNetworkParser called on " << onc_blob; |
194 JSONStringValueSerializer deserializer(onc_blob); | 196 JSONStringValueSerializer deserializer(onc_blob); |
195 deserializer.set_allow_trailing_comma(true); | 197 deserializer.set_allow_trailing_comma(true); |
196 scoped_ptr<base::Value> root(deserializer.Deserialize(NULL, &parse_error_)); | 198 scoped_ptr<base::Value> root(deserializer.Deserialize(NULL, &parse_error_)); |
197 | 199 |
198 if (!root.get() || root->GetType() != base::Value::TYPE_DICTIONARY) { | 200 if (!root.get() || root->GetType() != base::Value::TYPE_DICTIONARY) { |
199 LOG(WARNING) << "OncNetworkParser received bad ONC file: " << parse_error_; | 201 LOG(WARNING) << "OncNetworkParser received bad ONC file: " << parse_error_; |
200 } else { | 202 } else { |
(...skipping 21 matching lines...) Expand all Loading... |
222 | 224 |
223 // static | 225 // static |
224 const EnumMapper<PropertyIndex>* OncNetworkParser::property_mapper() { | 226 const EnumMapper<PropertyIndex>* OncNetworkParser::property_mapper() { |
225 return get_onc_mapper(); | 227 return get_onc_mapper(); |
226 } | 228 } |
227 | 229 |
228 int OncNetworkParser::GetNetworkConfigsSize() const { | 230 int OncNetworkParser::GetNetworkConfigsSize() const { |
229 return network_configs_ ? network_configs_->GetSize() : 0; | 231 return network_configs_ ? network_configs_->GetSize() : 0; |
230 } | 232 } |
231 | 233 |
| 234 Network* OncNetworkParser::ParseNetwork(int n) { |
| 235 CHECK(network_configs_); |
| 236 CHECK(static_cast<size_t>(n) < network_configs_->GetSize()); |
| 237 CHECK_GE(n, 0); |
| 238 DictionaryValue* info = NULL; |
| 239 if (!network_configs_->GetDictionary(n, &info)) { |
| 240 parse_error_ = l10n_util::GetStringUTF8( |
| 241 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); |
| 242 return NULL; |
| 243 } |
| 244 |
| 245 if (VLOG_IS_ON(2)) { |
| 246 std::string network_json; |
| 247 base::JSONWriter::Write(static_cast<base::Value*>(info), |
| 248 true, &network_json); |
| 249 VLOG(2) << "Parsing network at index " << n |
| 250 << ": " << network_json; |
| 251 } |
| 252 |
| 253 return CreateNetworkFromInfo(std::string(), *info); |
| 254 } |
| 255 |
232 int OncNetworkParser::GetCertificatesSize() const { | 256 int OncNetworkParser::GetCertificatesSize() const { |
233 return certificates_ ? certificates_->GetSize() : 0; | 257 return certificates_ ? certificates_->GetSize() : 0; |
234 } | 258 } |
235 | 259 |
236 scoped_refptr<net::X509Certificate> OncNetworkParser::ParseCertificate( | 260 scoped_refptr<net::X509Certificate> OncNetworkParser::ParseCertificate( |
237 int cert_index) { | 261 int cert_index) { |
238 CHECK(certificates_); | 262 CHECK(certificates_); |
239 CHECK(static_cast<size_t>(cert_index) < certificates_->GetSize()); | 263 CHECK(static_cast<size_t>(cert_index) < certificates_->GetSize()); |
240 CHECK_GE(cert_index, 0); | 264 CHECK_GE(cert_index, 0); |
241 base::DictionaryValue* certificate = NULL; | 265 base::DictionaryValue* certificate = NULL; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 return ParseClientCertificate(cert_index, guid, certificate); | 310 return ParseClientCertificate(cert_index, guid, certificate); |
287 } | 311 } |
288 | 312 |
289 LOG(WARNING) << "ONC File: certificate of unknown type: " << cert_type | 313 LOG(WARNING) << "ONC File: certificate of unknown type: " << cert_type |
290 << " at index " << cert_index; | 314 << " at index " << cert_index; |
291 parse_error_ = l10n_util::GetStringUTF8( | 315 parse_error_ = l10n_util::GetStringUTF8( |
292 IDS_NETWORK_CONFIG_ERROR_CERT_TYPE_MISSING); | 316 IDS_NETWORK_CONFIG_ERROR_CERT_TYPE_MISSING); |
293 return NULL; | 317 return NULL; |
294 } | 318 } |
295 | 319 |
296 Network* OncNetworkParser::ParseNetwork(int n) { | |
297 CHECK(network_configs_); | |
298 CHECK(static_cast<size_t>(n) < network_configs_->GetSize()); | |
299 CHECK_GE(n, 0); | |
300 DictionaryValue* info = NULL; | |
301 if (!network_configs_->GetDictionary(n, &info)) { | |
302 parse_error_ = l10n_util::GetStringUTF8( | |
303 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); | |
304 return NULL; | |
305 } | |
306 | |
307 if (VLOG_IS_ON(2)) { | |
308 std::string network_json; | |
309 base::JSONWriter::Write(static_cast<base::Value*>(info), | |
310 true, &network_json); | |
311 VLOG(2) << "Parsing network at index " << n | |
312 << ": " << network_json; | |
313 } | |
314 | |
315 return CreateNetworkFromInfo(std::string(), *info); | |
316 } | |
317 | |
318 Network* OncNetworkParser::CreateNetworkFromInfo( | 320 Network* OncNetworkParser::CreateNetworkFromInfo( |
319 const std::string& service_path, | 321 const std::string& service_path, |
320 const DictionaryValue& info) { | 322 const DictionaryValue& info) { |
321 ConnectionType type = ParseTypeFromDictionary(info); | 323 ConnectionType type = ParseTypeFromDictionary(info); |
322 if (type == TYPE_UNKNOWN) { // Return NULL if cannot parse network type. | 324 if (type == TYPE_UNKNOWN) { // Return NULL if cannot parse network type. |
323 parse_error_ = l10n_util::GetStringUTF8( | 325 parse_error_ = l10n_util::GetStringUTF8( |
324 IDS_NETWORK_CONFIG_ERROR_NETWORK_TYPE_MISSING); | 326 IDS_NETWORK_CONFIG_ERROR_NETWORK_TYPE_MISSING); |
325 return NULL; | 327 return NULL; |
326 } | 328 } |
327 scoped_ptr<Network> network(CreateNewNetwork(type, service_path)); | 329 scoped_ptr<Network> network(CreateNewNetwork(type, service_path)); |
| 330 |
| 331 // Initialize UI data. |
| 332 NetworkUIData ui_data; |
| 333 ui_data.set_onc_source(onc_source_); |
| 334 ui_data.FillDictionary(network->ui_data()); |
| 335 |
| 336 // Parse all properties recursively. |
328 if (!ParseNestedObject(network.get(), | 337 if (!ParseNestedObject(network.get(), |
329 "NetworkConfiguration", | 338 "NetworkConfiguration", |
330 static_cast<const base::Value&>(info), | 339 static_cast<const base::Value&>(info), |
331 network_configuration_signature, | 340 network_configuration_signature, |
332 ParseNetworkConfigurationValue)) { | 341 ParseNetworkConfigurationValue)) { |
333 LOG(WARNING) << "Network " << network->name() << " failed to parse."; | 342 LOG(WARNING) << "Network " << network->name() << " failed to parse."; |
334 if (parse_error_.empty()) | 343 if (parse_error_.empty()) |
335 parse_error_ = l10n_util::GetStringUTF8( | 344 parse_error_ = l10n_util::GetStringUTF8( |
336 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); | 345 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); |
337 return NULL; | 346 return NULL; |
338 } | 347 } |
| 348 |
| 349 // Update the UI data property. |
| 350 std::string ui_data_json; |
| 351 base::JSONWriter::Write(network->ui_data(), false, &ui_data_json); |
| 352 base::StringValue ui_data_string_value(ui_data_json); |
| 353 network->UpdatePropertyMap(PROPERTY_INDEX_UI_DATA, ui_data_string_value); |
| 354 |
339 if (VLOG_IS_ON(2)) { | 355 if (VLOG_IS_ON(2)) { |
340 VLOG(2) << "Created Network '" << network->name() | 356 VLOG(2) << "Created Network '" << network->name() |
341 << "' from info. Path:" << service_path | 357 << "' from info. Path:" << service_path |
342 << " Type:" << ConnectionTypeToString(type); | 358 << " Type:" << ConnectionTypeToString(type); |
343 } | 359 } |
| 360 |
344 return network.release(); | 361 return network.release(); |
345 } | 362 } |
346 | 363 |
| 364 bool OncNetworkParser::ParseNestedObject(Network* network, |
| 365 const std::string& onc_type, |
| 366 const base::Value& value, |
| 367 OncValueSignature* signature, |
| 368 ParserPointer parser) { |
| 369 bool any_errors = false; |
| 370 if (!value.IsType(base::Value::TYPE_DICTIONARY)) { |
| 371 VLOG(1) << network->name() << ": expected object of type " << onc_type; |
| 372 parse_error_ = l10n_util::GetStringUTF8( |
| 373 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); |
| 374 return false; |
| 375 } |
| 376 VLOG(2) << "Parsing nested object of type " << onc_type; |
| 377 const DictionaryValue* dict = NULL; |
| 378 value.GetAsDictionary(&dict); |
| 379 for (DictionaryValue::key_iterator iter = dict->begin_keys(); |
| 380 iter != dict->end_keys(); ++iter) { |
| 381 const std::string& key = *iter; |
| 382 |
| 383 // Recommended keys are only of interest to the UI code and the UI reads it |
| 384 // directly from the ONC blob. |
| 385 if (key == "Recommended") |
| 386 continue; |
| 387 |
| 388 base::Value* inner_value = NULL; |
| 389 dict->GetWithoutPathExpansion(key, &inner_value); |
| 390 CHECK(inner_value != NULL); |
| 391 int field_index; |
| 392 for (field_index = 0; signature[field_index].field != NULL; ++field_index) { |
| 393 if (key == signature[field_index].field) |
| 394 break; |
| 395 } |
| 396 if (signature[field_index].field == NULL) { |
| 397 VLOG(1) << network->name() << ": unexpected field: " |
| 398 << key << ", in type: " << onc_type; |
| 399 any_errors = true; |
| 400 continue; |
| 401 } |
| 402 if (!inner_value->IsType(signature[field_index].type)) { |
| 403 VLOG(1) << network->name() << ": field with wrong type: " << key |
| 404 << ", actual type: " << inner_value->GetType() |
| 405 << ", expected type: " << signature[field_index].type; |
| 406 any_errors = true; |
| 407 continue; |
| 408 } |
| 409 PropertyIndex index = signature[field_index].index; |
| 410 // We need to UpdatePropertyMap now since parser might want to |
| 411 // change the mapped value. |
| 412 network->UpdatePropertyMap(index, *inner_value); |
| 413 if (!parser(this, index, *inner_value, network)) { |
| 414 VLOG(1) << network->name() << ": field not parsed: " << key; |
| 415 any_errors = true; |
| 416 continue; |
| 417 } |
| 418 if (VLOG_IS_ON(2)) { |
| 419 std::string value_json; |
| 420 base::JSONWriter::Write(inner_value, true, &value_json); |
| 421 VLOG(2) << network->name() << ": Successfully parsed [" << key |
| 422 << "(" << index << ")] = " << value_json; |
| 423 } |
| 424 } |
| 425 if (any_errors) { |
| 426 parse_error_ = l10n_util::GetStringUTF8( |
| 427 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); |
| 428 } |
| 429 return !any_errors; |
| 430 } |
| 431 |
347 Network* OncNetworkParser::CreateNewNetwork( | 432 Network* OncNetworkParser::CreateNewNetwork( |
348 ConnectionType type, const std::string& service_path) { | 433 ConnectionType type, const std::string& service_path) { |
349 Network* network = NetworkParser::CreateNewNetwork(type, service_path); | 434 Network* network = NetworkParser::CreateNewNetwork(type, service_path); |
350 if (network) { | 435 if (network) { |
351 if (type == TYPE_WIFI) | 436 if (type == TYPE_WIFI) |
352 network->SetNetworkParser(new OncWifiNetworkParser()); | 437 network->SetNetworkParser(new OncWifiNetworkParser()); |
353 else if (type == TYPE_VPN) | 438 else if (type == TYPE_VPN) |
354 network->SetNetworkParser(new OncVirtualNetworkParser()); | 439 network->SetNetworkParser(new OncVirtualNetworkParser()); |
355 } | 440 } |
356 return network; | 441 return network; |
(...skipping 15 matching lines...) Expand all Loading... |
372 return type_string; | 457 return type_string; |
373 } | 458 } |
374 | 459 |
375 std::string OncNetworkParser::GetGuidFromDictionary( | 460 std::string OncNetworkParser::GetGuidFromDictionary( |
376 const base::DictionaryValue& info) { | 461 const base::DictionaryValue& info) { |
377 std::string guid_string; | 462 std::string guid_string; |
378 info.GetString("GUID", &guid_string); | 463 info.GetString("GUID", &guid_string); |
379 return guid_string; | 464 return guid_string; |
380 } | 465 } |
381 | 466 |
| 467 // static |
| 468 bool OncNetworkParser::ParseNetworkConfigurationValue( |
| 469 OncNetworkParser* parser, |
| 470 PropertyIndex index, |
| 471 const base::Value& value, |
| 472 Network* network) { |
| 473 switch (index) { |
| 474 case PROPERTY_INDEX_ONC_WIFI: { |
| 475 return parser->ParseNestedObject(network, |
| 476 "WiFi", |
| 477 value, |
| 478 wifi_signature, |
| 479 OncWifiNetworkParser::ParseWifiValue); |
| 480 } |
| 481 case PROPERTY_INDEX_ONC_VPN: { |
| 482 if (!CheckNetworkType(network, TYPE_VPN, "VPN")) |
| 483 return false; |
| 484 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
| 485 // Got the "VPN" field. Immediately store the VPN.Type field |
| 486 // value so that we can properly validate fields in the VPN |
| 487 // object based on the type. |
| 488 const DictionaryValue* dict = NULL; |
| 489 CHECK(value.GetAsDictionary(&dict)); |
| 490 std::string provider_type_string; |
| 491 if (!dict->GetString("Type", &provider_type_string)) { |
| 492 VLOG(1) << network->name() << ": VPN.Type is missing"; |
| 493 return false; |
| 494 } |
| 495 ProviderType provider_type = |
| 496 OncVirtualNetworkParser::ParseProviderType(provider_type_string); |
| 497 virtual_network->set_provider_type(provider_type); |
| 498 return parser->ParseNestedObject(network, |
| 499 "VPN", |
| 500 value, |
| 501 vpn_signature, |
| 502 OncVirtualNetworkParser::ParseVPNValue); |
| 503 return true; |
| 504 } |
| 505 case PROPERTY_INDEX_ONC_REMOVE: |
| 506 VLOG(1) << network->name() << ": Remove field not yet implemented"; |
| 507 return false; |
| 508 case PROPERTY_INDEX_TYPE: { |
| 509 // Update property with native value for type. |
| 510 std::string str = |
| 511 NativeNetworkParser::network_type_mapper()->GetKey(network->type()); |
| 512 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); |
| 513 network->UpdatePropertyMap(PROPERTY_INDEX_TYPE, *val.get()); |
| 514 return true; |
| 515 } |
| 516 case PROPERTY_INDEX_GUID: |
| 517 case PROPERTY_INDEX_NAME: |
| 518 // Fall back to generic parser for these. |
| 519 return parser->ParseValue(index, value, network); |
| 520 default: |
| 521 break; |
| 522 } |
| 523 return false; |
| 524 } |
| 525 |
| 526 // static |
| 527 bool OncNetworkParser::CheckNetworkType(Network* network, |
| 528 ConnectionType expected, |
| 529 const std::string& onc_type) { |
| 530 if (expected != network->type()) { |
| 531 LOG(WARNING) << network->name() << ": " |
| 532 << onc_type << " field unexpected for this type network"; |
| 533 return false; |
| 534 } |
| 535 return true; |
| 536 } |
| 537 |
382 scoped_refptr<net::X509Certificate> | 538 scoped_refptr<net::X509Certificate> |
383 OncNetworkParser::ParseServerOrCaCertificate( | 539 OncNetworkParser::ParseServerOrCaCertificate( |
384 int cert_index, | 540 int cert_index, |
385 const std::string& cert_type, | 541 const std::string& cert_type, |
386 const std::string& guid, | 542 const std::string& guid, |
387 base::DictionaryValue* certificate) { | 543 base::DictionaryValue* certificate) { |
388 net::CertDatabase cert_database; | 544 net::CertDatabase cert_database; |
389 bool web_trust = false; | 545 bool web_trust = false; |
390 base::ListValue* trust_list = NULL; | 546 base::ListValue* trust_list = NULL; |
391 if (certificate->GetList("Trust", &trust_list)) { | 547 if (certificate->GetList("Trust", &trust_list)) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 } else { | 697 } else { |
542 LOG(WARNING) << "ONC File: Unable to find private key for cert at index" | 698 LOG(WARNING) << "ONC File: Unable to find private key for cert at index" |
543 << cert_index; | 699 << cert_index; |
544 } | 700 } |
545 | 701 |
546 VLOG(2) << "Successfully imported client certificate at index " | 702 VLOG(2) << "Successfully imported client certificate at index " |
547 << cert_index; | 703 << cert_index; |
548 return cert_result; | 704 return cert_result; |
549 } | 705 } |
550 | 706 |
551 bool OncNetworkParser::ParseNestedObject(Network* network, | |
552 const std::string& onc_type, | |
553 const base::Value& value, | |
554 OncValueSignature* signature, | |
555 ParserPointer parser) { | |
556 bool any_errors = false; | |
557 if (!value.IsType(base::Value::TYPE_DICTIONARY)) { | |
558 VLOG(1) << network->name() << ": expected object of type " << onc_type; | |
559 parse_error_ = l10n_util::GetStringUTF8( | |
560 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); | |
561 return false; | |
562 } | |
563 VLOG(2) << "Parsing nested object of type " << onc_type; | |
564 const DictionaryValue* dict = NULL; | |
565 value.GetAsDictionary(&dict); | |
566 for (DictionaryValue::key_iterator iter = dict->begin_keys(); | |
567 iter != dict->end_keys(); ++iter) { | |
568 const std::string& key = *iter; | |
569 base::Value* inner_value = NULL; | |
570 dict->GetWithoutPathExpansion(key, &inner_value); | |
571 CHECK(inner_value != NULL); | |
572 int field_index; | |
573 for (field_index = 0; signature[field_index].field != NULL; ++field_index) { | |
574 if (key == signature[field_index].field) | |
575 break; | |
576 } | |
577 if (signature[field_index].field == NULL) { | |
578 VLOG(1) << network->name() << ": unexpected field: " | |
579 << key << ", in type: " << onc_type; | |
580 any_errors = true; | |
581 continue; | |
582 } | |
583 if (!inner_value->IsType(signature[field_index].type)) { | |
584 VLOG(1) << network->name() << ": field with wrong type: " << key | |
585 << ", actual type: " << inner_value->GetType() | |
586 << ", expected type: " << signature[field_index].type; | |
587 any_errors = true; | |
588 continue; | |
589 } | |
590 PropertyIndex index = signature[field_index].index; | |
591 // We need to UpdatePropertyMap now since parser might want to | |
592 // change the mapped value. | |
593 network->UpdatePropertyMap(index, *inner_value); | |
594 if (!parser(this, index, *inner_value, network)) { | |
595 VLOG(1) << network->name() << ": field not parsed: " << key; | |
596 any_errors = true; | |
597 continue; | |
598 } | |
599 if (VLOG_IS_ON(2)) { | |
600 std::string value_json; | |
601 base::JSONWriter::Write(inner_value, true, &value_json); | |
602 VLOG(2) << network->name() << ": Successfully parsed [" << key | |
603 << "(" << index << ")] = " << value_json; | |
604 } | |
605 } | |
606 if (any_errors) | |
607 parse_error_ = l10n_util::GetStringUTF8( | |
608 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); | |
609 return !any_errors; | |
610 } | |
611 | |
612 // static | |
613 bool OncNetworkParser::CheckNetworkType(Network* network, | |
614 ConnectionType expected, | |
615 const std::string& onc_type) { | |
616 if (expected != network->type()) { | |
617 LOG(WARNING) << network->name() << ": " | |
618 << onc_type << " field unexpected for this type network"; | |
619 return false; | |
620 } | |
621 return true; | |
622 } | |
623 | |
624 // static | |
625 bool OncNetworkParser::ParseNetworkConfigurationValue( | |
626 OncNetworkParser* parser, | |
627 PropertyIndex index, | |
628 const base::Value& value, | |
629 Network* network) { | |
630 switch (index) { | |
631 case PROPERTY_INDEX_ONC_WIFI: { | |
632 return parser->ParseNestedObject(network, | |
633 "WiFi", | |
634 value, | |
635 wifi_signature, | |
636 OncWifiNetworkParser::ParseWifiValue); | |
637 } | |
638 case PROPERTY_INDEX_ONC_VPN: { | |
639 if (!CheckNetworkType(network, TYPE_VPN, "VPN")) | |
640 return false; | |
641 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
642 // Got the "VPN" field. Immediately store the VPN.Type field | |
643 // value so that we can properly validate fields in the VPN | |
644 // object based on the type. | |
645 const DictionaryValue* dict = NULL; | |
646 CHECK(value.GetAsDictionary(&dict)); | |
647 std::string provider_type_string; | |
648 if (!dict->GetString("Type", &provider_type_string)) { | |
649 VLOG(1) << network->name() << ": VPN.Type is missing"; | |
650 return false; | |
651 } | |
652 ProviderType provider_type = | |
653 OncVirtualNetworkParser::ParseProviderType(provider_type_string); | |
654 virtual_network->set_provider_type(provider_type); | |
655 return parser->ParseNestedObject(network, | |
656 "VPN", | |
657 value, | |
658 vpn_signature, | |
659 OncVirtualNetworkParser::ParseVPNValue); | |
660 return true; | |
661 } | |
662 case PROPERTY_INDEX_ONC_REMOVE: | |
663 VLOG(1) << network->name() << ": Remove field not yet implemented"; | |
664 return false; | |
665 case PROPERTY_INDEX_TYPE: { | |
666 // Update property with native value for type. | |
667 std::string str = | |
668 NativeNetworkParser::network_type_mapper()->GetKey(network->type()); | |
669 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); | |
670 network->UpdatePropertyMap(PROPERTY_INDEX_TYPE, *val.get()); | |
671 return true; | |
672 } | |
673 case PROPERTY_INDEX_GUID: | |
674 case PROPERTY_INDEX_NAME: | |
675 // Fall back to generic parser for these. | |
676 return parser->ParseValue(index, value, network); | |
677 default: | |
678 break; | |
679 } | |
680 return false; | |
681 } | |
682 | |
683 // static | |
684 bool OncNetworkParser::DeleteCertAndKeyByNickname(const std::string& label) { | |
685 net::CertificateList cert_list; | |
686 ListCertsWithNickname(label, &cert_list); | |
687 net::CertDatabase cert_db; | |
688 bool result = true; | |
689 for (net::CertificateList::iterator iter = cert_list.begin(); | |
690 iter != cert_list.end(); ++iter) { | |
691 // If we fail, we try and delete the rest still. | |
692 // TODO(gspencer): this isn't very "transactional". If we fail on some, but | |
693 // not all, then it's possible to leave things in a weird state. | |
694 // Luckily there should only be one cert with a particular | |
695 // label, and the cert not being found is one of the few reasons the | |
696 // delete could fail, but still... The other choice is to return | |
697 // failure immediately, but that doesn't seem to do what is intended. | |
698 if (!cert_db.DeleteCertAndKey(iter->get())) | |
699 result = false; | |
700 } | |
701 return result; | |
702 } | |
703 | |
704 // static | 707 // static |
705 void OncNetworkParser::ListCertsWithNickname(const std::string& label, | 708 void OncNetworkParser::ListCertsWithNickname(const std::string& label, |
706 net::CertificateList* result) { | 709 net::CertificateList* result) { |
707 net::CertificateList all_certs; | 710 net::CertificateList all_certs; |
708 net::CertDatabase cert_db; | 711 net::CertDatabase cert_db; |
709 cert_db.ListCerts(&all_certs); | 712 cert_db.ListCerts(&all_certs); |
710 result->clear(); | 713 result->clear(); |
711 for (net::CertificateList::iterator iter = all_certs.begin(); | 714 for (net::CertificateList::iterator iter = all_certs.begin(); |
712 iter != all_certs.end(); ++iter) { | 715 iter != all_certs.end(); ++iter) { |
713 if (iter->get()->os_cert_handle()->nickname) { | 716 if (iter->get()->os_cert_handle()->nickname) { |
(...skipping 20 matching lines...) Expand all Loading... |
734 char* private_key_nickname = PK11_GetPrivateKeyNickname(private_key); | 737 char* private_key_nickname = PK11_GetPrivateKeyNickname(private_key); |
735 if (private_key_nickname && private_key_nickname == label) | 738 if (private_key_nickname && private_key_nickname == label) |
736 result->push_back(*iter); | 739 result->push_back(*iter); |
737 PORT_Free(private_key_nickname); | 740 PORT_Free(private_key_nickname); |
738 SECKEY_DestroyPrivateKey(private_key); | 741 SECKEY_DestroyPrivateKey(private_key); |
739 } | 742 } |
740 } | 743 } |
741 } | 744 } |
742 | 745 |
743 // static | 746 // static |
| 747 bool OncNetworkParser::DeleteCertAndKeyByNickname(const std::string& label) { |
| 748 net::CertificateList cert_list; |
| 749 ListCertsWithNickname(label, &cert_list); |
| 750 net::CertDatabase cert_db; |
| 751 bool result = true; |
| 752 for (net::CertificateList::iterator iter = cert_list.begin(); |
| 753 iter != cert_list.end(); ++iter) { |
| 754 // If we fail, we try and delete the rest still. |
| 755 // TODO(gspencer): this isn't very "transactional". If we fail on some, but |
| 756 // not all, then it's possible to leave things in a weird state. |
| 757 // Luckily there should only be one cert with a particular |
| 758 // label, and the cert not being found is one of the few reasons the |
| 759 // delete could fail, but still... The other choice is to return |
| 760 // failure immediately, but that doesn't seem to do what is intended. |
| 761 if (!cert_db.DeleteCertAndKey(iter->get())) |
| 762 result = false; |
| 763 } |
| 764 return result; |
| 765 } |
| 766 |
| 767 // static |
744 std::string OncNetworkParser::GetPkcs11IdFromCertGuid(const std::string& guid) { | 768 std::string OncNetworkParser::GetPkcs11IdFromCertGuid(const std::string& guid) { |
745 // We have to look up the GUID to find the PKCS#11 ID that is needed. | 769 // We have to look up the GUID to find the PKCS#11 ID that is needed. |
746 net::CertificateList cert_list; | 770 net::CertificateList cert_list; |
747 ListCertsWithNickname(guid, &cert_list); | 771 ListCertsWithNickname(guid, &cert_list); |
748 DCHECK_EQ(1ul, cert_list.size()); | 772 DCHECK_EQ(1ul, cert_list.size()); |
749 if (cert_list.size() == 1) | 773 if (cert_list.size() == 1) |
750 return x509_certificate_model::GetPkcs11Id(cert_list[0]->os_cert_handle()); | 774 return x509_certificate_model::GetPkcs11Id(cert_list[0]->os_cert_handle()); |
751 return std::string(); | 775 return std::string(); |
752 } | 776 } |
753 | 777 |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 // on the value of AuthenticationType. | 1250 // on the value of AuthenticationType. |
1227 { "L2TP-IPsec", PROVIDER_TYPE_L2TP_IPSEC_PSK }, | 1251 { "L2TP-IPsec", PROVIDER_TYPE_L2TP_IPSEC_PSK }, |
1228 { "OpenVPN", PROVIDER_TYPE_OPEN_VPN }, | 1252 { "OpenVPN", PROVIDER_TYPE_OPEN_VPN }, |
1229 }; | 1253 }; |
1230 CR_DEFINE_STATIC_LOCAL(EnumMapper<ProviderType>, parser, | 1254 CR_DEFINE_STATIC_LOCAL(EnumMapper<ProviderType>, parser, |
1231 (table, arraysize(table), PROVIDER_TYPE_MAX)); | 1255 (table, arraysize(table), PROVIDER_TYPE_MAX)); |
1232 return parser.Get(type); | 1256 return parser.Get(type); |
1233 } | 1257 } |
1234 | 1258 |
1235 } // namespace chromeos | 1259 } // namespace chromeos |
OLD | NEW |