1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/network/managed_network_configuration_handler_impl.h"
10 #include "base/guid.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/stl_util.h"
16 #include "base/values.h"
17 #include "chromeos/dbus/shill_manager_client.h"
18 #include "chromeos/dbus/shill_profile_client.h"
19 #include "chromeos/dbus/shill_service_client.h"
20 #include "chromeos/network/device_state.h"
21 #include "chromeos/network/network_configuration_handler.h"
22 #include "chromeos/network/network_device_handler.h"
23 #include "chromeos/network/network_event_log.h"
24 #include "chromeos/network/network_policy_observer.h"
25 #include "chromeos/network/network_profile.h"
26 #include "chromeos/network/network_profile_handler.h"
27 #include "chromeos/network/network_state.h"
28 #include "chromeos/network/network_state_handler.h"
29 #include "chromeos/network/network_ui_data.h"
30 #include "chromeos/network/network_util.h"
31 #include "chromeos/network/onc/onc_merger.h"
32 #include "chromeos/network/onc/onc_signature.h"
33 #include "chromeos/network/onc/onc_translator.h"
34 #include "chromeos/network/onc/onc_utils.h"
35 #include "chromeos/network/onc/onc_validator.h"
36 #include "chromeos/network/policy_util.h"
37 #include "chromeos/network/shill_property_util.h"
38 #include "components/onc/onc_constants.h"
39 #include "third_party/cros_system_api/dbus/service_constants.h"
45 using GuidToPolicyMap
= ManagedNetworkConfigurationHandler::GuidToPolicyMap
;
47 // These are error strings used for error callbacks. None of these error
48 // messages are user-facing: they should only appear in logs.
49 const char kInvalidUserSettings
[] = "InvalidUserSettings";
50 const char kNetworkAlreadyConfigured
[] = "NetworkAlreadyConfigured";
51 const char kPoliciesNotInitialized
[] = "PoliciesNotInitialized";
52 const char kProfileNotInitialized
[] = "ProfileNotInitialized";
53 const char kUnconfiguredNetwork
[] = "UnconfiguredNetwork";
54 const char kUnknownNetwork
[] = "UnknownNetwork";
56 std::string
ToDebugString(::onc::ONCSource source
,
57 const std::string
& userhash
) {
58 return source
== ::onc::ONC_SOURCE_USER_POLICY
?
59 ("user policy of " + userhash
) : "device policy";
62 void InvokeErrorCallback(const std::string
& service_path
,
63 const network_handler::ErrorCallback
& error_callback
,
64 const std::string
& error_name
) {
65 std::string error_msg
= "ManagedConfig Error: " + error_name
;
66 NET_LOG_ERROR(error_msg
, service_path
);
67 network_handler::RunErrorCallback(
68 error_callback
, service_path
, error_name
, error_msg
);
71 void LogErrorWithDict(const tracked_objects::Location
& from_where
,
72 const std::string
& error_name
,
73 scoped_ptr
<base::DictionaryValue
> error_data
) {
74 device_event_log::AddEntry(from_where
.file_name(), from_where
.line_number(),
75 device_event_log::LOG_TYPE_NETWORK
,
76 device_event_log::LOG_LEVEL_ERROR
, error_name
);
79 const base::DictionaryValue
* GetByGUID(const GuidToPolicyMap
& policies
,
80 const std::string
& guid
) {
81 GuidToPolicyMap::const_iterator it
= policies
.find(guid
);
82 if (it
== policies
.end())
89 struct ManagedNetworkConfigurationHandlerImpl::Policies
{
92 GuidToPolicyMap per_network_config
;
93 base::DictionaryValue global_network_config
;
96 ManagedNetworkConfigurationHandlerImpl::Policies::~Policies() {
97 STLDeleteValues(&per_network_config
);
100 void ManagedNetworkConfigurationHandlerImpl::AddObserver(
101 NetworkPolicyObserver
* observer
) {
102 observers_
.AddObserver(observer
);
105 void ManagedNetworkConfigurationHandlerImpl::RemoveObserver(
106 NetworkPolicyObserver
* observer
) {
107 observers_
.RemoveObserver(observer
);
110 // GetManagedProperties
112 void ManagedNetworkConfigurationHandlerImpl::GetManagedProperties(
113 const std::string
& userhash
,
114 const std::string
& service_path
,
115 const network_handler::DictionaryResultCallback
& callback
,
116 const network_handler::ErrorCallback
& error_callback
) {
117 if (!GetPoliciesForUser(userhash
) || !GetPoliciesForUser(std::string())) {
118 InvokeErrorCallback(service_path
, error_callback
, kPoliciesNotInitialized
);
121 NET_LOG_USER("GetManagedProperties", service_path
);
122 network_configuration_handler_
->GetShillProperties(
125 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback
,
126 weak_ptr_factory_
.GetWeakPtr(),
128 &ManagedNetworkConfigurationHandlerImpl::SendManagedProperties
,
129 weak_ptr_factory_
.GetWeakPtr(), userhash
, callback
,
134 void ManagedNetworkConfigurationHandlerImpl::SendManagedProperties(
135 const std::string
& userhash
,
136 const network_handler::DictionaryResultCallback
& callback
,
137 const network_handler::ErrorCallback
& error_callback
,
138 const std::string
& service_path
,
139 scoped_ptr
<base::DictionaryValue
> shill_properties
) {
140 std::string profile_path
;
141 shill_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
143 const NetworkProfile
* profile
=
144 network_profile_handler_
->GetProfileForPath(profile_path
);
146 NET_LOG_ERROR("No profile for service: " + profile_path
, service_path
);
148 scoped_ptr
<NetworkUIData
> ui_data
=
149 shill_property_util::GetUIDataFromProperties(*shill_properties
);
151 const base::DictionaryValue
* user_settings
= NULL
;
153 if (ui_data
&& profile
) {
154 user_settings
= ui_data
->user_settings();
155 } else if (profile
) {
156 NET_LOG_ERROR("Service contains empty or invalid UIData", service_path
);
157 // TODO(pneubeck): add a conversion of user configured entries of old
158 // ChromeOS versions. We will have to use a heuristic to determine which
159 // properties _might_ be user configured.
163 shill_properties
->GetStringWithoutPathExpansion(shill::kGuidProperty
, &guid
);
165 ::onc::ONCSource onc_source
;
166 FindPolicyByGUID(userhash
, guid
, &onc_source
);
167 const NetworkState
* network_state
=
168 network_state_handler_
->GetNetworkState(service_path
);
169 scoped_ptr
<base::DictionaryValue
> active_settings(
170 onc::TranslateShillServiceToONCPart(*shill_properties
, onc_source
,
171 &onc::kNetworkWithStateSignature
,
174 const base::DictionaryValue
* network_policy
= NULL
;
175 const base::DictionaryValue
* global_policy
= NULL
;
177 const Policies
* policies
= GetPoliciesForProfile(*profile
);
180 service_path
, error_callback
, kPoliciesNotInitialized
);
184 network_policy
= GetByGUID(policies
->per_network_config
, guid
);
185 global_policy
= &policies
->global_network_config
;
188 scoped_ptr
<base::DictionaryValue
> augmented_properties(
189 policy_util::CreateManagedONC(global_policy
,
192 active_settings
.get(),
194 callback
.Run(service_path
, *augmented_properties
);
199 void ManagedNetworkConfigurationHandlerImpl::GetProperties(
200 const std::string
& userhash
,
201 const std::string
& service_path
,
202 const network_handler::DictionaryResultCallback
& callback
,
203 const network_handler::ErrorCallback
& error_callback
) {
204 NET_LOG_USER("GetProperties", service_path
);
205 network_configuration_handler_
->GetShillProperties(
208 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback
,
209 weak_ptr_factory_
.GetWeakPtr(),
210 base::Bind(&ManagedNetworkConfigurationHandlerImpl::SendProperties
,
211 weak_ptr_factory_
.GetWeakPtr(), userhash
, callback
,
216 void ManagedNetworkConfigurationHandlerImpl::SendProperties(
217 const std::string
& userhash
,
218 const network_handler::DictionaryResultCallback
& callback
,
219 const network_handler::ErrorCallback
& error_callback
,
220 const std::string
& service_path
,
221 scoped_ptr
<base::DictionaryValue
> shill_properties
) {
222 const NetworkState
* network_state
=
223 network_state_handler_
->GetNetworkState(service_path
);
226 shill_properties
->GetStringWithoutPathExpansion(shill::kGuidProperty
, &guid
);
228 ::onc::ONCSource onc_source
;
229 FindPolicyByGUID(userhash
, guid
, &onc_source
);
231 scoped_ptr
<base::DictionaryValue
> onc_network(
232 onc::TranslateShillServiceToONCPart(*shill_properties
, onc_source
,
233 &onc::kNetworkWithStateSignature
,
235 callback
.Run(service_path
, *onc_network
);
240 void ManagedNetworkConfigurationHandlerImpl::SetProperties(
241 const std::string
& service_path
,
242 const base::DictionaryValue
& user_settings
,
243 const base::Closure
& callback
,
244 const network_handler::ErrorCallback
& error_callback
) {
245 const NetworkState
* state
=
246 network_state_handler_
->GetNetworkStateFromServicePath(
247 service_path
, true /* configured_only */);
249 InvokeErrorCallback(service_path
, error_callback
, kUnknownNetwork
);
253 std::string guid
= state
->guid();
254 DCHECK(!guid
.empty());
256 const std::string
& profile_path
= state
->profile_path();
257 const NetworkProfile
*profile
=
258 network_profile_handler_
->GetProfileForPath(profile_path
);
260 // TODO(pneubeck): create an initial configuration in this case. As for
261 // CreateConfiguration, user settings from older ChromeOS versions have to
262 // be determined here.
263 InvokeErrorCallback(service_path
, error_callback
, kUnconfiguredNetwork
);
267 VLOG(2) << "SetProperties: Found GUID " << guid
<< " and profile "
268 << profile
->ToDebugString();
270 const Policies
* policies
= GetPoliciesForProfile(*profile
);
272 InvokeErrorCallback(service_path
, error_callback
, kPoliciesNotInitialized
);
276 // We need to ensure that required configuration properties (e.g. Type) are
277 // included for ONC validation and translation to Shill properties.
278 scoped_ptr
<base::DictionaryValue
> user_settings_copy(
279 user_settings
.DeepCopy());
280 user_settings_copy
->SetStringWithoutPathExpansion(
281 ::onc::network_config::kType
,
282 network_util::TranslateShillTypeToONC(state
->type()));
283 user_settings_copy
->MergeDictionary(&user_settings
);
285 // Validate the ONC dictionary. We are liberal and ignore unknown field
286 // names. User settings are only partial ONC, thus we ignore missing fields.
287 onc::Validator
validator(false, // Ignore unknown fields.
288 false, // Ignore invalid recommended field names.
289 false, // Ignore missing fields.
290 false); // This ONC does not come from policy.
292 onc::Validator::Result validation_result
;
293 scoped_ptr
<base::DictionaryValue
> validated_user_settings
=
294 validator
.ValidateAndRepairObject(
295 &onc::kNetworkConfigurationSignature
,
298 if (validation_result
== onc::Validator::INVALID
) {
299 InvokeErrorCallback(service_path
, error_callback
, kInvalidUserSettings
);
302 if (validation_result
== onc::Validator::VALID_WITH_WARNINGS
)
303 LOG(WARNING
) << "Validation of ONC user settings produced warnings.";
305 // Fill in HexSSID field from contents of SSID field if not set already.
306 if (user_settings_copy
) {
307 onc::FillInHexSSIDFieldsInOncObject(onc::kNetworkConfigurationSignature
,
308 validated_user_settings
.get());
311 const base::DictionaryValue
* network_policy
=
312 GetByGUID(policies
->per_network_config
, guid
);
313 VLOG(2) << "This configuration is " << (network_policy
? "" : "not ")
316 scoped_ptr
<base::DictionaryValue
> shill_dictionary(
317 policy_util::CreateShillConfiguration(*profile
,
319 &policies
->global_network_config
,
321 validated_user_settings
.get()));
323 // 'Carrier' needs to be handled specially if set.
324 base::DictionaryValue
* cellular
= nullptr;
325 if (validated_user_settings
->GetDictionaryWithoutPathExpansion(
326 ::onc::network_config::kCellular
, &cellular
)) {
328 if (cellular
->GetStringWithoutPathExpansion(::onc::cellular::kCarrier
,
330 network_device_handler_
->SetCarrier(
331 state
->device_path(), carrier
,
333 &ManagedNetworkConfigurationHandlerImpl::SetShillProperties
,
334 weak_ptr_factory_
.GetWeakPtr(), service_path
,
335 base::Passed(&shill_dictionary
), callback
, error_callback
),
341 SetShillProperties(service_path
, shill_dictionary
.Pass(), callback
,
345 void ManagedNetworkConfigurationHandlerImpl::SetShillProperties(
346 const std::string
& service_path
,
347 scoped_ptr
<base::DictionaryValue
> shill_dictionary
,
348 const base::Closure
& callback
,
349 const network_handler::ErrorCallback
& error_callback
) {
350 network_configuration_handler_
->SetShillProperties(
351 service_path
, *shill_dictionary
,
352 NetworkConfigurationObserver::SOURCE_USER_ACTION
, callback
,
356 void ManagedNetworkConfigurationHandlerImpl::CreateConfiguration(
357 const std::string
& userhash
,
358 const base::DictionaryValue
& properties
,
359 const network_handler::StringResultCallback
& callback
,
360 const network_handler::ErrorCallback
& error_callback
) const {
361 const Policies
* policies
= GetPoliciesForUser(userhash
);
363 InvokeErrorCallback("", error_callback
, kPoliciesNotInitialized
);
367 if (policy_util::FindMatchingPolicy(policies
->per_network_config
,
369 InvokeErrorCallback("", error_callback
, kNetworkAlreadyConfigured
);
373 const NetworkProfile
* profile
=
374 network_profile_handler_
->GetProfileForUserhash(userhash
);
376 InvokeErrorCallback("", error_callback
, kProfileNotInitialized
);
380 // TODO(pneubeck): In case of WiFi, check that no other configuration for the
381 // same {SSID, mode, security} exists. We don't support such multiple
382 // configurations, yet.
384 // Generate a new GUID for this configuration. Ignore the maybe provided GUID
385 // in |properties| as it is not our own and from an untrusted source.
386 std::string guid
= base::GenerateGUID();
387 scoped_ptr
<base::DictionaryValue
> shill_dictionary(
388 policy_util::CreateShillConfiguration(*profile
,
390 NULL
, // no global policy
391 NULL
, // no network policy
394 network_configuration_handler_
->CreateShillConfiguration(
395 *shill_dictionary
, NetworkConfigurationObserver::SOURCE_USER_ACTION
,
396 callback
, error_callback
);
399 void ManagedNetworkConfigurationHandlerImpl::RemoveConfiguration(
400 const std::string
& service_path
,
401 const base::Closure
& callback
,
402 const network_handler::ErrorCallback
& error_callback
) const {
403 network_configuration_handler_
->RemoveConfiguration(
404 service_path
, NetworkConfigurationObserver::SOURCE_USER_ACTION
, callback
,
408 void ManagedNetworkConfigurationHandlerImpl::SetPolicy(
409 ::onc::ONCSource onc_source
,
410 const std::string
& userhash
,
411 const base::ListValue
& network_configs_onc
,
412 const base::DictionaryValue
& global_network_config
) {
413 VLOG(1) << "Setting policies from " << ToDebugString(onc_source
, userhash
)
416 // |userhash| must be empty for device policies.
417 DCHECK(onc_source
!= ::onc::ONC_SOURCE_DEVICE_POLICY
||
419 Policies
* policies
= NULL
;
420 if (ContainsKey(policies_by_user_
, userhash
)) {
421 policies
= policies_by_user_
[userhash
].get();
423 policies
= new Policies
;
424 policies_by_user_
[userhash
] = make_linked_ptr(policies
);
427 policies
->global_network_config
.MergeDictionary(&global_network_config
);
429 GuidToPolicyMap old_per_network_config
;
430 policies
->per_network_config
.swap(old_per_network_config
);
432 // This stores all GUIDs of policies that have changed or are new.
433 std::set
<std::string
> modified_policies
;
435 for (base::ListValue::const_iterator it
= network_configs_onc
.begin();
436 it
!= network_configs_onc
.end(); ++it
) {
437 const base::DictionaryValue
* network
= NULL
;
438 (*it
)->GetAsDictionary(&network
);
442 network
->GetStringWithoutPathExpansion(::onc::network_config::kGUID
, &guid
);
443 DCHECK(!guid
.empty());
445 if (policies
->per_network_config
.count(guid
) > 0) {
446 NET_LOG_ERROR("ONC from " + ToDebugString(onc_source
, userhash
) +
447 " contains several entries for the same GUID ", guid
);
448 delete policies
->per_network_config
[guid
];
450 const base::DictionaryValue
* new_entry
= network
->DeepCopy();
451 policies
->per_network_config
[guid
] = new_entry
;
453 const base::DictionaryValue
* old_entry
= old_per_network_config
[guid
];
454 if (!old_entry
|| !old_entry
->Equals(new_entry
))
455 modified_policies
.insert(guid
);
458 STLDeleteValues(&old_per_network_config
);
459 ApplyOrQueuePolicies(userhash
, &modified_policies
);
460 FOR_EACH_OBSERVER(NetworkPolicyObserver
, observers_
,
461 PoliciesChanged(userhash
));
464 bool ManagedNetworkConfigurationHandlerImpl::IsAnyPolicyApplicationRunning()
466 return !policy_applicators_
.empty() || !queued_modified_policies_
.empty();
469 bool ManagedNetworkConfigurationHandlerImpl::ApplyOrQueuePolicies(
470 const std::string
& userhash
,
471 std::set
<std::string
>* modified_policies
) {
472 DCHECK(modified_policies
);
474 const NetworkProfile
* profile
=
475 network_profile_handler_
->GetProfileForUserhash(userhash
);
477 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing "
478 << "policy application.";
479 // OnProfileAdded will apply all policies for this userhash.
483 if (ContainsKey(policy_applicators_
, userhash
)) {
484 // A previous policy application is still running. Queue the modified
486 // Note, even if |modified_policies| is empty, this means that a policy
487 // application will be queued.
488 queued_modified_policies_
[userhash
].insert(modified_policies
->begin(),
489 modified_policies
->end());
490 VLOG(1) << "Previous PolicyApplicator still running. Postponing policy "
495 const Policies
* policies
= policies_by_user_
[userhash
].get();
498 PolicyApplicator
* applicator
=
499 new PolicyApplicator(*profile
,
500 policies
->per_network_config
,
501 policies
->global_network_config
,
504 policy_applicators_
[userhash
] = make_linked_ptr(applicator
);
509 void ManagedNetworkConfigurationHandlerImpl::OnProfileAdded(
510 const NetworkProfile
& profile
) {
511 VLOG(1) << "Adding profile " << profile
.ToDebugString() << "'.";
513 const Policies
* policies
= GetPoliciesForProfile(profile
);
515 VLOG(1) << "The relevant policy is not initialized, "
516 << "postponing policy application.";
521 std::set
<std::string
> policy_guids
;
522 for (GuidToPolicyMap::const_iterator it
=
523 policies
->per_network_config
.begin();
524 it
!= policies
->per_network_config
.end(); ++it
) {
525 policy_guids
.insert(it
->first
);
528 const bool started_policy_application
=
529 ApplyOrQueuePolicies(profile
.userhash
, &policy_guids
);
530 DCHECK(started_policy_application
);
533 void ManagedNetworkConfigurationHandlerImpl::OnProfileRemoved(
534 const NetworkProfile
& profile
) {
535 // Nothing to do in this case.
538 void ManagedNetworkConfigurationHandlerImpl::CreateConfigurationFromPolicy(
539 const base::DictionaryValue
& shill_properties
) {
540 network_configuration_handler_
->CreateShillConfiguration(
541 shill_properties
, NetworkConfigurationObserver::SOURCE_POLICY
,
543 &ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork
,
544 weak_ptr_factory_
.GetWeakPtr()),
545 base::Bind(&LogErrorWithDict
, FROM_HERE
));
548 void ManagedNetworkConfigurationHandlerImpl::
549 UpdateExistingConfigurationWithPropertiesFromPolicy(
550 const base::DictionaryValue
& existing_properties
,
551 const base::DictionaryValue
& new_properties
) {
552 base::DictionaryValue shill_properties
;
555 existing_properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
557 if (profile
.empty()) {
558 NET_LOG_ERROR("Missing profile property",
559 shill_property_util::GetNetworkIdFromProperties(
560 existing_properties
));
563 shill_properties
.SetStringWithoutPathExpansion(shill::kProfileProperty
,
566 if (!shill_property_util::CopyIdentifyingProperties(
568 true /* properties were read from Shill */,
569 &shill_properties
)) {
570 NET_LOG_ERROR("Missing identifying properties",
571 shill_property_util::GetNetworkIdFromProperties(
572 existing_properties
));
575 shill_properties
.MergeDictionary(&new_properties
);
577 network_configuration_handler_
->CreateShillConfiguration(
578 shill_properties
, NetworkConfigurationObserver::SOURCE_POLICY
,
580 &ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork
,
581 weak_ptr_factory_
.GetWeakPtr()),
582 base::Bind(&LogErrorWithDict
, FROM_HERE
));
585 void ManagedNetworkConfigurationHandlerImpl::OnPoliciesApplied(
586 const NetworkProfile
& profile
) {
587 const std::string
& userhash
= profile
.userhash
;
588 VLOG(1) << "Policy application for user '" << userhash
<< "' finished.";
590 base::MessageLoop::current()->DeleteSoon(
591 FROM_HERE
, policy_applicators_
[userhash
].release());
592 policy_applicators_
.erase(userhash
);
594 if (ContainsKey(queued_modified_policies_
, userhash
)) {
595 std::set
<std::string
> modified_policies
;
596 queued_modified_policies_
[userhash
].swap(modified_policies
);
597 // Remove |userhash| from the queue.
598 queued_modified_policies_
.erase(userhash
);
599 ApplyOrQueuePolicies(userhash
, &modified_policies
);
602 NetworkPolicyObserver
, observers_
, PoliciesApplied(userhash
));
606 const base::DictionaryValue
*
607 ManagedNetworkConfigurationHandlerImpl::FindPolicyByGUID(
608 const std::string userhash
,
609 const std::string
& guid
,
610 ::onc::ONCSource
* onc_source
) const {
611 *onc_source
= ::onc::ONC_SOURCE_NONE
;
613 if (!userhash
.empty()) {
614 const Policies
* user_policies
= GetPoliciesForUser(userhash
);
616 const base::DictionaryValue
* policy
=
617 GetByGUID(user_policies
->per_network_config
, guid
);
619 *onc_source
= ::onc::ONC_SOURCE_USER_POLICY
;
625 const Policies
* device_policies
= GetPoliciesForUser(std::string());
626 if (device_policies
) {
627 const base::DictionaryValue
* policy
=
628 GetByGUID(device_policies
->per_network_config
, guid
);
630 *onc_source
= ::onc::ONC_SOURCE_DEVICE_POLICY
;
638 const GuidToPolicyMap
*
639 ManagedNetworkConfigurationHandlerImpl::GetNetworkConfigsFromPolicy(
640 const std::string
& userhash
) const {
641 const Policies
* policies
= GetPoliciesForUser(userhash
);
645 return &policies
->per_network_config
;
648 const base::DictionaryValue
*
649 ManagedNetworkConfigurationHandlerImpl::GetGlobalConfigFromPolicy(
650 const std::string
& userhash
) const {
651 const Policies
* policies
= GetPoliciesForUser(userhash
);
655 return &policies
->global_network_config
;
658 const base::DictionaryValue
*
659 ManagedNetworkConfigurationHandlerImpl::FindPolicyByGuidAndProfile(
660 const std::string
& guid
,
661 const std::string
& profile_path
) const {
662 const NetworkProfile
* profile
=
663 network_profile_handler_
->GetProfileForPath(profile_path
);
665 NET_LOG_ERROR("Profile path unknown:" + profile_path
, guid
);
669 const Policies
* policies
= GetPoliciesForProfile(*profile
);
673 return GetByGUID(policies
->per_network_config
, guid
);
676 const ManagedNetworkConfigurationHandlerImpl::Policies
*
677 ManagedNetworkConfigurationHandlerImpl::GetPoliciesForUser(
678 const std::string
& userhash
) const {
679 UserToPoliciesMap::const_iterator it
= policies_by_user_
.find(userhash
);
680 if (it
== policies_by_user_
.end())
682 return it
->second
.get();
685 const ManagedNetworkConfigurationHandlerImpl::Policies
*
686 ManagedNetworkConfigurationHandlerImpl::GetPoliciesForProfile(
687 const NetworkProfile
& profile
) const {
688 DCHECK(profile
.type() != NetworkProfile::TYPE_SHARED
||
689 profile
.userhash
.empty());
690 return GetPoliciesForUser(profile
.userhash
);
693 ManagedNetworkConfigurationHandlerImpl::ManagedNetworkConfigurationHandlerImpl()
694 : network_state_handler_(NULL
),
695 network_profile_handler_(NULL
),
696 network_configuration_handler_(NULL
),
697 network_device_handler_(NULL
),
698 weak_ptr_factory_(this) {
699 CHECK(base::MessageLoop::current());
702 ManagedNetworkConfigurationHandlerImpl::
703 ~ManagedNetworkConfigurationHandlerImpl() {
704 if (network_profile_handler_
)
705 network_profile_handler_
->RemoveObserver(this);
708 void ManagedNetworkConfigurationHandlerImpl::Init(
709 NetworkStateHandler
* network_state_handler
,
710 NetworkProfileHandler
* network_profile_handler
,
711 NetworkConfigurationHandler
* network_configuration_handler
,
712 NetworkDeviceHandler
* network_device_handler
) {
713 network_state_handler_
= network_state_handler
;
714 network_profile_handler_
= network_profile_handler
;
715 network_configuration_handler_
= network_configuration_handler
;
716 network_device_handler_
= network_device_handler
;
717 network_profile_handler_
->AddObserver(this);
720 void ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork(
721 const std::string
& service_path
) {
722 if (service_path
.empty())
725 NetworkPolicyObserver
, observers_
, PolicyAppliedToNetwork(service_path
));
728 // Get{Managed}Properties helpers
730 void ManagedNetworkConfigurationHandlerImpl::GetDeviceStateProperties(
731 const std::string
& service_path
,
732 base::DictionaryValue
* properties
) {
733 std::string connection_state
;
734 properties
->GetStringWithoutPathExpansion(
735 shill::kStateProperty
, &connection_state
);
736 if (!NetworkState::StateIsConnected(connection_state
))
739 // Get the IPConfig properties from the device and store them in "IPConfigs"
740 // (plural) in the properties dictionary. (Note: Shill only provides a single
741 // "IPConfig" property for a network service, but a consumer of this API may
742 // want information about all ipv4 and ipv6 IPConfig properties.
744 properties
->GetStringWithoutPathExpansion(shill::kDeviceProperty
, &device
);
745 const DeviceState
* device_state
=
746 network_state_handler_
->GetDeviceState(device
);
748 NET_LOG_ERROR("GetDeviceProperties: no device: " + device
, service_path
);
752 // Get the hardware MAC address from the DeviceState.
753 if (!device_state
->mac_address().empty()) {
754 properties
->SetStringWithoutPathExpansion(
755 shill::kAddressProperty
, device_state
->mac_address());
758 // Convert IPConfig dictionary to a ListValue.
759 base::ListValue
* ip_configs
= new base::ListValue
;
760 for (base::DictionaryValue::Iterator
iter(device_state
->ip_configs());
761 !iter
.IsAtEnd(); iter
.Advance()) {
762 ip_configs
->Append(iter
.value().DeepCopy());
764 properties
->SetWithoutPathExpansion(shill::kIPConfigsProperty
, ip_configs
);
767 void ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback(
768 GetDevicePropertiesCallback send_callback
,
769 const std::string
& service_path
,
770 const base::DictionaryValue
& shill_properties
) {
771 scoped_ptr
<base::DictionaryValue
> shill_properties_copy(
772 shill_properties
.DeepCopy());
775 shill_properties
.GetStringWithoutPathExpansion(shill::kGuidProperty
, &guid
);
777 // Unmanaged networks are assigned a GUID in NetworkState. Provide this
778 // value in the ONC dictionary.
779 const NetworkState
* state
=
780 network_state_handler_
->GetNetworkState(service_path
);
781 if (state
&& !state
->guid().empty()) {
782 guid
= state
->guid();
783 shill_properties_copy
->SetStringWithoutPathExpansion(shill::kGuidProperty
,
786 LOG(ERROR
) << "Network has no GUID specified: " << service_path
;
791 shill_properties_copy
->GetStringWithoutPathExpansion(shill::kTypeProperty
,
793 // Add associated DeviceState properties for non-VPN networks.
794 if (type
!= shill::kTypeVPN
)
795 GetDeviceStateProperties(service_path
, shill_properties_copy
.get());
797 // Only request additional Device properties for Cellular networks with a
799 std::string device_path
;
800 if (!network_device_handler_
||
801 type
!= shill::kTypeCellular
||
802 !shill_properties_copy
->GetStringWithoutPathExpansion(
803 shill::kDeviceProperty
, &device_path
) ||
804 device_path
.empty()) {
805 send_callback
.Run(service_path
, shill_properties_copy
.Pass());
809 // Request the device properties. On success or failure pass (a possibly
810 // modified) |shill_properties| to |send_callback|.
811 scoped_ptr
<base::DictionaryValue
> shill_properties_copy_error_copy(
812 shill_properties_copy
->DeepCopy());
813 network_device_handler_
->GetDeviceProperties(
815 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
816 GetDevicePropertiesSuccess
,
817 weak_ptr_factory_
.GetWeakPtr(),
819 base::Passed(&shill_properties_copy
),
821 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
822 GetDevicePropertiesFailure
,
823 weak_ptr_factory_
.GetWeakPtr(),
825 base::Passed(&shill_properties_copy_error_copy
),
829 void ManagedNetworkConfigurationHandlerImpl::GetDevicePropertiesSuccess(
830 const std::string
& service_path
,
831 scoped_ptr
<base::DictionaryValue
> network_properties
,
832 GetDevicePropertiesCallback send_callback
,
833 const std::string
& device_path
,
834 const base::DictionaryValue
& device_properties
) {
835 // Create a "Device" dictionary in |network_properties|.
836 network_properties
->SetWithoutPathExpansion(
837 shill::kDeviceProperty
, device_properties
.DeepCopy());
838 send_callback
.Run(service_path
, network_properties
.Pass());
841 void ManagedNetworkConfigurationHandlerImpl::GetDevicePropertiesFailure(
842 const std::string
& service_path
,
843 scoped_ptr
<base::DictionaryValue
> network_properties
,
844 GetDevicePropertiesCallback send_callback
,
845 const std::string
& error_name
,
846 scoped_ptr
<base::DictionaryValue
> error_data
) {
847 NET_LOG_ERROR("Error getting device properties", service_path
);
848 send_callback
.Run(service_path
, network_properties
.Pass());
852 } // namespace chromeos