Chromium Code Reviews| Index: chrome/browser/chromeos/cros/onc_network_parser.cc |
| diff --git a/chrome/browser/chromeos/cros/onc_network_parser.cc b/chrome/browser/chromeos/cros/onc_network_parser.cc |
| index 55f8e9a4c017fff0ece9c1fd5b8833c15e61f8d1..e4781d7e42e915d6cb861ee3cbc143e67b907dc3 100644 |
| --- a/chrome/browser/chromeos/cros/onc_network_parser.cc |
| +++ b/chrome/browser/chromeos/cros/onc_network_parser.cc |
| @@ -4,8 +4,8 @@ |
| #include "chrome/browser/chromeos/cros/onc_network_parser.h" |
| -#include <pk11pub.h> |
| #include <keyhi.h> |
| +#include <pk11pub.h> |
| #include "base/base64.h" |
| #include "base/json/json_value_serializer.h" |
| @@ -183,8 +183,10 @@ std::string ConvertValueToString(const base::Value& value) { |
| // -------------------- OncNetworkParser -------------------- |
| -OncNetworkParser::OncNetworkParser(const std::string& onc_blob) |
| +OncNetworkParser::OncNetworkParser(const std::string& onc_blob, |
| + NetworkUIData::ONCSource onc_source) |
| : NetworkParser(get_onc_mapper()), |
| + onc_source_(onc_source), |
| network_configs_(NULL), |
| certificates_(NULL) { |
| VLOG(2) << __func__ << ": OncNetworkParser called on " << onc_blob; |
| @@ -226,6 +228,23 @@ int OncNetworkParser::GetNetworkConfigsSize() const { |
| return network_configs_ ? network_configs_->GetSize() : 0; |
| } |
| +Network* OncNetworkParser::ParseNetwork(int n) { |
| + if (!network_configs_) |
| + return NULL; |
| + DictionaryValue* info = NULL; |
| + if (!network_configs_->GetDictionary(n, &info)) |
| + return NULL; |
| + if (VLOG_IS_ON(2)) { |
| + std::string network_json; |
| + base::JSONWriter::Write(static_cast<base::Value*>(info), |
| + true, &network_json); |
| + VLOG(2) << "Parsing network at index " << n |
| + << ": " << network_json; |
| + } |
| + |
| + return CreateNetworkFromInfo(std::string(), *info); |
| +} |
| + |
| int OncNetworkParser::GetCertificatesSize() const { |
| return certificates_ ? certificates_->GetSize() : 0; |
| } |
| @@ -282,23 +301,6 @@ scoped_refptr<net::X509Certificate> OncNetworkParser::ParseCertificate( |
| return NULL; |
| } |
| -Network* OncNetworkParser::ParseNetwork(int n) { |
| - if (!network_configs_) |
| - return NULL; |
| - DictionaryValue* info = NULL; |
| - if (!network_configs_->GetDictionary(n, &info)) |
| - return NULL; |
| - if (VLOG_IS_ON(2)) { |
| - std::string network_json; |
| - base::JSONWriter::Write(static_cast<base::Value*>(info), |
| - true, &network_json); |
| - VLOG(2) << "Parsing network at index " << n |
| - << ": " << network_json; |
| - } |
| - |
| - return CreateNetworkFromInfo(std::string(), *info); |
| -} |
| - |
| Network* OncNetworkParser::CreateNetworkFromInfo( |
| const std::string& service_path, |
| const DictionaryValue& info) { |
| @@ -306,6 +308,16 @@ Network* OncNetworkParser::CreateNetworkFromInfo( |
| if (type == TYPE_UNKNOWN) // Return NULL if cannot parse network type. |
| return NULL; |
| scoped_ptr<Network> network(CreateNewNetwork(type, service_path)); |
| + |
| + // Initialize UI data. |
| + NetworkUIData ui_data; |
| + ui_data.set_onc_source(onc_source_); |
| + ui_data.FillDictionary(network->ui_data()); |
| + |
| + // Copy ONC to the network object. |
| + network->onc()->MergeDictionary(&info); |
| + |
| + // Parse all properties recursively. |
| if (!ParseNestedObject(network.get(), |
| "NetworkConfiguration", |
| static_cast<const base::Value&>(info), |
| @@ -314,14 +326,85 @@ Network* OncNetworkParser::CreateNetworkFromInfo( |
| LOG(WARNING) << "Network " << network->name() << " failed to parse."; |
| return NULL; |
| } |
| + |
| + // Update the UI data property. |
| + std::string ui_data_json; |
| + base::JSONWriter::Write(network->ui_data(), false, &ui_data_json); |
| + base::StringValue ui_data_string_value(ui_data_json); |
| + network->UpdatePropertyMap(PROPERTY_INDEX_UI_DATA, ui_data_string_value); |
| + |
| if (VLOG_IS_ON(2)) { |
| VLOG(2) << "Created Network '" << network->name() |
| << "' from info. Path:" << service_path |
| << " Type:" << ConnectionTypeToString(type); |
| } |
| + |
| return network.release(); |
| } |
| +bool OncNetworkParser::ParseNestedObject(Network* network, |
| + const std::string& onc_type, |
| + const base::Value& value, |
| + OncValueSignature* signature, |
| + ParserPointer parser) { |
| + bool any_errors = false; |
| + if (!value.IsType(base::Value::TYPE_DICTIONARY)) { |
| + VLOG(1) << network->name() << ": expected object of type " << onc_type; |
| + return false; |
| + } |
| + VLOG(2) << "Parsing nested object of type " << onc_type; |
| + const DictionaryValue* dict = NULL; |
| + value.GetAsDictionary(&dict); |
| + for (DictionaryValue::key_iterator iter = dict->begin_keys(); |
| + iter != dict->end_keys(); ++iter) { |
| + const std::string& key = *iter; |
| + |
| + // The list of Recommended key is only of interest to the UI code and the UI |
|
stevenjb
2011/12/14 00:27:38
nit: s/The list of Recommended key is/Recommended
Mattias Nissler (ping if slow)
2011/12/14 20:46:38
Done.
|
| + // reads it directly from the ONC blob. |
| + if (key == "Recommended") |
| + continue; |
| + |
| + base::Value* inner_value = NULL; |
| + dict->GetWithoutPathExpansion(key, &inner_value); |
| + CHECK(inner_value != NULL); |
| + int field_index; |
| + for (field_index = 0; signature[field_index].field != NULL; ++field_index) { |
| + if (key == signature[field_index].field) |
| + break; |
| + } |
| + if (signature[field_index].field == NULL) { |
| + VLOG(1) << network->name() << ": unexpected field: " |
| + << key << ", in type: " << onc_type; |
| + any_errors = true; |
| + continue; |
| + } |
| + if (!inner_value->IsType(signature[field_index].type)) { |
| + VLOG(1) << network->name() << ": field with wrong type: " << key |
| + << ", actual type: " << inner_value->GetType() |
| + << ", expected type: " << signature[field_index].type; |
| + any_errors = true; |
| + continue; |
| + } |
| + PropertyIndex index = signature[field_index].index; |
| + // We need to UpdatePropertyMap now since parser might want to |
| + // change the mapped value. |
| + network->UpdatePropertyMap(index, *inner_value); |
| + if (!parser(this, index, *inner_value, network)) { |
| + VLOG(1) << network->name() << ": field not parsed: " << key; |
| + any_errors = true; |
| + continue; |
| + } |
| + |
| + if (VLOG_IS_ON(2)) { |
| + std::string value_json; |
| + base::JSONWriter::Write(inner_value, true, &value_json); |
| + VLOG(2) << network->name() << ": Successfully parsed [" << key |
| + << "(" << index << ")] = " << value_json; |
| + } |
| + } |
| + return !any_errors; |
| +} |
| + |
| Network* OncNetworkParser::CreateNewNetwork( |
| ConnectionType type, const std::string& service_path) { |
| Network* network = NetworkParser::CreateNewNetwork(type, service_path); |
| @@ -357,6 +440,77 @@ std::string OncNetworkParser::GetGuidFromDictionary( |
| return guid_string; |
| } |
| +// static |
| +bool OncNetworkParser::ParseNetworkConfigurationValue( |
| + OncNetworkParser* parser, |
| + PropertyIndex index, |
| + const base::Value& value, |
| + Network* network) { |
| + switch (index) { |
| + case PROPERTY_INDEX_ONC_WIFI: { |
| + return parser->ParseNestedObject(network, |
| + "WiFi", |
| + value, |
| + wifi_signature, |
| + OncWifiNetworkParser::ParseWifiValue); |
| + } |
| + case PROPERTY_INDEX_ONC_VPN: { |
| + if (!CheckNetworkType(network, TYPE_VPN, "VPN")) |
| + return false; |
| + VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
| + // Got the "VPN" field. Immediately store the VPN.Type field |
| + // value so that we can properly validate fields in the VPN |
| + // object based on the type. |
| + const DictionaryValue* dict = NULL; |
| + CHECK(value.GetAsDictionary(&dict)); |
| + std::string provider_type_string; |
| + if (!dict->GetString("Type", &provider_type_string)) { |
| + VLOG(1) << network->name() << ": VPN.Type is missing"; |
| + return false; |
| + } |
| + ProviderType provider_type = |
| + OncVirtualNetworkParser::ParseProviderType(provider_type_string); |
| + virtual_network->set_provider_type(provider_type); |
| + return parser->ParseNestedObject(network, |
| + "VPN", |
| + value, |
| + vpn_signature, |
| + OncVirtualNetworkParser::ParseVPNValue); |
| + return true; |
| + } |
| + case PROPERTY_INDEX_ONC_REMOVE: |
| + VLOG(1) << network->name() << ": Remove field not yet implemented"; |
| + return false; |
| + case PROPERTY_INDEX_TYPE: { |
| + // Update property with native value for type. |
| + std::string str = |
| + NativeNetworkParser::network_type_mapper()->GetKey(network->type()); |
| + scoped_ptr<StringValue> val(Value::CreateStringValue(str)); |
| + network->UpdatePropertyMap(PROPERTY_INDEX_TYPE, *val.get()); |
| + return true; |
| + } |
| + case PROPERTY_INDEX_GUID: |
| + case PROPERTY_INDEX_NAME: |
| + // Fall back to generic parser for these. |
| + return parser->ParseValue(index, value, network); |
| + default: |
| + break; |
| + } |
| + return false; |
| +} |
| + |
| +// static |
| +bool OncNetworkParser::CheckNetworkType(Network* network, |
| + ConnectionType expected, |
| + const std::string& onc_type) { |
| + if (expected != network->type()) { |
| + LOG(WARNING) << network->name() << ": " |
| + << onc_type << " field unexpected for this type network"; |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| scoped_refptr<net::X509Certificate> |
| OncNetworkParser::ParseServerOrCaCertificate( |
| int cert_index, |
| @@ -506,154 +660,6 @@ scoped_refptr<net::X509Certificate> OncNetworkParser::ParseClientCertificate( |
| return cert_result; |
| } |
| -bool OncNetworkParser::ParseNestedObject(Network* network, |
| - const std::string& onc_type, |
| - const base::Value& value, |
| - OncValueSignature* signature, |
| - ParserPointer parser) { |
| - bool any_errors = false; |
| - if (!value.IsType(base::Value::TYPE_DICTIONARY)) { |
| - VLOG(1) << network->name() << ": expected object of type " << onc_type; |
| - return false; |
| - } |
| - VLOG(2) << "Parsing nested object of type " << onc_type; |
| - const DictionaryValue* dict = NULL; |
| - value.GetAsDictionary(&dict); |
| - for (DictionaryValue::key_iterator iter = dict->begin_keys(); |
| - iter != dict->end_keys(); ++iter) { |
| - const std::string& key = *iter; |
| - base::Value* inner_value = NULL; |
| - dict->GetWithoutPathExpansion(key, &inner_value); |
| - CHECK(inner_value != NULL); |
| - int field_index; |
| - for (field_index = 0; signature[field_index].field != NULL; ++field_index) { |
| - if (key == signature[field_index].field) |
| - break; |
| - } |
| - if (signature[field_index].field == NULL) { |
| - VLOG(1) << network->name() << ": unexpected field: " |
| - << key << ", in type: " << onc_type; |
| - any_errors = true; |
| - continue; |
| - } |
| - if (!inner_value->IsType(signature[field_index].type)) { |
| - VLOG(1) << network->name() << ": field with wrong type: " << key |
| - << ", actual type: " << inner_value->GetType() |
| - << ", expected type: " << signature[field_index].type; |
| - any_errors = true; |
| - continue; |
| - } |
| - PropertyIndex index = signature[field_index].index; |
| - // We need to UpdatePropertyMap now since parser might want to |
| - // change the mapped value. |
| - network->UpdatePropertyMap(index, *inner_value); |
| - if (!parser(this, index, *inner_value, network)) { |
| - VLOG(1) << network->name() << ": field not parsed: " << key; |
| - any_errors = true; |
| - continue; |
| - } |
| - if (VLOG_IS_ON(2)) { |
| - std::string value_json; |
| - base::JSONWriter::Write(inner_value, true, &value_json); |
| - VLOG(2) << network->name() << ": Successfully parsed [" << key |
| - << "(" << index << ")] = " << value_json; |
| - } |
| - } |
| - return !any_errors; |
| -} |
| - |
| -// static |
| -bool OncNetworkParser::CheckNetworkType(Network* network, |
| - ConnectionType expected, |
| - const std::string& onc_type) { |
| - if (expected != network->type()) { |
| - LOG(WARNING) << network->name() << ": " |
| - << onc_type << " field unexpected for this type network"; |
| - return false; |
| - } |
| - return true; |
| -} |
| - |
| -// static |
| -bool OncNetworkParser::ParseNetworkConfigurationValue( |
| - OncNetworkParser* parser, |
| - PropertyIndex index, |
| - const base::Value& value, |
| - Network* network) { |
| - switch (index) { |
| - case PROPERTY_INDEX_ONC_WIFI: { |
| - return parser->ParseNestedObject(network, |
| - "WiFi", |
| - value, |
| - wifi_signature, |
| - OncWifiNetworkParser::ParseWifiValue); |
| - } |
| - case PROPERTY_INDEX_ONC_VPN: { |
| - if (!CheckNetworkType(network, TYPE_VPN, "VPN")) |
| - return false; |
| - VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
| - // Got the "VPN" field. Immediately store the VPN.Type field |
| - // value so that we can properly validate fields in the VPN |
| - // object based on the type. |
| - const DictionaryValue* dict = NULL; |
| - CHECK(value.GetAsDictionary(&dict)); |
| - std::string provider_type_string; |
| - if (!dict->GetString("Type", &provider_type_string)) { |
| - VLOG(1) << network->name() << ": VPN.Type is missing"; |
| - return false; |
| - } |
| - ProviderType provider_type = |
| - OncVirtualNetworkParser::ParseProviderType(provider_type_string); |
| - virtual_network->set_provider_type(provider_type); |
| - return parser->ParseNestedObject(network, |
| - "VPN", |
| - value, |
| - vpn_signature, |
| - OncVirtualNetworkParser::ParseVPNValue); |
| - return true; |
| - } |
| - case PROPERTY_INDEX_ONC_REMOVE: |
| - VLOG(1) << network->name() << ": Remove field not yet implemented"; |
| - return false; |
| - case PROPERTY_INDEX_TYPE: { |
| - // Update property with native value for type. |
| - std::string str = |
| - NativeNetworkParser::network_type_mapper()->GetKey(network->type()); |
| - scoped_ptr<StringValue> val(Value::CreateStringValue(str)); |
| - network->UpdatePropertyMap(PROPERTY_INDEX_TYPE, *val.get()); |
| - return true; |
| - } |
| - case PROPERTY_INDEX_GUID: |
| - case PROPERTY_INDEX_NAME: |
| - // Fall back to generic parser for these. |
| - return parser->ParseValue(index, value, network); |
| - default: |
| - break; |
| - } |
| - return false; |
| -} |
| - |
| -// static |
| -bool OncNetworkParser::DeleteCertAndKeyByNickname(const std::string& label) { |
| - net::CertificateList cert_list; |
| - ListCertsWithNickname(label, &cert_list); |
| - net::CertDatabase cert_db; |
| - bool result = true; |
| - for (net::CertificateList::iterator iter = cert_list.begin(); |
| - iter != cert_list.end(); ++iter) { |
| - // If we fail, we try and delete the rest still. |
| - // TODO(gspencer): this isn't very "transactional". If we fail on some, but |
| - // not all, then it's possible to leave things in a weird state. |
| - // Luckily there should only be one cert with a particular |
| - // label, and the cert not being found is one of the few reasons the |
| - // delete could fail, but still... The other choice is to return |
| - // failure immediately, but that doesn't seem to do what is intended. |
| - if (!cert_db.DeleteCertAndKey(iter->get())) |
| - result = false; |
| - } |
| - return result; |
| -} |
| - |
| // static |
| void OncNetworkParser::ListCertsWithNickname(const std::string& label, |
| net::CertificateList* result) { |
| @@ -693,6 +699,27 @@ void OncNetworkParser::ListCertsWithNickname(const std::string& label, |
| } |
| } |
| +// static |
| +bool OncNetworkParser::DeleteCertAndKeyByNickname(const std::string& label) { |
| + net::CertificateList cert_list; |
| + ListCertsWithNickname(label, &cert_list); |
| + net::CertDatabase cert_db; |
| + bool result = true; |
| + for (net::CertificateList::iterator iter = cert_list.begin(); |
| + iter != cert_list.end(); ++iter) { |
| + // If we fail, we try and delete the rest still. |
| + // TODO(gspencer): this isn't very "transactional". If we fail on some, but |
| + // not all, then it's possible to leave things in a weird state. |
| + // Luckily there should only be one cert with a particular |
| + // label, and the cert not being found is one of the few reasons the |
| + // delete could fail, but still... The other choice is to return |
| + // failure immediately, but that doesn't seem to do what is intended. |
| + if (!cert_db.DeleteCertAndKey(iter->get())) |
| + result = false; |
| + } |
| + return result; |
| +} |
| + |
| // -------------------- OncWirelessNetworkParser -------------------- |
| OncWirelessNetworkParser::OncWirelessNetworkParser() {} |