| // Copyright (c) 2012 The Chromium OS 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 SHILL_WIFI_SERVICE_ |
| #define SHILL_WIFI_SERVICE_ |
| |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include <base/memory/scoped_ptr.h> |
| |
| #include "shill/dbus_proxies/supplicant-interface.h" |
| #include "shill/dbus_properties.h" |
| #include "shill/event_dispatcher.h" |
| #include "shill/key_value_store.h" |
| #include "shill/refptr_types.h" |
| #include "shill/service.h" |
| |
| namespace shill { |
| |
| class CertificateFile; |
| class ControlInterface; |
| class EventDispatcher; |
| class Error; |
| class Manager; |
| class Metrics; |
| class WiFiProvider; |
| |
| class WiFiService : public Service { |
| public: |
| // TODO(pstew): Storage constants shouldn't need to be public |
| // crbug.com/208736 |
| static const char kStorageHiddenSSID[]; |
| static const char kStorageMode[]; |
| static const char kStoragePassphrase[]; |
| static const char kStorageSecurity[]; |
| static const char kStorageSecurityClass[]; |
| static const char kStorageSSID[]; |
| |
| WiFiService(ControlInterface *control_interface, |
| EventDispatcher *dispatcher, |
| Metrics *metrics, |
| Manager *manager, |
| WiFiProvider *provider, |
| const std::vector<uint8_t> &ssid, |
| const std::string &mode, |
| const std::string &security, |
| bool hidden_ssid); |
| ~WiFiService(); |
| |
| // Inherited from Service. |
| virtual void Connect(Error *error, const char *reason); |
| virtual void Disconnect(Error *error); |
| virtual bool Is8021x() const; |
| |
| virtual void AddEndpoint(const WiFiEndpointConstRefPtr &endpoint); |
| virtual void RemoveEndpoint(const WiFiEndpointConstRefPtr &endpoint); |
| virtual int GetEndpointCount() const { return endpoints_.size(); } |
| |
| // Called to update the identity of the currently connected endpoint. |
| // To indicate that there is no currently connect endpoint, call with |
| // |endpoint| set to NULL. |
| virtual void NotifyCurrentEndpoint(const WiFiEndpointConstRefPtr &endpoint); |
| // Called to inform of changes in the properties of an endpoint. |
| // (Not necessarily the currently connected endpoint.) |
| virtual void NotifyEndpointUpdated(const WiFiEndpointConstRefPtr &endpoint); |
| |
| // wifi_<MAC>_<BSSID>_<mode_string>_<security_string> |
| std::string GetStorageIdentifier() const; |
| static bool ParseStorageIdentifier(const std::string &storage_name, |
| std::string *address, |
| std::string *mode, |
| std::string *security); |
| |
| // Iterate over |storage| looking for WiFi servces with "old-style" |
| // properties that don't include explicit type/mode/security, and add |
| // these properties. Returns true if any entries were fixed. |
| static bool FixupServiceEntries(StoreInterface *storage); |
| |
| // Validate |mode| against all valid and supported service modes. |
| static bool IsValidMode(const std::string &mode); |
| |
| // Validate |method| against all valid and supported security methods. |
| static bool IsValidSecurityMethod(const std::string &method); |
| |
| const std::string &mode() const { return mode_; } |
| const std::string &key_management() const { return GetEAPKeyManagement(); } |
| const std::vector<uint8_t> &ssid() const { return ssid_; } |
| const std::string &bssid() const { return bssid_; } |
| const std::vector<uint16> &frequency_list() const { return frequency_list_; } |
| uint16 physical_mode() const { return physical_mode_; } |
| uint16 frequency() const { return frequency_; } |
| |
| // WiFi services can load from profile entries other than their current |
| // storage identifier. Override the methods from the parent Service |
| // class which pertain to whether this service may be loaded from |storage|. |
| virtual std::string GetLoadableStorageIdentifier( |
| const StoreInterface &storage) const; |
| virtual bool IsLoadableFrom(const StoreInterface &storage) const; |
| |
| // Overrride Load and Save from parent Service class. We will call |
| // the parent method. |
| virtual bool Load(StoreInterface *storage); |
| virtual bool Save(StoreInterface *storage); |
| virtual bool Unload(); |
| |
| // Override SetState from parent Service class. We will call the |
| // parent method. |
| virtual void SetState(ConnectState state) override; |
| |
| virtual bool HasEndpoints() const { return !endpoints_.empty(); } |
| virtual bool IsVisible() const override; |
| bool IsSecurityMatch(const std::string &security) const; |
| |
| // Used by WiFi objects to indicate that the credentials for this network |
| // have been called into question. This method returns true if given this |
| // suspicion, if it is probable that indeed these credentials are likely |
| // to be incorrect. Credentials that have never been used before are |
| // considered suspect by default, while those which have been used |
| // successfully in the past must have this method called a number of times |
| // since the last time ResetSuspectedCredentialsFailures() was called. |
| virtual bool AddSuspectedCredentialFailure(); |
| virtual void ResetSuspectedCredentialFailures(); |
| |
| bool hidden_ssid() const { return hidden_ssid_; } |
| bool ieee80211w_required() const { return ieee80211w_required_; } |
| |
| void InitializeCustomMetrics() const; |
| virtual void SendPostReadyStateMetrics( |
| int64 time_resume_to_ready_milliseconds) const; |
| |
| // Clear any cached credentials stored in wpa_supplicant related to |this|. |
| // This will disconnect this service if it is currently connected. |
| void ClearCachedCredentials(); |
| |
| // Override from parent Service class to correctly update connectability |
| // when the EAP credentials change for 802.1x networks. |
| void OnEapCredentialsChanged(); |
| |
| // Override from parent Service class to register hidden services once they |
| // have been configured. |
| virtual void OnProfileConfigured(); |
| |
| // Called by WiFiProvider to reset the WiFi device reference on shutdown. |
| virtual void ResetWiFi(); |
| |
| // Called by WiFi to retrieve configuration parameters for wpa_supplicant. |
| virtual DBusPropertiesMap GetSupplicantConfigurationParameters() const; |
| |
| // "wpa", "rsn" and "psk" are equivalent from a configuration perspective. |
| // This function maps them all into "psk". |
| static std::string GetSecurityClass(const std::string &security); |
| |
| virtual bool IsAutoConnectable(const char **reason) const; |
| |
| // Signal level in dBm. If no current endpoint, returns |
| // std::numeric_limits<int>::min(). |
| int16 SignalLevel() const; |
| |
| void set_expecting_disconnect(bool val) { expecting_disconnect_ = val; } |
| bool expecting_disconnect() const { return expecting_disconnect_; } |
| |
| protected: |
| virtual void SetEAPKeyManagement(const std::string &key_management); |
| virtual std::string GetTethering(Error *error) const override; |
| |
| private: |
| friend class WiFiServiceSecurityTest; |
| friend class WiFiServiceTest; // SetPassphrase |
| friend class WiFiServiceUpdateFromEndpointsTest; // SignalToStrength |
| FRIEND_TEST(MetricsTest, WiFiServicePostReady); |
| FRIEND_TEST(MetricsTest, WiFiServicePostReadyAdHoc); |
| FRIEND_TEST(MetricsTest, WiFiServicePostReadyEAP); |
| FRIEND_TEST(WiFiMainTest, CurrentBSSChangedUpdateServiceEndpoint); |
| FRIEND_TEST(WiFiProviderTest, OnEndpointAddedWithSecurity); // security_ |
| FRIEND_TEST(WiFiServiceTest, AutoConnect); |
| FRIEND_TEST(WiFiServiceTest, ClearWriteOnlyDerivedProperty); // passphrase_ |
| FRIEND_TEST(WiFiServiceTest, ComputeCipher8021x); |
| FRIEND_TEST(WiFiServiceTest, ConnectTask8021x); |
| FRIEND_TEST(WiFiServiceTest, ConnectTaskDynamicWEP); |
| FRIEND_TEST(WiFiServiceTest, ConnectTaskPSK); |
| FRIEND_TEST(WiFiServiceTest, ConnectTaskRSN); |
| FRIEND_TEST(WiFiServiceTest, ConnectTaskWEP); |
| FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA); |
| FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA80211w); |
| FRIEND_TEST(WiFiServiceTest, GetTethering); |
| FRIEND_TEST(WiFiServiceTest, IsAutoConnectable); |
| FRIEND_TEST(WiFiServiceTest, LoadHidden); |
| FRIEND_TEST(WiFiServiceTest, LoadAndUnloadPassphrase); |
| FRIEND_TEST(WiFiServiceTest, SecurityFromCurrentEndpoint); // GetSecurity |
| FRIEND_TEST(WiFiServiceTest, SetPassphraseRemovesCachedCredentials); |
| FRIEND_TEST(WiFiServiceTest, SignalToStrength); // SignalToStrength |
| FRIEND_TEST(WiFiServiceTest, SuspectedCredentialFailure); |
| FRIEND_TEST(WiFiServiceTest, UpdateSecurity); // SetEAPKeyManagement |
| |
| static const char kAutoConnNoEndpoint[]; |
| static const char kAnyDeviceAddress[]; |
| static const int kSuspectedCredentialFailureThreshold; |
| |
| // Override the base clase implementation, because we need to allow |
| // arguments that aren't base class methods. |
| void HelpRegisterConstDerivedString( |
| const std::string &name, |
| std::string(WiFiService::*get)(Error *error)); |
| void HelpRegisterDerivedString( |
| const std::string &name, |
| std::string(WiFiService::*get)(Error *error), |
| bool(WiFiService::*set)(const std::string &value, Error *error)); |
| void HelpRegisterWriteOnlyDerivedString( |
| const std::string &name, |
| bool(WiFiService::*set)(const std::string &value, Error *error), |
| void(WiFiService::*clear)(Error *error), |
| const std::string *default_value); |
| |
| std::string GetDeviceRpcId(Error *error) const; |
| |
| void ClearPassphrase(Error *error); |
| void UpdateConnectable(); |
| void UpdateFromEndpoints(); |
| void UpdateSecurity(); |
| |
| static CryptoAlgorithm ComputeCipher8021x( |
| const std::set<WiFiEndpointConstRefPtr> &endpoints); |
| static void ValidateWEPPassphrase(const std::string &passphrase, |
| Error *error); |
| static void ValidateWPAPassphrase(const std::string &passphrase, |
| Error *error); |
| static void ParseWEPPassphrase(const std::string &passphrase, |
| int *key_index, |
| std::vector<uint8> *password_bytes, |
| Error *error); |
| static bool CheckWEPIsHex(const std::string &passphrase, Error *error); |
| static bool CheckWEPKeyIndex(const std::string &passphrase, Error *error); |
| static bool CheckWEPPrefix(const std::string &passphrase, Error *error); |
| |
| // Maps a signal value, in dBm, to a "strength" value, from |
| // |Service::kStrengthMin| to |Service:kStrengthMax|. |
| static uint8 SignalToStrength(int16 signal_dbm); |
| |
| // Create a default group name for this WiFi service. |
| std::string GetDefaultStorageIdentifier() const; |
| |
| // Return the security of this service. If connected, the security |
| // reported from the currently connected endpoint is returned. Otherwise |
| // the configured security for the service is returned. |
| std::string GetSecurity(Error *error); |
| |
| // Profile data for a WPA/RSN service can be stored under a number of |
| // different security types. These functions create different storage |
| // property lists based on whether they are saved with their generic |
| // "psk" name or if they use the (legacy) specific "wpa" or "rsn" names. |
| KeyValueStore GetStorageProperties() const; |
| |
| // Validate then apply a passphrase for this service. |
| bool SetPassphrase(const std::string &passphrase, Error *error); |
| |
| // Select a WiFi device (e.g, for connecting a hidden service with no |
| // endpoints). |
| WiFiRefPtr ChooseDevice(); |
| |
| void SetWiFi(const WiFiRefPtr &new_wifi); |
| |
| // Properties |
| std::string passphrase_; |
| bool need_passphrase_; |
| const std::string security_; |
| // TODO(cmasone): see if the below can be pulled from the endpoint associated |
| // with this service instead. |
| const std::string mode_; |
| std::string auth_mode_; |
| bool hidden_ssid_; |
| uint16 frequency_; |
| std::vector<uint16> frequency_list_; |
| uint16 physical_mode_; |
| // The raw dBm signal strength from the associated endpoint. |
| int16 raw_signal_strength_; |
| std::string hex_ssid_; |
| std::string storage_identifier_; |
| std::string bssid_; |
| Stringmap vendor_information_; |
| // The country code reported by the current endpoint. |
| std::string country_code_; |
| // If |security_| == kSecurity8021x, the crypto algorithm being used. |
| // (Otherwise, crypto algorithm is implied by |security_|.) |
| CryptoAlgorithm cipher_8021x_; |
| |
| // Track the number of consecutive times our current credentials have |
| // been called into question. |
| int suspected_credential_failures_; |
| |
| // Track whether or not we've warned about large signal values. |
| // Used to avoid spamming the log. |
| static bool logged_signal_warning; |
| |
| WiFiRefPtr wifi_; |
| std::set<WiFiEndpointConstRefPtr> endpoints_; |
| WiFiEndpointConstRefPtr current_endpoint_; |
| const std::vector<uint8_t> ssid_; |
| // Track whether IEEE 802.11w (Protected Management Frame) support is |
| // mandated by one or more endpoints we have seen that provide this service. |
| bool ieee80211w_required_; |
| // Flag indicating if service disconnect is initiated by user for |
| // connecting to other service. |
| bool expecting_disconnect_; |
| scoped_ptr<CertificateFile> certificate_file_; |
| // Bare pointer is safe because WiFi service instances are owned by |
| // the WiFiProvider and are guaranteed to be deallocated by the time |
| // the WiFiProvider is. |
| WiFiProvider *provider_; |
| |
| DISALLOW_COPY_AND_ASSIGN(WiFiService); |
| }; |
| |
| } // namespace shill |
| |
| #endif // SHILL_WIFI_SERVICE_ |