Index: chrome/browser/chromeos/cros/network_library_impl_base.cc |
diff --git a/chrome/browser/chromeos/cros/network_library_impl_base.cc b/chrome/browser/chromeos/cros/network_library_impl_base.cc |
index 9c264ad2bad30435dc9122b028c6e63357205745..28c24a82c50df00933dab2f712bd2d861f1e40b9 100644 |
--- a/chrome/browser/chromeos/cros/network_library_impl_base.cc |
+++ b/chrome/browser/chromeos/cros/network_library_impl_base.cc |
@@ -6,16 +6,18 @@ |
#include "base/bind.h" |
#include "base/json/json_reader.h" |
+#include "base/json/json_writer.h" |
#include "base/memory/scoped_vector.h" |
#include "base/metrics/histogram.h" |
#include "base/stl_util.h" |
-#include "chrome/browser/chromeos/cros/native_network_parser.h" |
#include "chrome/browser/chromeos/cros/network_constants.h" |
-#include "chrome/browser/chromeos/cros/onc_network_parser.h" |
+#include "chrome/browser/chromeos/login/user_manager.h" |
+#include "chrome/browser/chromeos/net/onc_utils.h" |
#include "chrome/browser/chromeos/network_login_observer.h" |
#include "chromeos/network/onc/onc_certificate_importer.h" |
#include "chromeos/network/onc/onc_constants.h" |
#include "chromeos/network/onc/onc_signature.h" |
+#include "chromeos/network/onc/onc_translator.h" |
#include "chromeos/network/onc/onc_utils.h" |
#include "chromeos/network/onc/onc_validator.h" |
#include "content/public/browser/browser_thread.h" |
@@ -1030,6 +1032,28 @@ void NetworkLibraryImplBase::SwitchToPreferredNetwork() { |
} |
} |
+namespace { |
+ |
+class UserStringSubstitution : public onc::StringSubstitution { |
+ public: |
+ UserStringSubstitution() {} |
+ virtual bool GetSubstitute(std::string placeholder, |
+ std::string* substitute) const { |
+ if (!UserManager::Get()->IsUserLoggedIn()) |
+ return false; |
+ const User* logged_in_user = UserManager::Get()->GetLoggedInUser(); |
+ if (placeholder == onc::substitutes::kLoginIDField) |
+ *substitute = logged_in_user->GetAccountName(false); |
+ else if (placeholder == onc::substitutes::kEmailField) |
+ *substitute = logged_in_user->email(); |
+ else |
+ return false; |
+ return true; |
+ } |
+}; |
+ |
+} // namespace |
+ |
bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, |
const std::string& passphrase, |
onc::ONCSource source, |
@@ -1078,11 +1102,13 @@ bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, |
false, // Ignore invalid recommended field names. |
true, // Fail on missing fields. |
from_policy); |
+ validator.SetOncSource(source); |
onc::Validator::Result validation_result; |
- validator.ValidateAndRepairObject(&onc::kToplevelConfigurationSignature, |
- *root_dict, |
- &validation_result); |
+ root_dict = validator.ValidateAndRepairObject( |
+ &onc::kToplevelConfigurationSignature, |
+ *root_dict, |
+ &validation_result); |
if (from_policy) { |
UMA_HISTOGRAM_BOOLEAN("Enterprise.ONC.PolicyValidation", |
@@ -1093,10 +1119,12 @@ bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, |
if (validation_result == onc::Validator::VALID_WITH_WARNINGS) { |
LOG(WARNING) << "ONC from " << onc::GetSourceAsString(source) |
<< " produced warnings."; |
- } else if (validation_result == onc::Validator::INVALID) { |
+ success = false; |
+ } else if (validation_result == onc::Validator::INVALID || |
+ root_dict == NULL) { |
LOG(ERROR) << "ONC from " << onc::GetSourceAsString(source) |
<< " is invalid and couldn't be repaired."; |
- success = false; |
+ return false; |
} |
const base::ListValue* certificates; |
@@ -1125,32 +1153,24 @@ bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, |
network_ids.clear(); |
if (has_network_configurations) { |
VLOG(2) << "ONC file has " << network_configs->GetSize() << " networks"; |
- OncNetworkParser parser(*network_configs, source); |
+ for (base::ListValue::const_iterator it(network_configs->begin()); |
+ it != network_configs->end(); ++it) { |
+ const base::DictionaryValue* network; |
+ (*it)->GetAsDictionary(&network); |
- for (int i = 0; i < parser.GetNetworkConfigsSize(); i++) { |
- // Parse Open Network Configuration blob into a temporary Network object. |
bool marked_for_removal = false; |
- scoped_ptr<Network> network(parser.ParseNetwork(i, &marked_for_removal)); |
- if (!network) { |
- LOG(ERROR) << "Error during ONC parsing network at index " << i |
- << " from " << onc::GetSourceAsString(source); |
- success = false; |
- continue; |
- } |
+ network->GetBooleanWithoutPathExpansion(onc::kRemove, |
+ &marked_for_removal); |
- // Disallow anything but WiFi and Ethernet for device-level policy (which |
- // corresponds to shared networks). See also http://crosbug.com/28741. |
- if (source == onc::ONC_SOURCE_DEVICE_POLICY && |
- network->type() != TYPE_WIFI && |
- network->type() != TYPE_ETHERNET) { |
- LOG(WARNING) << "Ignoring device-level policy-pushed network of type " |
- << network->type(); |
- continue; |
- } |
+ std::string type; |
+ network->GetStringWithoutPathExpansion(onc::kType, &type); |
+ |
+ std::string guid; |
+ network->GetStringWithoutPathExpansion(onc::kGUID, &guid); |
if (source == onc::ONC_SOURCE_USER_IMPORT && marked_for_removal) { |
// User import supports the removal of networks by ID. |
- removal_ids.insert(network->unique_id()); |
+ removal_ids.insert(guid); |
continue; |
} |
@@ -1161,47 +1181,70 @@ bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, |
if (marked_for_removal) |
continue; |
+ // Expand strings like LoginID |
+ base::DictionaryValue* expanded_network = network->DeepCopy(); |
+ UserStringSubstitution substitution; |
+ onc::ExpandStringsInOncObject(onc::kNetworkConfigurationSignature, |
+ substitution, |
+ expanded_network); |
+ |
// Update the ONC map. |
- const base::DictionaryValue*& entry = |
- network_onc_map_[network->unique_id()]; |
+ const base::DictionaryValue*& entry = network_onc_map_[guid]; |
delete entry; |
- entry = parser.GetNetworkConfig(i)->DeepCopy(); |
+ entry = expanded_network; |
// Configure the network. |
- base::DictionaryValue dict; |
- for (Network::PropertyMap::const_iterator props = |
- network->property_map_.begin(); |
- props != network->property_map_.end(); ++props) { |
- std::string key = |
- NativeNetworkParser::property_mapper()->GetKey(props->first); |
- if (!key.empty()) |
- dict.SetWithoutPathExpansion(key, props->second->DeepCopy()); |
- else |
- VLOG(2) << "Property " << props->first << " will not be sent"; |
+ scoped_ptr<base::DictionaryValue> shill_dict = |
+ onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, |
+ *expanded_network); |
+ |
+ // Set the ProxyConfig. |
+ const base::DictionaryValue* proxy_settings; |
+ if (expanded_network->GetDictionaryWithoutPathExpansion( |
+ onc::kProxySettings, |
+ &proxy_settings)) { |
+ scoped_ptr<base::DictionaryValue> proxy_config = |
+ onc::ConvertOncProxySettingsToProxyConfig(*proxy_settings); |
+ std::string proxy_json; |
+ base::JSONWriter::Write(proxy_config.get(), &proxy_json); |
+ shill_dict->SetStringWithoutPathExpansion( |
+ flimflam::kProxyConfigProperty, |
+ proxy_json); |
} |
+ // Set the UIData. |
+ scoped_ptr<NetworkUIData> ui_data = |
+ onc::CreateUIData(source, *expanded_network); |
+ base::DictionaryValue ui_data_dict; |
+ ui_data->FillDictionary(&ui_data_dict); |
+ std::string ui_data_json; |
+ base::JSONWriter::Write(&ui_data_dict, &ui_data_json); |
+ shill_dict->SetStringWithoutPathExpansion(flimflam::kUIDataProperty, |
+ ui_data_json); |
+ |
// Set the appropriate profile for |source|. |
- if (profile != NULL) |
- dict.SetString(flimflam::kProfileProperty, profile->path); |
+ if (profile != NULL) { |
+ shill_dict->SetStringWithoutPathExpansion(flimflam::kProfileProperty, |
+ profile->path); |
+ } |
// For Ethernet networks, apply them to the current Ethernet service. |
- if (network->type() == TYPE_ETHERNET) { |
+ if (type == onc::kEthernet) { |
const EthernetNetwork* ethernet = ethernet_network(); |
if (ethernet) { |
- CallConfigureService(ethernet->unique_id(), &dict); |
+ CallConfigureService(ethernet->unique_id(), shill_dict.get()); |
} else { |
LOG(WARNING) << "Tried to import ONC with an Ethernet network when " |
<< "there is no active Ethernet connection."; |
} |
} else { |
- CallConfigureService(network->unique_id(), &dict); |
+ CallConfigureService(guid, shill_dict.get()); |
} |
- // Store the unique identifier of the network that is defined in the ONC |
- // blob in |network_ids|. The identifiers are later used to clean out any |
- // previously-existing networks that had been configured through policy |
- // but are no longer specified in the updated ONC blob. |
- network_ids.insert(network->unique_id()); |
+ // Store the network's identifier. The identifiers are later used to clean |
+ // out any previously-existing networks that had been configured through |
+ // policy but are no longer specified in the updated ONC blob. |
+ network_ids.insert(guid); |
} |
} |