Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/network/managed_network_configuration_handler.h" | 5 #include "chromeos/network/managed_network_configuration_handler.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/guid.h" | 11 #include "base/guid.h" |
| 12 #include "base/json/json_writer.h" | 12 #include "base/json/json_writer.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 16 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 18 #include "base/string_util.h" | |
| 18 #include "base/values.h" | 19 #include "base/values.h" |
| 19 #include "chromeos/dbus/dbus_method_call_status.h" | 20 #include "chromeos/dbus/dbus_method_call_status.h" |
| 20 #include "chromeos/dbus/dbus_thread_manager.h" | 21 #include "chromeos/dbus/dbus_thread_manager.h" |
| 21 #include "chromeos/dbus/shill_manager_client.h" | 22 #include "chromeos/dbus/shill_manager_client.h" |
| 22 #include "chromeos/dbus/shill_profile_client.h" | 23 #include "chromeos/dbus/shill_profile_client.h" |
| 23 #include "chromeos/dbus/shill_service_client.h" | 24 #include "chromeos/dbus/shill_service_client.h" |
| 24 #include "chromeos/network/network_configuration_handler.h" | 25 #include "chromeos/network/network_configuration_handler.h" |
| 25 #include "chromeos/network/network_event_log.h" | 26 #include "chromeos/network/network_event_log.h" |
| 26 #include "chromeos/network/network_handler_callbacks.h" | 27 #include "chromeos/network/network_handler_callbacks.h" |
| 28 #include "chromeos/network/network_profile.h" | |
| 29 #include "chromeos/network/network_profile_handler.h" | |
| 27 #include "chromeos/network/network_state.h" | 30 #include "chromeos/network/network_state.h" |
| 28 #include "chromeos/network/network_state_handler.h" | 31 #include "chromeos/network/network_state_handler.h" |
| 29 #include "chromeos/network/network_ui_data.h" | 32 #include "chromeos/network/network_ui_data.h" |
| 30 #include "chromeos/network/onc/onc_constants.h" | 33 #include "chromeos/network/onc/onc_constants.h" |
| 31 #include "chromeos/network/onc/onc_merger.h" | 34 #include "chromeos/network/onc/onc_merger.h" |
| 32 #include "chromeos/network/onc/onc_signature.h" | 35 #include "chromeos/network/onc/onc_signature.h" |
| 33 #include "chromeos/network/onc/onc_translator.h" | 36 #include "chromeos/network/onc/onc_translator.h" |
| 34 #include "chromeos/network/onc/onc_utils.h" | 37 #include "chromeos/network/onc/onc_utils.h" |
| 35 #include "chromeos/network/onc/onc_validator.h" | 38 #include "chromeos/network/onc/onc_validator.h" |
| 36 #include "dbus/object_path.h" | 39 #include "dbus/object_path.h" |
| 37 #include "third_party/cros_system_api/dbus/service_constants.h" | 40 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 38 | 41 |
| 39 namespace chromeos { | 42 namespace chromeos { |
| 40 | 43 |
| 44 struct ManagedNetworkConfigurationHandler::Policies { | |
| 45 typedef std::map<std::string, const base::DictionaryValue*> Map; | |
| 46 | |
| 47 ~Policies() { | |
| 48 STLDeleteValues(&map); | |
| 49 } | |
| 50 | |
| 51 const base::DictionaryValue* GetByGUID(const std::string& guid) const { | |
| 52 Map::const_iterator it = map.find(guid); | |
| 53 if (it == map.end()) | |
| 54 return NULL; | |
| 55 return it->second; | |
| 56 } | |
| 57 | |
| 58 // Objects of this struct own the map entries (policies). | |
| 59 Map map; | |
| 60 }; | |
|
stevenjb
2013/04/26 21:00:49
This seems unnecessary and confusing. Why not just
pneubeck (no reviews)
2013/04/29 18:05:51
Seems that I was overprotective against copies of
| |
| 61 | |
| 41 namespace { | 62 namespace { |
| 42 | 63 |
| 43 ManagedNetworkConfigurationHandler* g_configuration_handler_instance = NULL; | 64 ManagedNetworkConfigurationHandler* g_configuration_handler_instance = NULL; |
| 44 | 65 |
| 45 const char kLogModule[] = "ManagedNetworkConfigurationHandler"; | 66 const char kLogModule[] = "ManagedNetworkConfigurationHandler"; |
| 46 | 67 |
| 47 // These are error strings used for error callbacks. None of these error | 68 // These are error strings used for error callbacks. None of these error |
| 48 // messages are user-facing: they should only appear in logs. | 69 // messages are user-facing: they should only appear in logs. |
| 49 const char kInvalidUserSettingsMessage[] = "User settings are invalid."; | 70 const char kInvalidUserSettingsMessage[] = "User settings are invalid."; |
| 50 const char kInvalidUserSettings[] = "Error.InvalidUserSettings"; | 71 const char kInvalidUserSettings[] = "Error.InvalidUserSettings"; |
| 51 const char kNetworkAlreadyConfiguredMessage[] = | 72 const char kNetworkAlreadyConfiguredMessage[] = |
| 52 "Network is already configured."; | 73 "Network is already configured."; |
| 53 const char kNetworkAlreadyConfigured[] = "Error.NetworkAlreadyConfigured"; | 74 const char kNetworkAlreadyConfigured[] = "Error.NetworkAlreadyConfigured"; |
| 54 const char kPoliciesNotInitializedMessage[] = "Policies not initialized."; | 75 const char kPoliciesNotInitializedMessage[] = "Policies not initialized."; |
| 55 const char kPoliciesNotInitialized[] = "Error.PoliciesNotInitialized"; | 76 const char kPoliciesNotInitialized[] = "Error.PoliciesNotInitialized"; |
| 77 const char kProfileNotInitializedMessage[] = "Profile not initialized."; | |
| 78 const char kProfileNotInitialized[] = "Error.ProflieNotInitialized"; | |
| 56 const char kServicePath[] = "servicePath"; | 79 const char kServicePath[] = "servicePath"; |
| 57 const char kSetOnUnconfiguredNetworkMessage[] = | 80 const char kSetOnUnconfiguredNetworkMessage[] = |
| 58 "Unable to modify properties of an unconfigured network."; | 81 "Unable to modify properties of an unconfigured network."; |
| 59 const char kSetOnUnconfiguredNetwork[] = "Error.SetCalledOnUnconfiguredNetwork"; | 82 const char kSetOnUnconfiguredNetwork[] = "Error.SetCalledOnUnconfiguredNetwork"; |
| 60 const char kUIDataErrorMessage[] = "UI data contains errors."; | 83 const char kUIDataErrorMessage[] = "UI data contains errors."; |
| 61 const char kUIDataError[] = "Error.UIData"; | 84 const char kUIDataError[] = "Error.UIData"; |
| 85 const char kUnknownProfilePathMessage[] = "Profile path is unknown."; | |
| 86 const char kUnknownProfilePath[] = "Error.UnknownProfilePath"; | |
| 62 const char kUnknownServicePathMessage[] = "Service path is unknown."; | 87 const char kUnknownServicePathMessage[] = "Service path is unknown."; |
| 63 const char kUnknownServicePath[] = "Error.UnknownServicePath"; | 88 const char kUnknownServicePath[] = "Error.UnknownServicePath"; |
| 64 | 89 |
| 65 enum ProfileType { | |
| 66 PROFILE_NONE, // Not in any profile. | |
| 67 PROFILE_SHARED, // In the shared profile, shared by all users on device. | |
| 68 PROFILE_USER // In the user profile, not visible to other users. | |
| 69 }; | |
| 70 | |
| 71 const char kSharedProfilePath[] = "/profile/default"; | |
| 72 const char kUserProfilePath[] = "/profile/chronos/shill"; | |
| 73 | |
| 74 // This fake credential contains a random postfix which is extremly unlikely to | 90 // This fake credential contains a random postfix which is extremly unlikely to |
| 75 // be used by any user. | 91 // be used by any user. |
| 76 const char kFakeCredential[] = "FAKE_CREDENTIAL_VPaJDV9x"; | 92 const char kFakeCredential[] = "FAKE_CREDENTIAL_VPaJDV9x"; |
| 77 | 93 |
| 94 std::string PolicySource(onc::ONCSource source, | |
| 95 const std::string& userhash) { | |
| 96 return source == onc::ONC_SOURCE_USER_POLICY ? | |
| 97 ("user policy of " + userhash) : "device policy"; | |
| 98 } | |
|
stevenjb
2013/04/26 21:00:49
Is this only for logging? If so, name it appropria
pneubeck (no reviews)
2013/04/29 18:05:51
Done.
| |
| 99 | |
| 78 void RunErrorCallback(const std::string& service_path, | 100 void RunErrorCallback(const std::string& service_path, |
| 79 const std::string& error_name, | 101 const std::string& error_name, |
| 80 const std::string& error_message, | 102 const std::string& error_message, |
| 81 const network_handler::ErrorCallback& error_callback) { | 103 const network_handler::ErrorCallback& error_callback) { |
| 82 network_event_log::AddEntry(kLogModule, error_name, error_message); | 104 network_event_log::AddEntry(kLogModule, error_name, error_message); |
| 83 error_callback.Run( | 105 error_callback.Run( |
| 84 error_name, | 106 error_name, |
| 85 make_scoped_ptr( | 107 make_scoped_ptr( |
| 86 network_handler::CreateErrorData(service_path, | 108 network_handler::CreateErrorData(service_path, |
| 87 error_name, | 109 error_name, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 // value to overwrite whatever is stored in Shill. | 197 // value to overwrite whatever is stored in Shill. |
| 176 } | 198 } |
| 177 } | 199 } |
| 178 } | 200 } |
| 179 | 201 |
| 180 // Creates a Shill property dictionary from the given arguments. The resulting | 202 // Creates a Shill property dictionary from the given arguments. The resulting |
| 181 // dictionary will be sent to Shill by the caller. Depending on the profile | 203 // dictionary will be sent to Shill by the caller. Depending on the profile |
| 182 // path, |policy| is interpreted as the user or device policy and |settings| as | 204 // path, |policy| is interpreted as the user or device policy and |settings| as |
| 183 // the user or shared settings. | 205 // the user or shared settings. |
| 184 scoped_ptr<base::DictionaryValue> CreateShillConfiguration( | 206 scoped_ptr<base::DictionaryValue> CreateShillConfiguration( |
| 185 const std::string& profile_path, | 207 const NetworkProfile& profile, |
| 186 const std::string& guid, | 208 const std::string& guid, |
| 187 const base::DictionaryValue* policy, | 209 const base::DictionaryValue* policy, |
| 188 const base::DictionaryValue* settings) { | 210 const base::DictionaryValue* settings) { |
| 189 scoped_ptr<base::DictionaryValue> effective; | 211 scoped_ptr<base::DictionaryValue> effective; |
| 190 | |
| 191 onc::ONCSource onc_source; | 212 onc::ONCSource onc_source; |
| 192 if (policy) { | 213 if (policy) { |
| 193 if (profile_path == kSharedProfilePath) { | 214 switch (profile.type()) { |
| 194 effective = onc::MergeSettingsAndPoliciesToEffective( | 215 case NetworkProfile::TYPE_SHARED: { |
| 195 NULL, // no user policy | 216 effective = onc::MergeSettingsAndPoliciesToEffective( |
| 196 policy, // device policy | 217 NULL, // no user policy |
| 197 NULL, // no user settings | 218 policy, // device policy |
| 198 settings); // shared settings | 219 NULL, // no user settings |
| 199 onc_source = onc::ONC_SOURCE_DEVICE_POLICY; | 220 settings); // shared settings |
| 200 } else { | 221 onc_source = onc::ONC_SOURCE_DEVICE_POLICY; |
| 201 effective = onc::MergeSettingsAndPoliciesToEffective( | 222 break; |
| 202 policy, // user policy | 223 } |
| 203 NULL, // no device policy | 224 case NetworkProfile::TYPE_USER: { |
| 204 settings, // user settings | 225 effective = onc::MergeSettingsAndPoliciesToEffective( |
| 205 NULL); // no shared settings | 226 policy, // user policy |
| 206 onc_source = onc::ONC_SOURCE_USER_POLICY; | 227 NULL, // no device policy |
| 228 settings, // user settings | |
| 229 NULL); // no shared settings | |
| 230 onc_source = onc::ONC_SOURCE_USER_POLICY; | |
| 231 break; | |
| 232 } | |
|
stevenjb
2013/04/26 21:00:49
nit: I tend to prefer if() over case for complex c
pneubeck (no reviews)
2013/04/29 18:05:51
Done.
| |
| 207 } | 233 } |
| 208 } else if (settings) { | 234 } else if (settings) { |
| 209 effective.reset(settings->DeepCopy()); | 235 effective.reset(settings->DeepCopy()); |
| 210 // TODO(pneubeck): change to source ONC_SOURCE_USER | 236 // TODO(pneubeck): change to source ONC_SOURCE_USER |
| 211 onc_source = onc::ONC_SOURCE_NONE; | 237 onc_source = onc::ONC_SOURCE_NONE; |
| 212 } else { | 238 } else { |
| 213 NOTREACHED(); | 239 NOTREACHED(); |
| 214 onc_source = onc::ONC_SOURCE_NONE; | 240 onc_source = onc::ONC_SOURCE_NONE; |
| 215 } | 241 } |
| 216 | 242 |
| 217 RemoveFakeCredentials(onc::kNetworkConfigurationSignature, | 243 RemoveFakeCredentials(onc::kNetworkConfigurationSignature, |
| 218 effective.get()); | 244 effective.get()); |
| 219 | 245 |
| 220 effective->SetStringWithoutPathExpansion(onc::network_config::kGUID, guid); | 246 effective->SetStringWithoutPathExpansion(onc::network_config::kGUID, guid); |
| 221 | 247 |
| 222 scoped_ptr<base::DictionaryValue> shill_dictionary( | 248 scoped_ptr<base::DictionaryValue> shill_dictionary( |
| 223 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, | 249 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, |
| 224 *effective)); | 250 *effective)); |
| 225 | 251 |
| 226 shill_dictionary->SetStringWithoutPathExpansion(flimflam::kProfileProperty, | 252 shill_dictionary->SetStringWithoutPathExpansion(flimflam::kProfileProperty, |
| 227 profile_path); | 253 profile.path); |
| 228 | 254 |
| 229 scoped_ptr<NetworkUIData> ui_data; | 255 scoped_ptr<NetworkUIData> ui_data; |
| 230 if (policy) | 256 if (policy) |
| 231 ui_data = CreateUIDataFromONC(onc_source, *policy); | 257 ui_data = CreateUIDataFromONC(onc_source, *policy); |
| 232 else | 258 else |
| 233 ui_data.reset(new NetworkUIData()); | 259 ui_data.reset(new NetworkUIData()); |
| 234 | 260 |
| 235 if (settings) { | 261 if (settings) { |
| 236 // Shill doesn't know that sensitive data is contained in the UIData | 262 // Shill doesn't know that sensitive data is contained in the UIData |
| 237 // property and might write it into logs or other insecure places. Thus, we | 263 // property and might write it into logs or other insecure places. Thus, we |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 policy.GetStringWithoutPathExpansion(onc::wifi::kSSID, &policy_ssid); | 302 policy.GetStringWithoutPathExpansion(onc::wifi::kSSID, &policy_ssid); |
| 277 std::string network_ssid; | 303 std::string network_ssid; |
| 278 onc_network_part.GetStringWithoutPathExpansion(onc::wifi::kSSID, | 304 onc_network_part.GetStringWithoutPathExpansion(onc::wifi::kSSID, |
| 279 &network_ssid); | 305 &network_ssid); |
| 280 return (policy_ssid == network_ssid); | 306 return (policy_ssid == network_ssid); |
| 281 } | 307 } |
| 282 | 308 |
| 283 // Returns the policy of |policies| matching |onc_network_part|, if any | 309 // Returns the policy of |policies| matching |onc_network_part|, if any |
| 284 // exists. Returns NULL otherwise. | 310 // exists. Returns NULL otherwise. |
| 285 const base::DictionaryValue* FindMatchingPolicy( | 311 const base::DictionaryValue* FindMatchingPolicy( |
| 286 const ManagedNetworkConfigurationHandler::PolicyMap &policies, | 312 const ManagedNetworkConfigurationHandler::Policies &policies, |
| 287 const base::DictionaryValue& onc_network_part) { | 313 const base::DictionaryValue& onc_network_part) { |
| 288 for (ManagedNetworkConfigurationHandler::PolicyMap::const_iterator it = | 314 for (ManagedNetworkConfigurationHandler::Policies::Map::const_iterator it = |
| 289 policies.begin(); it != policies.end(); ++it) { | 315 policies.map.begin(); it != policies.map.end(); ++it) { |
| 290 if (IsPolicyMatching(*it->second, onc_network_part)) | 316 if (IsPolicyMatching(*it->second, onc_network_part)) |
| 291 return it->second; | 317 return it->second; |
| 292 } | 318 } |
| 293 return NULL; | 319 return NULL; |
| 294 } | 320 } |
| 295 | 321 |
| 296 void TranslatePropertiesToOncAndRunCallback( | 322 void TranslatePropertiesToOncAndRunCallback( |
| 297 const network_handler::DictionaryResultCallback& callback, | 323 const network_handler::DictionaryResultCallback& callback, |
| 298 const std::string& service_path, | 324 const std::string& service_path, |
| 299 const base::DictionaryValue& shill_properties) { | 325 const base::DictionaryValue& shill_properties) { |
| 300 scoped_ptr<base::DictionaryValue> onc_network( | 326 scoped_ptr<base::DictionaryValue> onc_network( |
| 301 onc::TranslateShillServiceToONCPart( | 327 onc::TranslateShillServiceToONCPart( |
| 302 shill_properties, | 328 shill_properties, |
| 303 &onc::kNetworkWithStateSignature)); | 329 &onc::kNetworkWithStateSignature)); |
| 304 callback.Run(service_path, *onc_network); | 330 callback.Run(service_path, *onc_network); |
| 305 } | 331 } |
| 306 | 332 |
| 307 } // namespace | 333 } // namespace |
| 308 | 334 |
| 309 // static | 335 // static |
| 310 void ManagedNetworkConfigurationHandler::Initialize() { | 336 void ManagedNetworkConfigurationHandler::Initialize( |
| 337 NetworkProfileHandler* profile_handler) { | |
| 311 CHECK(!g_configuration_handler_instance); | 338 CHECK(!g_configuration_handler_instance); |
| 312 g_configuration_handler_instance = new ManagedNetworkConfigurationHandler; | 339 g_configuration_handler_instance = |
| 340 new ManagedNetworkConfigurationHandler(profile_handler); | |
| 313 } | 341 } |
| 314 | 342 |
| 315 // static | 343 // static |
| 316 bool ManagedNetworkConfigurationHandler::IsInitialized() { | 344 bool ManagedNetworkConfigurationHandler::IsInitialized() { |
| 317 return g_configuration_handler_instance; | 345 return g_configuration_handler_instance; |
| 318 } | 346 } |
| 319 | 347 |
| 320 // static | 348 // static |
| 321 void ManagedNetworkConfigurationHandler::Shutdown() { | 349 void ManagedNetworkConfigurationHandler::Shutdown() { |
| 322 CHECK(g_configuration_handler_instance); | 350 CHECK(g_configuration_handler_instance); |
| 323 delete g_configuration_handler_instance; | 351 delete g_configuration_handler_instance; |
| 324 g_configuration_handler_instance = NULL; | 352 g_configuration_handler_instance = NULL; |
| 325 } | 353 } |
| 326 | 354 |
| 327 // static | 355 // static |
| 328 ManagedNetworkConfigurationHandler* ManagedNetworkConfigurationHandler::Get() { | 356 ManagedNetworkConfigurationHandler* ManagedNetworkConfigurationHandler::Get() { |
| 329 CHECK(g_configuration_handler_instance); | 357 CHECK(g_configuration_handler_instance); |
| 330 return g_configuration_handler_instance; | 358 return g_configuration_handler_instance; |
| 331 } | 359 } |
| 332 | 360 |
| 333 void ManagedNetworkConfigurationHandler::GetManagedProperties( | 361 void ManagedNetworkConfigurationHandler::GetManagedProperties( |
| 362 const std::string& userhash, | |
| 334 const std::string& service_path, | 363 const std::string& service_path, |
| 335 const network_handler::DictionaryResultCallback& callback, | 364 const network_handler::DictionaryResultCallback& callback, |
| 336 const network_handler::ErrorCallback& error_callback) { | 365 const network_handler::ErrorCallback& error_callback) { |
| 337 if (!user_policies_initialized_ || !device_policies_initialized_) { | 366 if (!GetPoliciesForUser(userhash) || !GetPoliciesForUser(std::string())) { |
| 338 RunErrorCallback(service_path, | 367 RunErrorCallback(service_path, |
| 339 kPoliciesNotInitialized, | 368 kPoliciesNotInitialized, |
| 340 kPoliciesNotInitializedMessage, | 369 kPoliciesNotInitializedMessage, |
| 341 error_callback); | 370 error_callback); |
| 342 return; | 371 return; |
| 343 } | 372 } |
| 344 NetworkConfigurationHandler::Get()->GetProperties( | 373 NetworkConfigurationHandler::Get()->GetProperties( |
| 345 service_path, | 374 service_path, |
| 346 base::Bind( | 375 base::Bind( |
| 347 &ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback, | 376 &ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback, |
| 348 weak_ptr_factory_.GetWeakPtr(), | 377 weak_ptr_factory_.GetWeakPtr(), |
| 349 callback, | 378 callback, |
| 350 error_callback), | 379 error_callback), |
| 351 error_callback); | 380 error_callback); |
| 352 } | 381 } |
| 353 | 382 |
| 354 void ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback( | 383 void ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback( |
| 355 const network_handler::DictionaryResultCallback& callback, | 384 const network_handler::DictionaryResultCallback& callback, |
| 356 const network_handler::ErrorCallback& error_callback, | 385 const network_handler::ErrorCallback& error_callback, |
| 357 const std::string& service_path, | 386 const std::string& service_path, |
| 358 const base::DictionaryValue& shill_properties) { | 387 const base::DictionaryValue& shill_properties) { |
| 359 std::string profile_path; | 388 std::string profile_path; |
| 360 ProfileType profile_type = PROFILE_NONE; | 389 shill_properties.GetStringWithoutPathExpansion(flimflam::kProfileProperty, |
| 361 if (shill_properties.GetStringWithoutPathExpansion( | 390 &profile_path); |
| 362 flimflam::kProfileProperty, &profile_path)) { | 391 const NetworkProfile* profile = |
| 363 if (profile_path == kSharedProfilePath) | 392 profile_handler_->GetProfileForPath(profile_path); |
| 364 profile_type = PROFILE_SHARED; | 393 if (!profile) { |
| 365 else if (!profile_path.empty()) | 394 VLOG(1) << "No or no known profile received for service " |
| 366 profile_type = PROFILE_USER; | 395 << service_path << "."; |
| 367 } else { | |
| 368 VLOG(1) << "No profile path for service " << service_path << "."; | |
| 369 } | 396 } |
| 370 | 397 |
| 371 scoped_ptr<NetworkUIData> ui_data = GetUIData(shill_properties); | 398 scoped_ptr<NetworkUIData> ui_data = GetUIData(shill_properties); |
| 372 | 399 |
| 373 const base::DictionaryValue* user_settings = NULL; | 400 const base::DictionaryValue* user_settings = NULL; |
| 374 const base::DictionaryValue* shared_settings = NULL; | 401 const base::DictionaryValue* shared_settings = NULL; |
| 375 | 402 |
| 376 if (ui_data) { | 403 if (ui_data && profile) { |
| 377 if (profile_type == PROFILE_SHARED) | 404 switch (profile->type()) { |
| 378 shared_settings = ui_data->user_settings(); | 405 case NetworkProfile::TYPE_SHARED: |
| 379 else if (profile_type == PROFILE_USER) | 406 shared_settings = ui_data->user_settings(); |
| 380 user_settings = ui_data->user_settings(); | 407 break; |
| 381 } else if (profile_type != PROFILE_NONE) { | 408 case NetworkProfile::TYPE_USER: |
| 409 user_settings = ui_data->user_settings(); | |
| 410 break; | |
| 411 } | |
|
stevenjb
2013/04/26 21:00:49
nit: Again, even though it's less complex, if/else
pneubeck (no reviews)
2013/04/29 18:05:51
Done.
| |
| 412 } else if (profile) { | |
| 382 LOG(WARNING) << "Service " << service_path << " of profile " | 413 LOG(WARNING) << "Service " << service_path << " of profile " |
| 383 << profile_path << " contains no or no valid UIData."; | 414 << profile_path << " contains no or no valid UIData."; |
| 384 // TODO(pneubeck): add a conversion of user configured entries of old | 415 // TODO(pneubeck): add a conversion of user configured entries of old |
| 385 // ChromeOS versions. We will have to use a heuristic to determine which | 416 // ChromeOS versions. We will have to use a heuristic to determine which |
| 386 // properties _might_ be user configured. | 417 // properties _might_ be user configured. |
| 387 } | 418 } |
| 388 | 419 |
| 389 scoped_ptr<base::DictionaryValue> active_settings( | 420 scoped_ptr<base::DictionaryValue> active_settings( |
| 390 onc::TranslateShillServiceToONCPart( | 421 onc::TranslateShillServiceToONCPart( |
| 391 shill_properties, | 422 shill_properties, |
| 392 &onc::kNetworkWithStateSignature)); | 423 &onc::kNetworkWithStateSignature)); |
| 393 | 424 |
| 394 std::string guid; | 425 std::string guid; |
| 395 active_settings->GetStringWithoutPathExpansion(onc::network_config::kGUID, | 426 active_settings->GetStringWithoutPathExpansion(onc::network_config::kGUID, |
| 396 &guid); | 427 &guid); |
| 397 | 428 |
| 398 const base::DictionaryValue* user_policy = NULL; | 429 const base::DictionaryValue* user_policy = NULL; |
| 399 const base::DictionaryValue* device_policy = NULL; | 430 const base::DictionaryValue* device_policy = NULL; |
| 400 if (!guid.empty()) { | 431 if (!guid.empty() && profile) { |
| 401 // We already checked that the policies were initialized. No need to do that | 432 const Policies* policies = GetPoliciesForProfile(*profile); |
| 402 // again. | 433 if (!policies) { |
| 403 if (profile_type == PROFILE_SHARED) | 434 RunErrorCallback(service_path, |
| 404 device_policy = device_policies_by_guid_[guid]; | 435 kPoliciesNotInitialized, |
| 405 else if (profile_type == PROFILE_USER) | 436 kPoliciesNotInitializedMessage, |
| 406 user_policy = user_policies_by_guid_[guid]; | 437 error_callback); |
| 438 return; | |
| 439 } | |
| 440 const base::DictionaryValue* policy = policies->GetByGUID(guid); | |
| 441 switch (profile->type()) { | |
| 442 case NetworkProfile::TYPE_SHARED: | |
| 443 device_policy = policy; | |
| 444 break; | |
| 445 case NetworkProfile::TYPE_USER: | |
| 446 user_policy = policy; | |
| 447 break; | |
|
stevenjb
2013/04/26 21:00:49
nit: ditto
pneubeck (no reviews)
2013/04/29 18:05:51
Done.
| |
| 448 } | |
| 407 } | 449 } |
| 408 | 450 |
| 409 // This call also removes credentials from policies. | 451 // This call also removes credentials from policies. |
| 410 scoped_ptr<base::DictionaryValue> augmented_properties = | 452 scoped_ptr<base::DictionaryValue> augmented_properties = |
| 411 onc::MergeSettingsAndPoliciesToAugmented( | 453 onc::MergeSettingsAndPoliciesToAugmented( |
| 412 onc::kNetworkConfigurationSignature, | 454 onc::kNetworkConfigurationSignature, |
| 413 user_policy, | 455 user_policy, |
| 414 device_policy, | 456 device_policy, |
| 415 user_settings, | 457 user_settings, |
| 416 shared_settings, | 458 shared_settings, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 449 // TODO(pneubeck): create an initial configuration in this case. As for | 491 // TODO(pneubeck): create an initial configuration in this case. As for |
| 450 // CreateConfiguration, user settings from older ChromeOS versions have to | 492 // CreateConfiguration, user settings from older ChromeOS versions have to |
| 451 // determined here. | 493 // determined here. |
| 452 RunErrorCallback(service_path, | 494 RunErrorCallback(service_path, |
| 453 kSetOnUnconfiguredNetwork, | 495 kSetOnUnconfiguredNetwork, |
| 454 kSetOnUnconfiguredNetworkMessage, | 496 kSetOnUnconfiguredNetworkMessage, |
| 455 error_callback); | 497 error_callback); |
| 456 return; | 498 return; |
| 457 } | 499 } |
| 458 | 500 |
| 501 const std::string& profile_path = state->profile_path(); | |
| 502 const NetworkProfile *profile = | |
| 503 profile_handler_->GetProfileForPath(profile_path); | |
| 504 if (!profile) { | |
| 505 RunErrorCallback(service_path, | |
| 506 kUnknownProfilePath, | |
| 507 kUnknownProfilePathMessage, | |
| 508 error_callback); | |
| 509 return; | |
| 510 } | |
| 511 | |
| 512 VLOG(2) << "SetProperties: Found GUID " << guid << " and profile " | |
| 513 << ProfileToString(profile); | |
| 514 | |
| 515 const Policies* policies = GetPoliciesForProfile(*profile); | |
| 516 if (!policies) { | |
| 517 RunErrorCallback(service_path, | |
| 518 kPoliciesNotInitialized, | |
| 519 kPoliciesNotInitializedMessage, | |
| 520 error_callback); | |
| 521 return; | |
| 522 } | |
| 523 | |
| 459 // Validate the ONC dictionary. We are liberal and ignore unknown field | 524 // Validate the ONC dictionary. We are liberal and ignore unknown field |
| 460 // names. User settings are only partial ONC, thus we ignore missing fields. | 525 // names. User settings are only partial ONC, thus we ignore missing fields. |
| 461 onc::Validator validator(false, // Ignore unknown fields. | 526 onc::Validator validator(false, // Ignore unknown fields. |
| 462 false, // Ignore invalid recommended field names. | 527 false, // Ignore invalid recommended field names. |
| 463 false, // Ignore missing fields. | 528 false, // Ignore missing fields. |
| 464 false); // This ONC does not comes from policy. | 529 false); // This ONC does not comes from policy. |
| 465 | 530 |
| 466 onc::Validator::Result validation_result; | 531 onc::Validator::Result validation_result; |
| 467 scoped_ptr<base::DictionaryValue> validated_user_settings = | 532 scoped_ptr<base::DictionaryValue> validated_user_settings = |
| 468 validator.ValidateAndRepairObject( | 533 validator.ValidateAndRepairObject( |
| 469 &onc::kNetworkConfigurationSignature, | 534 &onc::kNetworkConfigurationSignature, |
| 470 user_settings, | 535 user_settings, |
| 471 &validation_result); | 536 &validation_result); |
| 472 | 537 |
| 473 if (validation_result == onc::Validator::INVALID) { | 538 if (validation_result == onc::Validator::INVALID) { |
| 474 LOG(ERROR) << "ONC user settings are invalid and couldn't be repaired."; | |
| 475 RunErrorCallback(service_path, | 539 RunErrorCallback(service_path, |
| 476 kInvalidUserSettings, | 540 kInvalidUserSettings, |
| 477 kInvalidUserSettingsMessage, | 541 kInvalidUserSettingsMessage, |
| 478 error_callback); | 542 error_callback); |
| 479 return; | 543 return; |
| 480 } | 544 } |
| 481 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) | 545 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) |
| 482 LOG(WARNING) << "Validation of ONC user settings produced warnings."; | 546 LOG(WARNING) << "Validation of ONC user settings produced warnings."; |
| 483 | 547 |
| 484 VLOG(2) << "SetProperties: Found GUID " << guid << " and profile " | 548 const base::DictionaryValue* policy = policies->GetByGUID(guid); |
| 485 << state->profile_path(); | |
| 486 | |
| 487 const PolicyMap* policies_by_guid = | |
| 488 GetPoliciesForProfile(state->profile_path()); | |
| 489 | |
| 490 if (!policies_by_guid) { | |
| 491 RunErrorCallback(service_path, | |
| 492 kPoliciesNotInitialized, | |
| 493 kPoliciesNotInitializedMessage, | |
| 494 error_callback); | |
| 495 return; | |
| 496 } | |
| 497 | |
| 498 const base::DictionaryValue* policy = NULL; | |
| 499 PolicyMap::const_iterator it = policies_by_guid->find(guid); | |
| 500 if (it != policies_by_guid->end()) | |
| 501 policy = it->second; | |
| 502 | |
| 503 VLOG(2) << "This configuration is " << (policy ? "" : "not ") << "managed."; | 549 VLOG(2) << "This configuration is " << (policy ? "" : "not ") << "managed."; |
| 504 | 550 |
| 505 scoped_ptr<base::DictionaryValue> shill_dictionary( | 551 scoped_ptr<base::DictionaryValue> shill_dictionary( |
| 506 CreateShillConfiguration(state->profile_path(), guid, policy, | 552 CreateShillConfiguration(*profile, guid, policy, &user_settings)); |
| 507 &user_settings)); | |
| 508 | 553 |
| 509 NetworkConfigurationHandler::Get()->SetProperties(service_path, | 554 NetworkConfigurationHandler::Get()->SetProperties(service_path, |
| 510 *shill_dictionary, | 555 *shill_dictionary, |
| 511 callback, | 556 callback, |
| 512 error_callback); | 557 error_callback); |
| 513 } | 558 } |
| 514 | 559 |
| 515 void ManagedNetworkConfigurationHandler::Connect( | 560 void ManagedNetworkConfigurationHandler::Connect( |
| 516 const std::string& service_path, | 561 const std::string& service_path, |
| 517 const base::Closure& callback, | 562 const base::Closure& callback, |
| 518 const network_handler::ErrorCallback& error_callback) const { | 563 const network_handler::ErrorCallback& error_callback) const { |
| 519 NetworkConfigurationHandler::Get()->Connect(service_path, | 564 NetworkConfigurationHandler::Get()->Connect(service_path, |
| 520 callback, | 565 callback, |
| 521 error_callback); | 566 error_callback); |
| 522 } | 567 } |
| 523 | 568 |
| 524 void ManagedNetworkConfigurationHandler::Disconnect( | 569 void ManagedNetworkConfigurationHandler::Disconnect( |
| 525 const std::string& service_path, | 570 const std::string& service_path, |
| 526 const base::Closure& callback, | 571 const base::Closure& callback, |
| 527 const network_handler::ErrorCallback& error_callback) const { | 572 const network_handler::ErrorCallback& error_callback) const { |
| 528 NetworkConfigurationHandler::Get()->Disconnect(service_path, | 573 NetworkConfigurationHandler::Get()->Disconnect(service_path, |
| 529 callback, | 574 callback, |
| 530 error_callback); | 575 error_callback); |
| 531 } | 576 } |
| 532 | 577 |
| 533 void ManagedNetworkConfigurationHandler::CreateConfiguration( | 578 void ManagedNetworkConfigurationHandler::CreateConfiguration( |
| 579 const std::string& userhash, | |
| 534 const base::DictionaryValue& properties, | 580 const base::DictionaryValue& properties, |
| 535 const network_handler::StringResultCallback& callback, | 581 const network_handler::StringResultCallback& callback, |
| 536 const network_handler::ErrorCallback& error_callback) const { | 582 const network_handler::ErrorCallback& error_callback) const { |
| 537 std::string profile_path = kUserProfilePath; | 583 const Policies* policies = GetPoliciesForUser(userhash); |
| 538 const PolicyMap* policies_by_guid = GetPoliciesForProfile(profile_path); | 584 if (!policies) { |
| 539 | |
| 540 if (!policies_by_guid) { | |
| 541 RunErrorCallback("", | 585 RunErrorCallback("", |
| 542 kPoliciesNotInitialized, | 586 kPoliciesNotInitialized, |
| 543 kPoliciesNotInitializedMessage, | 587 kPoliciesNotInitializedMessage, |
| 544 error_callback); | 588 error_callback); |
| 545 return; | 589 return; |
| 546 } | 590 } |
| 547 | 591 |
| 548 if (FindMatchingPolicy(*policies_by_guid, properties)) { | 592 if (FindMatchingPolicy(*policies, properties)) { |
| 549 RunErrorCallback("", | 593 RunErrorCallback("", |
| 550 kNetworkAlreadyConfigured, | 594 kNetworkAlreadyConfigured, |
| 551 kNetworkAlreadyConfiguredMessage, | 595 kNetworkAlreadyConfiguredMessage, |
| 552 error_callback); | 596 error_callback); |
| 553 } | 597 } |
| 554 | 598 |
| 599 const NetworkProfile* profile = | |
| 600 profile_handler_->GetProfileForUserhash(userhash); | |
| 601 if (!profile) { | |
| 602 RunErrorCallback("", | |
| 603 kProfileNotInitialized, | |
| 604 kProfileNotInitializedMessage, | |
| 605 error_callback); | |
| 606 } | |
| 607 | |
| 555 // TODO(pneubeck): In case of WiFi, check that no other configuration for the | 608 // TODO(pneubeck): In case of WiFi, check that no other configuration for the |
| 556 // same {SSID, mode, security} exists. We don't support such multiple | 609 // same {SSID, mode, security} exists. We don't support such multiple |
| 557 // configurations, yet. | 610 // configurations, yet. |
| 558 | 611 |
| 559 // Generate a new GUID for this configuration. Ignore the maybe provided GUID | 612 // Generate a new GUID for this configuration. Ignore the maybe provided GUID |
| 560 // in |properties| as it is not our own and from an untrusted source. | 613 // in |properties| as it is not our own and from an untrusted source. |
| 561 std::string guid = base::GenerateGUID(); | 614 std::string guid = base::GenerateGUID(); |
| 562 | |
| 563 scoped_ptr<base::DictionaryValue> shill_dictionary( | 615 scoped_ptr<base::DictionaryValue> shill_dictionary( |
| 564 CreateShillConfiguration(profile_path, guid, NULL /*no policy*/, | 616 CreateShillConfiguration(*profile, guid, NULL /*no policy*/, |
| 565 &properties)); | 617 &properties)); |
| 566 | 618 |
| 567 NetworkConfigurationHandler::Get()->CreateConfiguration(*shill_dictionary, | 619 NetworkConfigurationHandler::Get()->CreateConfiguration(*shill_dictionary, |
| 568 callback, | 620 callback, |
| 569 error_callback); | 621 error_callback); |
| 570 } | 622 } |
| 571 | 623 |
| 572 void ManagedNetworkConfigurationHandler::RemoveConfiguration( | 624 void ManagedNetworkConfigurationHandler::RemoveConfiguration( |
| 573 const std::string& service_path, | 625 const std::string& service_path, |
| 574 const base::Closure& callback, | 626 const base::Closure& callback, |
| 575 const network_handler::ErrorCallback& error_callback) const { | 627 const network_handler::ErrorCallback& error_callback) const { |
| 576 NetworkConfigurationHandler::Get()->RemoveConfiguration(service_path, | 628 NetworkConfigurationHandler::Get()->RemoveConfiguration(service_path, |
| 577 callback, | 629 callback, |
| 578 error_callback); | 630 error_callback); |
| 579 } | 631 } |
| 580 | 632 |
| 581 // This class compares (entry point is Run()) |modified_policies| with the | 633 // This class compares (entry point is Run()) |modified_policies| with the |
| 582 // existing entries in the provided Shill profile |profile|. It fetches all | 634 // existing entries in the provided Shill profile |profile|. It fetches all |
| 583 // entries in parallel (GetProfileProperties), compares each entry with the | 635 // entries in parallel (GetProfileProperties), compares each entry with the |
| 584 // current policies (GetEntry) and adds all missing policies | 636 // current policies (GetEntry) and adds all missing policies |
| 585 // (~PolicyApplicator). | 637 // (~PolicyApplicator). |
| 586 class ManagedNetworkConfigurationHandler::PolicyApplicator | 638 class ManagedNetworkConfigurationHandler::PolicyApplicator |
| 587 : public base::RefCounted<PolicyApplicator> { | 639 : public base::RefCounted<PolicyApplicator> { |
| 588 public: | 640 public: |
| 589 typedef ManagedNetworkConfigurationHandler::PolicyMap PolicyMap; | 641 typedef ManagedNetworkConfigurationHandler::Policies Policies; |
| 590 | 642 |
| 591 // |modified_policies| must not be NULL and will be empty afterwards. | 643 // |modified_policies| must not be NULL and will be empty afterwards. |
| 592 PolicyApplicator(base::WeakPtr<ManagedNetworkConfigurationHandler> handler, | 644 PolicyApplicator(base::WeakPtr<ManagedNetworkConfigurationHandler> handler, |
| 593 const std::string& profile, | 645 const NetworkProfile& profile, |
| 594 std::set<std::string>* modified_policies) | 646 std::set<std::string>* modified_policies) |
| 595 : handler_(handler), | 647 : handler_(handler), |
| 596 profile_path_(profile) { | 648 profile_(profile) { |
| 597 remaining_policies_.swap(*modified_policies); | 649 remaining_policies_.swap(*modified_policies); |
| 598 } | 650 } |
| 599 | 651 |
| 600 void Run() { | 652 void Run() { |
| 601 DBusThreadManager::Get()->GetShillProfileClient()->GetProperties( | 653 DBusThreadManager::Get()->GetShillProfileClient()->GetProperties( |
| 602 dbus::ObjectPath(profile_path_), | 654 dbus::ObjectPath(profile_.path), |
| 603 base::Bind(&PolicyApplicator::GetProfileProperties, this), | 655 base::Bind(&PolicyApplicator::GetProfileProperties, this), |
| 604 base::Bind(&LogErrorMessage, FROM_HERE)); | 656 base::Bind(&LogErrorMessage, FROM_HERE)); |
| 605 } | 657 } |
| 606 | 658 |
| 607 private: | 659 private: |
| 608 friend class base::RefCounted<PolicyApplicator>; | 660 friend class base::RefCounted<PolicyApplicator>; |
| 609 | 661 |
| 610 void GetProfileProperties(const base::DictionaryValue& profile_properties) { | 662 void GetProfileProperties(const base::DictionaryValue& profile_properties) { |
| 611 if (!handler_) { | 663 if (!handler_) { |
| 612 LOG(WARNING) << "Handler destructed during policy application to profile " | 664 LOG(WARNING) << "Handler destructed during policy application to profile " |
| 613 << profile_path_; | 665 << ProfileToString(&profile_); |
| 614 return; | 666 return; |
| 615 } | 667 } |
| 616 | 668 |
| 617 VLOG(2) << "Received properties for profile " << profile_path_; | 669 VLOG(2) << "Received properties for profile " << ProfileToString(&profile_); |
| 618 const base::ListValue* entries = NULL; | 670 const base::ListValue* entries = NULL; |
| 619 if (!profile_properties.GetListWithoutPathExpansion( | 671 if (!profile_properties.GetListWithoutPathExpansion( |
| 620 flimflam::kEntriesProperty, &entries)) { | 672 flimflam::kEntriesProperty, &entries)) { |
| 621 LOG(ERROR) << "Profile " << profile_path_ | 673 LOG(ERROR) << "Profile " << ProfileToString(&profile_) |
| 622 << " doesn't contain the property " | 674 << " doesn't contain the property " |
| 623 << flimflam::kEntriesProperty; | 675 << flimflam::kEntriesProperty; |
| 624 return; | 676 return; |
| 625 } | 677 } |
| 626 | 678 |
| 627 for (base::ListValue::const_iterator it = entries->begin(); | 679 for (base::ListValue::const_iterator it = entries->begin(); |
| 628 it != entries->end(); ++it) { | 680 it != entries->end(); ++it) { |
| 629 std::string entry; | 681 std::string entry; |
| 630 (*it)->GetAsString(&entry); | 682 (*it)->GetAsString(&entry); |
| 631 | 683 |
| 632 std::ostringstream entry_failure; | 684 std::ostringstream entry_failure; |
| 633 DBusThreadManager::Get()->GetShillProfileClient()->GetEntry( | 685 DBusThreadManager::Get()->GetShillProfileClient()->GetEntry( |
| 634 dbus::ObjectPath(profile_path_), | 686 dbus::ObjectPath(profile_.path), |
| 635 entry, | 687 entry, |
| 636 base::Bind(&PolicyApplicator::GetEntry, this, entry), | 688 base::Bind(&PolicyApplicator::GetEntry, this, entry), |
| 637 base::Bind(&LogErrorMessage, FROM_HERE)); | 689 base::Bind(&LogErrorMessage, FROM_HERE)); |
| 638 } | 690 } |
| 639 } | 691 } |
| 640 | 692 |
| 641 void GetEntry(const std::string& entry, | 693 void GetEntry(const std::string& entry, |
| 642 const base::DictionaryValue& entry_properties) { | 694 const base::DictionaryValue& entry_properties) { |
| 643 if (!handler_) { | 695 if (!handler_) { |
| 644 LOG(WARNING) << "Handler destructed during policy application to profile " | 696 LOG(WARNING) << "Handler destructed during policy application to profile " |
| 645 << profile_path_; | 697 << ProfileToString(&profile_); |
| 646 return; | 698 return; |
| 647 } | 699 } |
| 648 | 700 |
| 649 VLOG(2) << "Received properties for entry " << entry << " of profile " | 701 VLOG(2) << "Received properties for entry " << entry << " of profile " |
| 650 << profile_path_; | 702 << ProfileToString(&profile_); |
| 651 | 703 |
| 652 scoped_ptr<base::DictionaryValue> onc_part( | 704 scoped_ptr<base::DictionaryValue> onc_part( |
| 653 onc::TranslateShillServiceToONCPart( | 705 onc::TranslateShillServiceToONCPart( |
| 654 entry_properties, | 706 entry_properties, |
| 655 &onc::kNetworkWithStateSignature)); | 707 &onc::kNetworkWithStateSignature)); |
| 656 | 708 |
| 657 std::string old_guid; | 709 std::string old_guid; |
| 658 if (!onc_part->GetStringWithoutPathExpansion(onc::network_config::kGUID, | 710 if (!onc_part->GetStringWithoutPathExpansion(onc::network_config::kGUID, |
| 659 &old_guid)) { | 711 &old_guid)) { |
| 660 LOG(WARNING) << "Entry " << entry << " of profile " << profile_path_ | 712 LOG(WARNING) << "Entry " << entry << " of profile " |
| 661 << " doesn't contain a GUID."; | 713 << ProfileToString(&profile_) << " doesn't contain a GUID."; |
| 662 // This might be an entry of an older ChromeOS version. Assume it to be | 714 // This might be an entry of an older ChromeOS version. Assume it to be |
| 663 // unmanaged. | 715 // unmanaged. |
| 664 return; | 716 return; |
| 665 } | 717 } |
| 666 | 718 |
| 667 scoped_ptr<NetworkUIData> ui_data = GetUIData(entry_properties); | 719 scoped_ptr<NetworkUIData> ui_data = GetUIData(entry_properties); |
| 668 if (!ui_data) { | 720 if (!ui_data) { |
| 669 VLOG(1) << "Entry " << entry << " of profile " << profile_path_ | 721 VLOG(1) << "Entry " << entry << " of profile " |
| 722 << ProfileToString(&profile_) | |
| 670 << " contains no or no valid UIData."; | 723 << " contains no or no valid UIData."; |
| 671 // This might be an entry of an older ChromeOS version. Assume it to be | 724 // This might be an entry of an older ChromeOS version. Assume it to be |
| 672 // unmanaged. | 725 // unmanaged. |
| 673 return; | 726 return; |
| 674 } | 727 } |
| 675 | 728 |
| 676 bool was_managed = | 729 bool was_managed = |
| 677 (ui_data->onc_source() == onc::ONC_SOURCE_DEVICE_POLICY || | 730 (ui_data->onc_source() == onc::ONC_SOURCE_DEVICE_POLICY || |
| 678 ui_data->onc_source() == onc::ONC_SOURCE_USER_POLICY); | 731 ui_data->onc_source() == onc::ONC_SOURCE_USER_POLICY); |
| 679 | 732 |
| 680 // The relevant policy must have been initialized, otherwise we hadn't Run | 733 // The relevant policy must have been initialized, otherwise we hadn't Run |
| 681 // this PolicyApplicator. | 734 // this PolicyApplicator. |
| 682 const PolicyMap& policies_by_guid = | 735 const Policies& policies = *handler_->GetPoliciesForProfile(profile_); |
| 683 *handler_->GetPoliciesForProfile(profile_path_); | |
| 684 | 736 |
| 685 const base::DictionaryValue* new_policy = NULL; | 737 const base::DictionaryValue* new_policy = NULL; |
| 686 if (was_managed) { | 738 if (was_managed) { |
| 687 // If we have a GUID that might match a current policy, do a lookup using | 739 // If we have a GUID that might match a current policy, do a lookup using |
| 688 // that GUID at first. In particular this is necessary, as some networks | 740 // that GUID at first. In particular this is necessary, as some networks |
| 689 // can't be matched to policies by properties (e.g. VPN). | 741 // can't be matched to policies by properties (e.g. VPN). |
| 690 PolicyMap::const_iterator it = policies_by_guid.find(old_guid); | 742 new_policy = policies.GetByGUID(old_guid); |
| 691 if (it != policies_by_guid.end()) | |
| 692 new_policy = it->second; | |
| 693 } | 743 } |
| 694 | 744 |
| 695 if (!new_policy) { | 745 if (!new_policy) { |
| 696 // If we didn't find a policy by GUID, still a new policy might match. | 746 // If we didn't find a policy by GUID, still a new policy might match. |
| 697 new_policy = FindMatchingPolicy(policies_by_guid, *onc_part); | 747 new_policy = FindMatchingPolicy(policies, *onc_part); |
| 698 } | 748 } |
| 699 | 749 |
| 700 if (new_policy) { | 750 if (new_policy) { |
| 701 std::string new_guid; | 751 std::string new_guid; |
| 702 new_policy->GetStringWithoutPathExpansion(onc::network_config::kGUID, | 752 new_policy->GetStringWithoutPathExpansion(onc::network_config::kGUID, |
| 703 &new_guid); | 753 &new_guid); |
| 704 | 754 |
| 705 VLOG_IF(1, was_managed && old_guid != new_guid) | 755 VLOG_IF(1, was_managed && old_guid != new_guid) |
| 706 << "Updating configuration previously managed by policy " << old_guid | 756 << "Updating configuration previously managed by policy " << old_guid |
| 707 << " with new policy " << new_guid << "."; | 757 << " with new policy " << new_guid << "."; |
| 708 VLOG_IF(1, !was_managed) | 758 VLOG_IF(1, !was_managed) |
| 709 << "Applying policy " << new_guid << " to previously unmanaged " | 759 << "Applying policy " << new_guid << " to previously unmanaged " |
| 710 << "configuration."; | 760 << "configuration."; |
| 711 | 761 |
| 712 if (old_guid == new_guid && | 762 if (old_guid == new_guid && |
| 713 remaining_policies_.find(new_guid) == remaining_policies_.end()) { | 763 remaining_policies_.find(new_guid) == remaining_policies_.end()) { |
| 714 VLOG(1) << "Not updating existing managed configuration with guid " | 764 VLOG(1) << "Not updating existing managed configuration with guid " |
| 715 << new_guid << " because the policy didn't change."; | 765 << new_guid << " because the policy didn't change."; |
| 716 } else { | 766 } else { |
| 717 VLOG_IF(1, old_guid == new_guid) | 767 VLOG_IF(1, old_guid == new_guid) |
| 718 << "Updating previously managed configuration with the updated " | 768 << "Updating previously managed configuration with the updated " |
| 719 << "policy " << new_guid << "."; | 769 << "policy " << new_guid << "."; |
| 720 | 770 |
| 721 // Update the existing configuration with the maybe changed | 771 // Update the existing configuration with the maybe changed |
| 722 // policy. Thereby the GUID might change. | 772 // policy. Thereby the GUID might change. |
| 723 scoped_ptr<base::DictionaryValue> shill_dictionary = | 773 scoped_ptr<base::DictionaryValue> shill_dictionary = |
| 724 CreateShillConfiguration(profile_path_, new_guid, new_policy, | 774 CreateShillConfiguration(profile_, new_guid, new_policy, |
| 725 ui_data->user_settings()); | 775 ui_data->user_settings()); |
| 726 NetworkConfigurationHandler::Get()->CreateConfiguration( | 776 NetworkConfigurationHandler::Get()->CreateConfiguration( |
| 727 *shill_dictionary, | 777 *shill_dictionary, |
| 728 base::Bind(&IgnoreString), | 778 base::Bind(&IgnoreString), |
| 729 base::Bind(&LogErrorWithDict, FROM_HERE)); | 779 base::Bind(&LogErrorWithDict, FROM_HERE)); |
| 730 remaining_policies_.erase(new_guid); | 780 remaining_policies_.erase(new_guid); |
| 731 } | 781 } |
| 732 } else if (was_managed) { | 782 } else if (was_managed) { |
| 733 VLOG(1) << "Removing configuration previously managed by policy " | 783 VLOG(1) << "Removing configuration previously managed by policy " |
| 734 << old_guid << ", because the policy was removed."; | 784 << old_guid << ", because the policy was removed."; |
| 735 | 785 |
| 736 // Remove the entry, because the network was managed but isn't anymore. | 786 // Remove the entry, because the network was managed but isn't anymore. |
| 737 // Note: An alternative might be to preserve the user settings, but it's | 787 // Note: An alternative might be to preserve the user settings, but it's |
| 738 // unclear which values originating the policy should be removed. | 788 // unclear which values originating the policy should be removed. |
| 739 DeleteEntry(entry); | 789 DeleteEntry(entry); |
| 740 } else { | 790 } else { |
| 741 VLOG(2) << "Ignore unmanaged entry."; | 791 VLOG(2) << "Ignore unmanaged entry."; |
| 742 | 792 |
| 743 // The entry wasn't managed and doesn't match any current policy. Thus | 793 // The entry wasn't managed and doesn't match any current policy. Thus |
| 744 // leave it as it is. | 794 // leave it as it is. |
| 745 } | 795 } |
| 746 } | 796 } |
| 747 | 797 |
| 748 void DeleteEntry(const std::string& entry) { | 798 void DeleteEntry(const std::string& entry) { |
| 749 DBusThreadManager::Get()->GetShillProfileClient()->DeleteEntry( | 799 DBusThreadManager::Get()->GetShillProfileClient()->DeleteEntry( |
| 750 dbus::ObjectPath(profile_path_), | 800 dbus::ObjectPath(profile_.path), |
| 751 entry, | 801 entry, |
| 752 base::Bind(&base::DoNothing), | 802 base::Bind(&base::DoNothing), |
| 753 base::Bind(&LogErrorMessage, FROM_HERE)); | 803 base::Bind(&LogErrorMessage, FROM_HERE)); |
| 754 } | 804 } |
| 755 | 805 |
| 756 virtual ~PolicyApplicator() { | 806 virtual ~PolicyApplicator() { |
| 807 if (!handler_) { | |
| 808 LOG(WARNING) << "Handler destructed during policy application to profile " | |
| 809 << ProfileToString(&profile_); | |
| 810 return; | |
| 811 } | |
| 812 | |
| 757 if (remaining_policies_.empty()) | 813 if (remaining_policies_.empty()) |
| 758 return; | 814 return; |
| 759 | 815 |
| 760 VLOG(2) << "Create new managed network configurations in profile" | 816 VLOG(2) << "Create new managed network configurations in profile" |
| 761 << profile_path_ << "."; | 817 << ProfileToString(&profile_) << "."; |
| 762 // All profile entries were compared to policies. |configureGUIDs_| contains | 818 // All profile entries were compared to policies. |configureGUIDs_| contains |
| 763 // all matched policies. From the remainder of policies, new configurations | 819 // all matched policies. From the remainder of policies, new configurations |
| 764 // have to be created. | 820 // have to be created. |
| 765 | 821 |
| 766 // The relevant policy must have been initialized, otherwise we hadn't Run | 822 // The relevant policy must have been initialized, otherwise we hadn't Run |
| 767 // this PolicyApplicator. | 823 // this PolicyApplicator. |
| 768 const PolicyMap& policies_by_guid = | 824 const Policies& policies = *handler_->GetPoliciesForProfile(profile_); |
| 769 *handler_->GetPoliciesForProfile(profile_path_); | |
| 770 | 825 |
| 771 for (std::set<std::string>::iterator it = remaining_policies_.begin(); | 826 for (std::set<std::string>::iterator it = remaining_policies_.begin(); |
| 772 it != remaining_policies_.end(); ++it) { | 827 it != remaining_policies_.end(); ++it) { |
| 773 PolicyMap::const_iterator policy_it = policies_by_guid.find(*it); | 828 const base::DictionaryValue* policy = policies.GetByGUID(*it); |
| 774 if (policy_it == policies_by_guid.end()) { | 829 if (!policy) { |
| 775 LOG(ERROR) << "Policy " << *it << " doesn't exist anymore."; | 830 LOG(ERROR) << "Policy " << *it << " doesn't exist anymore."; |
| 776 continue; | 831 continue; |
| 777 } | 832 } |
| 778 | 833 |
| 779 const base::DictionaryValue* policy = policy_it->second; | |
| 780 | |
| 781 VLOG(1) << "Creating new configuration managed by policy " << *it | 834 VLOG(1) << "Creating new configuration managed by policy " << *it |
| 782 << " in profile " << profile_path_ << "."; | 835 << " in profile " << ProfileToString(&profile_) << "."; |
| 783 | 836 |
| 784 scoped_ptr<base::DictionaryValue> shill_dictionary = | 837 scoped_ptr<base::DictionaryValue> shill_dictionary = |
| 785 CreateShillConfiguration(profile_path_, *it, policy, NULL); | 838 CreateShillConfiguration(profile_, *it, policy, |
| 839 NULL /* no user settings */); | |
| 786 NetworkConfigurationHandler::Get()->CreateConfiguration( | 840 NetworkConfigurationHandler::Get()->CreateConfiguration( |
| 787 *shill_dictionary, | 841 *shill_dictionary, |
| 788 base::Bind(&IgnoreString), | 842 base::Bind(&IgnoreString), |
| 789 base::Bind(&LogErrorWithDict, FROM_HERE)); | 843 base::Bind(&LogErrorWithDict, FROM_HERE)); |
| 790 } | 844 } |
| 791 } | 845 } |
| 792 | 846 |
| 793 std::set<std::string> remaining_policies_; | 847 std::set<std::string> remaining_policies_; |
| 794 base::WeakPtr<ManagedNetworkConfigurationHandler> handler_; | 848 base::WeakPtr<ManagedNetworkConfigurationHandler> handler_; |
| 795 std::string profile_path_; | 849 NetworkProfile profile_; |
| 796 | 850 |
| 797 DISALLOW_COPY_AND_ASSIGN(PolicyApplicator); | 851 DISALLOW_COPY_AND_ASSIGN(PolicyApplicator); |
| 798 }; | 852 }; |
| 799 | 853 |
| 800 void ManagedNetworkConfigurationHandler::SetPolicy( | 854 void ManagedNetworkConfigurationHandler::SetPolicy( |
| 801 onc::ONCSource onc_source, | 855 onc::ONCSource onc_source, |
| 856 const std::string& userhash, | |
| 802 const base::ListValue& network_configs_onc) { | 857 const base::ListValue& network_configs_onc) { |
| 803 VLOG(1) << "Setting policies for ONC source " | 858 VLOG(1) << "Setting policies from " << PolicySource(onc_source, userhash) |
| 804 << onc::GetSourceAsString(onc_source) << "."; | 859 << "."; |
| 805 | 860 |
| 806 PolicyMap* policies; | 861 // |userhash| must be empty for device policies. |
| 807 std::string profile; | 862 DCHECK(onc_source != chromeos::onc::ONC_SOURCE_DEVICE_POLICY || |
| 808 if (onc_source == chromeos::onc::ONC_SOURCE_USER_POLICY) { | 863 userhash.empty()); |
| 809 policies = &user_policies_by_guid_; | 864 Policies*& policies = policies_by_user_[userhash]; |
| 810 profile = kUserProfilePath; | 865 if (!policies) |
| 811 user_policies_initialized_ = true; | 866 policies = new Policies; |
| 812 } else { | |
| 813 policies = &device_policies_by_guid_; | |
| 814 profile = kSharedProfilePath; | |
| 815 device_policies_initialized_ = true; | |
| 816 } | |
| 817 | 867 |
| 818 PolicyMap old_policies; | 868 Policies::Map old_policies; |
| 819 policies->swap(old_policies); | 869 policies->map.swap(old_policies); |
| 820 | 870 |
| 821 // This stores all GUIDs of policies that have changed or are new. | 871 // This stores all GUIDs of policies that have changed or are new. |
| 822 std::set<std::string> modified_policies; | 872 std::set<std::string> modified_policies; |
| 823 | 873 |
| 824 for (base::ListValue::const_iterator it = network_configs_onc.begin(); | 874 for (base::ListValue::const_iterator it = network_configs_onc.begin(); |
| 825 it != network_configs_onc.end(); ++it) { | 875 it != network_configs_onc.end(); ++it) { |
| 826 const base::DictionaryValue* network = NULL; | 876 const base::DictionaryValue* network = NULL; |
| 827 (*it)->GetAsDictionary(&network); | 877 (*it)->GetAsDictionary(&network); |
| 828 DCHECK(network); | 878 DCHECK(network); |
| 829 | 879 |
| 830 std::string guid; | 880 std::string guid; |
| 831 network->GetStringWithoutPathExpansion(onc::network_config::kGUID, &guid); | 881 network->GetStringWithoutPathExpansion(onc::network_config::kGUID, &guid); |
| 832 DCHECK(!guid.empty()); | 882 DCHECK(!guid.empty()); |
| 833 | 883 |
| 834 if (policies->count(guid) > 0) { | 884 if (policies->map.count(guid) > 0) { |
| 835 LOG(ERROR) << "ONC from " << onc::GetSourceAsString(onc_source) | 885 LOG(ERROR) << "ONC from " << PolicySource(onc_source, userhash) |
| 836 << " contains several entries for the same GUID " | 886 << " contains several entries for the same GUID " |
| 837 << guid << "."; | 887 << guid << "."; |
| 838 delete (*policies)[guid]; | 888 delete policies->map[guid]; |
| 839 } | 889 } |
| 840 const base::DictionaryValue* new_entry = network->DeepCopy(); | 890 const base::DictionaryValue* new_entry = network->DeepCopy(); |
| 841 (*policies)[guid] = new_entry; | 891 policies->map[guid] = new_entry; |
| 842 | 892 |
| 843 const base::DictionaryValue* old_entry = old_policies[guid]; | 893 const base::DictionaryValue* old_entry = old_policies[guid]; |
| 844 if (!old_entry || !old_entry->Equals(new_entry)) | 894 if (!old_entry || !old_entry->Equals(new_entry)) |
| 845 modified_policies.insert(guid); | 895 modified_policies.insert(guid); |
| 846 } | 896 } |
| 847 | 897 |
| 848 STLDeleteValues(&old_policies); | 898 STLDeleteValues(&old_policies); |
| 849 | 899 |
| 900 const NetworkProfile* profile = | |
| 901 profile_handler_->GetProfileForUserhash(userhash); | |
| 902 if (!profile) { | |
| 903 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing " | |
| 904 << "policy application."; | |
| 905 return; | |
| 906 } | |
| 907 | |
| 908 scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator( | |
| 909 weak_ptr_factory_.GetWeakPtr(), | |
| 910 *profile, | |
| 911 &modified_policies); | |
| 912 applicator->Run(); | |
| 913 } | |
| 914 | |
| 915 void ManagedNetworkConfigurationHandler::OnProfileAdded( | |
| 916 const NetworkProfile& profile) { | |
| 917 VLOG(1) << "Adding profile " << ProfileToString(&profile) << "'."; | |
| 918 | |
| 919 const Policies* policies = GetPoliciesForProfile(profile); | |
| 920 if (!policies) { | |
| 921 VLOG(1) << "The relevant policy is not initialized, " | |
| 922 << "postponing policy application."; | |
| 923 return; | |
| 924 } | |
| 925 | |
| 926 std::set<std::string> policy_guids; | |
| 927 for (Policies::Map::const_iterator it = policies->map.begin(); | |
| 928 it != policies->map.end(); ++it) { | |
| 929 policy_guids.insert(it->first); | |
| 930 } | |
| 931 | |
| 850 scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator( | 932 scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator( |
| 851 weak_ptr_factory_.GetWeakPtr(), | 933 weak_ptr_factory_.GetWeakPtr(), |
| 852 profile, | 934 profile, |
| 853 &modified_policies); | 935 &policy_guids); |
| 854 applicator->Run(); | 936 applicator->Run(); |
| 855 } | 937 } |
| 856 | 938 |
| 857 const ManagedNetworkConfigurationHandler::PolicyMap* | 939 void ManagedNetworkConfigurationHandler::OnProfileRemoved( |
| 858 ManagedNetworkConfigurationHandler::GetPoliciesForProfile( | 940 const NetworkProfile& profile) { |
| 859 const std::string& profile) const { | 941 // Nothing to do in this case. |
| 860 if (profile == kSharedProfilePath) { | |
| 861 if (device_policies_initialized_) | |
| 862 return &device_policies_by_guid_; | |
| 863 } else if (user_policies_initialized_) { | |
| 864 return &user_policies_by_guid_; | |
| 865 } | |
| 866 return NULL; | |
| 867 } | 942 } |
| 868 | 943 |
| 869 ManagedNetworkConfigurationHandler::ManagedNetworkConfigurationHandler() | 944 const ManagedNetworkConfigurationHandler::Policies* |
| 870 : user_policies_initialized_(false), | 945 ManagedNetworkConfigurationHandler::GetPoliciesForUser( |
| 871 device_policies_initialized_(false), | 946 const std::string& userhash) const { |
| 947 UserToPolicies::const_iterator it = policies_by_user_.find(userhash); | |
| 948 if (it == policies_by_user_.end()) | |
| 949 return NULL; | |
| 950 return it->second; | |
| 951 } | |
| 952 | |
| 953 const ManagedNetworkConfigurationHandler::Policies* | |
| 954 ManagedNetworkConfigurationHandler::GetPoliciesForProfile( | |
| 955 const NetworkProfile& profile) const { | |
| 956 DCHECK(profile.type() != NetworkProfile::TYPE_SHARED || | |
| 957 profile.userhash.empty()); | |
| 958 return GetPoliciesForUser(profile.userhash); | |
| 959 } | |
| 960 | |
| 961 ManagedNetworkConfigurationHandler::ManagedNetworkConfigurationHandler( | |
| 962 NetworkProfileHandler* profile_handler) | |
| 963 : profile_handler_(profile_handler), | |
| 872 weak_ptr_factory_(this) { | 964 weak_ptr_factory_(this) { |
| 965 profile_handler_->AddObserver(this); | |
| 873 } | 966 } |
| 874 | 967 |
| 875 ManagedNetworkConfigurationHandler::~ManagedNetworkConfigurationHandler() { | 968 ManagedNetworkConfigurationHandler::~ManagedNetworkConfigurationHandler() { |
| 876 STLDeleteValues(&user_policies_by_guid_); | 969 profile_handler_->RemoveObserver(this); |
| 877 STLDeleteValues(&device_policies_by_guid_); | 970 STLDeleteValues(&policies_by_user_); |
| 878 } | 971 } |
| 879 | 972 |
| 880 } // namespace chromeos | 973 } // namespace chromeos |
| OLD | NEW |