network_connection_handler.h revision 58537e28ecd584eab876aee8be7156509866d23a
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/values.h"
15#include "chromeos/cert_loader.h"
16#include "chromeos/chromeos_export.h"
17#include "chromeos/dbus/dbus_method_call_status.h"
18#include "chromeos/login/login_state.h"
19#include "chromeos/network/network_handler.h"
20#include "chromeos/network/network_handler_callbacks.h"
21#include "chromeos/network/network_state_handler_observer.h"
22
23namespace chromeos {
24
25class NetworkState;
26class NetworkUIData;
27
28// The NetworkConnectionHandler class is used to manage network connection
29// requests. This is the only class that should make Shill Connect calls.
30// It handles the following steps:
31// 1. Determine whether or not sufficient information (e.g. passphrase) is
32//    known to be available to connect to the network.
33// 2. Request additional information (e.g. user data which contains certificate
34//    information) and determine whether sufficient information is available.
35// 3. Possibly configure the network certificate info (tpm slot and pkcs11 id).
36// 4. Send the connect request.
37// 5. Wait for the network state to change to a non connecting state.
38// 6. Invoke the appropriate callback (always) on success or failure.
39//
40// NetworkConnectionHandler depends on NetworkStateHandler for immediately
41// available State information, and NetworkConfigurationHandler for any
42// configuration calls.
43
44class CHROMEOS_EXPORT NetworkConnectionHandler
45    : public LoginState::Observer,
46      public CertLoader::Observer,
47      public NetworkStateHandlerObserver,
48      public base::SupportsWeakPtr<NetworkConnectionHandler> {
49 public:
50  // Constants for |error_name| from |error_callback| for Connect.
51
52  //  No network matching |service_path| is found (hidden networks must be
53  //  configured before connecting).
54  static const char kErrorNotFound[];
55
56  // Already connected to the network.
57  static const char kErrorConnected[];
58
59  // Already connecting to the network.
60  static const char kErrorConnecting[];
61
62  // The passphrase is missing or invalid.
63  static const char kErrorPassphraseRequired[];
64
65  static const char kErrorActivationRequired[];
66
67  // The network requires a cert and none exists.
68  static const char kErrorCertificateRequired[];
69
70  // The network had an authentication error, indicating that additional or
71  // different authentication information is required.
72  static const char kErrorAuthenticationRequired[];
73
74  // Additional configuration is required.
75  static const char kErrorConfigurationRequired[];
76
77  // Configuration failed during the configure stage of the connect flow.
78  static const char kErrorConfigureFailed[];
79
80  // For Disconnect or Activate, an unexpected DBus or Shill error occurred.
81  static const char kErrorShillError[];
82
83  // A new network connect request canceled this one.
84  static const char kErrorConnectCanceled[];
85
86  // Constants for |error_name| from |error_callback| for Disconnect.
87  static const char kErrorNotConnected[];
88
89  virtual ~NetworkConnectionHandler();
90
91  // ConnectToNetwork() will start an asynchronous connection attempt.
92  // On success, |success_callback| will be called.
93  // On failure, |error_callback| will be called with |error_name| one of the
94  //   constants defined above, or flimflam::kErrorConnectFailed or
95  //   flimflam::kErrorBadPassphrase if the Shill Error property (from a
96  //   previous connect attempt) was set to one of those.
97  // |error_message| will contain an additional error string for debugging.
98  // If |check_error_state| is true, the current state of the network is
99  //  checked for errors, otherwise current state is ignored (e.g. for recently
100  //  configured networks or repeat attempts).
101  void ConnectToNetwork(const std::string& service_path,
102                        const base::Closure& success_callback,
103                        const network_handler::ErrorCallback& error_callback,
104                        bool check_error_state);
105
106  // DisconnectNetwork() will send a Disconnect request to Shill.
107  // On success, |success_callback| will be called.
108  // On failure, |error_callback| will be called with |error_name| one of:
109  //  kErrorNotFound if no network matching |service_path| is found.
110  //  kErrorNotConnected if not connected to the network.
111  //  kErrorShillError if a DBus or Shill error occurred.
112  // |error_message| will contain and additional error string for debugging.
113  void DisconnectNetwork(const std::string& service_path,
114                         const base::Closure& success_callback,
115                         const network_handler::ErrorCallback& error_callback);
116
117  // Returns true if ConnectToNetwork has been called with |service_path| and
118  // has not completed (i.e. success or error callback has been called).
119  bool HasConnectingNetwork(const std::string& service_path);
120
121  // Returns true if there are any pending connect requests.
122  bool HasPendingConnectRequest();
123
124  // NetworkStateHandlerObserver
125  virtual void NetworkListChanged() OVERRIDE;
126  virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE;
127
128  // LoginState::Observer
129  virtual void LoggedInStateChanged(LoginState::LoggedInState state) OVERRIDE;
130
131  // CertLoader::Observer
132  virtual void OnCertificatesLoaded(const net::CertificateList& cert_list,
133                                    bool initial_load) OVERRIDE;
134
135 private:
136  friend class NetworkHandler;
137  friend class NetworkConnectionHandlerTest;
138
139  struct ConnectRequest;
140
141  NetworkConnectionHandler();
142
143  void Init(NetworkStateHandler* network_state_handler,
144            NetworkConfigurationHandler* network_configuration_handler);
145
146  ConnectRequest* GetPendingRequest(const std::string& service_path);
147
148  // Callback from Shill.Service.GetProperties. Parses |properties| to verify
149  // whether or not the network appears to be configured. If configured,
150  // attempts a connection, otherwise invokes error_callback from
151  // pending_requests_[service_path]. |check_error_state| is passed from
152  // ConnectToNetwork(), see comment for info.
153  void VerifyConfiguredAndConnect(bool check_error_state,
154                                  const std::string& service_path,
155                                  const base::DictionaryValue& properties);
156
157  // Calls Shill.Manager.Connect asynchronously.
158  void CallShillConnect(const std::string& service_path);
159
160  // Handle failure from ConfigurationHandler calls.
161  void HandleConfigurationFailure(
162      const std::string& service_path,
163      const std::string& error_name,
164      scoped_ptr<base::DictionaryValue> error_data);
165
166  // Handle success or failure from Shill.Service.Connect.
167  void HandleShillConnectSuccess(const std::string& service_path);
168  void HandleShillConnectFailure(const std::string& service_path,
169                                 const std::string& error_name,
170                                 const std::string& error_message);
171
172  void CheckPendingRequest(const std::string service_path);
173  void CheckAllPendingRequests();
174
175  // Returns the PKCS#11 ID of a cert matching the certificate pattern in
176  // |ui_data|. Returns empty string otherwise.
177  std::string CertificateIsConfigured(NetworkUIData* ui_data);
178  void ErrorCallbackForPendingRequest(const std::string& service_path,
179                                      const std::string& error_name);
180
181  // Calls Shill.Manager.Disconnect asynchronously.
182  void CallShillDisconnect(
183      const std::string& service_path,
184      const base::Closure& success_callback,
185      const network_handler::ErrorCallback& error_callback);
186
187  // Handle success from Shill.Service.Disconnect.
188  void HandleShillDisconnectSuccess(const std::string& service_path,
189                                    const base::Closure& success_callback);
190
191
192  // Local references to the associated handler instances.
193  CertLoader* cert_loader_;
194  NetworkStateHandler* network_state_handler_;
195  NetworkConfigurationHandler* network_configuration_handler_;
196
197  // Map of pending connect requests, used to prevent repeated attempts while
198  // waiting for Shill and to trigger callbacks on eventual success or failure.
199  std::map<std::string, ConnectRequest> pending_requests_;
200  scoped_ptr<ConnectRequest> queued_connect_;
201
202  // Track certificate loading state.
203  bool logged_in_;
204  bool certificates_loaded_;
205
206  DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandler);
207};
208
209}  // namespace chromeos
210
211#endif  // CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_
212