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