diff options
author | mnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-15 11:59:10 +0000 |
---|---|---|
committer | mnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-15 11:59:10 +0000 |
commit | d8b2401d17ed34fa38620b9e7586b27fcef28ab3 (patch) | |
tree | 086ae30f92116a15581aebf8798c9bee828be260 | |
parent | 0cba296108328045bad62e2286f5ec6a2e4fd7e8 (diff) | |
download | chromium_src-d8b2401d17ed34fa38620b9e7586b27fcef28ab3.zip chromium_src-d8b2401d17ed34fa38620b9e7586b27fcef28ab3.tar.gz chromium_src-d8b2401d17ed34fa38620b9e7586b27fcef28ab3.tar.bz2 |
Set onc_source UI data parameter when importing ONC.
BUG=chromium-os:23124
TEST=Set up a policy-configured ONC network, observe that the network settings are locked down and the network cannot be removed.
Review URL: http://codereview.chromium.org/8804020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114622 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 355 insertions, 276 deletions
diff --git a/chrome/browser/chromeos/cros/enum_mapper.h b/chrome/browser/chromeos/cros/enum_mapper.h new file mode 100644 index 0000000..0dfbd97 --- /dev/null +++ b/chrome/browser/chromeos/cros/enum_mapper.h @@ -0,0 +1,80 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_CROS_ENUM_MAPPER_H_ +#define CHROME_BROWSER_CHROMEOS_CROS_ENUM_MAPPER_H_ +#pragma once + +#include <map> +#include <string> + +#include "base/basictypes.h" + +namespace chromeos { + +// This turns an array of string-to-enum-value mappings into a class +// that can cache the mapping and do quick lookups using an actual map +// class. Usage is something like: +// +// const char kKey1[] = "key1"; +// const char kKey2[] = "key2"; +// +// enum EnumFoo { +// UNKNOWN = 0, +// FOO = 1, +// BAR = 2, +// }; +// +// const EnumMapper<EnumFoo>::Pair index_table[] = { +// { kKey1, FOO }, +// { kKey2, BAR }, +// }; +// +// EnumMapper<EnumFoo> mapper(index_table, arraysize(index_table), UNKNOWN); +// EnumFoo value = mapper.Get(kKey1); // Returns FOO. +// EnumFoo value = mapper.Get('boo'); // Returns UNKNOWN. +template <typename EnumType> +class EnumMapper { + public: + struct Pair { + const char* key; + const EnumType value; + }; + + EnumMapper(const Pair* list, size_t num_entries, EnumType unknown) + : unknown_value_(unknown) { + for (size_t i = 0; i < num_entries; ++i, ++list) { + enum_map_[list->key] = list->value; + inverse_enum_map_[list->value] = list->key; + } + } + + EnumType Get(const std::string& type) const { + EnumMapConstIter iter = enum_map_.find(type); + if (iter != enum_map_.end()) + return iter->second; + return unknown_value_; + } + + std::string GetKey(EnumType type) const { + InverseEnumMapConstIter iter = inverse_enum_map_.find(type); + if (iter != inverse_enum_map_.end()) + return iter->second; + return std::string(); + } + + private: + typedef typename std::map<std::string, EnumType> EnumMap; + typedef typename std::map<EnumType, std::string> InverseEnumMap; + typedef typename EnumMap::const_iterator EnumMapConstIter; + typedef typename InverseEnumMap::const_iterator InverseEnumMapConstIter; + EnumMap enum_map_; + InverseEnumMap inverse_enum_map_; + EnumType unknown_value_; + DISALLOW_COPY_AND_ASSIGN(EnumMapper); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_CROS_ENUM_MAPPER_H_ diff --git a/chrome/browser/chromeos/cros/mock_network_library.h b/chrome/browser/chromeos/cros/mock_network_library.h index 293149b..ff959d8 100644 --- a/chrome/browser/chromeos/cros/mock_network_library.h +++ b/chrome/browser/chromeos/cros/mock_network_library.h @@ -155,8 +155,9 @@ class MockNetworkLibrary : public NetworkLibrary { HardwareAddressFormat)); MOCK_METHOD1(SetIPConfig, void(const NetworkIPConfig&)); MOCK_METHOD0(SwitchToPreferredNetwork, void(void)); - MOCK_METHOD3(LoadOncNetworks, bool(const std::string&, + MOCK_METHOD4(LoadOncNetworks, bool(const std::string&, const std::string&, + NetworkUIData::ONCSource, std::string*)); MOCK_METHOD2(SetActiveNetwork, bool(ConnectionType, const std::string&)); }; diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index d1625d1..b6acf1a 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -31,7 +31,6 @@ #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/native_network_constants.h" #include "chrome/browser/chromeos/cros/native_network_parser.h" -#include "chrome/browser/chromeos/cros/network_ui_data.h" #include "chrome/browser/chromeos/cros/onc_network_parser.h" #include "chrome/browser/chromeos/cros_settings.h" #include "chrome/browser/chromeos/network_login_observer.h" @@ -1746,6 +1745,7 @@ class NetworkLibraryImplBase : public NetworkLibrary { virtual void SwitchToPreferredNetwork() OVERRIDE; virtual bool LoadOncNetworks(const std::string& onc_blob, const std::string& passcode, + NetworkUIData::ONCSource source, std::string* error) OVERRIDE; virtual bool SetActiveNetwork(ConnectionType type, const std::string& service_path) OVERRIDE; @@ -2836,9 +2836,10 @@ void NetworkLibraryImplBase::SwitchToPreferredNetwork() { bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, const std::string& passcode, + NetworkUIData::ONCSource source, std::string* error) { // TODO(gspencer): Add support for decrypting onc files. crbug.com/19397 - OncNetworkParser parser(onc_blob); + OncNetworkParser parser(onc_blob, source); if (!parser.parse_error().empty()) { if (error) @@ -5121,7 +5122,7 @@ void NetworkLibraryImplStub::Init() { " ]," " \"Certificates\": []" "}"); - LoadOncNetworks(test_blob, "", NULL); + LoadOncNetworks(test_blob, "", NetworkUIData::ONC_SOURCE_USER_IMPORT, NULL); } //////////////////////////////////////////////////////////////////////////// diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h index 5fe3a90..7f22d19 100644 --- a/chrome/browser/chromeos/cros/network_library.h +++ b/chrome/browser/chromeos/cros/network_library.h @@ -18,6 +18,7 @@ #include "base/observer_list.h" #include "base/string16.h" #include "base/timer.h" +#include "chrome/browser/chromeos/cros/network_ui_data.h" #include "third_party/cros/chromeos_network.h" namespace base { @@ -1793,6 +1794,7 @@ class NetworkLibrary { // the error message. virtual bool LoadOncNetworks(const std::string& onc_blob, const std::string& passcode, + NetworkUIData::ONCSource source, std::string* error) = 0; // This sets the active network for the network type. Note: priority order diff --git a/chrome/browser/chromeos/cros/network_parser.h b/chrome/browser/chromeos/cros/network_parser.h index a1a53e2..6a61cdc 100644 --- a/chrome/browser/chromeos/cros/network_parser.h +++ b/chrome/browser/chromeos/cros/network_parser.h @@ -6,10 +6,11 @@ #define CHROME_BROWSER_CHROMEOS_CROS_NETWORK_PARSER_H_ #pragma once -#include <string> #include <map> +#include <string> #include "base/memory/scoped_ptr.h" +#include "chrome/browser/chromeos/cros/enum_mapper.h" #include "chrome/browser/chromeos/cros/network_library.h" namespace base { @@ -21,68 +22,6 @@ namespace chromeos { class NetworkDevice; -// This turns an array of string-to-enum-value mappings into a class -// that can cache the mapping and do quick lookups using an actual map -// class. Usage is something like: -// -// const char kKey1[] = "key1"; -// const char kKey2[] = "key2"; -// -// enum EnumFoo { -// UNKNOWN = 0, -// FOO = 1, -// BAR = 2, -// }; -// -// const EnumMapper<EnumFoo>::Pair index_table[] = { -// { kKey1, FOO }, -// { kKey2, BAR }, -// }; -// -// EnumMapper<EnumFoo> mapper(index_table, arraysize(index_table), UNKNOWN); -// EnumFoo value = mapper.Get(kKey1); // Returns FOO. -// EnumFoo value = mapper.Get('boo'); // Returns UNKNOWN. -template <typename EnumType> -class EnumMapper { - public: - struct Pair { - const char* key; - const EnumType value; - }; - - EnumMapper(const Pair* list, size_t num_entries, EnumType unknown) - : unknown_value_(unknown) { - for (size_t i = 0; i < num_entries; ++i, ++list) { - enum_map_[list->key] = list->value; - inverse_enum_map_[list->value] = list->key; - } - } - - EnumType Get(const std::string& type) const { - EnumMapConstIter iter = enum_map_.find(type); - if (iter != enum_map_.end()) - return iter->second; - return unknown_value_; - } - - std::string GetKey(EnumType type) const { - InverseEnumMapConstIter iter = inverse_enum_map_.find(type); - if (iter != inverse_enum_map_.end()) - return iter->second; - return std::string(); - } - - private: - typedef typename std::map<std::string, EnumType> EnumMap; - typedef typename std::map<EnumType, std::string> InverseEnumMap; - typedef typename EnumMap::const_iterator EnumMapConstIter; - typedef typename InverseEnumMap::const_iterator InverseEnumMapConstIter; - EnumMap enum_map_; - InverseEnumMap inverse_enum_map_; - EnumType unknown_value_; - DISALLOW_COPY_AND_ASSIGN(EnumMapper); -}; - // This takes a Value of a particular form, and maps the keys in the // dictionary to a NetworkDevice object to initialize it properly. // Subclasses of this can then customize its methods to parse either diff --git a/chrome/browser/chromeos/cros/network_ui_data.cc b/chrome/browser/chromeos/cros/network_ui_data.cc index 9fae463..b546b48 100644 --- a/chrome/browser/chromeos/cros/network_ui_data.cc +++ b/chrome/browser/chromeos/cros/network_ui_data.cc @@ -68,6 +68,8 @@ void NetworkUIData::SetProperty(const char* property_key, } void NetworkUIData::FillDictionary(base::DictionaryValue* dict) const { + dict->Clear(); + std::string source_string(GetONCSourceMapper().GetKey(onc_source_)); if (!source_string.empty()) dict->SetString(kKeyONCSource, source_string); diff --git a/chrome/browser/chromeos/cros/network_ui_data.h b/chrome/browser/chromeos/cros/network_ui_data.h index 7b3d24f..7d07744 100644 --- a/chrome/browser/chromeos/cros/network_ui_data.h +++ b/chrome/browser/chromeos/cros/network_ui_data.h @@ -11,7 +11,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/values.h" -#include "chrome/browser/chromeos/cros/network_parser.h" +#include "chrome/browser/chromeos/cros/enum_mapper.h" namespace chromeos { diff --git a/chrome/browser/chromeos/cros/onc_network_parser.cc b/chrome/browser/chromeos/cros/onc_network_parser.cc index eedf109..82b183f 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" @@ -186,8 +186,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; @@ -229,6 +231,28 @@ int OncNetworkParser::GetNetworkConfigsSize() const { return network_configs_ ? network_configs_->GetSize() : 0; } +Network* OncNetworkParser::ParseNetwork(int n) { + CHECK(network_configs_); + CHECK(static_cast<size_t>(n) < network_configs_->GetSize()); + CHECK_GE(n, 0); + DictionaryValue* info = NULL; + if (!network_configs_->GetDictionary(n, &info)) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); + 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; } @@ -293,28 +317,6 @@ scoped_refptr<net::X509Certificate> OncNetworkParser::ParseCertificate( return NULL; } -Network* OncNetworkParser::ParseNetwork(int n) { - CHECK(network_configs_); - CHECK(static_cast<size_t>(n) < network_configs_->GetSize()); - CHECK_GE(n, 0); - DictionaryValue* info = NULL; - if (!network_configs_->GetDictionary(n, &info)) { - parse_error_ = l10n_util::GetStringUTF8( - IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); - 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) { @@ -325,6 +327,13 @@ Network* OncNetworkParser::CreateNetworkFromInfo( 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()); + + // Parse all properties recursively. if (!ParseNestedObject(network.get(), "NetworkConfiguration", static_cast<const base::Value&>(info), @@ -336,14 +345,90 @@ Network* OncNetworkParser::CreateNetworkFromInfo( IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); 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; + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); + 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; + + // Recommended keys are only of interest to the UI code and the UI 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; + } + } + if (any_errors) { + parse_error_ = l10n_util::GetStringUTF8( + IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); + } + return !any_errors; +} + Network* OncNetworkParser::CreateNewNetwork( ConnectionType type, const std::string& service_path) { Network* network = NetworkParser::CreateNewNetwork(type, service_path); @@ -379,6 +464,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, @@ -548,159 +704,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; - parse_error_ = l10n_util::GetStringUTF8( - IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); - 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; - } - } - if (any_errors) - parse_error_ = l10n_util::GetStringUTF8( - IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); - 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) { @@ -741,6 +744,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; +} + +// static std::string OncNetworkParser::GetPkcs11IdFromCertGuid(const std::string& guid) { // We have to look up the GUID to find the PKCS#11 ID that is needed. net::CertificateList cert_list; diff --git a/chrome/browser/chromeos/cros/onc_network_parser.h b/chrome/browser/chromeos/cros/onc_network_parser.h index c3f94b8..56eb0c5 100644 --- a/chrome/browser/chromeos/cros/onc_network_parser.h +++ b/chrome/browser/chromeos/cros/onc_network_parser.h @@ -13,6 +13,7 @@ #include "base/memory/scoped_ptr.h" #include "base/values.h" #include "chrome/browser/chromeos/cros/network_parser.h" +#include "chrome/browser/chromeos/cros/network_ui_data.h" namespace base { class DictionaryValue; @@ -51,7 +52,8 @@ class OncNetworkParser : public NetworkParser { const base::Value&, Network*); - explicit OncNetworkParser(const std::string& onc_blob); + OncNetworkParser(const std::string& onc_blob, + NetworkUIData::ONCSource onc_source); virtual ~OncNetworkParser(); static const EnumMapper<PropertyIndex>* property_mapper(); @@ -140,6 +142,9 @@ class OncNetworkParser : public NetworkParser { // Error message from the JSON parser, if applicable. std::string parse_error_; + // Where the ONC blob comes from. + NetworkUIData::ONCSource onc_source_; + scoped_ptr<base::DictionaryValue> root_dict_; base::ListValue* network_configs_; base::ListValue* certificates_; diff --git a/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc b/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc index 9b3ece0..6e377e1 100644 --- a/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc +++ b/chrome/browser/chromeos/cros/onc_network_parser_unittest.cc @@ -259,7 +259,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkWifi1) { " }" " }]" "}"); - OncNetworkParser parser(test_blob); + OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -294,7 +294,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkWifiEAP1) { " }" " }]" "}"); - OncNetworkParser parser(test_blob); + OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -333,7 +333,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkWifiEAP2) { " }" " }]" "}"); - OncNetworkParser parser(test_blob); + OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -361,7 +361,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkOpenVPN) { " \"NetworkConfigurations\": [") + std::string(kNetworkConfigurationOpenVPN) + std::string( " ]}")); - OncNetworkParser parser(test_blob); + OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -440,7 +440,7 @@ TEST_F(OncNetworkParserTest, TestCreateNetworkL2TPIPsec) { " ]," " \"Certificates\": []" "}"); - OncNetworkParser parser(test_blob); + OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetNetworkConfigsSize()); EXPECT_EQ(0, parser.GetCertificatesSize()); @@ -506,7 +506,7 @@ TEST_F(OncNetworkParserTest, TestAddClientCertificate) { " ]," "}"); std::string test_guid("{f998f760-272b-6939-4c2beffe428697ac}"); - OncNetworkParser parser(test_blob); + OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); scoped_refptr<net::X509Certificate> cert = parser.ParseCertificate(0).get(); @@ -576,7 +576,7 @@ TEST_F(OncNetworkParserTest, TestAddServerCertificate) { " ]," "}"); std::string test_guid("{f998f760-272b-6939-4c2beffe428697aa}"); - OncNetworkParser parser(test_blob); + OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); scoped_refptr<net::X509Certificate> cert = parser.ParseCertificate(0).get(); @@ -607,7 +607,7 @@ TEST_F(OncNetworkParserTest, TestAddAuthorityCertificate) { " ]," "}")); std::string test_guid("{f998f760-272b-6939-4c2beffe428697ab}"); - OncNetworkParser parser(test_blob); + OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); ASSERT_EQ(1, parser.GetCertificatesSize()); scoped_refptr<net::X509Certificate> cert = parser.ParseCertificate(0).get(); @@ -628,7 +628,6 @@ TEST_F(OncNetworkParserTest, TestAddAuthorityCertificate) { SECKEYPublicKeyList* pubkey_list = PK11_ListPublicKeysInSlot(slot_->os_module_handle(), NULL); EXPECT_FALSE(pubkey_list); - } TEST_F(OncNetworkParserTest, TestNetworkAndCertificate) { @@ -641,7 +640,7 @@ TEST_F(OncNetworkParserTest, TestNetworkAndCertificate) { std::string(kCertificateWebAuthority) + std::string( " ]," "}")); - OncNetworkParser parser(test_blob); + OncNetworkParser parser(test_blob, NetworkUIData::ONC_SOURCE_USER_IMPORT); EXPECT_EQ(1, parser.GetCertificatesSize()); EXPECT_TRUE(parser.ParseCertificate(0)); diff --git a/chrome/browser/policy/configuration_policy_handler_chromeos.cc b/chrome/browser/policy/configuration_policy_handler_chromeos.cc index e35e211..8c0f1d8 100644 --- a/chrome/browser/policy/configuration_policy_handler_chromeos.cc +++ b/chrome/browser/policy/configuration_policy_handler_chromeos.cc @@ -18,8 +18,10 @@ namespace policy { NetworkConfigurationPolicyHandler::NetworkConfigurationPolicyHandler( - ConfigurationPolicyType type) - : TypeCheckingPolicyHandler(type, Value::TYPE_STRING) {} + ConfigurationPolicyType type, + chromeos::NetworkUIData::ONCSource onc_source) + : TypeCheckingPolicyHandler(type, Value::TYPE_STRING), + onc_source_(onc_source) {} NetworkConfigurationPolicyHandler::~NetworkConfigurationPolicyHandler() {} @@ -33,7 +35,7 @@ bool NetworkConfigurationPolicyHandler::CheckPolicySettings( if (value) { std::string onc_blob; value->GetAsString(&onc_blob); - chromeos::OncNetworkParser parser(onc_blob); + chromeos::OncNetworkParser parser(onc_blob, onc_source_); if (!parser.parse_error().empty()) { errors->AddError(policy_type(), IDS_POLICY_NETWORK_CONFIG_PARSE_ERROR, diff --git a/chrome/browser/policy/configuration_policy_handler_chromeos.h b/chrome/browser/policy/configuration_policy_handler_chromeos.h index e612f7b..74ca276 100644 --- a/chrome/browser/policy/configuration_policy_handler_chromeos.h +++ b/chrome/browser/policy/configuration_policy_handler_chromeos.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_HANDLER_CHROMEOS_H_ #pragma once +#include "chrome/browser/chromeos/cros/network_ui_data.h" #include "chrome/browser/policy/configuration_policy_handler.h" namespace policy { @@ -15,7 +16,9 @@ namespace policy { // generates error messages. class NetworkConfigurationPolicyHandler : public TypeCheckingPolicyHandler { public: - explicit NetworkConfigurationPolicyHandler(ConfigurationPolicyType type); + NetworkConfigurationPolicyHandler( + ConfigurationPolicyType type, + chromeos::NetworkUIData::ONCSource onc_source); virtual ~NetworkConfigurationPolicyHandler(); // ConfigurationPolicyHandler methods: @@ -36,6 +39,8 @@ class NetworkConfigurationPolicyHandler : public TypeCheckingPolicyHandler { // their values with placeholders. static void StripSensitiveValues(DictionaryValue* network_dict); + chromeos::NetworkUIData::ONCSource onc_source_; + DISALLOW_COPY_AND_ASSIGN(NetworkConfigurationPolicyHandler); }; diff --git a/chrome/browser/policy/configuration_policy_handler_chromeos_unittest.cc b/chrome/browser/policy/configuration_policy_handler_chromeos_unittest.cc index 882a105..7cc1f8a4 100644 --- a/chrome/browser/policy/configuration_policy_handler_chromeos_unittest.cc +++ b/chrome/browser/policy/configuration_policy_handler_chromeos_unittest.cc @@ -12,7 +12,9 @@ namespace policy { TEST(NetworkConfigurationPolicyHandlerTest, Empty) { PolicyMap policy_map; - NetworkConfigurationPolicyHandler handler(kPolicyOpenNetworkConfiguration); + NetworkConfigurationPolicyHandler handler( + kPolicyOpenNetworkConfiguration, + chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY); PolicyErrorMap errors; EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.GetErrors(kPolicyOpenNetworkConfiguration).empty()); @@ -35,7 +37,9 @@ TEST(NetworkConfigurationPolicyHandlerTest, ValidONC) { PolicyMap policy_map; policy_map.Set(kPolicyOpenNetworkConfiguration, Value::CreateStringValue(kTestONC)); - NetworkConfigurationPolicyHandler handler(kPolicyOpenNetworkConfiguration); + NetworkConfigurationPolicyHandler handler( + kPolicyOpenNetworkConfiguration, + chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY); PolicyErrorMap errors; EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_TRUE(errors.GetErrors(kPolicyOpenNetworkConfiguration).empty()); @@ -45,7 +49,9 @@ TEST(NetworkConfigurationPolicyHandlerTest, WrongType) { PolicyMap policy_map; policy_map.Set(kPolicyOpenNetworkConfiguration, Value::CreateBooleanValue(false)); - NetworkConfigurationPolicyHandler handler(kPolicyOpenNetworkConfiguration); + NetworkConfigurationPolicyHandler handler( + kPolicyOpenNetworkConfiguration, + chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY); PolicyErrorMap errors; EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_FALSE(errors.GetErrors(kPolicyOpenNetworkConfiguration).empty()); @@ -56,7 +62,9 @@ TEST(NetworkConfigurationPolicyHandlerTest, JSONParseError) { PolicyMap policy_map; policy_map.Set(kPolicyOpenNetworkConfiguration, Value::CreateStringValue(kTestONC)); - NetworkConfigurationPolicyHandler handler(kPolicyOpenNetworkConfiguration); + NetworkConfigurationPolicyHandler handler( + kPolicyOpenNetworkConfiguration, + chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY); PolicyErrorMap errors; EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors)); EXPECT_FALSE(errors.GetErrors(kPolicyOpenNetworkConfiguration).empty()); @@ -79,7 +87,9 @@ TEST(NetworkConfigurationPolicyHandlerTest, Sanitization) { PolicyMap policy_map; policy_map.Set(kPolicyOpenNetworkConfiguration, Value::CreateStringValue(kTestONC)); - NetworkConfigurationPolicyHandler handler(kPolicyOpenNetworkConfiguration); + NetworkConfigurationPolicyHandler handler( + kPolicyOpenNetworkConfiguration, + chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY); PolicyErrorMap errors; handler.PrepareForDisplaying(&policy_map); const Value* sanitized = policy_map.Get(kPolicyOpenNetworkConfiguration); diff --git a/chrome/browser/policy/configuration_policy_handler_list.cc b/chrome/browser/policy/configuration_policy_handler_list.cc index f8493e5..72b8723d 100644 --- a/chrome/browser/policy/configuration_policy_handler_list.cc +++ b/chrome/browser/policy/configuration_policy_handler_list.cc @@ -231,10 +231,12 @@ ConfigurationPolicyHandlerList::ConfigurationPolicyHandlerList() { #if defined(OS_CHROMEOS) handlers_.push_back( new NetworkConfigurationPolicyHandler( - kPolicyDeviceOpenNetworkConfiguration)); + kPolicyDeviceOpenNetworkConfiguration, + chromeos::NetworkUIData::ONC_SOURCE_DEVICE_POLICY)); handlers_.push_back( new NetworkConfigurationPolicyHandler( - kPolicyOpenNetworkConfiguration)); + kPolicyOpenNetworkConfiguration, + chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY)); #endif // defined(OS_CHROMEOS) } diff --git a/chrome/browser/policy/network_configuration_updater.cc b/chrome/browser/policy/network_configuration_updater.cc index a1597ca..d03bf544 100644 --- a/chrome/browser/policy/network_configuration_updater.cc +++ b/chrome/browser/policy/network_configuration_updater.cc @@ -36,14 +36,17 @@ void NetworkConfigurationUpdater::Update() { } ApplyNetworkConfiguration(policy, kPolicyDeviceOpenNetworkConfiguration, + chromeos::NetworkUIData::ONC_SOURCE_DEVICE_POLICY, &device_network_config_); ApplyNetworkConfiguration(policy, kPolicyOpenNetworkConfiguration, + chromeos::NetworkUIData::ONC_SOURCE_USER_POLICY, &user_network_config_); } void NetworkConfigurationUpdater::ApplyNetworkConfiguration( const PolicyMap& policy_map, ConfigurationPolicyType policy_type, + chromeos::NetworkUIData::ONCSource onc_source, std::string* cached_value) { std::string new_network_config; const base::Value* value = policy_map.Get(policy_type); @@ -57,9 +60,10 @@ void NetworkConfigurationUpdater::ApplyNetworkConfiguration( if (*cached_value != new_network_config) { *cached_value = new_network_config; std::string error; - if (!network_library_->LoadOncNetworks(new_network_config, "", &error)) { + if (!network_library_->LoadOncNetworks(new_network_config, "", onc_source, + &error)) { LOG(WARNING) << "Network library failed to load ONC configuration:" - << error; + << error; } } } diff --git a/chrome/browser/policy/network_configuration_updater.h b/chrome/browser/policy/network_configuration_updater.h index 9282a3c..27a149a 100644 --- a/chrome/browser/policy/network_configuration_updater.h +++ b/chrome/browser/policy/network_configuration_updater.h @@ -8,6 +8,7 @@ #include <string> +#include "chrome/browser/chromeos/cros/network_ui_data.h" #include "chrome/browser/policy/configuration_policy_provider.h" namespace chromeos { @@ -39,6 +40,7 @@ class NetworkConfigurationUpdater // updated). void ApplyNetworkConfiguration(const PolicyMap& policy_map, ConfigurationPolicyType policy_type, + chromeos::NetworkUIData::ONCSource onc_source, std::string* cached_value); // Wraps the provider we read network configuration from. diff --git a/chrome/browser/policy/network_configuration_updater_unittest.cc b/chrome/browser/policy/network_configuration_updater_unittest.cc index 82db2e9..2ef0734 100644 --- a/chrome/browser/policy/network_configuration_updater_unittest.cc +++ b/chrome/browser/policy/network_configuration_updater_unittest.cc @@ -27,7 +27,7 @@ class NetworkConfigurationUpdaterTest TEST_P(NetworkConfigurationUpdaterTest, InitialUpdate) { provider_.AddPolicy(GetParam(), Value::CreateStringValue(kFakeONC)); - EXPECT_CALL(network_library_, LoadOncNetworks(kFakeONC, "", _)) + EXPECT_CALL(network_library_, LoadOncNetworks(kFakeONC, "", _, _)) .WillRepeatedly(Return(true)); NetworkConfigurationUpdater updater(&provider_, &network_library_); @@ -38,20 +38,20 @@ TEST_P(NetworkConfigurationUpdaterTest, PolicyChange) { NetworkConfigurationUpdater updater(&provider_, &network_library_); // We should update if policy changes. - EXPECT_CALL(network_library_, LoadOncNetworks(kFakeONC, "", _)) + EXPECT_CALL(network_library_, LoadOncNetworks(kFakeONC, "", _, _)) .WillOnce(Return(true)); provider_.AddPolicy(GetParam(), Value::CreateStringValue(kFakeONC)); provider_.NotifyPolicyUpdated(); Mock::VerifyAndClearExpectations(&network_library_); // No update if the set the same value again. - EXPECT_CALL(network_library_, LoadOncNetworks(kFakeONC, "", _)) + EXPECT_CALL(network_library_, LoadOncNetworks(kFakeONC, "", _, _)) .Times(0); provider_.NotifyPolicyUpdated(); Mock::VerifyAndClearExpectations(&network_library_); // Another update is expected if the policy goes away. - EXPECT_CALL(network_library_, LoadOncNetworks("", "", _)) + EXPECT_CALL(network_library_, LoadOncNetworks("", "", _, _)) .WillOnce(Return(true)); provider_.RemovePolicy(GetParam()); provider_.NotifyPolicyUpdated(); diff --git a/chrome/browser/ui/webui/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals_ui.cc index 09851c0..806bb18 100644 --- a/chrome/browser/ui/webui/net_internals_ui.cc +++ b/chrome/browser/ui/webui/net_internals_ui.cc @@ -1297,7 +1297,8 @@ void NetInternalsMessageHandler::OnImportONCFile(const ListValue* list) { std::string error; chromeos::CrosLibrary::Get()->GetNetworkLibrary()-> - LoadOncNetworks(onc_blob, passcode, &error); + LoadOncNetworks(onc_blob, passcode, + chromeos::NetworkUIData::ONC_SOURCE_USER_IMPORT, &error); SendJavascriptCommand("receivedONCFileParse", Value::CreateStringValue(error)); } diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc index ce6c4e0..949ece1 100644 --- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc @@ -189,8 +189,7 @@ NetworkInfoDictionary::NetworkInfoDictionary( set_remembered(true); set_shared(remembered->profile_type() == chromeos::PROFILE_SHARED); set_needs_new_plan(false); - set_policy_managed( - network ? chromeos::NetworkUIData::IsManaged(network) : false); + set_policy_managed(chromeos::NetworkUIData::IsManaged(remembered)); } DictionaryValue* NetworkInfoDictionary::BuildDictionary() { diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b7b12f1..1f3dd40 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -420,6 +420,7 @@ 'browser/chromeos/cros/cros_library.h', 'browser/chromeos/cros/cryptohome_library.cc', 'browser/chromeos/cros/cryptohome_library.h', + 'browser/chromeos/cros/enum_mapper.h', 'browser/chromeos/cros/library_loader.cc', 'browser/chromeos/cros/library_loader.h', 'browser/chromeos/cros/native_network_constants.cc', |