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