1 // Copyright (c) 2012 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 #ifndef CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_
6 #define CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_
11 #include "base/basictypes.h"
12 #include "base/callback.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/time/time.h"
15 #include "base/values.h"
16 #include "chromeos/cert_loader.h"
17 #include "chromeos/chromeos_export.h"
18 #include "chromeos/dbus/dbus_method_call_status.h"
19 #include "chromeos/login/login_state.h"
20 #include "chromeos/network/network_handler.h"
21 #include "chromeos/network/network_handler_callbacks.h"
22 #include "chromeos/network/network_policy_observer.h"
23 #include "chromeos/network/network_state_handler_observer.h"
29 // The NetworkConnectionHandler class is used to manage network connection
30 // requests. This is the only class that should make Shill Connect calls.
31 // It handles the following steps:
32 // 1. Determine whether or not sufficient information (e.g. passphrase) is
33 // known to be available to connect to the network.
34 // 2. Request additional information (e.g. user data which contains certificate
35 // information) and determine whether sufficient information is available.
36 // 3. Possibly configure the network certificate info (tpm slot and pkcs11 id).
37 // 4. Send the connect request.
38 // 5. Wait for the network state to change to a non connecting state.
39 // 6. Invoke the appropriate callback (always) on success or failure.
41 // NetworkConnectionHandler depends on NetworkStateHandler for immediately
42 // available State information, and NetworkConfigurationHandler for any
43 // configuration calls.
45 class CHROMEOS_EXPORT NetworkConnectionHandler
46 : public LoginState::Observer
,
47 public CertLoader::Observer
,
48 public NetworkStateHandlerObserver
,
49 public NetworkPolicyObserver
,
50 public base::SupportsWeakPtr
<NetworkConnectionHandler
> {
52 // Constants for |error_name| from |error_callback| for Connect.
54 // No network matching |service_path| is found (hidden networks must be
55 // configured before connecting).
56 static const char kErrorNotFound
[];
58 // Already connected to the network.
59 static const char kErrorConnected
[];
61 // Already connecting to the network.
62 static const char kErrorConnecting
[];
64 // The passphrase is missing or invalid.
65 static const char kErrorPassphraseRequired
[];
67 static const char kErrorActivationRequired
[];
69 // The network requires a cert and none exists.
70 static const char kErrorCertificateRequired
[];
72 // The network had an authentication error, indicating that additional or
73 // different authentication information is required.
74 static const char kErrorAuthenticationRequired
[];
76 // Additional configuration is required.
77 static const char kErrorConfigurationRequired
[];
79 // Configuration failed during the configure stage of the connect flow.
80 static const char kErrorConfigureFailed
[];
82 // For Disconnect or Activate, an unexpected DBus or Shill error occurred.
83 static const char kErrorShillError
[];
85 // A new network connect request canceled this one.
86 static const char kErrorConnectCanceled
[];
88 // Constants for |error_name| from |error_callback| for Disconnect.
89 static const char kErrorNotConnected
[];
91 // Certificate load timed out.
92 static const char kErrorCertLoadTimeout
[];
94 virtual ~NetworkConnectionHandler();
96 // ConnectToNetwork() will start an asynchronous connection attempt.
97 // On success, |success_callback| will be called.
98 // On failure, |error_callback| will be called with |error_name| one of the
99 // constants defined above, or shill::kErrorConnectFailed or
100 // shill::kErrorBadPassphrase if the Shill Error property (from a
101 // previous connect attempt) was set to one of those.
102 // |error_message| will contain an additional error string for debugging.
103 // If |check_error_state| is true, the current state of the network is
104 // checked for errors, otherwise current state is ignored (e.g. for recently
105 // configured networks or repeat attempts).
106 void ConnectToNetwork(const std::string
& service_path
,
107 const base::Closure
& success_callback
,
108 const network_handler::ErrorCallback
& error_callback
,
109 bool check_error_state
);
111 // DisconnectNetwork() will send a Disconnect request to Shill.
112 // On success, |success_callback| will be called.
113 // On failure, |error_callback| will be called with |error_name| one of:
114 // kErrorNotFound if no network matching |service_path| is found.
115 // kErrorNotConnected if not connected to the network.
116 // kErrorShillError if a DBus or Shill error occurred.
117 // |error_message| will contain and additional error string for debugging.
118 void DisconnectNetwork(const std::string
& service_path
,
119 const base::Closure
& success_callback
,
120 const network_handler::ErrorCallback
& error_callback
);
122 // Returns true if ConnectToNetwork has been called with |service_path| and
123 // has not completed (i.e. success or error callback has been called).
124 bool HasConnectingNetwork(const std::string
& service_path
);
126 // Returns true if there are any pending connect requests.
127 bool HasPendingConnectRequest();
129 // NetworkStateHandlerObserver
130 virtual void NetworkListChanged() OVERRIDE
;
131 virtual void NetworkPropertiesUpdated(const NetworkState
* network
) OVERRIDE
;
133 // LoginState::Observer
134 virtual void LoggedInStateChanged() OVERRIDE
;
136 // CertLoader::Observer
137 virtual void OnCertificatesLoaded(const net::CertificateList
& cert_list
,
138 bool initial_load
) OVERRIDE
;
140 // NetworkPolicyObserver
141 virtual void PolicyChanged(const std::string
& userhash
) OVERRIDE
;
144 friend class NetworkHandler
;
145 friend class NetworkConnectionHandlerTest
;
147 struct ConnectRequest
;
149 NetworkConnectionHandler();
151 void Init(NetworkStateHandler
* network_state_handler
,
152 NetworkConfigurationHandler
* network_configuration_handler
,
153 ManagedNetworkConfigurationHandler
*
154 managed_network_configuration_handler
);
156 ConnectRequest
* GetPendingRequest(const std::string
& service_path
);
158 // Callback from Shill.Service.GetProperties. Parses |properties| to verify
159 // whether or not the network appears to be configured. If configured,
160 // attempts a connection, otherwise invokes error_callback from
161 // pending_requests_[service_path]. |check_error_state| is passed from
162 // ConnectToNetwork(), see comment for info.
163 void VerifyConfiguredAndConnect(bool check_error_state
,
164 const std::string
& service_path
,
165 const base::DictionaryValue
& properties
);
167 // Queues a connect request until certificates have loaded.
168 void QueueConnectRequest(const std::string
& service_path
);
170 // Checks to see if certificates have loaded and if not, cancels any queued
171 // connect request and notifies the user.
172 void CheckCertificatesLoaded();
174 // Handles connecting to a queued network after certificates are loaded or
175 // handle cert load timeout.
176 void ConnectToQueuedNetwork();
178 // Calls Shill.Manager.Connect asynchronously.
179 void CallShillConnect(const std::string
& service_path
);
181 // Handles failure from ConfigurationHandler calls.
182 void HandleConfigurationFailure(
183 const std::string
& service_path
,
184 const std::string
& error_name
,
185 scoped_ptr
<base::DictionaryValue
> error_data
);
187 // Handles success or failure from Shill.Service.Connect.
188 void HandleShillConnectSuccess(const std::string
& service_path
);
189 void HandleShillConnectFailure(const std::string
& service_path
,
190 const std::string
& error_name
,
191 const std::string
& error_message
);
193 void CheckPendingRequest(const std::string service_path
);
194 void CheckAllPendingRequests();
196 void ErrorCallbackForPendingRequest(const std::string
& service_path
,
197 const std::string
& error_name
);
199 // Calls Shill.Manager.Disconnect asynchronously.
200 void CallShillDisconnect(
201 const std::string
& service_path
,
202 const base::Closure
& success_callback
,
203 const network_handler::ErrorCallback
& error_callback
);
205 // Handle success from Shill.Service.Disconnect.
206 void HandleShillDisconnectSuccess(const std::string
& service_path
,
207 const base::Closure
& success_callback
);
209 // If the policy to prevent unmanaged & shared networks to autoconnect is
210 // enabled, then disconnect all such networks except wired networks. Does
211 // nothing on consecutive calls.
212 // This is enforced once after a user logs in 1) to allow mananged networks to
213 // autoconnect and 2) to prevent a previous user from foisting a network on
214 // the new user. Therefore, this function is called on startup, at login and
215 // when the device policy is changed.
216 void DisconnectIfPolicyRequires();
218 // Requests a connect to the 'best' available network once after login and
219 // after any disconnect required by policy is executed (see
220 // DisconnectIfPolicyRequires()). To include networks with client
221 // certificates, no request is sent until certificates are loaded. Therefore,
222 // this function is called on the initial certificate load and by
223 // DisconnectIfPolicyRequires().
224 void ConnectToBestNetworkAfterLogin();
226 // Local references to the associated handler instances.
227 CertLoader
* cert_loader_
;
228 NetworkStateHandler
* network_state_handler_
;
229 NetworkConfigurationHandler
* configuration_handler_
;
230 ManagedNetworkConfigurationHandler
* managed_configuration_handler_
;
232 // Map of pending connect requests, used to prevent repeated attempts while
233 // waiting for Shill and to trigger callbacks on eventual success or failure.
234 std::map
<std::string
, ConnectRequest
> pending_requests_
;
235 scoped_ptr
<ConnectRequest
> queued_connect_
;
237 // Track certificate loading state.
239 bool certificates_loaded_
;
240 base::TimeTicks logged_in_time_
;
242 // Whether the autoconnect policy was applied already, see
243 // DisconnectIfPolicyRequires().
244 bool applied_autoconnect_policy_
;
246 // Whether the handler already requested a 'ConnectToBestNetwork' after login,
247 // see ConnectToBestNetworkAfterLogin().
248 bool requested_connect_to_best_network_
;
250 DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandler
);
253 } // namespace chromeos
255 #endif // CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_