// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_ #define CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_ #include <set> #include <string> #include "base/basictypes.h" #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "base/values.h" #include "chromeos/cert_loader.h" #include "chromeos/chromeos_export.h" #include "chromeos/dbus/dbus_method_call_status.h" #include "chromeos/login/login_state.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_handler_callbacks.h" #include "chromeos/network/network_state_handler_observer.h" namespace chromeos { class NetworkState; class NetworkUIData; // The NetworkConnectionHandler class is used to manage network connection // requests. This is the only class that should make Shill Connect calls. // It handles the following steps: // 1. Determine whether or not sufficient information (e.g. passphrase) is // known to be available to connect to the network. // 2. Request additional information (e.g. user data which contains certificate // information) and determine whether sufficient information is available. // 3. Possibly configure the network certificate info (tpm slot and pkcs11 id). // 4. Send the connect request. // 5. Wait for the network state to change to a non connecting state. // 6. Invoke the appropriate callback (always) on success or failure. // // NetworkConnectionHandler depends on NetworkStateHandler for immediately // available State information, and NetworkConfigurationHandler for any // configuration calls. class CHROMEOS_EXPORT NetworkConnectionHandler : public LoginState::Observer, public CertLoader::Observer, public NetworkStateHandlerObserver, public base::SupportsWeakPtr<NetworkConnectionHandler> { public: // Constants for |error_name| from |error_callback| for Connect. // No network matching |service_path| is found (hidden networks must be // configured before connecting). static const char kErrorNotFound[]; // Already connected to the network. static const char kErrorConnected[]; // Already connecting to the network. static const char kErrorConnecting[]; // The passphrase is missing or invalid. static const char kErrorPassphraseRequired[]; static const char kErrorActivationRequired[]; // The network requires a cert and none exists. static const char kErrorCertificateRequired[]; // The network had an authentication error, indicating that additional or // different authentication information is required. static const char kErrorAuthenticationRequired[]; // Additional configuration is required. static const char kErrorConfigurationRequired[]; // Configuration failed during the configure stage of the connect flow. static const char kErrorConfigureFailed[]; // For Disconnect or Activate, an unexpected DBus or Shill error occurred. static const char kErrorShillError[]; // A new network connect request canceled this one. static const char kErrorConnectCanceled[]; // Constants for |error_name| from |error_callback| for Disconnect. static const char kErrorNotConnected[]; // Certificate load timed out. static const char kErrorCertLoadTimeout[]; virtual ~NetworkConnectionHandler(); // ConnectToNetwork() will start an asynchronous connection attempt. // On success, |success_callback| will be called. // On failure, |error_callback| will be called with |error_name| one of the // constants defined above, or shill::kErrorConnectFailed or // shill::kErrorBadPassphrase if the Shill Error property (from a // previous connect attempt) was set to one of those. // |error_message| will contain an additional error string for debugging. // If |check_error_state| is true, the current state of the network is // checked for errors, otherwise current state is ignored (e.g. for recently // configured networks or repeat attempts). void ConnectToNetwork(const std::string& service_path, const base::Closure& success_callback, const network_handler::ErrorCallback& error_callback, bool check_error_state); // DisconnectNetwork() will send a Disconnect request to Shill. // On success, |success_callback| will be called. // On failure, |error_callback| will be called with |error_name| one of: // kErrorNotFound if no network matching |service_path| is found. // kErrorNotConnected if not connected to the network. // kErrorShillError if a DBus or Shill error occurred. // |error_message| will contain and additional error string for debugging. void DisconnectNetwork(const std::string& service_path, const base::Closure& success_callback, const network_handler::ErrorCallback& error_callback); // Returns true if ConnectToNetwork has been called with |service_path| and // has not completed (i.e. success or error callback has been called). bool HasConnectingNetwork(const std::string& service_path); // Returns true if there are any pending connect requests. bool HasPendingConnectRequest(); // NetworkStateHandlerObserver virtual void NetworkListChanged() OVERRIDE; virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE; // LoginState::Observer virtual void LoggedInStateChanged() OVERRIDE; // CertLoader::Observer virtual void OnCertificatesLoaded(const net::CertificateList& cert_list, bool initial_load) OVERRIDE; private: friend class NetworkHandler; friend class NetworkConnectionHandlerTest; struct ConnectRequest; NetworkConnectionHandler(); void Init(NetworkStateHandler* network_state_handler, NetworkConfigurationHandler* network_configuration_handler); ConnectRequest* GetPendingRequest(const std::string& service_path); // Callback from Shill.Service.GetProperties. Parses |properties| to verify // whether or not the network appears to be configured. If configured, // attempts a connection, otherwise invokes error_callback from // pending_requests_[service_path]. |check_error_state| is passed from // ConnectToNetwork(), see comment for info. void VerifyConfiguredAndConnect(bool check_error_state, const std::string& service_path, const base::DictionaryValue& properties); // Queues a connect request until certificates have loaded. void QueueConnectRequest(const std::string& service_path); // Checks to see if certificates have loaded and if not, cancels any queued // connect request and notifies the user. void CheckCertificatesLoaded(); // Handles connecting to a queued network after certificates are loaded or // handle cert load timeout. void ConnectToQueuedNetwork(); // Calls Shill.Manager.Connect asynchronously. void CallShillConnect(const std::string& service_path); // Handles failure from ConfigurationHandler calls. void HandleConfigurationFailure( const std::string& service_path, const std::string& error_name, scoped_ptr<base::DictionaryValue> error_data); // Handles success or failure from Shill.Service.Connect. void HandleShillConnectSuccess(const std::string& service_path); void HandleShillConnectFailure(const std::string& service_path, const std::string& error_name, const std::string& error_message); void CheckPendingRequest(const std::string service_path); void CheckAllPendingRequests(); // Returns the PKCS#11 ID of a cert matching the certificate pattern in // |ui_data|. Returns empty string otherwise. std::string CertificateIsConfigured(NetworkUIData* ui_data); void ErrorCallbackForPendingRequest(const std::string& service_path, const std::string& error_name); // Calls Shill.Manager.Disconnect asynchronously. void CallShillDisconnect( const std::string& service_path, const base::Closure& success_callback, const network_handler::ErrorCallback& error_callback); // Handle success from Shill.Service.Disconnect. void HandleShillDisconnectSuccess(const std::string& service_path, const base::Closure& success_callback); // Local references to the associated handler instances. CertLoader* cert_loader_; NetworkStateHandler* network_state_handler_; NetworkConfigurationHandler* network_configuration_handler_; // Map of pending connect requests, used to prevent repeated attempts while // waiting for Shill and to trigger callbacks on eventual success or failure. std::map<std::string, ConnectRequest> pending_requests_; scoped_ptr<ConnectRequest> queued_connect_; // Track certificate loading state. bool logged_in_; bool certificates_loaded_; base::TimeTicks logged_in_time_; DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandler); }; } // namespace chromeos #endif // CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_