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