OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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. | |
4 | |
5 #include "chromeos/network/auto_connect_handler.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/bind_helpers.h" | |
11 #include "base/values.h" | |
12 #include "chromeos/dbus/dbus_thread_manager.h" | |
13 #include "chromeos/dbus/shill_service_client.h" | |
14 #include "chromeos/network/managed_network_configuration_handler.h" | |
15 #include "chromeos/network/network_event_log.h" | |
16 #include "chromeos/network/network_state.h" | |
17 #include "dbus/object_path.h" | |
18 | |
19 namespace chromeos { | |
20 | |
21 AutoConnectHandler::AutoConnectHandler() | |
22 : client_cert_resolver_(nullptr), | |
23 request_best_connection_pending_(false), | |
24 device_policy_applied_(false), | |
25 user_policy_applied_(false), | |
26 client_certs_resolved_(false), | |
27 applied_autoconnect_policy_(false) { | |
28 } | |
29 | |
30 AutoConnectHandler::~AutoConnectHandler() { | |
31 if (client_cert_resolver_) | |
32 client_cert_resolver_->RemoveObserver(this); | |
33 if (LoginState::IsInitialized()) | |
34 LoginState::Get()->RemoveObserver(this); | |
35 if (managed_configuration_handler_) | |
36 managed_configuration_handler_->RemoveObserver(this); | |
37 } | |
38 | |
39 void AutoConnectHandler::Init( | |
40 ClientCertResolver* client_cert_resolver, | |
41 NetworkConnectionHandler* network_connection_handler, | |
42 NetworkStateHandler* network_state_handler, | |
43 ManagedNetworkConfigurationHandler* managed_network_configuration_handler) { | |
44 if (LoginState::IsInitialized()) | |
45 LoginState::Get()->AddObserver(this); | |
46 | |
47 client_cert_resolver_ = client_cert_resolver; | |
48 if (client_cert_resolver_) | |
49 client_cert_resolver_->AddObserver(this); | |
50 | |
51 network_connection_handler_ = network_connection_handler; | |
52 if (network_connection_handler_) | |
53 network_connection_handler_->AddObserver(this); | |
54 | |
55 network_state_handler_ = network_state_handler; | |
56 | |
57 if (managed_network_configuration_handler) { | |
58 managed_configuration_handler_ = managed_network_configuration_handler; | |
59 managed_configuration_handler_->AddObserver(this); | |
60 } | |
61 | |
62 if (LoginState::IsInitialized()) | |
63 LoggedInStateChanged(); | |
64 } | |
65 | |
66 void AutoConnectHandler::LoggedInStateChanged() { | |
67 if (!LoginState::Get()->IsUserLoggedIn()) | |
68 return; | |
69 | |
70 // Disconnect before connecting, to ensure that we do not disconnect a network | |
71 // that we just connected. | |
72 DisconnectIfPolicyRequires(); | |
73 NET_LOG_DEBUG("RequestBestConnection", "User logged in"); | |
74 RequestBestConnection(); | |
75 } | |
76 | |
77 void AutoConnectHandler::ConnectToNetworkRequested() { | |
78 // Stop any pending request to connect to the best newtork. | |
79 request_best_connection_pending_ = false; | |
80 } | |
81 | |
82 void AutoConnectHandler::PoliciesChanged(const std::string& userhash) { | |
83 // Ignore user policies. | |
84 if (!userhash.empty()) | |
85 return; | |
86 DisconnectIfPolicyRequires(); | |
87 } | |
88 | |
89 void AutoConnectHandler::PoliciesApplied(const std::string& userhash) { | |
90 if (userhash.empty()) | |
91 device_policy_applied_ = true; | |
92 else | |
93 user_policy_applied_ = true; | |
94 | |
95 // Request to connect to the best network only if there is at least one | |
96 // managed network. Otherwise only process existing requests. | |
97 const ManagedNetworkConfigurationHandler::GuidToPolicyMap* managed_networks = | |
98 managed_configuration_handler_->GetNetworkConfigsFromPolicy(userhash); | |
99 DCHECK(managed_networks); | |
100 if (managed_networks->empty()) { | |
101 CheckBestConnection(); | |
102 } else { | |
103 NET_LOG_DEBUG("RequestBestConnection", "Policy applied"); | |
104 RequestBestConnection(); | |
105 } | |
stevenjb
2014/11/07 17:19:06
nit: invert this logic to be consistent with the l
pneubeck (no reviews)
2014/11/08 16:49:55
Done.
| |
106 } | |
107 | |
108 void AutoConnectHandler::ResolveRequestCompleted( | |
109 bool network_properties_changed) { | |
110 client_certs_resolved_ = true; | |
111 | |
112 // Only request to connect to the best network if network properties were | |
113 // actually changed. Otherwise only process existing requests. | |
114 if (network_properties_changed) { | |
115 NET_LOG_DEBUG("RequestBestConnection", | |
116 "Client certificate patterns resolved"); | |
117 RequestBestConnection(); | |
118 } else { | |
119 CheckBestConnection(); | |
120 } | |
121 } | |
122 | |
123 void AutoConnectHandler::RequestBestConnection() { | |
124 request_best_connection_pending_ = true; | |
125 CheckBestConnection(); | |
126 } | |
127 | |
128 void AutoConnectHandler::CheckBestConnection() { | |
129 // Return immediately if there is currently no request pending to change to | |
130 // the best network. | |
131 if (!request_best_connection_pending_) | |
132 return; | |
133 | |
134 bool policy_application_running = | |
135 managed_configuration_handler_->IsAnyPolicyApplicationRunning(); | |
136 bool client_cert_resolve_task_running = | |
137 client_cert_resolver_->IsAnyResolveTaskRunning(); | |
138 VLOG(2) << "device policy applied: " << device_policy_applied_ | |
139 << "\nuser policy applied: " << user_policy_applied_ | |
140 << "\npolicy application running: " << policy_application_running | |
141 << "\nclient cert patterns resolved: " << client_certs_resolved_ | |
142 << "\nclient cert resolve task running: " | |
143 << client_cert_resolve_task_running; | |
144 if (!device_policy_applied_ || policy_application_running || | |
145 client_cert_resolve_task_running) { | |
146 return; | |
147 } | |
148 | |
149 if (LoginState::Get()->IsUserLoggedIn()) { | |
150 // Before changing connection after login, we wait at least for: | |
151 // - user policy applied at least once | |
152 // - client certificate patterns resolved | |
153 if (!user_policy_applied_ || !client_certs_resolved_) | |
154 return; | |
155 } | |
156 | |
157 request_best_connection_pending_ = false; | |
158 NET_LOG_EVENT("ConnectToBestWifiNetwork", ""); | |
159 network_state_handler_->ConnectToBestWifiNetwork(); | |
stevenjb
2014/11/07 17:19:06
Should we remove this from NSH/SPH and make the Sh
pneubeck (no reviews)
2014/11/08 16:49:55
can't move it without further changes. NSH is at f
| |
160 } | |
161 | |
162 void AutoConnectHandler::DisconnectIfPolicyRequires() { | |
163 if (applied_autoconnect_policy_ || !LoginState::Get()->IsUserLoggedIn()) | |
164 return; | |
165 | |
166 const base::DictionaryValue* global_network_config = | |
167 managed_configuration_handler_->GetGlobalConfigFromPolicy(std::string()); | |
stevenjb
2014/11/07 17:19:06
nit: comment what std::string() represents
pneubeck (no reviews)
2014/11/08 16:49:55
Done.
| |
168 | |
169 if (!global_network_config) | |
170 return; // Device policy is not set, yet. | |
171 | |
172 applied_autoconnect_policy_ = true; | |
173 | |
174 bool only_policy_autoconnect = false; | |
175 global_network_config->GetBooleanWithoutPathExpansion( | |
176 ::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect, | |
177 &only_policy_autoconnect); | |
178 | |
179 if (only_policy_autoconnect) | |
180 DisconnectFromUnmanagedSharedWiFiNetworks(); | |
181 } | |
182 | |
183 void AutoConnectHandler::DisconnectFromUnmanagedSharedWiFiNetworks() { | |
184 NET_LOG_DEBUG("DisconnectFromUnmanagedSharedWiFiNetworks", ""); | |
185 | |
186 NetworkStateHandler::NetworkStateList networks; | |
187 network_state_handler_->GetVisibleNetworkListByType( | |
188 NetworkTypePattern::Wireless(), &networks); | |
189 for (const NetworkState* network : networks) { | |
190 if (!(network->IsConnectingState() || network->IsConnectedState())) | |
191 break; // Connected and connecting networks are listed first. | |
192 | |
193 if (network->IsPrivate()) | |
194 continue; | |
195 | |
196 const bool network_is_policy_managed = | |
197 !network->profile_path().empty() && !network->guid().empty() && | |
198 managed_configuration_handler_->FindPolicyByGuidAndProfile( | |
199 network->guid(), network->profile_path()); | |
200 if (network_is_policy_managed) | |
201 continue; | |
202 | |
203 NET_LOG_EVENT("Disconnect Forced by Policy", network->path()); | |
204 DBusThreadManager::Get()->GetShillServiceClient()->Disconnect( | |
205 dbus::ObjectPath(network->path()), base::Bind(&base::DoNothing), | |
206 base::Bind(&network_handler::ShillErrorCallbackFunction, | |
207 "AutoConnectHandler.Disconnect failed", network->path(), | |
208 network_handler::ErrorCallback())); | |
209 } | |
210 } | |
211 | |
212 } // namespace chromeos | |
OLD | NEW |