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 25 namespace chromeos { 26 27 class NetworkState; 28 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. 40 // 41 // NetworkConnectionHandler depends on NetworkStateHandler for immediately 42 // available State information, and NetworkConfigurationHandler for any 43 // configuration calls. 44 45 class CHROMEOS_EXPORT NetworkConnectionHandler 46 : public LoginState::Observer, 47 public CertLoader::Observer, 48 public NetworkStateHandlerObserver, 49 public NetworkPolicyObserver, 50 public base::SupportsWeakPtr<NetworkConnectionHandler> { 51 public: 52 // Constants for |error_name| from |error_callback| for Connect. 53 54 // No network matching |service_path| is found (hidden networks must be 55 // configured before connecting). 56 static const char kErrorNotFound[]; 57 58 // Already connected to the network. 59 static const char kErrorConnected[]; 60 61 // Already connecting to the network. 62 static const char kErrorConnecting[]; 63 64 // The passphrase is missing or invalid. 65 static const char kErrorPassphraseRequired[]; 66 67 static const char kErrorActivationRequired[]; 68 69 // The network requires a cert and none exists. 70 static const char kErrorCertificateRequired[]; 71 72 // The network had an authentication error, indicating that additional or 73 // different authentication information is required. 74 static const char kErrorAuthenticationRequired[]; 75 76 // Additional configuration is required. 77 static const char kErrorConfigurationRequired[]; 78 79 // Configuration failed during the configure stage of the connect flow. 80 static const char kErrorConfigureFailed[]; 81 82 // For Disconnect or Activate, an unexpected DBus or Shill error occurred. 83 static const char kErrorShillError[]; 84 85 // A new network connect request canceled this one. 86 static const char kErrorConnectCanceled[]; 87 88 // Constants for |error_name| from |error_callback| for Disconnect. 89 static const char kErrorNotConnected[]; 90 91 // Certificate load timed out. 92 static const char kErrorCertLoadTimeout[]; 93 94 virtual ~NetworkConnectionHandler(); 95 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); 110 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); 121 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); 125 126 // Returns true if there are any pending connect requests. 127 bool HasPendingConnectRequest(); 128 129 // NetworkStateHandlerObserver 130 virtual void NetworkListChanged() OVERRIDE; 131 virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE; 132 133 // LoginState::Observer 134 virtual void LoggedInStateChanged() OVERRIDE; 135 136 // CertLoader::Observer 137 virtual void OnCertificatesLoaded(const net::CertificateList& cert_list, 138 bool initial_load) OVERRIDE; 139 140 // NetworkPolicyObserver 141 virtual void PolicyChanged(const std::string& userhash) OVERRIDE; 142 143 private: 144 friend class NetworkHandler; 145 friend class NetworkConnectionHandlerTest; 146 147 struct ConnectRequest; 148 149 NetworkConnectionHandler(); 150 151 void Init(NetworkStateHandler* network_state_handler, 152 NetworkConfigurationHandler* network_configuration_handler, 153 ManagedNetworkConfigurationHandler* 154 managed_network_configuration_handler); 155 156 ConnectRequest* GetPendingRequest(const std::string& service_path); 157 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); 166 167 // Queues a connect request until certificates have loaded. 168 void QueueConnectRequest(const std::string& service_path); 169 170 // Checks to see if certificates have loaded and if not, cancels any queued 171 // connect request and notifies the user. 172 void CheckCertificatesLoaded(); 173 174 // Handles connecting to a queued network after certificates are loaded or 175 // handle cert load timeout. 176 void ConnectToQueuedNetwork(); 177 178 // Calls Shill.Manager.Connect asynchronously. 179 void CallShillConnect(const std::string& service_path); 180 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); 186 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); 192 193 void CheckPendingRequest(const std::string service_path); 194 void CheckAllPendingRequests(); 195 196 void ErrorCallbackForPendingRequest(const std::string& service_path, 197 const std::string& error_name); 198 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); 204 205 // Handle success from Shill.Service.Disconnect. 206 void HandleShillDisconnectSuccess(const std::string& service_path, 207 const base::Closure& success_callback); 208 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(); 217 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(); 225 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_; 231 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_; 236 237 // Track certificate loading state. 238 bool logged_in_; 239 bool certificates_loaded_; 240 base::TimeTicks logged_in_time_; 241 242 // Whether the autoconnect policy was applied already, see 243 // DisconnectIfPolicyRequires(). 244 bool applied_autoconnect_policy_; 245 246 // Whether the handler already requested a 'ConnectToBestNetwork' after login, 247 // see ConnectToBestNetworkAfterLogin(). 248 bool requested_connect_to_best_network_; 249 250 DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandler); 251 }; 252 253 } // namespace chromeos 254 255 #endif // CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_ 256