Home | History | Annotate | Download | only in wifi
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef SHILL_WIFI_WIFI_SERVICE_H_
     18 #define SHILL_WIFI_WIFI_SERVICE_H_
     19 
     20 #include <memory>
     21 #include <set>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include "shill/event_dispatcher.h"
     26 #include "shill/key_value_store.h"
     27 #include "shill/refptr_types.h"
     28 #include "shill/service.h"
     29 
     30 namespace shill {
     31 
     32 class CertificateFile;
     33 class ControlInterface;
     34 class EventDispatcher;
     35 class Error;
     36 class Manager;
     37 class Metrics;
     38 class WiFiProvider;
     39 
     40 class WiFiService : public Service {
     41  public:
     42   // TODO(pstew): Storage constants shouldn't need to be public
     43   // crbug.com/208736
     44   static const char kStorageHiddenSSID[];
     45   static const char kStorageMode[];
     46   static const char kStoragePassphrase[];
     47   static const char kStorageSecurity[];
     48   static const char kStorageSecurityClass[];
     49   static const char kStorageSSID[];
     50   static const char kStoragePreferredDevice[];
     51   static const char kStorageRoamThreshold[];
     52   static const char kStorageRoamThresholdSet[];
     53 
     54   WiFiService(ControlInterface* control_interface,
     55               EventDispatcher* dispatcher,
     56               Metrics* metrics,
     57               Manager* manager,
     58               WiFiProvider* provider,
     59               const std::vector<uint8_t>& ssid,
     60               const std::string& mode,
     61               const std::string& security,
     62               bool hidden_ssid);
     63   ~WiFiService();
     64 
     65   // Inherited from Service.
     66   void Connect(Error* error, const char* reason) override;
     67   void Disconnect(Error* error, const char* reason) override;
     68   bool Is8021x() const override;
     69 
     70   virtual void AddEndpoint(const WiFiEndpointConstRefPtr& endpoint);
     71   virtual void RemoveEndpoint(const WiFiEndpointConstRefPtr& endpoint);
     72   virtual int GetEndpointCount() const { return endpoints_.size(); }
     73 
     74   // Called to update the identity of the currently connected endpoint.
     75   // To indicate that there is no currently connect endpoint, call with
     76   // |endpoint| set to nullptr.
     77   virtual void NotifyCurrentEndpoint(const WiFiEndpointConstRefPtr& endpoint);
     78   // Called to inform of changes in the properties of an endpoint.
     79   // (Not necessarily the currently connected endpoint.)
     80   virtual void NotifyEndpointUpdated(const WiFiEndpointConstRefPtr& endpoint);
     81 
     82   // wifi_<MAC>_<BSSID>_<mode_string>_<security_string>
     83   std::string GetStorageIdentifier() const override;
     84   static bool ParseStorageIdentifier(const std::string& storage_name,
     85                                      std::string* address,
     86                                      std::string* mode,
     87                                      std::string* security);
     88 
     89   // Iterate over |storage| looking for WiFi servces with "old-style"
     90   // properties that don't include explicit type/mode/security, and add
     91   // these properties.  Returns true if any entries were fixed.
     92   static bool FixupServiceEntries(StoreInterface* storage);
     93 
     94   // Validate |mode| against all valid and supported service modes.
     95   static bool IsValidMode(const std::string& mode);
     96 
     97   // Validate |method| against all valid and supported security methods.
     98   static bool IsValidSecurityMethod(const std::string& method);
     99 
    100   // Validate |security_class| against all valid and supported
    101   // security classes.
    102   static bool IsValidSecurityClass(const std::string& security_class);
    103 
    104   const std::string& mode() const { return mode_; }
    105   const std::string& key_management() const { return GetEAPKeyManagement(); }
    106   const std::vector<uint8_t>& ssid() const { return ssid_; }
    107   const std::string& bssid() const { return bssid_; }
    108   const std::vector<uint16_t>& frequency_list() const {
    109     return frequency_list_;
    110   }
    111   uint16_t physical_mode() const { return physical_mode_; }
    112   uint16_t frequency() const { return frequency_; }
    113 
    114   // WiFi services can load from profile entries other than their current
    115   // storage identifier.  Override the methods from the parent Service
    116   // class which pertain to whether this service may be loaded from |storage|.
    117   std::string GetLoadableStorageIdentifier(
    118       const StoreInterface& storage) const override;
    119   bool IsLoadableFrom(const StoreInterface& storage) const override;
    120 
    121   // Override Load and Save from parent Service class.  We will call
    122   // the parent method.
    123   bool Load(StoreInterface* storage) override;
    124   bool Save(StoreInterface* storage) override;
    125   bool Unload() override;
    126 
    127   // Override SetState from parent Service class.  We will call the
    128   // parent method.
    129   void SetState(ConnectState state) override;
    130 
    131   virtual bool HasEndpoints() const { return !endpoints_.empty(); }
    132   bool IsVisible() const override;
    133   bool IsSecurityMatch(const std::string& security) const;
    134 
    135   // Used by WiFi objects to indicate that the credentials for this network
    136   // have been called into question.  This method returns true if given this
    137   // suspicion, if it is probable that indeed these credentials are likely
    138   // to be incorrect.  Credentials that have never been used before are
    139   // considered suspect by default, while those which have been used
    140   // successfully in the past must have this method called a number of times
    141   // since the last time ResetSuspectedCredentialsFailures() was called.
    142   virtual bool AddSuspectedCredentialFailure();
    143   virtual void ResetSuspectedCredentialFailures();
    144 
    145   bool hidden_ssid() const { return hidden_ssid_; }
    146   bool ieee80211w_required() const { return ieee80211w_required_; }
    147 
    148   void InitializeCustomMetrics() const;
    149   void SendPostReadyStateMetrics(
    150       int64_t time_resume_to_ready_milliseconds) const override;
    151 
    152   // Clear any cached credentials stored in wpa_supplicant related to |this|.
    153   // This will disconnect this service if it is currently connected.
    154   void ClearCachedCredentials();
    155 
    156   // Override from parent Service class to correctly update connectability
    157   // when the EAP credentials change for 802.1x networks.
    158   void OnEapCredentialsChanged(
    159       Service::UpdateCredentialsReason reason) override;
    160 
    161   // Called by WiFiService to reset state associated with prior success
    162   // of a connection with particular EAP credentials or a passphrase.
    163   void OnCredentialChange(Service::UpdateCredentialsReason reason);
    164 
    165   // Override from parent Service class to register hidden services once they
    166   // have been configured.
    167   void OnProfileConfigured() override;
    168 
    169   // Called by WiFiProvider to reset the WiFi device reference on shutdown.
    170   virtual void ResetWiFi();
    171 
    172   // Called by WiFi to retrieve configuration parameters for wpa_supplicant.
    173   virtual KeyValueStore GetSupplicantConfigurationParameters() const;
    174 
    175   // "wpa", "rsn" and "psk" are equivalent from a configuration perspective.
    176   // This function maps them all into "psk".
    177   static std::string ComputeSecurityClass(const std::string& security);
    178 
    179   bool IsAutoConnectable(const char** reason) const override;
    180 
    181   // Signal level in dBm.  If no current endpoint, returns
    182   // std::numeric_limits<int>::min().
    183   int16_t SignalLevel() const;
    184 
    185   void set_expecting_disconnect(bool val) { expecting_disconnect_ = val; }
    186   bool expecting_disconnect() const { return expecting_disconnect_; }
    187 
    188   uint16_t roam_threshold_db() { return roam_threshold_db_; }
    189   bool roam_threshold_db_set() { return roam_threshold_db_set_; }
    190 
    191  protected:
    192   void SetEAPKeyManagement(const std::string& key_management) override;
    193   std::string GetTethering(Error* error) const override;
    194 
    195  private:
    196   friend class WiFiServiceSecurityTest;
    197   friend class WiFiServiceTest;  // SetPassphrase
    198   friend class WiFiServiceUpdateFromEndpointsTest;  // SignalToStrength
    199   FRIEND_TEST(MetricsTest, WiFiServicePostReady);
    200   FRIEND_TEST(MetricsTest, WiFiServicePostReadyAdHoc);
    201   FRIEND_TEST(MetricsTest, WiFiServicePostReadyEAP);
    202   FRIEND_TEST(WiFiMainTest, CurrentBSSChangedUpdateServiceEndpoint);
    203   FRIEND_TEST(WiFiMainTest, RoamThresholdProperty);
    204   FRIEND_TEST(WiFiProviderTest, OnEndpointAddedWithSecurity);  // security_
    205   FRIEND_TEST(WiFiServiceTest, AutoConnect);
    206   FRIEND_TEST(WiFiServiceTest, ClearWriteOnlyDerivedProperty);  // passphrase_
    207   FRIEND_TEST(WiFiServiceTest, ComputeCipher8021x);
    208   FRIEND_TEST(WiFiServiceTest, ConnectTask8021x);
    209   FRIEND_TEST(WiFiServiceTest, ConnectTaskDynamicWEP);
    210   FRIEND_TEST(WiFiServiceTest, ConnectTaskPSK);
    211   FRIEND_TEST(WiFiServiceTest, ConnectTaskRSN);
    212   FRIEND_TEST(WiFiServiceTest, ConnectTaskWEP);
    213   FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA);
    214   FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA80211w);
    215   FRIEND_TEST(WiFiServiceTest, GetTethering);
    216   FRIEND_TEST(WiFiServiceTest, IsAutoConnectable);
    217   FRIEND_TEST(WiFiServiceTest, LoadHidden);
    218   FRIEND_TEST(WiFiServiceTest, SetPassphraseForNonPassphraseService);
    219   FRIEND_TEST(WiFiServiceTest, LoadAndUnloadPassphrase);
    220   FRIEND_TEST(WiFiServiceTest, LoadPassphraseClearCredentials);
    221   FRIEND_TEST(WiFiServiceTest, SecurityFromCurrentEndpoint);  // GetSecurity
    222   FRIEND_TEST(WiFiServiceTest, SetPassphraseResetHasEverConnected);
    223   FRIEND_TEST(WiFiServiceTest, SetPassphraseRemovesCachedCredentials);
    224   FRIEND_TEST(WiFiServiceTest, SignalToStrength);  // SignalToStrength
    225   FRIEND_TEST(WiFiServiceTest, SuspectedCredentialFailure);
    226   FRIEND_TEST(WiFiServiceTest, UpdateSecurity);  // SetEAPKeyManagement
    227   FRIEND_TEST(WiFiServiceTest, ConnectWithPreferredDevice);
    228   FRIEND_TEST(WiFiServiceTest, ConfigurePreferredDevice);
    229   FRIEND_TEST(WiFiServiceTest, LoadAndUnloadPreferredDevice);
    230   FRIEND_TEST(WiFiServiceTest, ChooseDevice);
    231   FRIEND_TEST(WiFiServiceUpdateFromEndpointsTest,
    232               AddEndpointWithPreferredDevice);
    233   FRIEND_TEST(WiFiServiceTest, SaveLoadRoamThreshold);
    234 
    235   static const char kAutoConnNoEndpoint[];
    236   static const char kAnyDeviceAddress[];
    237   static const int kSuspectedCredentialFailureThreshold;
    238 
    239   // Override the base clase implementation, because we need to allow
    240   // arguments that aren't base class methods.
    241   void HelpRegisterConstDerivedString(
    242       const std::string& name,
    243       std::string(WiFiService::*get)(Error* error));
    244   void HelpRegisterDerivedString(
    245       const std::string& name,
    246       std::string(WiFiService::*get)(Error* error),
    247       bool(WiFiService::*set)(const std::string& value, Error* error));
    248   void HelpRegisterWriteOnlyDerivedString(
    249       const std::string& name,
    250       bool(WiFiService::*set)(const std::string& value, Error* error),
    251       void(WiFiService::*clear)(Error* error),
    252       const std::string* default_value);
    253   void HelpRegisterDerivedUint16(
    254       const std::string& name,
    255       uint16_t(WiFiService::*get)(Error* error),
    256       bool(WiFiService::*set)(const uint16_t& value, Error* error),
    257       void(WiFiService::*clear)(Error* error));
    258 
    259   std::string GetDeviceRpcId(Error* error) const override;
    260 
    261   void ClearPassphrase(Error* error);
    262   void UpdateConnectable();
    263   void UpdateFromEndpoints();
    264   void UpdateSecurity();
    265 
    266   static CryptoAlgorithm ComputeCipher8021x(
    267       const std::set<WiFiEndpointConstRefPtr>& endpoints);
    268   static void ValidateWEPPassphrase(const std::string& passphrase,
    269                                     Error* error);
    270   static void ValidateWPAPassphrase(const std::string& passphrase,
    271                                     Error* error);
    272   static void ParseWEPPassphrase(const std::string& passphrase,
    273                                  int* key_index,
    274                                  std::vector<uint8_t>* password_bytes,
    275                                  Error* error);
    276   static bool CheckWEPIsHex(const std::string& passphrase, Error* error);
    277   static bool CheckWEPKeyIndex(const std::string& passphrase, Error* error);
    278   static bool CheckWEPPrefix(const std::string& passphrase, Error* error);
    279 
    280   // Maps a signal value, in dBm, to a "strength" value, from
    281   // |Service::kStrengthMin| to |Service:kStrengthMax|.
    282   static uint8_t SignalToStrength(int16_t signal_dbm);
    283 
    284   // Create a default group name for this WiFi service.
    285   std::string GetDefaultStorageIdentifier() const;
    286 
    287   // Return the security of this service.  If connected, the security
    288   // reported from the currently connected endpoint is returned.  Otherwise
    289   // the configured security for the service is returned.
    290   std::string GetSecurity(Error* error);
    291 
    292   // Return the security class of this service.  If connected, the
    293   // security class of the currently connected endpoint is returned.
    294   // Otherwise the configured security class for the service is
    295   // returned.
    296   //
    297   // See also: ComputeSecurityClass.
    298   std::string GetSecurityClass(Error* error);
    299 
    300   // Profile data for a WPA/RSN service can be stored under a number of
    301   // different security types.  These functions create different storage
    302   // property lists based on whether they are saved with their generic
    303   // "psk" name or if they use the (legacy) specific "wpa" or "rsn" names.
    304   KeyValueStore GetStorageProperties() const;
    305 
    306   // Called from DBus and during Load to validate and apply a passphrase for
    307   // this service.  If the passphrase is successfully changed, UpdateConnectable
    308   // and OnCredentialChange are both called and the method returns true.  This
    309   // method will return false if the passphrase cannot be set.  If the
    310   // passphrase is already set to the value of |passphrase|, this method will
    311   // return false.  If it is due to an error, |error| will be populated with the
    312   // appropriate information.
    313   bool SetPassphrase(const std::string& passphrase, Error* error);
    314 
    315   // Called by SetPassphrase and LoadPassphrase to perform the check on a
    316   // passphrase change.  |passphrase| is the new passphrase to be used for the
    317   // service.  If the new passphrase is not different from the existing
    318   // passphrase, SetPassphraseInternal will return false.  |reason| signals how
    319   // the SetPassphraseInternal method was triggered.  If the method was called
    320   // from Load, the has_ever_connected flag will not be reset.  If the method
    321   // was called from SetPassphrase, has_ever_connected will be set to false.
    322   bool SetPassphraseInternal(const std::string& passphrase,
    323                              Service::UpdateCredentialsReason reason);
    324 
    325   // Select a WiFi device (e.g, for connecting a hidden service with no
    326   // endpoints).
    327   WiFiRefPtr ChooseDevice();
    328 
    329   std::string GetPreferredDevice(Error* error);
    330   // Called from DBus and during load to apply the preferred device for this
    331   // service.
    332   bool SetPreferredDevice(const std::string& device_name, Error* error);
    333 
    334   void SetWiFi(const WiFiRefPtr& new_wifi);
    335 
    336   // This method can't be 'const' because it is passed to
    337   // HelpRegisterDerivedUint16, which doesn't take const methods.
    338   uint16_t GetRoamThreshold(Error* error) /*const*/;
    339   bool SetRoamThreshold(const uint16_t& threshold, Error* error);
    340   void ClearRoamThreshold(Error* error);
    341 
    342   // Properties
    343   std::string passphrase_;
    344   bool need_passphrase_;
    345   const std::string security_;
    346   // TODO(cmasone): see if the below can be pulled from the endpoint associated
    347   // with this service instead.
    348   const std::string mode_;
    349   std::string auth_mode_;
    350   bool hidden_ssid_;
    351   uint16_t frequency_;
    352   std::vector<uint16_t> frequency_list_;
    353   uint16_t physical_mode_;
    354   // Preferred device to use for connecting to this service.
    355   std::string preferred_device_;
    356   // The raw dBm signal strength from the associated endpoint.
    357   int16_t raw_signal_strength_;
    358   std::string hex_ssid_;
    359   std::string storage_identifier_;
    360   std::string bssid_;
    361   Stringmap vendor_information_;
    362   // The country code reported by the current endpoint.
    363   std::string country_code_;
    364   // If |security_| == kSecurity8021x, the crypto algorithm being used.
    365   // (Otherwise, crypto algorithm is implied by |security_|.)
    366   CryptoAlgorithm cipher_8021x_;
    367 
    368   // Track the number of consecutive times our current credentials have
    369   // been called into question.
    370   int suspected_credential_failures_;
    371 
    372   // Track whether or not we've warned about large signal values.
    373   // Used to avoid spamming the log.
    374   static bool logged_signal_warning;
    375 
    376   WiFiRefPtr wifi_;
    377   std::set<WiFiEndpointConstRefPtr> endpoints_;
    378   WiFiEndpointConstRefPtr current_endpoint_;
    379   const std::vector<uint8_t> ssid_;
    380   // Track whether IEEE 802.11w (Protected Management Frame) support is
    381   // mandated by one or more endpoints we have seen that provide this service.
    382   bool ieee80211w_required_;
    383   // Flag indicating if service disconnect is initiated by user for
    384   // connecting to other service.
    385   bool expecting_disconnect_;
    386   std::unique_ptr<CertificateFile> certificate_file_;
    387   uint16_t roam_threshold_db_;
    388   bool roam_threshold_db_set_;
    389   // Bare pointer is safe because WiFi service instances are owned by
    390   // the WiFiProvider and are guaranteed to be deallocated by the time
    391   // the WiFiProvider is.
    392   WiFiProvider* provider_;
    393 
    394   DISALLOW_COPY_AND_ASSIGN(WiFiService);
    395 };
    396 
    397 }  // namespace shill
    398 
    399 #endif  // SHILL_WIFI_WIFI_SERVICE_H_
    400