Home | History | Annotate | Download | only in network
      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