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 #include "shill/wifi/wifi_service.h" 18 19 #include <limits> 20 #include <map> 21 #include <set> 22 #include <string> 23 #include <vector> 24 25 #include <base/strings/stringprintf.h> 26 #include <base/strings/string_number_conversions.h> 27 #include <base/strings/string_util.h> 28 #if defined(__ANDROID__) 29 #include <dbus/service_constants.h> 30 #else 31 #include <chromeos/dbus/service_constants.h> 32 #endif // __ANDROID__ 33 #include <gmock/gmock.h> 34 #include <gtest/gtest.h> 35 36 #include "shill/event_dispatcher.h" 37 #include "shill/manager.h" 38 #include "shill/metrics.h" 39 #include "shill/mock_adaptors.h" 40 #include "shill/mock_certificate_file.h" 41 #include "shill/mock_control.h" 42 #include "shill/mock_eap_credentials.h" 43 #include "shill/mock_log.h" 44 #include "shill/mock_manager.h" 45 #include "shill/mock_profile.h" 46 #include "shill/mock_service.h" 47 #include "shill/mock_store.h" 48 #include "shill/property_store_unittest.h" 49 #include "shill/refptr_types.h" 50 #include "shill/service_property_change_test.h" 51 #include "shill/supplicant/wpa_supplicant.h" 52 #include "shill/technology.h" 53 #include "shill/tethering.h" 54 #include "shill/wifi/mock_wifi.h" 55 #include "shill/wifi/mock_wifi_provider.h" 56 #include "shill/wifi/wifi_endpoint.h" 57 58 using base::FilePath; 59 using std::map; 60 using std::set; 61 using std::string; 62 using std::vector; 63 using ::testing::_; 64 using ::testing::AnyNumber; 65 using ::testing::DoAll; 66 using ::testing::EndsWith; 67 using ::testing::HasSubstr; 68 using ::testing::Mock; 69 using ::testing::NiceMock; 70 using ::testing::Return; 71 using ::testing::ReturnRef; 72 using ::testing::SetArgumentPointee; 73 using ::testing::StrEq; 74 using ::testing::StrNe; 75 using ::testing::StrictMock; 76 77 namespace shill { 78 79 class WiFiServiceTest : public PropertyStoreTest { 80 public: 81 WiFiServiceTest() 82 : mock_manager_(control_interface(), dispatcher(), metrics()), 83 wifi_( 84 new NiceMock<MockWiFi>(control_interface(), 85 dispatcher(), 86 metrics(), 87 manager(), 88 "wifi", 89 fake_mac, 90 0)), 91 simple_ssid_(1, 'a'), 92 simple_ssid_string_("a") {} 93 virtual ~WiFiServiceTest() {} 94 95 protected: 96 static const char fake_mac[]; 97 98 MockEapCredentials* SetMockEap( 99 const WiFiServiceRefPtr& service) { 100 MockEapCredentials* eap = new MockEapCredentials(); 101 service->eap_.reset(eap); // Passes ownership. 102 return eap; 103 } 104 bool CheckConnectable(const string& security, const char* passphrase, 105 bool is_1x_connectable) { 106 Error error; 107 WiFiServiceRefPtr service = MakeSimpleService(security); 108 if (passphrase) 109 service->SetPassphrase(passphrase, &error); 110 MockEapCredentials* eap = SetMockEap(service); 111 EXPECT_CALL(*eap, IsConnectable()) 112 .WillRepeatedly(Return(is_1x_connectable)); 113 const string kKeyManagement8021x(WPASupplicant::kKeyManagementIeee8021X); 114 if (security == kSecurityWep && is_1x_connectable) { 115 EXPECT_CALL(*eap, key_management()) 116 .WillRepeatedly(ReturnRef(kKeyManagement8021x)); 117 } 118 service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded); 119 return service->connectable(); 120 } 121 WiFiEndpoint* MakeEndpoint(const string& ssid, const string& bssid, 122 uint16_t frequency, int16_t signal_dbm, 123 bool has_wpa_property, bool has_rsn_property) { 124 return WiFiEndpoint::MakeEndpoint( 125 nullptr, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure, 126 frequency, signal_dbm, has_wpa_property, has_rsn_property); 127 } 128 WiFiEndpoint* MakeOpenEndpoint(const string& ssid, const string& bssid, 129 uint16_t frequency, int16_t signal_dbm) { 130 return WiFiEndpoint::MakeOpenEndpoint( 131 nullptr, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure, 132 frequency, signal_dbm); 133 } 134 WiFiEndpoint* MakeOpenEndpointWithWiFi(WiFiRefPtr wifi, 135 const string& ssid, 136 const string& bssid, 137 uint16_t frequency, 138 int16_t signal_dbm) { 139 return WiFiEndpoint::MakeOpenEndpoint( 140 nullptr, wifi, ssid, bssid, WPASupplicant::kNetworkModeInfrastructure, 141 frequency, signal_dbm); 142 } 143 WiFiServiceRefPtr MakeSimpleService(const string& security) { 144 return new WiFiService(control_interface(), 145 dispatcher(), 146 metrics(), 147 manager(), 148 &provider_, 149 simple_ssid_, 150 kModeManaged, 151 security, 152 false); 153 } 154 WiFiServiceRefPtr MakeGenericService() { 155 return MakeSimpleService(kSecurityWep); 156 } 157 void SetWiFi(WiFiServiceRefPtr service, WiFiRefPtr wifi) { 158 service->SetWiFi(wifi); // Has side-effects. 159 } 160 void SetWiFiForService(WiFiServiceRefPtr service, WiFiRefPtr wifi) { 161 service->wifi_ = wifi; 162 } 163 WiFiServiceRefPtr MakeServiceWithWiFi(const string& security) { 164 WiFiServiceRefPtr service = MakeSimpleService(security); 165 SetWiFiForService(service, wifi_); 166 return service; 167 } 168 WiFiServiceRefPtr MakeServiceWithMockManager() { 169 return new WiFiService(control_interface(), 170 dispatcher(), 171 metrics(), 172 &mock_manager_, 173 &provider_, 174 simple_ssid_, 175 kModeManaged, 176 kSecurityNone, 177 false); 178 } 179 scoped_refptr<MockWiFi> MakeSimpleWiFi(const string& link_name) { 180 return new NiceMock<MockWiFi>(control_interface(), 181 dispatcher(), 182 metrics(), 183 manager(), 184 link_name, 185 fake_mac, 186 0); 187 } 188 ServiceMockAdaptor* GetAdaptor(WiFiService* service) { 189 return static_cast<ServiceMockAdaptor*>(service->adaptor()); 190 } 191 Error::Type TestConfigurePassphrase(const string& security, 192 const char* passphrase) { 193 WiFiServiceRefPtr service = MakeSimpleService(security); 194 KeyValueStore args; 195 if (passphrase) { 196 args.SetString(kPassphraseProperty, passphrase); 197 } 198 Error error; 199 service->Configure(args, &error); 200 return error.type(); 201 } 202 bool SetRoamThreshold(WiFiServiceRefPtr service, uint16_t threshold) { 203 return service->SetRoamThreshold(threshold, nullptr); 204 } 205 uint16_t GetRoamThreshold(WiFiServiceRefPtr service) const { 206 return service->GetRoamThreshold(nullptr); 207 } 208 scoped_refptr<MockWiFi> wifi() { return wifi_; } 209 MockManager* mock_manager() { return &mock_manager_; } 210 MockWiFiProvider* provider() { return &provider_; } 211 string GetAnyDeviceAddress() { return WiFiService::kAnyDeviceAddress; } 212 const vector<uint8_t>& simple_ssid() { return simple_ssid_; } 213 const string& simple_ssid_string() { return simple_ssid_string_; } 214 215 private: 216 MockManager mock_manager_; 217 scoped_refptr<MockWiFi> wifi_; 218 MockWiFiProvider provider_; 219 const vector<uint8_t> simple_ssid_; 220 const string simple_ssid_string_; 221 }; 222 223 // static 224 const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF"; 225 226 MATCHER_P3(ContainsWiFiProperties, ssid, mode, security, "") { 227 string hex_ssid = base::HexEncode(ssid.data(), ssid.size()); 228 return 229 arg.ContainsString(WiFiService::kStorageType) && 230 arg.GetString(WiFiService::kStorageType) == kTypeWifi && 231 arg.ContainsString(WiFiService::kStorageSSID) && 232 arg.GetString(WiFiService::kStorageSSID) == hex_ssid && 233 arg.ContainsString(WiFiService::kStorageMode) && 234 arg.GetString(WiFiService::kStorageMode) == mode && 235 arg.ContainsString(WiFiService::kStorageSecurityClass) && 236 arg.GetString(WiFiService::kStorageSecurityClass) == security; 237 } 238 239 class WiFiServiceSecurityTest : public WiFiServiceTest { 240 public: 241 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service, 242 const string& security) { 243 string id = wifi_service->GetStorageIdentifier(); 244 size_t mac_pos = id.find(base::ToLowerASCII(GetAnyDeviceAddress())); 245 EXPECT_NE(mac_pos, string::npos); 246 size_t mode_pos = id.find(string(kModeManaged), mac_pos); 247 EXPECT_NE(mode_pos, string::npos); 248 return id.find(string(security), mode_pos) != string::npos; 249 } 250 251 // Test that a service that is created with security |from_security| 252 // gets by default a storage identifier with |to_security| as its 253 // security component, and that when saved, it sets the Security 254 // property in to |to_security| as well. 255 bool TestStorageMapping(const string& from_security, 256 const string& to_security) { 257 WiFiServiceRefPtr wifi_service = MakeSimpleService(from_security); 258 NiceMock<MockStore> mock_store; 259 EXPECT_CALL(mock_store, SetString(_, _, _)).WillRepeatedly(Return(true)); 260 EXPECT_CALL(mock_store, 261 SetString(_, WiFiService::kStorageSecurity, from_security)) 262 .Times(1); 263 EXPECT_CALL(mock_store, 264 SetString(_, WiFiService::kStorageSecurityClass, to_security)) 265 .Times(1); 266 wifi_service->Save(&mock_store); 267 return TestStorageSecurityIs(wifi_service, to_security); 268 } 269 270 // Test whether a service of type |service_security| can load from a 271 // storage interface containing an entry for |storage_security|. 272 // Make sure the result meets |expectation|. If |expectation| is 273 // true, also make sure the service storage identifier changes to 274 // match |storage_security|. 275 bool TestLoadMapping(const string& service_security, 276 const string& storage_security, 277 bool expectation) { 278 WiFiServiceRefPtr wifi_service = MakeSimpleService(service_security); 279 NiceMock<MockStore> mock_store; 280 EXPECT_CALL(mock_store, GetGroupsWithProperties(_)) 281 .WillRepeatedly(Return(set<string>())); 282 const string kStorageId = "storage_id"; 283 EXPECT_CALL(mock_store, ContainsGroup(kStorageId)) 284 .WillRepeatedly(Return(true)); 285 set<string> groups; 286 groups.insert(kStorageId); 287 EXPECT_CALL(mock_store, GetGroupsWithProperties( 288 ContainsWiFiProperties(wifi_service->ssid(), 289 kModeManaged, 290 storage_security))) 291 .WillRepeatedly(Return(groups)); 292 bool is_loadable = wifi_service->IsLoadableFrom(mock_store); 293 EXPECT_EQ(expectation, is_loadable); 294 bool is_loaded = wifi_service->Load(&mock_store); 295 EXPECT_EQ(expectation, is_loaded); 296 const string expected_identifier(expectation ? kStorageId : ""); 297 EXPECT_EQ(expected_identifier, 298 wifi_service->GetLoadableStorageIdentifier(mock_store)); 299 300 if (expectation != is_loadable || expectation != is_loaded) { 301 return false; 302 } else if (!expectation) { 303 return true; 304 } else { 305 return wifi_service->GetStorageIdentifier() == kStorageId; 306 } 307 } 308 }; 309 310 class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest { 311 public: 312 WiFiServiceUpdateFromEndpointsTest() 313 : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)), 314 kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)), 315 kGoodEndpointStrength( 316 WiFiService::SignalToStrength(kGoodEndpointSignal)), 317 service(MakeGenericService()), 318 adaptor(*GetAdaptor(service.get())) { 319 ok_endpoint = MakeOpenEndpoint( 320 simple_ssid_string(), kOkEndpointBssId, kOkEndpointFrequency, 321 kOkEndpointSignal); 322 good_endpoint = MakeOpenEndpoint( 323 simple_ssid_string(), kGoodEndpointBssId, kGoodEndpointFrequency, 324 kGoodEndpointSignal); 325 bad_endpoint = MakeOpenEndpoint( 326 simple_ssid_string(), kBadEndpointBssId, kBadEndpointFrequency, 327 kBadEndpointSignal); 328 } 329 330 protected: 331 static const uint16_t kOkEndpointFrequency = 2422; 332 static const uint16_t kBadEndpointFrequency = 2417; 333 static const uint16_t kGoodEndpointFrequency = 2412; 334 static const int16_t kOkEndpointSignal = -50; 335 static const int16_t kBadEndpointSignal = -75; 336 static const int16_t kGoodEndpointSignal = -25; 337 static const char* kOkEndpointBssId; 338 static const char* kGoodEndpointBssId; 339 static const char* kBadEndpointBssId; 340 // Can't be both static and const (because initialization requires a 341 // function call). So choose to be just const. 342 const uint8_t kOkEndpointStrength; 343 const uint8_t kBadEndpointStrength; 344 const uint8_t kGoodEndpointStrength; 345 WiFiEndpointRefPtr ok_endpoint; 346 WiFiEndpointRefPtr bad_endpoint; 347 WiFiEndpointRefPtr good_endpoint; 348 WiFiServiceRefPtr service; 349 ServiceMockAdaptor& adaptor; 350 }; 351 352 const char* WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId = 353 "00:00:00:00:00:01"; 354 const char* WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId = 355 "00:00:00:00:00:02"; 356 const char* WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId = 357 "00:00:00:00:00:03"; 358 359 class WiFiServiceFixupStorageTest : public WiFiServiceTest { 360 protected: 361 void AddGroup(string group_name) { 362 groups_.insert(group_name); 363 } 364 365 void AddServiceEntry(bool has_type, bool has_mode, bool has_security, 366 bool has_security_class) { 367 int index = groups_.size(); 368 string id = base::StringPrintf("%s_%d_%d_%s_%s", kTypeWifi, 369 index, index, kModeManaged, 370 kSecurityWpa); 371 AddGroup(id); 372 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageType, _)) 373 .WillOnce(Return(has_type)); 374 if (!has_type) { 375 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageType, 376 kTypeWifi)); 377 } 378 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageMode, _)) 379 .WillOnce(Return(has_mode)); 380 if (!has_mode) { 381 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageMode, 382 kModeManaged)); 383 } 384 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurity, _)) 385 .WillOnce(Return(has_security)); 386 if (!has_security) { 387 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurity, 388 kSecurityWpa)); 389 } 390 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurityClass, _)) 391 .WillOnce(Return(has_security_class)); 392 if (!has_security_class) { 393 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurityClass, 394 kSecurityPsk)); 395 } 396 } 397 398 bool FixupServiceEntries() { 399 EXPECT_CALL(store_, GetGroups()).WillOnce(Return(groups_)); 400 return WiFiService::FixupServiceEntries(&store_); 401 } 402 403 private: 404 StrictMock<MockStore> store_; 405 set<string> groups_; 406 }; 407 408 TEST_F(WiFiServiceTest, Constructor) { 409 string histogram = metrics()->GetFullMetricName( 410 Metrics::kMetricTimeToJoinMillisecondsSuffix, Technology::kWifi); 411 EXPECT_CALL(*metrics(), AddServiceStateTransitionTimer(_, _, _, _)) 412 .Times(AnyNumber()); 413 EXPECT_CALL(*metrics(), AddServiceStateTransitionTimer( 414 _, histogram, Service::kStateAssociating, Service::kStateConfiguring)); 415 MakeSimpleService(kSecurityNone); 416 } 417 418 TEST_F(WiFiServiceTest, StorageId) { 419 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityNone); 420 string id = wifi_service->GetStorageIdentifier(); 421 for (uint i = 0; i < id.length(); ++i) { 422 EXPECT_TRUE(id[i] == '_' || 423 isxdigit(id[i]) || 424 (isalpha(id[i]) && islower(id[i]))); 425 } 426 size_t mac_pos = id.find(base::ToLowerASCII(GetAnyDeviceAddress())); 427 EXPECT_NE(mac_pos, string::npos); 428 EXPECT_NE(id.find(string(kModeManaged), mac_pos), string::npos); 429 } 430 431 // Make sure the passphrase is registered as a write only property 432 // by reading and comparing all string properties returned on the store. 433 TEST_F(WiFiServiceTest, PassphraseWriteOnly) { 434 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityWpa); 435 ReadablePropertyConstIterator<string> it = 436 (wifi_service->store()).GetStringPropertiesIter(); 437 for ( ; !it.AtEnd(); it.Advance()) 438 EXPECT_NE(it.Key(), kPassphraseProperty); 439 } 440 441 // Make sure setting the passphrase via D-Bus Service.SetProperty validates 442 // the passphrase. 443 TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) { 444 // We only spot check two password cases here to make sure the 445 // SetProperty code path does validation. We're not going to exhaustively 446 // test for all types of passwords. 447 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityWep); 448 Error error; 449 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty( 450 kPassphraseProperty, "0:abcde", &error)); 451 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty( 452 kPassphraseProperty, "invalid", &error)); 453 EXPECT_EQ(Error::kInvalidPassphrase, error.type()); 454 } 455 456 TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) { 457 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityNone); 458 Error error; 459 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty( 460 kPassphraseProperty, "invalid", &error)); 461 EXPECT_EQ(Error::kNotSupported, error.type()); 462 } 463 464 TEST_F(WiFiServiceTest, NonUTF8SSID) { 465 vector<uint8_t> ssid; 466 467 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence 468 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(), 469 dispatcher(), 470 metrics(), 471 manager(), 472 provider(), 473 ssid, 474 kModeManaged, 475 kSecurityNone, 476 false); 477 brillo::VariantDictionary properties; 478 // if service doesn't propertly sanitize SSID, this will generate SIGABRT. 479 EXPECT_TRUE(wifi_service->store().GetProperties(&properties, nullptr)); 480 } 481 482 MATCHER(PSKSecurityArgs, "") { 483 return arg.ContainsString(WPASupplicant::kPropertySecurityProtocol) && 484 arg.GetString(WPASupplicant::kPropertySecurityProtocol) == 485 string("WPA RSN") && 486 arg.ContainsString(WPASupplicant::kPropertyPreSharedKey); 487 } 488 489 MATCHER_P(FrequencyArg, has_arg, "") { 490 return has_arg == 491 arg.ContainsInt(WPASupplicant::kNetworkPropertyFrequency); 492 } 493 494 TEST_F(WiFiServiceTest, ConnectReportBSSes) { 495 WiFiEndpointRefPtr endpoint1 = 496 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0); 497 WiFiEndpointRefPtr endpoint2 = 498 MakeOpenEndpoint("a", "00:00:00:00:00:02", 0, 0); 499 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone); 500 wifi_service->AddEndpoint(endpoint1); 501 wifi_service->AddEndpoint(endpoint2); 502 EXPECT_CALL(*metrics(), NotifyWifiAvailableBSSes(2)); 503 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 504 wifi_service->Connect(nullptr, "in test"); 505 } 506 507 TEST_F(WiFiServiceTest, ConnectWithPreferredDevice) { 508 // Setup service, device, and endpoints. 509 WiFiServiceRefPtr wifi_service = MakeServiceWithMockManager(); 510 const string kDeviceName1 = "test_device1"; 511 const string kDeviceName2 = "test_device2"; 512 scoped_refptr<MockWiFi> wifi1 = MakeSimpleWiFi(kDeviceName1); 513 scoped_refptr<MockWiFi> wifi2 = MakeSimpleWiFi(kDeviceName2); 514 WiFiEndpointRefPtr endpoint1 = 515 MakeOpenEndpointWithWiFi(wifi1, "a", "00:00:00:00:00:01", 0, 0); 516 WiFiEndpointRefPtr endpoint2 = 517 MakeOpenEndpointWithWiFi(wifi2, "a", "00:00:00:00:00:01", 0, 0); 518 519 wifi_service->SetPreferredDevice(kDeviceName1, nullptr); 520 wifi_service->AddEndpoint(endpoint1); 521 wifi_service->AddEndpoint(endpoint2); 522 EXPECT_EQ(wifi1, wifi_service->wifi_); 523 524 EXPECT_CALL(*wifi1, ConnectTo(wifi_service.get())); 525 EXPECT_CALL(*wifi2, ConnectTo(_)).Times(0); 526 wifi_service->Connect(nullptr, "in test"); 527 } 528 529 TEST_F(WiFiServiceTest, ConnectTaskWPA) { 530 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityWpa); 531 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 532 Error error; 533 wifi_service->SetPassphrase("0:mumblemumblem", &error); 534 wifi_service->Connect(nullptr, "in test"); 535 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 536 PSKSecurityArgs()); 537 } 538 539 TEST_F(WiFiServiceTest, ConnectTaskRSN) { 540 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityRsn); 541 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 542 Error error; 543 wifi_service->SetPassphrase("0:mumblemumblem", &error); 544 wifi_service->Connect(nullptr, "in test"); 545 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 546 PSKSecurityArgs()); 547 } 548 549 TEST_F(WiFiServiceTest, ConnectConditions) { 550 Error error; 551 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone); 552 scoped_refptr<MockProfile> mock_profile( 553 new NiceMock<MockProfile>(control_interface(), metrics(), manager())); 554 wifi_service->set_profile(mock_profile); 555 // With nothing else going on, the service should attempt to connect. 556 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 557 wifi_service->Connect(&error, "in test"); 558 Mock::VerifyAndClearExpectations(wifi().get()); 559 560 // But if we're already "connecting" or "connected" then we shouldn't attempt 561 // again. 562 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())).Times(0); 563 wifi_service->SetState(Service::kStateAssociating); 564 wifi_service->Connect(&error, "in test"); 565 wifi_service->SetState(Service::kStateConfiguring); 566 wifi_service->Connect(&error, "in test"); 567 wifi_service->SetState(Service::kStateConnected); 568 wifi_service->Connect(&error, "in test"); 569 wifi_service->SetState(Service::kStatePortal); 570 wifi_service->Connect(&error, "in test"); 571 wifi_service->SetState(Service::kStateOnline); 572 wifi_service->Connect(&error, "in test"); 573 Mock::VerifyAndClearExpectations(wifi().get()); 574 } 575 576 TEST_F(WiFiServiceTest, ConnectTaskPSK) { 577 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityPsk); 578 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 579 Error error; 580 wifi_service->SetPassphrase("0:mumblemumblem", &error); 581 wifi_service->Connect(nullptr, "in test"); 582 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 583 PSKSecurityArgs()); 584 } 585 586 TEST_F(WiFiServiceTest, ConnectTask8021x) { 587 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurity8021x); 588 service->mutable_eap()->set_identity("identity"); 589 service->mutable_eap()->set_password("mumble"); 590 service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded); 591 EXPECT_CALL(*wifi(), ConnectTo(service.get())); 592 service->Connect(nullptr, "in test"); 593 KeyValueStore params = service->GetSupplicantConfigurationParameters(); 594 EXPECT_TRUE( 595 params.ContainsString(WPASupplicant::kNetworkPropertyEapIdentity)); 596 EXPECT_TRUE(params.ContainsString(WPASupplicant::kNetworkPropertyCaPath)); 597 } 598 599 TEST_F(WiFiServiceTest, ConnectTask8021xWithMockEap) { 600 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurity8021x); 601 MockEapCredentials* eap = SetMockEap(service); 602 EXPECT_CALL(*eap, IsConnectable()).WillOnce(Return(true)); 603 EXPECT_CALL(*wifi(), ConnectTo(service.get())); 604 service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded); 605 service->Connect(nullptr, "in test"); 606 607 EXPECT_CALL(*eap, PopulateSupplicantProperties(_, _)); 608 // The mocked function does not actually set EAP parameters so we cannot 609 // expect them to be set. 610 service->GetSupplicantConfigurationParameters(); 611 } 612 613 TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) { 614 vector<uint8_t> ssid(1, 'a'); 615 WiFiEndpointRefPtr endpoint_nofreq = 616 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0); 617 WiFiEndpointRefPtr endpoint_freq = 618 MakeOpenEndpoint("a", "00:00:00:00:00:02", 2412, 0); 619 620 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone); 621 wifi_service->AddEndpoint(endpoint_freq); 622 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 623 wifi_service->Connect(nullptr, "in test"); 624 625 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 626 FrequencyArg(false)); 627 628 wifi_service = new WiFiService(control_interface(), 629 dispatcher(), 630 metrics(), 631 manager(), 632 provider(), 633 ssid, 634 kModeAdhoc, 635 kSecurityNone, 636 false); 637 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 638 SetWiFiForService(wifi_service, wifi()); 639 wifi_service->Connect(nullptr, "in test"); 640 641 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 642 FrequencyArg(false)); 643 644 wifi_service = new WiFiService(control_interface(), 645 dispatcher(), 646 metrics(), 647 manager(), 648 provider(), 649 ssid, 650 kModeAdhoc, 651 kSecurityNone, 652 false); 653 wifi_service->AddEndpoint(endpoint_nofreq); 654 SetWiFiForService(wifi_service, wifi()); 655 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 656 wifi_service->Connect(nullptr, "in test"); 657 658 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 659 FrequencyArg(false)); 660 661 wifi_service = new WiFiService(control_interface(), 662 dispatcher(), 663 metrics(), 664 manager(), 665 provider(), 666 ssid, 667 kModeAdhoc, 668 kSecurityNone, 669 false); 670 wifi_service->AddEndpoint(endpoint_freq); 671 SetWiFiForService(wifi_service, wifi()); 672 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 673 wifi_service->Connect(nullptr, "in test"); 674 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 675 FrequencyArg(true)); 676 } 677 678 TEST_F(WiFiServiceTest, ConnectTaskWPA80211w) { 679 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityPsk); 680 WiFiEndpointRefPtr endpoint = 681 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0); 682 endpoint->ieee80211w_required_ = true; 683 wifi_service->AddEndpoint(endpoint); 684 Error error; 685 wifi_service->SetPassphrase("0:mumblemumblem", &error); 686 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 687 wifi_service->Connect(nullptr, "in test"); 688 689 KeyValueStore params = 690 wifi_service->GetSupplicantConfigurationParameters(); 691 EXPECT_TRUE(params.ContainsString(WPASupplicant::kPropertySecurityProtocol)); 692 EXPECT_TRUE(params.ContainsString(WPASupplicant::kPropertyPreSharedKey)); 693 EXPECT_TRUE(params.ContainsUint(WPASupplicant::kNetworkPropertyIeee80211w)); 694 } 695 696 MATCHER_P(WEPSecurityArgsKeyIndex, index, "") { 697 uint32_t index_u32 = index; 698 return arg.ContainsString(WPASupplicant::kPropertyAuthAlg) && 699 arg.ContainsUint8s( 700 WPASupplicant::kPropertyWEPKey + base::IntToString(index)) && 701 arg.ContainsUint(WPASupplicant::kPropertyWEPTxKeyIndex) && 702 (arg.GetUint(WPASupplicant::kPropertyWEPTxKeyIndex) == index_u32); 703 } 704 705 TEST_F(WiFiServiceTest, ConnectTaskWEP) { 706 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityWep); 707 Error error; 708 wifi_service->SetPassphrase("0:abcdefghijklm", &error); 709 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 710 wifi_service->Connect(nullptr, "in test"); 711 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 712 WEPSecurityArgsKeyIndex(0)); 713 714 wifi_service->SetPassphrase("abcdefghijklm", &error); 715 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 716 wifi_service->Connect(nullptr, "in test"); 717 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 718 WEPSecurityArgsKeyIndex(0)); 719 720 wifi_service->SetPassphrase("1:abcdefghijklm", &error); 721 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 722 wifi_service->Connect(nullptr, "in test"); 723 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 724 WEPSecurityArgsKeyIndex(1)); 725 726 wifi_service->SetPassphrase("2:abcdefghijklm", &error); 727 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 728 wifi_service->Connect(nullptr, "in test"); 729 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 730 WEPSecurityArgsKeyIndex(2)); 731 732 wifi_service->SetPassphrase("3:abcdefghijklm", &error); 733 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 734 wifi_service->Connect(nullptr, "in test"); 735 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(), 736 WEPSecurityArgsKeyIndex(3)); 737 } 738 739 // Dynamic WEP + 802.1x. 740 TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) { 741 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityWep); 742 743 wifi_service->mutable_eap()->SetKeyManagement("IEEE8021X", nullptr); 744 wifi_service->mutable_eap()->set_identity("something"); 745 wifi_service->mutable_eap()->set_password("mumble"); 746 wifi_service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded); 747 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())); 748 wifi_service->Connect(nullptr, "in test"); 749 KeyValueStore params = 750 wifi_service->GetSupplicantConfigurationParameters(); 751 EXPECT_TRUE( 752 params.ContainsString(WPASupplicant::kNetworkPropertyEapIdentity)); 753 EXPECT_TRUE(params.ContainsString(WPASupplicant::kNetworkPropertyCaPath)); 754 EXPECT_FALSE( 755 params.ContainsString(WPASupplicant::kPropertySecurityProtocol)); 756 } 757 758 TEST_F(WiFiServiceTest, SetPassphraseResetHasEverConnected) { 759 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityRsn); 760 const string kPassphrase = "abcdefgh"; 761 762 Error error; 763 // A changed passphrase should reset has_ever_connected_ field. 764 wifi_service->has_ever_connected_ = true; 765 EXPECT_TRUE(wifi_service->has_ever_connected()); 766 wifi_service->SetPassphrase(kPassphrase, &error); 767 EXPECT_FALSE(wifi_service->has_ever_connected()); 768 } 769 770 TEST_F(WiFiServiceTest, SetPassphraseRemovesCachedCredentials) { 771 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityRsn); 772 773 const string kPassphrase = "abcdefgh"; 774 775 { 776 Error error; 777 // A changed passphrase should trigger cache removal. 778 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())); 779 wifi_service->SetPassphrase(kPassphrase, &error); 780 Mock::VerifyAndClearExpectations(wifi().get()); 781 EXPECT_TRUE(error.IsSuccess()); 782 } 783 784 { 785 Error error; 786 // An unchanged passphrase should not trigger cache removal. 787 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0); 788 wifi_service->SetPassphrase(kPassphrase, &error); 789 Mock::VerifyAndClearExpectations(wifi().get()); 790 EXPECT_TRUE(error.IsSuccess()); 791 } 792 793 { 794 Error error; 795 // A modified passphrase should trigger cache removal. 796 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())); 797 wifi_service->SetPassphrase(kPassphrase + "X", &error); 798 Mock::VerifyAndClearExpectations(wifi().get()); 799 EXPECT_TRUE(error.IsSuccess()); 800 } 801 802 { 803 Error error; 804 // A cleared passphrase should also trigger cache removal. 805 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())); 806 wifi_service->ClearPassphrase(&error); 807 Mock::VerifyAndClearExpectations(wifi().get()); 808 EXPECT_TRUE(error.IsSuccess()); 809 } 810 811 { 812 Error error; 813 // An invalid passphrase should not trigger cache removal. 814 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0); 815 wifi_service->SetPassphrase("", &error); 816 Mock::VerifyAndClearExpectations(wifi().get()); 817 EXPECT_FALSE(error.IsSuccess()); 818 } 819 820 { 821 // A change to EAP parameters in a PSK (non 802.1x) service will not 822 // trigger cache removal. 823 wifi_service->has_ever_connected_ = true; 824 EXPECT_TRUE(wifi_service->has_ever_connected()); 825 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())).Times(0); 826 wifi_service->OnEapCredentialsChanged(Service::kReasonPropertyUpdate); 827 EXPECT_TRUE(wifi_service->has_ever_connected()); 828 Mock::VerifyAndClearExpectations(wifi().get()); 829 } 830 831 WiFiServiceRefPtr eap_wifi_service = MakeServiceWithWiFi(kSecurity8021x); 832 833 { 834 // Any change to EAP parameters (including a null one) will trigger cache 835 // removal in an 802.1x service. This is a lot less granular than the 836 // passphrase checks above. 837 // Changes in EAP parameters should also clear has_ever_connected_. 838 eap_wifi_service->has_ever_connected_ = true; 839 EXPECT_TRUE(eap_wifi_service->has_ever_connected()); 840 EXPECT_CALL(*wifi(), ClearCachedCredentials(eap_wifi_service.get())); 841 eap_wifi_service->OnEapCredentialsChanged(Service::kReasonPropertyUpdate); 842 EXPECT_FALSE(eap_wifi_service->has_ever_connected()); 843 Mock::VerifyAndClearExpectations(wifi().get()); 844 } 845 } 846 847 // This test is somewhat redundant, since: 848 // 849 // a) we test that generic property setters return false on a null 850 // change (e.g. in PropertyAccessorTest.SignedIntCorrectness) 851 // b) we test that custom EAP property setters return false on a null 852 // change in EapCredentialsTest.CustomSetterNoopChange 853 // c) we test that the various custom accessors pass through the 854 // return value of custom setters 855 // (e.g. PropertyAccessorTest.CustomAccessorCorrectness) 856 // d) we test that PropertyStore skips the change callback when a 857 // property setter return false (PropertyStoreTypedTest.SetProperty) 858 // 859 // Nonetheless, I think it's worth testing the WiFi+EAP case directly. 860 TEST_F(WiFiServiceTest, EapAuthPropertyChangeClearsCachedCredentials) { 861 WiFiServiceRefPtr wifi_service = 862 MakeServiceWithWiFi(kSecurity8021x); 863 PropertyStore& property_store(*wifi_service->mutable_store()); 864 865 // Property with custom accessor. 866 const string kPassword = "abcdefgh"; 867 { 868 Error error; 869 // A changed passphrase should trigger cache removal. 870 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())); 871 EXPECT_TRUE(property_store.SetStringProperty( 872 kEapPasswordProperty, kPassword, &error)); 873 Mock::VerifyAndClearExpectations(wifi().get()); 874 EXPECT_TRUE(error.IsSuccess()); 875 } 876 { 877 Error error; 878 // An unchanged passphrase should not trigger cache removal. 879 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0); 880 EXPECT_FALSE(property_store.SetStringProperty( 881 kEapPasswordProperty, kPassword, &error)); 882 Mock::VerifyAndClearExpectations(wifi().get()); 883 EXPECT_TRUE(error.IsSuccess()); 884 } 885 { 886 Error error; 887 // A modified passphrase should trigger cache removal. 888 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())); 889 EXPECT_TRUE(property_store.SetStringProperty( 890 kEapPasswordProperty, kPassword + "X", &error)); 891 Mock::VerifyAndClearExpectations(wifi().get()); 892 EXPECT_TRUE(error.IsSuccess()); 893 } 894 895 // Property with generic accessor. 896 const string kCertId = "abcdefgh"; 897 { 898 Error error; 899 // A changed cert id should trigger cache removal. 900 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())); 901 EXPECT_TRUE(property_store.SetStringProperty( 902 kEapCertIdProperty, kCertId, &error)); 903 Mock::VerifyAndClearExpectations(wifi().get()); 904 EXPECT_TRUE(error.IsSuccess()); 905 } 906 { 907 Error error; 908 // An unchanged cert id should not trigger cache removal. 909 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0); 910 EXPECT_FALSE(property_store.SetStringProperty( 911 kEapCertIdProperty, kCertId, &error)); 912 Mock::VerifyAndClearExpectations(wifi().get()); 913 EXPECT_TRUE(error.IsSuccess()); 914 } 915 { 916 Error error; 917 // A modified cert id should trigger cache removal. 918 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())); 919 EXPECT_TRUE(property_store.SetStringProperty( 920 kEapCertIdProperty, kCertId + "X", &error)); 921 Mock::VerifyAndClearExpectations(wifi().get()); 922 EXPECT_TRUE(error.IsSuccess()); 923 } 924 } 925 926 TEST_F(WiFiServiceTest, LoadHidden) { 927 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone); 928 ASSERT_FALSE(service->hidden_ssid_); 929 NiceMock<MockStore> mock_store; 930 const string storage_id = service->GetStorageIdentifier(); 931 set<string> groups; 932 groups.insert(storage_id); 933 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id))) 934 .WillRepeatedly(Return(true)); 935 EXPECT_CALL(mock_store, GetGroupsWithProperties( 936 ContainsWiFiProperties( 937 simple_ssid(), kModeManaged, kSecurityNone))) 938 .WillRepeatedly(Return(groups)); 939 EXPECT_CALL(mock_store, GetBool(_, _, _)) 940 .WillRepeatedly(Return(false)); 941 EXPECT_CALL(mock_store, 942 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _)) 943 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true))); 944 EXPECT_TRUE(service->Load(&mock_store)); 945 EXPECT_TRUE(service->hidden_ssid_); 946 } 947 948 TEST_F(WiFiServiceTest, SetPassphraseForNonPassphraseService) { 949 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone); 950 NiceMock<MockStore> mock_store; 951 const string storage_id = service->GetStorageIdentifier(); 952 set<string> groups; 953 groups.insert(storage_id); 954 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id))) 955 .WillRepeatedly(Return(true)); 956 EXPECT_CALL(mock_store, GetGroupsWithProperties( 957 ContainsWiFiProperties( 958 simple_ssid(), kModeManaged, kSecurityNone))) 959 .WillRepeatedly(Return(groups)); 960 961 EXPECT_TRUE(service->Load(&mock_store)); 962 Error error; 963 EXPECT_FALSE(service->SetPassphrase("password", &error)); 964 EXPECT_TRUE(error.type() == Error::kNotSupported); 965 } 966 967 TEST_F(WiFiServiceTest, LoadMultipleMatchingGroups) { 968 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityNone); 969 set<string> groups; 970 groups.insert("id0"); 971 groups.insert("id1"); 972 // Make sure we retain the first matched group in the same way that 973 // WiFiService::Load() will. 974 string first_group = *groups.begin(); 975 976 NiceMock<MockStore> mock_store; 977 EXPECT_CALL(mock_store, GetGroupsWithProperties( 978 ContainsWiFiProperties( 979 simple_ssid(), kModeManaged, kSecurityNone))) 980 .WillRepeatedly(Return(groups)); 981 EXPECT_CALL(mock_store, ContainsGroup(first_group)) 982 .WillRepeatedly(Return(true)); 983 EXPECT_CALL(mock_store, ContainsGroup(StrNe(first_group))).Times(0); 984 EXPECT_CALL(mock_store, GetBool(first_group, _, _)) 985 .WillRepeatedly(Return(false)); 986 EXPECT_CALL(mock_store, GetBool(StrNe(first_group), _, _)).Times(0); 987 ScopedMockLog log; 988 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber()); 989 EXPECT_CALL(log, Log(logging::LOG_WARNING, _, 990 EndsWith("choosing the first."))); 991 EXPECT_TRUE(service->Load(&mock_store)); 992 } 993 994 TEST_F(WiFiServiceSecurityTest, WPAMapping) { 995 EXPECT_TRUE(TestStorageMapping(kSecurityRsn, kSecurityPsk)); 996 EXPECT_TRUE(TestStorageMapping(kSecurityWpa, kSecurityPsk)); 997 EXPECT_TRUE(TestStorageMapping(kSecurityPsk, kSecurityPsk)); 998 EXPECT_TRUE(TestStorageMapping(kSecurityWep, kSecurityWep)); 999 EXPECT_TRUE(TestStorageMapping(kSecurityNone, kSecurityNone)); 1000 EXPECT_TRUE(TestStorageMapping(kSecurity8021x, kSecurity8021x)); 1001 } 1002 1003 TEST_F(WiFiServiceSecurityTest, LoadMapping) { 1004 EXPECT_TRUE(TestLoadMapping(kSecurityRsn, kSecurityPsk, true)); 1005 EXPECT_TRUE(TestLoadMapping(kSecurityRsn, kSecurityRsn, false)); 1006 EXPECT_TRUE(TestLoadMapping(kSecurityRsn, kSecurityWpa, false)); 1007 EXPECT_TRUE(TestLoadMapping(kSecurityWpa, kSecurityPsk, true)); 1008 EXPECT_TRUE(TestLoadMapping(kSecurityWpa, kSecurityWpa, false)); 1009 EXPECT_TRUE(TestLoadMapping(kSecurityWpa, kSecurityRsn, false)); 1010 EXPECT_TRUE(TestLoadMapping(kSecurityWep, kSecurityWep, true)); 1011 EXPECT_TRUE(TestLoadMapping(kSecurityWep, kSecurityPsk, false)); 1012 } 1013 1014 TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) { 1015 WiFiServiceRefPtr service = MakeSimpleService(kSecurityPsk); 1016 NiceMock<MockStore> mock_store; 1017 const string kStorageId = service->GetStorageIdentifier(); 1018 EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId))) 1019 .WillRepeatedly(Return(true)); 1020 set<string> groups; 1021 groups.insert(kStorageId); 1022 EXPECT_CALL(mock_store, GetGroupsWithProperties( 1023 ContainsWiFiProperties( 1024 simple_ssid(), kModeManaged, kSecurityPsk))) 1025 .WillRepeatedly(Return(groups)); 1026 EXPECT_CALL(mock_store, GetBool(_, _, _)) 1027 .WillRepeatedly(Return(false)); 1028 const string kPassphrase = "passphrase"; 1029 EXPECT_CALL(mock_store, 1030 GetCryptedString(StrEq(kStorageId), 1031 WiFiService::kStoragePassphrase, _)) 1032 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPassphrase), Return(true))); 1033 EXPECT_CALL(mock_store, 1034 GetCryptedString(StrEq(kStorageId), 1035 StrNe(WiFiService::kStoragePassphrase), _)) 1036 .WillRepeatedly(Return(false)); 1037 EXPECT_TRUE(service->need_passphrase_); 1038 EXPECT_TRUE(service->Load(&mock_store)); 1039 EXPECT_EQ(kPassphrase, service->passphrase_); 1040 EXPECT_TRUE(service->connectable()); 1041 EXPECT_FALSE(service->need_passphrase_); 1042 service->Unload(); 1043 EXPECT_EQ(string(""), service->passphrase_); 1044 EXPECT_FALSE(service->connectable()); 1045 EXPECT_TRUE(service->need_passphrase_); 1046 } 1047 1048 TEST_F(WiFiServiceTest, LoadPassphraseClearCredentials) { 1049 const string kOldPassphrase = "oldpassphrase"; 1050 const string kPassphrase = "passphrase"; 1051 1052 const bool kHasEverConnected = true; 1053 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityPsk); 1054 NiceMock<MockStore> mock_store; 1055 const string kStorageId = service->GetStorageIdentifier(); 1056 EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId))) 1057 .WillRepeatedly(Return(true)); 1058 set<string> groups; 1059 groups.insert(kStorageId); 1060 EXPECT_CALL(mock_store, GetGroupsWithProperties( 1061 ContainsWiFiProperties( 1062 simple_ssid(), kModeManaged, kSecurityPsk))) 1063 .WillRepeatedly(Return(groups)); 1064 EXPECT_CALL(mock_store, GetBool(_, _, _)) 1065 .WillRepeatedly(Return(false)); 1066 EXPECT_CALL(mock_store, 1067 GetCryptedString(StrEq(kStorageId), 1068 WiFiService::kStoragePassphrase, _)) 1069 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPassphrase), Return(true))); 1070 EXPECT_CALL(mock_store, 1071 GetCryptedString(StrEq(kStorageId), 1072 StrNe(WiFiService::kStoragePassphrase), _)) 1073 .WillRepeatedly(Return(false)); 1074 EXPECT_CALL(mock_store, 1075 GetBool(kStorageId, Service::kStorageHasEverConnected, _)) 1076 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHasEverConnected), 1077 Return(true))); 1078 // Set old passphrase for service 1079 EXPECT_TRUE(service->need_passphrase_); 1080 service->passphrase_ = kOldPassphrase; 1081 service->has_ever_connected_ = true; 1082 1083 scoped_refptr<MockProfile> mock_profile( 1084 new NiceMock<MockProfile>(control_interface(), metrics(), manager())); 1085 service->set_profile(mock_profile); 1086 // Detect if the service is going to attempt to update the stored profile. 1087 EXPECT_CALL(*mock_profile, GetConstStorage()).Times(0); 1088 1089 // The kOldPassphrase is different than the newly loaded passhprase, 1090 // so the credentials should be cleared. 1091 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(1); 1092 EXPECT_CALL(*mock_profile, UpdateService(_)).Times(0); 1093 EXPECT_TRUE(service->Load(&mock_store)); 1094 EXPECT_EQ(kPassphrase, service->passphrase_); 1095 EXPECT_TRUE(service->has_ever_connected_); 1096 1097 Mock::VerifyAndClearExpectations(wifi().get()); 1098 Mock::VerifyAndClearExpectations(mock_profile.get()); 1099 1100 1101 // Repeat Service::Load with same old and new passphrase. Since the old 1102 // and new passphrase match, verify the cache is not cleared during 1103 // profile load. 1104 service->set_profile(mock_profile); 1105 EXPECT_CALL(*mock_profile, GetConstStorage()).Times(0); 1106 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0); 1107 EXPECT_TRUE(service->Load(&mock_store)); 1108 EXPECT_EQ(kPassphrase, service->passphrase_); 1109 EXPECT_TRUE(service->has_ever_connected_); 1110 } 1111 1112 TEST_F(WiFiServiceTest, ConfigureMakesConnectable) { 1113 string guid("legit_guid"); 1114 KeyValueStore args; 1115 args.SetString(kEapIdentityProperty, "legit_identity"); 1116 args.SetString(kEapPasswordProperty, "legit_password"); 1117 args.SetString(kEapMethodProperty, "PEAP"); 1118 args.SetString(kGuidProperty, guid); 1119 Error error; 1120 1121 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x); 1122 // Hack the GUID in so that we don't have to mess about with WiFi to regsiter 1123 // our service. This way, Manager will handle the lookup itself. 1124 service->SetGuid(guid, nullptr); 1125 manager()->RegisterService(service); 1126 EXPECT_FALSE(service->connectable()); 1127 EXPECT_EQ(service.get(), manager()->GetService(args, &error).get()); 1128 EXPECT_TRUE(error.IsSuccess()); 1129 EXPECT_TRUE(service->connectable()); 1130 } 1131 1132 TEST_F(WiFiServiceTest, ConfigurePassphrase) { 1133 EXPECT_EQ(Error::kNotSupported, 1134 TestConfigurePassphrase(kSecurityNone, "")); 1135 EXPECT_EQ(Error::kNotSupported, 1136 TestConfigurePassphrase(kSecurityNone, "foo")); 1137 EXPECT_EQ(Error::kSuccess, 1138 TestConfigurePassphrase(kSecurityWep, nullptr)); 1139 EXPECT_EQ(Error::kInvalidPassphrase, 1140 TestConfigurePassphrase(kSecurityWep, "")); 1141 EXPECT_EQ(Error::kInvalidPassphrase, 1142 TestConfigurePassphrase(kSecurityWep, "abcd")); 1143 EXPECT_EQ(Error::kSuccess, 1144 TestConfigurePassphrase(kSecurityWep, "abcde")); 1145 EXPECT_EQ(Error::kSuccess, 1146 TestConfigurePassphrase(kSecurityWep, "abcdefghijklm")); 1147 EXPECT_EQ(Error::kSuccess, 1148 TestConfigurePassphrase(kSecurityWep, "0:abcdefghijklm")); 1149 EXPECT_EQ(Error::kSuccess, 1150 TestConfigurePassphrase(kSecurityWep, "0102030405")); 1151 EXPECT_EQ(Error::kInvalidPassphrase, 1152 TestConfigurePassphrase(kSecurityWep, "0x0102030405")); 1153 EXPECT_EQ(Error::kInvalidPassphrase, 1154 TestConfigurePassphrase(kSecurityWep, "O102030405")); 1155 EXPECT_EQ(Error::kInvalidPassphrase, 1156 TestConfigurePassphrase(kSecurityWep, "1:O102030405")); 1157 EXPECT_EQ(Error::kInvalidPassphrase, 1158 TestConfigurePassphrase(kSecurityWep, "1:0xO102030405")); 1159 EXPECT_EQ(Error::kInvalidPassphrase, 1160 TestConfigurePassphrase(kSecurityWep, "0xO102030405")); 1161 EXPECT_EQ(Error::kSuccess, 1162 TestConfigurePassphrase(kSecurityWep, 1163 "0102030405060708090a0b0c0d")); 1164 EXPECT_EQ(Error::kSuccess, 1165 TestConfigurePassphrase(kSecurityWep, 1166 "0102030405060708090A0B0C0D")); 1167 EXPECT_EQ(Error::kSuccess, 1168 TestConfigurePassphrase(kSecurityWep, 1169 "0:0102030405060708090a0b0c0d")); 1170 EXPECT_EQ(Error::kSuccess, 1171 TestConfigurePassphrase(kSecurityWep, 1172 "0:0x0102030405060708090a0b0c0d")); 1173 EXPECT_EQ(Error::kSuccess, 1174 TestConfigurePassphrase(kSecurityWpa, nullptr)); 1175 EXPECT_EQ(Error::kSuccess, 1176 TestConfigurePassphrase(kSecurityWpa, "secure password")); 1177 EXPECT_EQ(Error::kInvalidPassphrase, 1178 TestConfigurePassphrase(kSecurityWpa, "")); 1179 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase( 1180 kSecurityWpa, 1181 string(IEEE_80211::kWPAAsciiMinLen, 'Z').c_str())); 1182 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase( 1183 kSecurityWpa, 1184 string(IEEE_80211::kWPAAsciiMaxLen, 'Z').c_str())); 1185 // subtle: invalid length for hex key, but valid as ascii passphrase 1186 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase( 1187 kSecurityWpa, 1188 string(IEEE_80211::kWPAHexLen-1, '1').c_str())); 1189 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase( 1190 kSecurityWpa, 1191 string(IEEE_80211::kWPAHexLen, '1').c_str())); 1192 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase( 1193 kSecurityWpa, 1194 string(IEEE_80211::kWPAAsciiMinLen-1, 'Z').c_str())); 1195 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase( 1196 kSecurityWpa, 1197 string(IEEE_80211::kWPAAsciiMaxLen+1, 'Z').c_str())); 1198 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase( 1199 kSecurityWpa, 1200 string(IEEE_80211::kWPAHexLen+1, '1').c_str())); 1201 } 1202 1203 TEST_F(WiFiServiceTest, ConfigureRedundantProperties) { 1204 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone); 1205 KeyValueStore args; 1206 args.SetString(kTypeProperty, kTypeWifi); 1207 args.SetString(kSSIDProperty, simple_ssid_string()); 1208 args.SetString(kSecurityProperty, kSecurityNone); 1209 args.SetString(kWifiHexSsid, "This is ignored even if it is invalid hex."); 1210 const string kGUID = "aguid"; 1211 args.SetString(kGuidProperty, kGUID); 1212 1213 EXPECT_EQ("", service->guid()); 1214 Error error; 1215 service->Configure(args, &error); 1216 EXPECT_TRUE(error.IsSuccess()); 1217 EXPECT_EQ(kGUID, service->guid()); 1218 } 1219 1220 TEST_F(WiFiServiceTest, DisconnectWithWiFi) { 1221 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityWep); 1222 EXPECT_CALL(*wifi(), DisconnectFromIfActive(service.get())).Times(1); 1223 Error error; 1224 service->Disconnect(&error, "in test"); 1225 } 1226 1227 TEST_F(WiFiServiceTest, DisconnectWithoutWiFi) { 1228 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep); 1229 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0); 1230 Error error; 1231 service->Disconnect(&error, "in test"); 1232 EXPECT_EQ(Error::kOperationFailed, error.type()); 1233 } 1234 1235 TEST_F(WiFiServiceTest, DisconnectWithoutWiFiWhileAssociating) { 1236 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep); 1237 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0); 1238 service->SetState(Service::kStateAssociating); 1239 ScopedMockLog log; 1240 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber()); 1241 EXPECT_CALL(log, Log(logging::LOG_ERROR, _, 1242 HasSubstr("WiFi endpoints do not (yet) exist."))); 1243 Error error; 1244 service->Disconnect(&error, "in test"); 1245 EXPECT_EQ(Error::kOperationFailed, error.type()); 1246 } 1247 1248 TEST_F(WiFiServiceTest, UnloadAndClearCacheWEP) { 1249 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityWep); 1250 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1); 1251 EXPECT_CALL(*wifi(), DisconnectFromIfActive(service.get())).Times(1); 1252 service->Unload(); 1253 } 1254 1255 TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) { 1256 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurity8021x); 1257 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1); 1258 EXPECT_CALL(*wifi(), DisconnectFromIfActive(service.get())).Times(1); 1259 service->Unload(); 1260 } 1261 1262 TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) { 1263 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone); 1264 const string storage_id = service->GetStorageIdentifier(); 1265 string address; 1266 string mode; 1267 string security; 1268 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode, 1269 &security)); 1270 EXPECT_EQ(base::ToLowerASCII(GetAnyDeviceAddress()), address); 1271 EXPECT_EQ(kModeManaged, mode); 1272 EXPECT_EQ(kSecurityNone, security); 1273 } 1274 1275 TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) { 1276 // Do a separate test for 802.1x, since kSecurity8021x contains a "_", 1277 // which needs to be dealt with specially in the parser. 1278 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x); 1279 const string storage_id = service->GetStorageIdentifier(); 1280 string address; 1281 string mode; 1282 string security; 1283 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode, 1284 &security)); 1285 EXPECT_EQ(base::ToLowerASCII(GetAnyDeviceAddress()), address); 1286 EXPECT_EQ(kModeManaged, mode); 1287 EXPECT_EQ(kSecurity8021x, security); 1288 } 1289 1290 TEST_F(WiFiServiceFixupStorageTest, FixedEntries) { 1291 const string kNonWiFiId = "vpn_foo"; 1292 const string kUnparsableWiFiId = "wifi_foo"; 1293 1294 AddGroup(kNonWiFiId); 1295 AddGroup(kUnparsableWiFiId); 1296 AddServiceEntry(true, true, true, true); 1297 AddServiceEntry(false, false, false, false); 1298 AddServiceEntry(true, true, true, true); 1299 AddServiceEntry(false, false, false, false); 1300 EXPECT_TRUE(FixupServiceEntries()); 1301 } 1302 1303 TEST_F(WiFiServiceFixupStorageTest, NoFixedEntries) { 1304 const string kNonWiFiId = "vpn_foo"; 1305 const string kUnparsableWiFiId = "wifi_foo"; 1306 1307 AddGroup(kNonWiFiId); 1308 AddGroup(kUnparsableWiFiId); 1309 AddServiceEntry(true, true, true, true); 1310 EXPECT_FALSE(FixupServiceEntries()); 1311 } 1312 1313 TEST_F(WiFiServiceFixupStorageTest, MissingTypeProperty) { 1314 AddServiceEntry(false, true, true, true); 1315 EXPECT_TRUE(FixupServiceEntries()); 1316 } 1317 1318 TEST_F(WiFiServiceFixupStorageTest, MissingModeProperty) { 1319 AddServiceEntry(true, false, true, true); 1320 EXPECT_TRUE(FixupServiceEntries()); 1321 } 1322 1323 TEST_F(WiFiServiceFixupStorageTest, MissingSecurityProperty) { 1324 AddServiceEntry(true, true, false, true); 1325 EXPECT_TRUE(FixupServiceEntries()); 1326 } 1327 1328 TEST_F(WiFiServiceFixupStorageTest, MissingSecurityClassProperty) { 1329 AddServiceEntry(true, true, true, false); 1330 EXPECT_TRUE(FixupServiceEntries()); 1331 } 1332 1333 TEST_F(WiFiServiceTest, Connectable) { 1334 // Open network should be connectable. 1335 EXPECT_TRUE(CheckConnectable(kSecurityNone, nullptr, false)); 1336 1337 // Open network should remain connectable if we try to set a password on it. 1338 EXPECT_TRUE(CheckConnectable(kSecurityNone, "abcde", false)); 1339 1340 // WEP network with passphrase set should be connectable. 1341 EXPECT_TRUE(CheckConnectable(kSecurityWep, "abcde", false)); 1342 1343 // WEP network without passphrase set should NOT be connectable. 1344 EXPECT_FALSE(CheckConnectable(kSecurityWep, nullptr, false)); 1345 1346 // A bad passphrase should not make a WEP network connectable. 1347 EXPECT_FALSE(CheckConnectable(kSecurityWep, "a", false)); 1348 1349 // Similar to WEP, for WPA. 1350 EXPECT_TRUE(CheckConnectable(kSecurityWpa, "abcdefgh", false)); 1351 EXPECT_FALSE(CheckConnectable(kSecurityWpa, nullptr, false)); 1352 EXPECT_FALSE(CheckConnectable(kSecurityWpa, "a", false)); 1353 1354 // 802.1x without connectable EAP credentials should NOT be connectable. 1355 EXPECT_FALSE(CheckConnectable(kSecurity8021x, nullptr, false)); 1356 1357 // 802.1x with connectable EAP credentials should be connectable. 1358 EXPECT_TRUE(CheckConnectable(kSecurity8021x, nullptr, true)); 1359 1360 // Dynamic WEP + 802.1X should be connectable under the same conditions. 1361 EXPECT_TRUE(CheckConnectable(kSecurityWep, nullptr, true)); 1362 } 1363 1364 TEST_F(WiFiServiceTest, IsAutoConnectable) { 1365 const char* reason; 1366 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone); 1367 EXPECT_CALL(*wifi(), IsIdle()) 1368 .WillRepeatedly(Return(true)); 1369 EXPECT_FALSE(service->HasEndpoints()); 1370 EXPECT_FALSE(service->IsAutoConnectable(&reason)); 1371 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason); 1372 1373 reason = ""; 1374 WiFiEndpointRefPtr endpoint = 1375 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0); 1376 service->AddEndpoint(endpoint); 1377 EXPECT_CALL(*wifi(), IsIdle()) 1378 .WillRepeatedly(Return(true)); 1379 EXPECT_TRUE(service->HasEndpoints()); 1380 EXPECT_TRUE(service->IsAutoConnectable(&reason)); 1381 EXPECT_STREQ("", reason); 1382 1383 // WiFi only supports connecting to one Service at a time. So, to 1384 // avoid disrupting connectivity, we only allow auto-connection to 1385 // a WiFiService when the corresponding WiFi is idle. 1386 EXPECT_CALL(*wifi(), IsIdle()) 1387 .WillRepeatedly(Return(false)); 1388 EXPECT_TRUE(service->HasEndpoints()); 1389 EXPECT_FALSE(service->IsAutoConnectable(&reason)); 1390 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason); 1391 } 1392 1393 TEST_F(WiFiServiceTest, AutoConnect) { 1394 const char* reason; 1395 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone); 1396 EXPECT_FALSE(service->IsAutoConnectable(&reason)); 1397 EXPECT_CALL(*wifi(), ConnectTo(_)).Times(0); 1398 service->AutoConnect(); 1399 dispatcher()->DispatchPendingEvents(); 1400 1401 WiFiEndpointRefPtr endpoint = 1402 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0); 1403 service->AddEndpoint(endpoint); 1404 EXPECT_CALL(*wifi(), IsIdle()) 1405 .WillRepeatedly(Return(true)); 1406 EXPECT_TRUE(service->IsAutoConnectable(&reason)); 1407 EXPECT_CALL(*wifi(), ConnectTo(_)); 1408 service->AutoConnect(); 1409 dispatcher()->DispatchPendingEvents(); 1410 1411 Error error; 1412 service->UserInitiatedDisconnect(&error); 1413 dispatcher()->DispatchPendingEvents(); 1414 EXPECT_FALSE(service->IsAutoConnectable(&reason)); 1415 } 1416 1417 TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) { 1418 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityWep); 1419 1420 EXPECT_EQ("", wifi_service->passphrase_); 1421 1422 Error error; 1423 const string kPassphrase = "0:abcde"; 1424 EXPECT_TRUE( 1425 wifi_service->mutable_store()->SetAnyProperty(kPassphraseProperty, 1426 brillo::Any(kPassphrase), 1427 &error)); 1428 EXPECT_EQ(kPassphrase, wifi_service->passphrase_); 1429 1430 EXPECT_TRUE(wifi_service->mutable_store()->ClearProperty(kPassphraseProperty, 1431 &error)); 1432 EXPECT_EQ("", wifi_service->passphrase_); 1433 } 1434 1435 TEST_F(WiFiServiceTest, SignalToStrength) { 1436 // Verify that our mapping is sane, in the sense that it preserves ordering. 1437 // We break the test into two domains, because we assume that positive 1438 // values aren't actually in dBm. 1439 for (int16_t i = std::numeric_limits<int16_t>::min(); i < 0; ++i) { 1440 int16_t current_mapped = WiFiService::SignalToStrength(i); 1441 int16_t next_mapped = WiFiService::SignalToStrength(i+1); 1442 EXPECT_LE(current_mapped, next_mapped) 1443 << "(original values " << i << " " << i+1 << ")"; 1444 EXPECT_GE(current_mapped, Service::kStrengthMin); 1445 EXPECT_LE(current_mapped, Service::kStrengthMax); 1446 } 1447 for (int16_t i = 1; i < std::numeric_limits<int16_t>::max(); ++i) { 1448 int16_t current_mapped = WiFiService::SignalToStrength(i); 1449 int16_t next_mapped = WiFiService::SignalToStrength(i+1); 1450 EXPECT_LE(current_mapped, next_mapped) 1451 << "(original values " << i << " " << i+1 << ")"; 1452 EXPECT_GE(current_mapped, Service::kStrengthMin); 1453 EXPECT_LE(current_mapped, Service::kStrengthMax); 1454 } 1455 } 1456 1457 TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) { 1458 // If the chosen signal values don't map to distinct strength 1459 // values, then we can't expect our other tests to pass. So verify 1460 // their distinctness. 1461 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength); 1462 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength); 1463 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength); 1464 } 1465 1466 TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) { 1467 // Initial endpoint updates values. 1468 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency)); 1469 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId)); 1470 EXPECT_CALL(adaptor, 1471 EmitUint8Changed(kSignalStrengthProperty, kOkEndpointStrength)); 1472 EXPECT_CALL(adaptor, 1473 EmitUint16Changed(kWifiPhyMode, Metrics::kWiFiNetworkPhyMode11b)); 1474 service->AddEndpoint(ok_endpoint); 1475 EXPECT_EQ(1, service->GetEndpointCount()); 1476 Mock::VerifyAndClearExpectations(&adaptor); 1477 1478 // Endpoint with stronger signal updates values. 1479 EXPECT_CALL(adaptor, 1480 EmitUint16Changed(kWifiFrequency, kGoodEndpointFrequency)); 1481 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kGoodEndpointBssId)); 1482 EXPECT_CALL(adaptor, 1483 EmitUint8Changed(kSignalStrengthProperty, kGoodEndpointStrength)); 1484 // However, both endpoints are 11b. 1485 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0); 1486 service->AddEndpoint(good_endpoint); 1487 EXPECT_EQ(2, service->GetEndpointCount()); 1488 Mock::VerifyAndClearExpectations(&adaptor); 1489 1490 // Endpoint with lower signal does not change values. 1491 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0); 1492 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0); 1493 EXPECT_CALL(adaptor, 1494 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0); 1495 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0); 1496 service->AddEndpoint(bad_endpoint); 1497 EXPECT_EQ(3, service->GetEndpointCount()); 1498 Mock::VerifyAndClearExpectations(&adaptor); 1499 1500 // Removing non-optimal endpoint does not change values. 1501 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0); 1502 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0); 1503 EXPECT_CALL(adaptor, 1504 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0); 1505 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0); 1506 service->RemoveEndpoint(bad_endpoint); 1507 EXPECT_EQ(2, service->GetEndpointCount()); 1508 Mock::VerifyAndClearExpectations(&adaptor); 1509 1510 // Removing optimal endpoint updates values. 1511 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency)); 1512 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId)); 1513 EXPECT_CALL(adaptor, 1514 EmitUint8Changed(kSignalStrengthProperty, kOkEndpointStrength)); 1515 // However, both endpoints are 11b. 1516 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0); 1517 service->RemoveEndpoint(good_endpoint); 1518 EXPECT_EQ(1, service->GetEndpointCount()); 1519 Mock::VerifyAndClearExpectations(&adaptor); 1520 1521 // Removing last endpoint updates values (and doesn't crash). 1522 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)); 1523 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)); 1524 EXPECT_CALL(adaptor, EmitUint8Changed(kSignalStrengthProperty, _)); 1525 EXPECT_CALL(adaptor, EmitUint16Changed( 1526 kWifiPhyMode, Metrics::kWiFiNetworkPhyModeUndef)); 1527 service->RemoveEndpoint(ok_endpoint); 1528 EXPECT_EQ(0, service->GetEndpointCount()); 1529 Mock::VerifyAndClearExpectations(&adaptor); 1530 } 1531 1532 TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) { 1533 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber()); 1534 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber()); 1535 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber()); 1536 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber()); 1537 service->AddEndpoint(bad_endpoint); 1538 service->AddEndpoint(ok_endpoint); 1539 EXPECT_EQ(2, service->GetEndpointCount()); 1540 Mock::VerifyAndClearExpectations(&adaptor); 1541 1542 // Setting current endpoint forces adoption of its values, even if it 1543 // doesn't have the highest signal. 1544 EXPECT_CALL(adaptor, 1545 EmitUint16Changed(kWifiFrequency, kBadEndpointFrequency)); 1546 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kBadEndpointBssId)); 1547 EXPECT_CALL(adaptor, 1548 EmitUint8Changed(kSignalStrengthProperty, kBadEndpointStrength)); 1549 service->NotifyCurrentEndpoint(bad_endpoint); 1550 Mock::VerifyAndClearExpectations(&adaptor); 1551 1552 // Adding a better endpoint doesn't matter, when current endpoint is set. 1553 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0); 1554 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0); 1555 EXPECT_CALL(adaptor, 1556 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0); 1557 service->AddEndpoint(good_endpoint); 1558 EXPECT_EQ(3, service->GetEndpointCount()); 1559 Mock::VerifyAndClearExpectations(&adaptor); 1560 1561 // Removing a better endpoint doesn't matter, when current endpoint is set. 1562 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0); 1563 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0); 1564 EXPECT_CALL(adaptor, 1565 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0); 1566 service->RemoveEndpoint(good_endpoint); 1567 Mock::VerifyAndClearExpectations(&adaptor); 1568 1569 // Removing the current endpoint is safe and sane. 1570 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency)); 1571 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId)); 1572 EXPECT_CALL(adaptor, 1573 EmitUint8Changed(kSignalStrengthProperty, kOkEndpointStrength)); 1574 service->RemoveEndpoint(bad_endpoint); 1575 Mock::VerifyAndClearExpectations(&adaptor); 1576 1577 // Clearing the current endpoint (without removing it) is also safe and sane. 1578 service->NotifyCurrentEndpoint(ok_endpoint); 1579 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0); 1580 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0); 1581 EXPECT_CALL(adaptor, 1582 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0); 1583 service->NotifyCurrentEndpoint(nullptr); 1584 Mock::VerifyAndClearExpectations(&adaptor); 1585 } 1586 1587 TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) { 1588 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber()); 1589 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber()); 1590 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber()); 1591 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber()); 1592 service->AddEndpoint(ok_endpoint); 1593 service->AddEndpoint(good_endpoint); 1594 EXPECT_EQ(2, service->GetEndpointCount()); 1595 Mock::VerifyAndClearExpectations(&adaptor); 1596 1597 // Updating sub-optimal Endpoint doesn't update Service. 1598 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0); 1599 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0); 1600 EXPECT_CALL(adaptor, 1601 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0); 1602 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2; 1603 service->NotifyEndpointUpdated(ok_endpoint); 1604 Mock::VerifyAndClearExpectations(&adaptor); 1605 1606 // Updating optimal Endpoint updates appropriate Service property. 1607 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0); 1608 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0); 1609 EXPECT_CALL(adaptor, EmitUint8Changed(kSignalStrengthProperty, _)); 1610 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1; 1611 service->NotifyEndpointUpdated(good_endpoint); 1612 Mock::VerifyAndClearExpectations(&adaptor); 1613 1614 // Change in optimal Endpoint updates Service properties. 1615 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency)); 1616 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId)); 1617 EXPECT_CALL(adaptor, EmitUint8Changed(kSignalStrengthProperty, _)); 1618 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2; 1619 service->NotifyEndpointUpdated(ok_endpoint); 1620 Mock::VerifyAndClearExpectations(&adaptor); 1621 } 1622 1623 TEST_F(WiFiServiceUpdateFromEndpointsTest, Ieee80211w) { 1624 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber()); 1625 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber()); 1626 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber()); 1627 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber()); 1628 service->AddEndpoint(ok_endpoint); 1629 EXPECT_FALSE(service->ieee80211w_required()); 1630 good_endpoint->ieee80211w_required_ = true; 1631 service->AddEndpoint(good_endpoint); 1632 EXPECT_TRUE(service->ieee80211w_required()); 1633 service->RemoveEndpoint(good_endpoint); 1634 EXPECT_TRUE(service->ieee80211w_required()); 1635 } 1636 1637 TEST_F(WiFiServiceUpdateFromEndpointsTest, PhysicalMode) { 1638 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber()); 1639 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber()); 1640 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber()); 1641 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber()); 1642 1643 // No endpoints -> undef. 1644 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode()); 1645 1646 // Endpoint has unknown physical mode -> undef. 1647 ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyModeUndef; 1648 service->AddEndpoint(ok_endpoint); 1649 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode()); 1650 1651 // New endpoint with 802.11a -> 802.11a. 1652 good_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11a; 1653 service->AddEndpoint(good_endpoint); 1654 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11a, service->physical_mode()); 1655 1656 // Remove 802.11a endpoint -> undef. 1657 service->RemoveEndpoint(good_endpoint); 1658 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode()); 1659 1660 // Change endpoint -> take endpoint's new value. 1661 ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11n; 1662 service->NotifyEndpointUpdated(ok_endpoint); 1663 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, service->physical_mode()); 1664 1665 // No endpoints -> undef. 1666 service->RemoveEndpoint(ok_endpoint); 1667 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode()); 1668 } 1669 1670 TEST_F(WiFiServiceUpdateFromEndpointsTest, WarningOnDisconnect) { 1671 service->AddEndpoint(ok_endpoint); 1672 service->SetState(Service::kStateAssociating); 1673 ScopedMockLog log; 1674 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber()); 1675 EXPECT_CALL(log, Log(logging::LOG_WARNING, _, 1676 EndsWith("disconnect due to no remaining endpoints."))); 1677 service->RemoveEndpoint(ok_endpoint); 1678 } 1679 1680 TEST_F(WiFiServiceUpdateFromEndpointsTest, AddEndpointWithPreferredDevice) { 1681 // Setup service, device, and endpoints. 1682 WiFiServiceRefPtr wifi_service = MakeServiceWithMockManager(); 1683 const string kDeviceName1 = "test_device1"; 1684 const string kDeviceName2 = "test_device2"; 1685 scoped_refptr<MockWiFi> wifi1 = MakeSimpleWiFi(kDeviceName1); 1686 scoped_refptr<MockWiFi> wifi2 = MakeSimpleWiFi(kDeviceName2); 1687 // Best signal for endpoint associated with the preferred device. 1688 const int16_t kPreferredDeviceBestSignal = -40; 1689 WiFiEndpointRefPtr endpoint0 = 1690 MakeOpenEndpointWithWiFi(wifi2, "a", "00:00:00:00:00:01", 0, 1691 kPreferredDeviceBestSignal + 10); 1692 WiFiEndpointRefPtr endpoint1 = 1693 MakeOpenEndpointWithWiFi(wifi1, "a", "00:00:00:00:00:01", 0, 1694 kPreferredDeviceBestSignal - 10); 1695 WiFiEndpointRefPtr endpoint2 = 1696 MakeOpenEndpointWithWiFi(wifi1, "a", "00:00:00:00:00:01", 0, 1697 kPreferredDeviceBestSignal); 1698 WiFiEndpointRefPtr endpoint3 = 1699 MakeOpenEndpointWithWiFi(wifi2, "a", "00:00:00:00:00:01", 0, 1700 kPreferredDeviceBestSignal + 10); 1701 1702 wifi_service->SetPreferredDevice(kDeviceName1, nullptr); 1703 1704 wifi_service->AddEndpoint(endpoint0); 1705 wifi_service->AddEndpoint(endpoint1); 1706 wifi_service->AddEndpoint(endpoint2); 1707 wifi_service->AddEndpoint(endpoint3); 1708 EXPECT_EQ(wifi1, wifi_service->wifi_); 1709 // Service should display the signal strength of the best signal endpoint 1710 // that's associated with the preferred device. 1711 EXPECT_EQ(WiFiService::SignalToStrength(kPreferredDeviceBestSignal), 1712 wifi_service->strength()); 1713 } 1714 1715 MATCHER_P(IsSetwiseEqual, expected_set, "") { 1716 set<uint16_t> arg_set(arg.begin(), arg.end()); 1717 return arg_set == expected_set; 1718 } 1719 1720 TEST_F(WiFiServiceUpdateFromEndpointsTest, FrequencyList) { 1721 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber()); 1722 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber()); 1723 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber()); 1724 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber()); 1725 1726 // No endpoints -> empty list. 1727 EXPECT_EQ(vector<uint16_t>(), service->frequency_list()); 1728 1729 // Add endpoint -> endpoint's frequency in list. 1730 EXPECT_CALL(adaptor, EmitUint16sChanged( 1731 kWifiFrequencyListProperty, vector<uint16_t>{kGoodEndpointFrequency})); 1732 service->AddEndpoint(good_endpoint); 1733 Mock::VerifyAndClearExpectations(&adaptor); 1734 1735 // Add another endpoint -> both frequencies in list. 1736 // Order doesn't matter. 1737 set<uint16_t> expected_frequencies{kGoodEndpointFrequency, 1738 kOkEndpointFrequency}; 1739 EXPECT_CALL(adaptor, EmitUint16sChanged( 1740 kWifiFrequencyListProperty, IsSetwiseEqual(expected_frequencies))); 1741 service->AddEndpoint(ok_endpoint); 1742 Mock::VerifyAndClearExpectations(&adaptor); 1743 1744 // Remove endpoint -> other endpoint's frequency remains. 1745 EXPECT_CALL(adaptor, EmitUint16sChanged( 1746 kWifiFrequencyListProperty, vector<uint16_t>{kOkEndpointFrequency})); 1747 service->RemoveEndpoint(good_endpoint); 1748 Mock::VerifyAndClearExpectations(&adaptor); 1749 1750 // Endpoint with same frequency -> frequency remains. 1751 // Notification may or may not occur -- don't care. 1752 // Frequency may or may not be repeated in list -- don't care. 1753 WiFiEndpointRefPtr same_freq_as_ok_endpoint = MakeOpenEndpoint( 1754 simple_ssid_string(), "aa:bb:cc:dd:ee:ff", ok_endpoint->frequency(), 0); 1755 service->AddEndpoint(same_freq_as_ok_endpoint); 1756 EXPECT_THAT(service->frequency_list(), 1757 IsSetwiseEqual(set<uint16_t>{kOkEndpointFrequency})); 1758 Mock::VerifyAndClearExpectations(&adaptor); 1759 1760 // Remove endpoint with same frequency -> frequency remains. 1761 // Notification may or may not occur -- don't care. 1762 service->RemoveEndpoint(ok_endpoint); 1763 EXPECT_EQ(vector<uint16_t>{same_freq_as_ok_endpoint->frequency()}, 1764 service->frequency_list()); 1765 Mock::VerifyAndClearExpectations(&adaptor); 1766 1767 // Remove last endpoint. Frequency list goes empty. 1768 EXPECT_CALL(adaptor, EmitUint16sChanged( 1769 kWifiFrequencyListProperty, vector<uint16_t>{})); 1770 service->RemoveEndpoint(same_freq_as_ok_endpoint); 1771 Mock::VerifyAndClearExpectations(&adaptor); 1772 } 1773 1774 TEST_F(WiFiServiceTest, SecurityFromCurrentEndpoint) { 1775 WiFiServiceRefPtr service(MakeSimpleService(kSecurityPsk)); 1776 EXPECT_EQ(kSecurityPsk, service->GetSecurity(nullptr)); 1777 WiFiEndpoint* endpoint = MakeOpenEndpoint( 1778 simple_ssid_string(), "00:00:00:00:00:00", 0, 0); 1779 service->AddEndpoint(endpoint); 1780 EXPECT_EQ(kSecurityPsk, service->GetSecurity(nullptr)); 1781 service->NotifyCurrentEndpoint(endpoint); 1782 EXPECT_EQ(kSecurityNone, service->GetSecurity(nullptr)); 1783 service->NotifyCurrentEndpoint(nullptr); 1784 EXPECT_EQ(kSecurityPsk, service->GetSecurity(nullptr)); 1785 } 1786 1787 TEST_F(WiFiServiceTest, UpdateSecurity) { 1788 // Cleartext and pre-shared-key crypto. 1789 { 1790 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone); 1791 EXPECT_EQ(Service::kCryptoNone, service->crypto_algorithm()); 1792 EXPECT_FALSE(service->key_rotation()); 1793 EXPECT_FALSE(service->endpoint_auth()); 1794 } 1795 { 1796 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep); 1797 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm()); 1798 EXPECT_FALSE(service->key_rotation()); 1799 EXPECT_FALSE(service->endpoint_auth()); 1800 } 1801 { 1802 WiFiServiceRefPtr service = MakeSimpleService(kSecurityPsk); 1803 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm()); 1804 EXPECT_TRUE(service->key_rotation()); 1805 EXPECT_FALSE(service->endpoint_auth()); 1806 } 1807 { 1808 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWpa); 1809 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm()); 1810 EXPECT_TRUE(service->key_rotation()); 1811 EXPECT_FALSE(service->endpoint_auth()); 1812 } 1813 { 1814 WiFiServiceRefPtr service = MakeSimpleService(kSecurityRsn); 1815 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm()); 1816 EXPECT_TRUE(service->key_rotation()); 1817 EXPECT_FALSE(service->endpoint_auth()); 1818 } 1819 1820 // Crypto with 802.1X key management. 1821 { 1822 // WEP 1823 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep); 1824 service->SetEAPKeyManagement("IEEE8021X"); 1825 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm()); 1826 EXPECT_TRUE(service->key_rotation()); 1827 EXPECT_TRUE(service->endpoint_auth()); 1828 } 1829 { 1830 // WPA 1831 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x); 1832 WiFiEndpointRefPtr endpoint = 1833 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false); 1834 service->AddEndpoint(endpoint); 1835 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm()); 1836 EXPECT_TRUE(service->key_rotation()); 1837 EXPECT_TRUE(service->endpoint_auth()); 1838 } 1839 { 1840 // RSN 1841 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x); 1842 WiFiEndpointRefPtr endpoint = 1843 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true); 1844 service->AddEndpoint(endpoint); 1845 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm()); 1846 EXPECT_TRUE(service->key_rotation()); 1847 EXPECT_TRUE(service->endpoint_auth()); 1848 } 1849 { 1850 // AP supports both WPA and RSN. 1851 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x); 1852 WiFiEndpointRefPtr endpoint = 1853 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true); 1854 service->AddEndpoint(endpoint); 1855 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm()); 1856 EXPECT_TRUE(service->key_rotation()); 1857 EXPECT_TRUE(service->endpoint_auth()); 1858 } 1859 } 1860 1861 TEST_F(WiFiServiceTest, ComputeCipher8021x) { 1862 // No endpoints. 1863 { 1864 const set<WiFiEndpointConstRefPtr> endpoints; 1865 EXPECT_EQ(Service::kCryptoNone, 1866 WiFiService::ComputeCipher8021x(endpoints)); 1867 } 1868 1869 // Single endpoint, various configs. 1870 { 1871 set<WiFiEndpointConstRefPtr> endpoints; 1872 endpoints.insert( 1873 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false)); 1874 EXPECT_EQ(Service::kCryptoNone, 1875 WiFiService::ComputeCipher8021x(endpoints)); 1876 } 1877 { 1878 set<WiFiEndpointConstRefPtr> endpoints; 1879 endpoints.insert( 1880 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false)); 1881 EXPECT_EQ(Service::kCryptoRc4, 1882 WiFiService::ComputeCipher8021x(endpoints)); 1883 } 1884 { 1885 set<WiFiEndpointConstRefPtr> endpoints; 1886 endpoints.insert( 1887 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true)); 1888 EXPECT_EQ(Service::kCryptoAes, 1889 WiFiService::ComputeCipher8021x(endpoints)); 1890 } 1891 { 1892 set<WiFiEndpointConstRefPtr> endpoints; 1893 endpoints.insert( 1894 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true)); 1895 EXPECT_EQ(Service::kCryptoAes, 1896 WiFiService::ComputeCipher8021x(endpoints)); 1897 } 1898 1899 // Multiple endpoints. 1900 { 1901 set<WiFiEndpointConstRefPtr> endpoints; 1902 endpoints.insert( 1903 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false)); 1904 endpoints.insert( 1905 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, false)); 1906 EXPECT_EQ(Service::kCryptoNone, 1907 WiFiService::ComputeCipher8021x(endpoints)); 1908 } 1909 { 1910 set<WiFiEndpointConstRefPtr> endpoints; 1911 endpoints.insert( 1912 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false)); 1913 endpoints.insert( 1914 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false)); 1915 EXPECT_EQ(Service::kCryptoNone, 1916 WiFiService::ComputeCipher8021x(endpoints)); 1917 } 1918 { 1919 set<WiFiEndpointConstRefPtr> endpoints; 1920 endpoints.insert( 1921 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false)); 1922 endpoints.insert( 1923 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false)); 1924 EXPECT_EQ(Service::kCryptoRc4, 1925 WiFiService::ComputeCipher8021x(endpoints)); 1926 } 1927 { 1928 set<WiFiEndpointConstRefPtr> endpoints; 1929 endpoints.insert( 1930 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false)); 1931 endpoints.insert( 1932 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true)); 1933 EXPECT_EQ(Service::kCryptoRc4, 1934 WiFiService::ComputeCipher8021x(endpoints)); 1935 } 1936 { 1937 set<WiFiEndpointConstRefPtr> endpoints; 1938 endpoints.insert( 1939 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true)); 1940 endpoints.insert( 1941 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true)); 1942 EXPECT_EQ(Service::kCryptoAes, 1943 WiFiService::ComputeCipher8021x(endpoints)); 1944 } 1945 { 1946 set<WiFiEndpointConstRefPtr> endpoints; 1947 endpoints.insert( 1948 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true)); 1949 endpoints.insert( 1950 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, true)); 1951 EXPECT_EQ(Service::kCryptoAes, 1952 WiFiService::ComputeCipher8021x(endpoints)); 1953 } 1954 } 1955 1956 TEST_F(WiFiServiceTest, Unload) { 1957 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityNone); 1958 EXPECT_CALL(*wifi(), DestroyIPConfigLease(service->GetStorageIdentifier())). 1959 Times(1); 1960 service->Unload(); 1961 } 1962 1963 TEST_F(WiFiServiceTest, PropertyChanges) { 1964 WiFiServiceRefPtr service = MakeServiceWithMockManager(); 1965 ServiceMockAdaptor* adaptor = GetAdaptor(service.get()); 1966 TestCommonPropertyChanges(service, adaptor); 1967 TestAutoConnectPropertyChange(service, adaptor); 1968 1969 EXPECT_CALL(*adaptor, 1970 EmitRpcIdentifierChanged(kDeviceProperty, _)); 1971 SetWiFi(service, wifi()); 1972 Mock::VerifyAndClearExpectations(adaptor); 1973 1974 EXPECT_CALL(*adaptor, 1975 EmitRpcIdentifierChanged(kDeviceProperty, _)); 1976 service->ResetWiFi(); 1977 Mock::VerifyAndClearExpectations(adaptor); 1978 } 1979 1980 // Custom property setters should return false, and make no changes, if 1981 // the new value is the same as the old value. 1982 TEST_F(WiFiServiceTest, CustomSetterNoopChange) { 1983 WiFiServiceRefPtr service = MakeServiceWithMockManager(); 1984 TestCustomSetterNoopChange(service, mock_manager()); 1985 } 1986 1987 TEST_F(WiFiServiceTest, SuspectedCredentialFailure) { 1988 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWpa); 1989 EXPECT_FALSE(service->has_ever_connected()); 1990 EXPECT_EQ(0, service->suspected_credential_failures_); 1991 1992 EXPECT_TRUE(service->AddSuspectedCredentialFailure()); 1993 EXPECT_EQ(0, service->suspected_credential_failures_); 1994 1995 service->has_ever_connected_ = true; 1996 for (int i = 0; i < WiFiService::kSuspectedCredentialFailureThreshold - 1; 1997 ++i) { 1998 EXPECT_FALSE(service->AddSuspectedCredentialFailure()); 1999 EXPECT_EQ(i + 1, service->suspected_credential_failures_); 2000 } 2001 2002 EXPECT_TRUE(service->AddSuspectedCredentialFailure()); 2003 // Make sure the failure state does not reset just because we ask again. 2004 EXPECT_TRUE(service->AddSuspectedCredentialFailure()); 2005 // Make sure the failure state resets because of a credential change. 2006 // A credential change changes the has_ever_connected to false and 2007 // immediately returns true when attempting to add the failure. 2008 Error error; 2009 service->SetPassphrase("Panchromatic Resonance", &error); 2010 EXPECT_TRUE(error.IsSuccess()); 2011 EXPECT_TRUE(service->AddSuspectedCredentialFailure()); 2012 EXPECT_EQ(0, service->suspected_credential_failures_); 2013 2014 // Make sure that we still return true after resetting the failure 2015 // count. 2016 service->suspected_credential_failures_ = 3; 2017 EXPECT_EQ(3, service->suspected_credential_failures_); 2018 service->ResetSuspectedCredentialFailures(); 2019 EXPECT_EQ(0, service->suspected_credential_failures_); 2020 EXPECT_TRUE(service->AddSuspectedCredentialFailure()); 2021 } 2022 2023 TEST_F(WiFiServiceTest, GetTethering) { 2024 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone); 2025 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr)); 2026 2027 // Since the device isn't connected, we shouldn't even query the WiFi device. 2028 EXPECT_CALL(*wifi(), IsConnectedViaTether()).Times(0); 2029 SetWiFiForService(service, wifi()); 2030 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr)); 2031 Mock::VerifyAndClearExpectations(wifi().get()); 2032 2033 scoped_refptr<MockProfile> mock_profile( 2034 new NiceMock<MockProfile>(control_interface(), metrics(), manager())); 2035 service->set_profile(mock_profile); 2036 service->SetState(Service::kStateConnected); 2037 2038 // A connected service should return "confirmed" iff the underlying device 2039 // reports it is tethered. 2040 EXPECT_CALL(*wifi(), IsConnectedViaTether()) 2041 .WillOnce(Return(true)) 2042 .WillOnce(Return(false)); 2043 EXPECT_EQ(kTetheringConfirmedState, service->GetTethering(nullptr)); 2044 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr)); 2045 Mock::VerifyAndClearExpectations(wifi().get()); 2046 2047 // Add two endpoints that have a BSSID associated with some Android devices 2048 // in tethering mode. 2049 WiFiEndpointRefPtr endpoint_android1 = 2050 MakeOpenEndpoint("a", "02:1a:11:00:00:01", 2412, 0); 2051 service->AddEndpoint(endpoint_android1); 2052 WiFiEndpointRefPtr endpoint_android2 = 2053 MakeOpenEndpoint("a", "02:1a:11:00:00:02", 2412, 0); 2054 service->AddEndpoint(endpoint_android2); 2055 2056 // Since there are two endpoints, we should not detect tethering mode. 2057 EXPECT_CALL(*wifi(), IsConnectedViaTether()).WillOnce(Return(false)); 2058 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr)); 2059 2060 // If the device reports that it is tethered, this should override any 2061 // findings gained from examining the endpoints. 2062 EXPECT_CALL(*wifi(), IsConnectedViaTether()).WillOnce(Return(true)); 2063 EXPECT_EQ(kTetheringConfirmedState, service->GetTethering(nullptr)); 2064 2065 // Continue in the un-tethered device case for a few more tests below. 2066 Mock::VerifyAndClearExpectations(wifi().get()); 2067 EXPECT_CALL(*wifi(), IsConnectedViaTether()) 2068 .WillRepeatedly(Return(false)); 2069 2070 // Removing an endpoint so we only have one should put us in the "Suspected" 2071 // state. 2072 service->RemoveEndpoint(endpoint_android1); 2073 EXPECT_EQ(kTetheringSuspectedState, service->GetTethering(nullptr)); 2074 2075 // Add a different endpoint which has a locally administered MAC address 2076 // but not one used by Android. 2077 service->RemoveEndpoint(endpoint_android2); 2078 WiFiEndpointRefPtr endpoint_ios = 2079 MakeOpenEndpoint("a", "02:00:00:00:00:01", 2412, 0); 2080 service->AddEndpoint(endpoint_ios); 2081 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr)); 2082 2083 // If this endpoint reports the right vendor OUI, we should suspect 2084 // it to be tethered. However since this evaluation normally only 2085 // happens in the endpoint constructor, we must force it to recalculate. 2086 endpoint_ios->vendor_information_.oui_set.insert(Tethering::kIosOui); 2087 endpoint_ios->CheckForTetheringSignature(); 2088 EXPECT_EQ(kTetheringSuspectedState, service->GetTethering(nullptr)); 2089 2090 // If the device reports that it is tethered, this should override any 2091 // findings gained from examining the endpoints. 2092 Mock::VerifyAndClearExpectations(wifi().get()); 2093 EXPECT_CALL(*wifi(), IsConnectedViaTether()).WillOnce(Return(true)); 2094 EXPECT_EQ(kTetheringConfirmedState, service->GetTethering(nullptr)); 2095 } 2096 2097 TEST_F(WiFiServiceTest, IsVisible) { 2098 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone); 2099 ServiceMockAdaptor* adaptor = GetAdaptor(wifi_service.get()); 2100 2101 // Adding the first endpoint emits a change: Visible = true. 2102 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, true)); 2103 WiFiEndpointRefPtr endpoint = 2104 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0); 2105 wifi_service->AddEndpoint(endpoint); 2106 EXPECT_TRUE(wifi_service->IsVisible()); 2107 Mock::VerifyAndClearExpectations(adaptor); 2108 2109 // Removing the last endpoint emits a change: Visible = false. 2110 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, false)); 2111 wifi_service->RemoveEndpoint(endpoint); 2112 EXPECT_FALSE(wifi_service->IsVisible()); 2113 Mock::VerifyAndClearExpectations(adaptor); 2114 2115 // Entering the a connecting state emits a change: Visible = true 2116 // although the service has no endpoints. 2117 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, true)); 2118 wifi_service->SetState(Service::kStateAssociating); 2119 EXPECT_TRUE(wifi_service->IsVisible()); 2120 Mock::VerifyAndClearExpectations(adaptor); 2121 2122 // Moving between connecting / connected states does not trigger an Emit. 2123 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, _)).Times(0); 2124 wifi_service->SetState(Service::kStateConfiguring); 2125 EXPECT_TRUE(wifi_service->IsVisible()); 2126 Mock::VerifyAndClearExpectations(adaptor); 2127 2128 // Entering the Idle state emits a change: Visible = false. 2129 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, false)); 2130 wifi_service->SetState(Service::kStateIdle); 2131 EXPECT_FALSE(wifi_service->IsVisible()); 2132 Mock::VerifyAndClearExpectations(adaptor); 2133 } 2134 2135 TEST_F(WiFiServiceTest, ConfigurePreferredDevice) { 2136 const string kDeviceName = "test_device"; 2137 2138 WiFiServiceRefPtr service = MakeGenericService(); 2139 KeyValueStore args; 2140 args.SetString(kWifiPreferredDeviceProperty, kDeviceName); 2141 2142 // With no wifi device. 2143 Error error; 2144 service->Configure(args, &error); 2145 EXPECT_EQ(Error::kSuccess, error.type()); 2146 EXPECT_EQ(kDeviceName, service->preferred_device_); 2147 2148 // With non-preferred wifi device. 2149 SetWiFiForService(service, wifi()); 2150 service->Configure(args, &error); 2151 EXPECT_EQ(Error::kSuccess, error.type()); 2152 EXPECT_EQ(nullptr, service->wifi_); 2153 EXPECT_EQ(kDeviceName, service->preferred_device_); 2154 2155 // With preferred wifi device. 2156 scoped_refptr<MockWiFi> preferred_wifi = MakeSimpleWiFi(kDeviceName); 2157 SetWiFiForService(service, preferred_wifi); 2158 service->Configure(args, &error); 2159 EXPECT_EQ(Error::kSuccess, error.type()); 2160 EXPECT_EQ(preferred_wifi, service->wifi_); 2161 EXPECT_EQ(kDeviceName, service->preferred_device_); 2162 } 2163 2164 TEST_F(WiFiServiceTest, LoadAndUnloadPreferredDevice) { 2165 WiFiServiceRefPtr service = MakeGenericService(); 2166 NiceMock<MockStore> mock_store; 2167 const string kStorageId = service->GetStorageIdentifier(); 2168 EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId))) 2169 .WillRepeatedly(Return(true)); 2170 set<string> groups; 2171 groups.insert(kStorageId); 2172 EXPECT_CALL(mock_store, GetGroupsWithProperties( 2173 ContainsWiFiProperties( 2174 simple_ssid(), kModeManaged, kSecurityWep))) 2175 .WillRepeatedly(Return(groups)); 2176 EXPECT_CALL(mock_store, GetBool(_, _, _)) 2177 .WillRepeatedly(Return(false)); 2178 const string kDeviceName = "test_device"; 2179 EXPECT_CALL(mock_store, 2180 GetString(StrEq(kStorageId), 2181 WiFiService::kStoragePreferredDevice, _)) 2182 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kDeviceName), Return(true))); 2183 EXPECT_CALL(mock_store, 2184 GetString(StrEq(kStorageId), 2185 StrNe(WiFiService::kStoragePreferredDevice), _)) 2186 .WillRepeatedly(Return(false)); 2187 2188 // With no wifi device. 2189 EXPECT_TRUE(service->Load(&mock_store)); 2190 EXPECT_EQ(kDeviceName, service->preferred_device_); 2191 service->Unload(); 2192 EXPECT_EQ("", service->preferred_device_); 2193 2194 // With non-preferred wifi device. 2195 SetWiFiForService(service, wifi()); 2196 EXPECT_TRUE(service->Load(&mock_store)); 2197 EXPECT_EQ(nullptr, service->wifi_); 2198 EXPECT_EQ(kDeviceName, service->preferred_device_); 2199 service->Unload(); 2200 EXPECT_EQ("", service->preferred_device_); 2201 2202 // With preferred wifi device. 2203 scoped_refptr<MockWiFi> preferred_wifi = MakeSimpleWiFi(kDeviceName); 2204 SetWiFiForService(service, preferred_wifi); 2205 EXPECT_TRUE(service->Load(&mock_store)); 2206 EXPECT_EQ(preferred_wifi, service->wifi_); 2207 EXPECT_EQ(kDeviceName, service->preferred_device_); 2208 service->Unload(); 2209 EXPECT_EQ("", service->preferred_device_); 2210 } 2211 2212 TEST_F(WiFiServiceTest, ChooseDevice) { 2213 const string kDeviceName1 = "test_device1"; 2214 const string kDeviceName2 = "test_device2"; 2215 scoped_refptr<MockWiFi> wifi1 = MakeSimpleWiFi(kDeviceName1); 2216 scoped_refptr<MockWiFi> wifi2 = MakeSimpleWiFi(kDeviceName2); 2217 WiFiServiceRefPtr service = MakeServiceWithMockManager(); 2218 2219 // No preferred device. 2220 EXPECT_CALL(*mock_manager(), GetEnabledDeviceByLinkName(_)).Times(0); 2221 EXPECT_CALL(*mock_manager(), 2222 GetEnabledDeviceWithTechnology(Technology::kWifi)) 2223 .WillOnce(Return(wifi1)); 2224 EXPECT_EQ(wifi1, service->ChooseDevice()); 2225 Mock::VerifyAndClearExpectations(mock_manager()); 2226 2227 // With preferred device. 2228 service->SetPreferredDevice(kDeviceName2, nullptr); 2229 EXPECT_CALL(*mock_manager(), GetEnabledDeviceByLinkName(kDeviceName2)) 2230 .WillOnce(Return(wifi2)); 2231 EXPECT_CALL(*mock_manager(), GetEnabledDeviceWithTechnology(_)).Times(0); 2232 EXPECT_EQ(wifi2, service->ChooseDevice()); 2233 Mock::VerifyAndClearExpectations(mock_manager()); 2234 } 2235 2236 TEST_F(WiFiServiceTest, RoamThresholdProperty) { 2237 WiFiServiceRefPtr service = MakeGenericService(); 2238 static const uint16_t kRoamThreshold16 = 16; 2239 static const uint16_t kRoamThreshold32 = 32; 2240 2241 EXPECT_TRUE(SetRoamThreshold(service, kRoamThreshold16)); 2242 EXPECT_EQ(GetRoamThreshold(service), kRoamThreshold16); 2243 2244 // Try a different number 2245 EXPECT_TRUE(SetRoamThreshold(service, kRoamThreshold32)); 2246 EXPECT_EQ(GetRoamThreshold(service), kRoamThreshold32); 2247 } 2248 2249 TEST_F(WiFiServiceTest, SaveLoadRoamThreshold) { 2250 WiFiServiceRefPtr service = MakeGenericService(); 2251 NiceMock<MockStore> mock_store; 2252 const uint16_t kRoamThreshold = 10; 2253 const string kStorageId = service->GetStorageIdentifier(); 2254 EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId))) 2255 .WillRepeatedly(Return(true)); 2256 set<string> groups; 2257 groups.insert(kStorageId); 2258 EXPECT_CALL(mock_store, GetGroupsWithProperties(ContainsWiFiProperties( 2259 simple_ssid(), kModeManaged, kSecurityWep))) 2260 .WillRepeatedly(Return(groups)); 2261 EXPECT_CALL(mock_store, GetBool(_, _, _)).Times(AnyNumber()); 2262 EXPECT_CALL(mock_store, SetBool(_, _, _)).Times(AnyNumber()); 2263 2264 // First, save these values. 2265 service->roam_threshold_db_ = kRoamThreshold; 2266 service->roam_threshold_db_set_ = true; 2267 EXPECT_CALL(mock_store, 2268 SetUint64(StrEq(kStorageId), WiFiService::kStorageRoamThreshold, 2269 kRoamThreshold)); 2270 EXPECT_CALL(mock_store, SetBool(StrEq(kStorageId), 2271 WiFiService::kStorageRoamThresholdSet, true)); 2272 EXPECT_TRUE(service->Save(&mock_store)); 2273 2274 // Then, load these values into the WiFiService members. 2275 service->roam_threshold_db_ = 0; 2276 service->roam_threshold_db_set_ = false; 2277 EXPECT_CALL(mock_store, GetUint64(StrEq(kStorageId), 2278 WiFiService::kStorageRoamThreshold, _)) 2279 .WillOnce(DoAll(SetArgumentPointee<2>(kRoamThreshold), Return(true))); 2280 EXPECT_CALL(mock_store, GetBool(StrEq(kStorageId), 2281 WiFiService::kStorageRoamThresholdSet, _)) 2282 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true))); 2283 EXPECT_TRUE(service->Load(&mock_store)); 2284 EXPECT_EQ(kRoamThreshold, service->roam_threshold_db_); 2285 EXPECT_TRUE(service->roam_threshold_db_set_); 2286 } 2287 2288 } // namespace shill 2289