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_endpoint.h" 18 19 #include <map> 20 #include <set> 21 #include <string> 22 #include <vector> 23 24 #include <base/stl_util.h> 25 #if defined(__ANDROID__) 26 #include <dbus/service_constants.h> 27 #else 28 #include <chromeos/dbus/service_constants.h> 29 #endif // __ANDROID__ 30 #include <gmock/gmock.h> 31 #include <gtest/gtest.h> 32 33 #include "shill/mock_log.h" 34 #include "shill/net/ieee80211.h" 35 #include "shill/property_store_unittest.h" 36 #include "shill/refptr_types.h" 37 #include "shill/supplicant/wpa_supplicant.h" 38 #include "shill/tethering.h" 39 #include "shill/wifi/mock_wifi.h" 40 41 using std::map; 42 using std::set; 43 using std::string; 44 using std::vector; 45 using ::testing::_; 46 using ::testing::HasSubstr; 47 using ::testing::Mock; 48 using ::testing::NiceMock; 49 50 namespace shill { 51 52 class WiFiEndpointTest : public PropertyStoreTest { 53 public: 54 WiFiEndpointTest() : wifi_( 55 new NiceMock<MockWiFi>( 56 control_interface(), 57 dispatcher(), 58 metrics(), 59 manager(), 60 "wifi", 61 "aabbccddeeff", // fake mac 62 0)) {} 63 virtual ~WiFiEndpointTest() {} 64 65 protected: 66 vector<string> make_string_vector1(const string& str1) { 67 vector<string> strvec; 68 strvec.push_back(str1); 69 return strvec; 70 } 71 72 vector<string> make_string_vector2(const string& str1, const string& str2) { 73 vector<string> strvec; 74 strvec.push_back(str1); 75 strvec.push_back(str2); 76 return strvec; 77 } 78 79 KeyValueStore make_key_management_args( 80 vector<string> key_management_method_strings) { 81 KeyValueStore args; 82 args.SetStrings(WPASupplicant::kSecurityMethodPropertyKeyManagement, 83 key_management_method_strings); 84 return args; 85 } 86 87 KeyValueStore make_privacy_args(bool is_private) { 88 KeyValueStore props; 89 props.SetBool(WPASupplicant::kPropertyPrivacy, is_private); 90 return props; 91 } 92 93 KeyValueStore make_security_args( 94 const string& security_protocol, 95 const string& key_management_method) { 96 KeyValueStore args; 97 vector<string> key_management_method_vector; 98 if (!key_management_method.empty()) { 99 key_management_method_vector = make_string_vector1(key_management_method); 100 } 101 args.SetKeyValueStore( 102 security_protocol, 103 make_key_management_args(key_management_method_vector)); 104 return args; 105 } 106 107 const char* ParseSecurity( 108 const KeyValueStore& properties) { 109 WiFiEndpoint::SecurityFlags security_flags; 110 return WiFiEndpoint::ParseSecurity(properties, &security_flags); 111 } 112 113 void AddIEWithData(uint8_t type, vector<uint8_t> data, vector<uint8_t>* ies) { 114 ies->push_back(type); // type 115 ies->push_back(data.size()); // length 116 ies->insert(ies->end(), data.begin(), data.end()); 117 } 118 119 void AddIE(uint8_t type, vector<uint8_t>* ies) { 120 AddIEWithData(type, vector<uint8_t>(1), ies); 121 } 122 123 void AddVendorIE(uint32_t oui, uint8_t vendor_type, 124 const vector<uint8_t>& data, 125 vector<uint8_t>* ies) { 126 ies->push_back(IEEE_80211::kElemIdVendor); // type 127 ies->push_back(4 + data.size()); // length 128 ies->push_back((oui >> 16) & 0xff); // OUI MSByte 129 ies->push_back((oui >> 8) & 0xff); // OUI middle octet 130 ies->push_back(oui & 0xff); // OUI LSByte 131 ies->push_back(vendor_type); // OUI Type 132 ies->insert(ies->end(), data.begin(), data.end()); 133 } 134 135 void AddWPSElement(uint16_t type, const string& value, 136 vector<uint8_t>* wps) { 137 wps->push_back(type >> 8); // type MSByte 138 wps->push_back(type); // type LSByte 139 CHECK(value.size() < std::numeric_limits<uint16_t>::max()); 140 wps->push_back((value.size() >> 8) & 0xff); // length MSByte 141 wps->push_back(value.size() & 0xff); // length LSByte 142 wps->insert(wps->end(), value.begin(), value.end()); 143 } 144 145 KeyValueStore MakeBSSPropertiesWithIEs(const vector<uint8_t>& ies) { 146 KeyValueStore properties; 147 properties.SetUint8s(WPASupplicant::kBSSPropertyIEs, ies); 148 return properties; 149 } 150 151 // Creates the RSN properties string (which still requires an information 152 // element prefix). 153 vector<uint8_t> MakeRSNProperties(uint16_t pairwise_count, 154 uint16_t authkey_count, 155 uint16_t capabilities) { 156 vector<uint8_t> rsn(IEEE_80211::kRSNIECipherCountOffset + 157 IEEE_80211::kRSNIECipherCountLen * 2 + 158 IEEE_80211::kRSNIESelectorLen * 159 (pairwise_count + authkey_count) + 160 IEEE_80211::kRSNIECapabilitiesLen); 161 162 // Set both cipher counts in little endian. 163 rsn[IEEE_80211::kRSNIECipherCountOffset] = pairwise_count & 0xff; 164 rsn[IEEE_80211::kRSNIECipherCountOffset + 1] = pairwise_count >> 8; 165 size_t authkey_offset = IEEE_80211::kRSNIECipherCountOffset + 166 IEEE_80211::kRSNIECipherCountLen + 167 pairwise_count * IEEE_80211::kRSNIESelectorLen; 168 rsn[authkey_offset] = authkey_count & 0xff; 169 rsn[authkey_offset + 1] = authkey_count >> 8; 170 171 // Set the little-endian capabilities field. 172 size_t capabilities_offset = rsn.size() - 2; 173 rsn[capabilities_offset] = capabilities & 0xff; 174 rsn[capabilities_offset + 1] = capabilities >> 8; 175 176 return rsn; 177 } 178 179 bool ParseIEs(const KeyValueStore& properties, 180 Metrics::WiFiNetworkPhyMode* phy_mode, 181 WiFiEndpoint::VendorInformation* vendor_information, 182 bool* ieee80211w_required, std::string* country_code) { 183 return WiFiEndpoint::ParseIEs(properties, phy_mode, vendor_information, 184 ieee80211w_required, country_code); 185 } 186 187 void SetVendorInformation( 188 const WiFiEndpointRefPtr& endpoint, 189 const WiFiEndpoint::VendorInformation& vendor_information) { 190 endpoint->vendor_information_ = vendor_information; 191 } 192 193 WiFiEndpoint* MakeEndpoint(ControlInterface* control_interface, 194 const WiFiRefPtr& wifi, 195 const std::string& ssid, 196 const std::string& bssid, 197 bool has_wpa_property, 198 bool has_rsn_property) { 199 return WiFiEndpoint::MakeEndpoint( 200 control_interface, wifi, ssid, bssid, 201 WPASupplicant::kNetworkModeInfrastructure, 0, 0, has_wpa_property, 202 has_rsn_property); 203 } 204 205 WiFiEndpoint* MakeOpenEndpoint(ControlInterface* control_interface, 206 const WiFiRefPtr& wifi, 207 const std::string& ssid, 208 const std::string& bssid) { 209 return WiFiEndpoint::MakeOpenEndpoint( 210 control_interface, wifi, ssid, bssid, 211 WPASupplicant::kNetworkModeInfrastructure, 0, 0); 212 } 213 214 scoped_refptr<MockWiFi> wifi() { return wifi_; } 215 216 private: 217 scoped_refptr<MockWiFi> wifi_; 218 }; 219 220 TEST_F(WiFiEndpointTest, ParseKeyManagementMethodsEAP) { 221 set<WiFiEndpoint::KeyManagement> parsed_methods; 222 WiFiEndpoint::ParseKeyManagementMethods( 223 make_key_management_args(make_string_vector1("something-eap")), 224 &parsed_methods); 225 EXPECT_TRUE( 226 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagement802_1x)); 227 EXPECT_FALSE( 228 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagementPSK)); 229 } 230 231 TEST_F(WiFiEndpointTest, ParseKeyManagementMethodsPSK) { 232 set<WiFiEndpoint::KeyManagement> parsed_methods; 233 WiFiEndpoint::ParseKeyManagementMethods( 234 make_key_management_args(make_string_vector1("something-psk")), 235 &parsed_methods); 236 EXPECT_TRUE( 237 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagementPSK)); 238 EXPECT_FALSE( 239 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagement802_1x)); 240 } 241 242 TEST_F(WiFiEndpointTest, ParseKeyManagementMethodsEAPAndPSK) { 243 set<WiFiEndpoint::KeyManagement> parsed_methods; 244 WiFiEndpoint::ParseKeyManagementMethods( 245 make_key_management_args( 246 make_string_vector2("something-eap", "something-psk")), 247 &parsed_methods); 248 EXPECT_TRUE( 249 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagement802_1x)); 250 EXPECT_TRUE( 251 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagementPSK)); 252 } 253 254 TEST_F(WiFiEndpointTest, ParseSecurityRSN802_1x) { 255 EXPECT_STREQ(kSecurity8021x, 256 ParseSecurity(make_security_args("RSN", "something-eap"))); 257 } 258 259 TEST_F(WiFiEndpointTest, ParseSecurityWPA802_1x) { 260 EXPECT_STREQ(kSecurity8021x, 261 ParseSecurity(make_security_args("WPA", "something-eap"))); 262 } 263 264 TEST_F(WiFiEndpointTest, ParseSecurityRSNPSK) { 265 EXPECT_STREQ(kSecurityRsn, 266 ParseSecurity(make_security_args("RSN", "something-psk"))); 267 } 268 269 TEST_F(WiFiEndpointTest, ParseSecurityWPAPSK) { 270 EXPECT_STREQ(kSecurityWpa, 271 ParseSecurity(make_security_args("WPA", "something-psk"))); 272 } 273 274 TEST_F(WiFiEndpointTest, ParseSecurityWEP) { 275 EXPECT_STREQ(kSecurityWep, ParseSecurity(make_privacy_args(true))); 276 } 277 278 TEST_F(WiFiEndpointTest, ParseSecurityNone) { 279 KeyValueStore top_params; 280 EXPECT_STREQ(kSecurityNone, ParseSecurity(top_params)); 281 } 282 283 TEST_F(WiFiEndpointTest, SSIDAndBSSIDString) { 284 const char kSSID[] = "The SSID"; 285 const char kBSSID[] = "00:01:02:03:04:05"; 286 287 // The MakeOpenEndpoint method translates both of the above parameters into 288 // binary equivalents before calling the Endpoint constructor. Let's make 289 // sure the Endpoint can translate them back losslessly to strings. 290 WiFiEndpointRefPtr endpoint = 291 MakeOpenEndpoint(nullptr, nullptr, kSSID, kBSSID); 292 EXPECT_EQ(kSSID, endpoint->ssid_string()); 293 EXPECT_EQ(kBSSID, endpoint->bssid_string()); 294 } 295 296 TEST_F(WiFiEndpointTest, SSIDWithNull) { 297 WiFiEndpointRefPtr endpoint = 298 MakeOpenEndpoint(nullptr, nullptr, string(1, 0), "00:00:00:00:00:01"); 299 EXPECT_EQ("?", endpoint->ssid_string()); 300 } 301 302 TEST_F(WiFiEndpointTest, DeterminePhyModeFromFrequency) { 303 { 304 KeyValueStore properties; 305 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11a, 306 WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 3200)); 307 } 308 { 309 KeyValueStore properties; 310 vector<uint32_t> rates(1, 22000000); 311 properties.SetUint32s(WPASupplicant::kBSSPropertyRates, rates); 312 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11b, 313 WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 2400)); 314 } 315 { 316 KeyValueStore properties; 317 vector<uint32_t> rates(1, 54000000); 318 properties.SetUint32s(WPASupplicant::kBSSPropertyRates, rates); 319 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11g, 320 WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 2400)); 321 } 322 { 323 KeyValueStore properties; 324 vector<uint32_t> rates; 325 properties.SetUint32s(WPASupplicant::kBSSPropertyRates, rates); 326 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11b, 327 WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 2400)); 328 } 329 } 330 331 TEST_F(WiFiEndpointTest, ParseIEs) { 332 { 333 vector<uint8_t> ies; 334 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 335 WiFiEndpoint::VendorInformation vendor_information; 336 EXPECT_FALSE(ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, 337 &vendor_information, nullptr, nullptr)); 338 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, phy_mode); 339 } 340 { 341 vector<uint8_t> ies; 342 AddIE(IEEE_80211::kElemIdErp, &ies); 343 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 344 WiFiEndpoint::VendorInformation vendor_information; 345 EXPECT_TRUE(ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, 346 &vendor_information, nullptr, nullptr)); 347 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11g, phy_mode); 348 } 349 { 350 vector<uint8_t> ies; 351 AddIE(IEEE_80211::kElemIdHTCap, &ies); 352 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 353 WiFiEndpoint::VendorInformation vendor_information; 354 EXPECT_TRUE(ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, 355 &vendor_information, nullptr, nullptr)); 356 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, phy_mode); 357 } 358 { 359 vector<uint8_t> ies; 360 AddIE(IEEE_80211::kElemIdHTInfo, &ies); 361 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 362 WiFiEndpoint::VendorInformation vendor_information; 363 EXPECT_TRUE(ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, 364 &vendor_information, nullptr, nullptr)); 365 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, phy_mode); 366 } 367 { 368 vector<uint8_t> ies; 369 AddIE(IEEE_80211::kElemIdErp, &ies); 370 AddIE(IEEE_80211::kElemIdHTCap, &ies); 371 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 372 WiFiEndpoint::VendorInformation vendor_information; 373 EXPECT_TRUE(ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, 374 &vendor_information, nullptr, nullptr)); 375 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, phy_mode); 376 } 377 { 378 vector<uint8_t> ies; 379 AddIE(IEEE_80211::kElemIdVHTCap, &ies); 380 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 381 WiFiEndpoint::VendorInformation vendor_information; 382 EXPECT_TRUE(ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, 383 &vendor_information, nullptr, nullptr)); 384 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11ac, phy_mode); 385 } 386 { 387 vector<uint8_t> ies; 388 AddIE(IEEE_80211::kElemIdVHTOperation, &ies); 389 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 390 WiFiEndpoint::VendorInformation vendor_information; 391 EXPECT_TRUE(ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, 392 &vendor_information, nullptr, nullptr)); 393 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11ac, phy_mode); 394 } 395 { 396 vector<uint8_t> ies; 397 AddIE(IEEE_80211::kElemIdErp, &ies); 398 AddIE(IEEE_80211::kElemIdHTCap, &ies); 399 AddIE(IEEE_80211::kElemIdVHTCap, &ies); 400 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 401 WiFiEndpoint::VendorInformation vendor_information; 402 EXPECT_TRUE(ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, 403 &vendor_information, nullptr, nullptr)); 404 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11ac, phy_mode); 405 } 406 } 407 408 TEST_F(WiFiEndpointTest, ParseVendorIEs) { 409 { 410 ScopedMockLog log; 411 EXPECT_CALL(log, Log(logging::LOG_ERROR, _, 412 HasSubstr("no room in IE for OUI and type field."))) 413 .Times(1); 414 vector<uint8_t> ies; 415 AddIE(IEEE_80211::kElemIdVendor, &ies); 416 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 417 WiFiEndpoint::VendorInformation vendor_information; 418 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 419 nullptr, nullptr); 420 } 421 { 422 vector<uint8_t> ies; 423 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 424 WiFiEndpoint::VendorInformation vendor_information; 425 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 426 nullptr, nullptr); 427 EXPECT_EQ("", vendor_information.wps_manufacturer); 428 EXPECT_EQ("", vendor_information.wps_model_name); 429 EXPECT_EQ("", vendor_information.wps_model_number); 430 EXPECT_EQ("", vendor_information.wps_device_name); 431 EXPECT_EQ(0, vendor_information.oui_set.size()); 432 } 433 { 434 ScopedMockLog log; 435 EXPECT_CALL(log, Log(logging::LOG_ERROR, _, 436 HasSubstr("IE extends past containing PDU"))).Times(1); 437 vector<uint8_t> ies; 438 AddVendorIE(0, 0, vector<uint8_t>(), &ies); 439 ies.resize(ies.size() - 1); // Cause an underrun in the data. 440 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 441 WiFiEndpoint::VendorInformation vendor_information; 442 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 443 nullptr, nullptr); 444 } 445 { 446 vector<uint8_t> ies; 447 const uint32_t kVendorOUI = 0xaabbcc; 448 AddVendorIE(kVendorOUI, 0, vector<uint8_t>(), &ies); 449 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, 0, vector<uint8_t>(), &ies); 450 AddVendorIE(IEEE_80211::kOUIVendorEpigram, 0, vector<uint8_t>(), &ies); 451 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 452 WiFiEndpoint::VendorInformation vendor_information; 453 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 454 nullptr, nullptr); 455 EXPECT_EQ("", vendor_information.wps_manufacturer); 456 EXPECT_EQ("", vendor_information.wps_model_name); 457 EXPECT_EQ("", vendor_information.wps_model_number); 458 EXPECT_EQ("", vendor_information.wps_device_name); 459 EXPECT_EQ(1, vendor_information.oui_set.size()); 460 EXPECT_FALSE(vendor_information.oui_set.find(kVendorOUI) == 461 vendor_information.oui_set.end()); 462 463 WiFiEndpointRefPtr endpoint = 464 MakeOpenEndpoint(nullptr, nullptr, string(1, 0), "00:00:00:00:00:01"); 465 SetVendorInformation(endpoint, vendor_information); 466 map<string, string> vendor_stringmap(endpoint->GetVendorInformation()); 467 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSManufacturerProperty)); 468 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSModelNameProperty)); 469 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSModelNumberProperty)); 470 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSDeviceNameProperty)); 471 EXPECT_EQ("aa-bb-cc", vendor_stringmap[kVendorOUIListProperty]); 472 } 473 { 474 ScopedMockLog log; 475 EXPECT_CALL(log, Log(logging::LOG_ERROR, _, 476 HasSubstr("WPS element extends past containing PDU"))) 477 .Times(1); 478 vector<uint8_t> ies; 479 vector<uint8_t> wps; 480 AddWPSElement(IEEE_80211::kWPSElementManufacturer, "foo", &wps); 481 wps.resize(wps.size() - 1); // Cause an underrun in the data. 482 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, 483 IEEE_80211::kOUIMicrosoftWPS, wps, &ies); 484 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 485 WiFiEndpoint::VendorInformation vendor_information; 486 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 487 nullptr, nullptr); 488 EXPECT_EQ("", vendor_information.wps_manufacturer); 489 } 490 { 491 vector<uint8_t> ies; 492 vector<uint8_t> wps; 493 const string kManufacturer("manufacturer"); 494 const string kModelName("modelname"); 495 const string kModelNumber("modelnumber"); 496 const string kDeviceName("devicename"); 497 AddWPSElement(IEEE_80211::kWPSElementManufacturer, kManufacturer, &wps); 498 AddWPSElement(IEEE_80211::kWPSElementModelName, kModelName, &wps); 499 AddWPSElement(IEEE_80211::kWPSElementModelNumber, kModelNumber, &wps); 500 AddWPSElement(IEEE_80211::kWPSElementDeviceName, kDeviceName, &wps); 501 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, 502 IEEE_80211::kOUIMicrosoftWPS, wps, &ies); 503 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 504 WiFiEndpoint::VendorInformation vendor_information; 505 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 506 nullptr, nullptr); 507 EXPECT_EQ(kManufacturer, vendor_information.wps_manufacturer); 508 EXPECT_EQ(kModelName, vendor_information.wps_model_name); 509 EXPECT_EQ(kModelNumber, vendor_information.wps_model_number); 510 EXPECT_EQ(kDeviceName, vendor_information.wps_device_name); 511 512 WiFiEndpointRefPtr endpoint = 513 MakeOpenEndpoint(nullptr, nullptr, string(1, 0), "00:00:00:00:00:01"); 514 SetVendorInformation(endpoint, vendor_information); 515 map<string, string> vendor_stringmap(endpoint->GetVendorInformation()); 516 EXPECT_EQ(kManufacturer, vendor_stringmap[kVendorWPSManufacturerProperty]); 517 EXPECT_EQ(kModelName, vendor_stringmap[kVendorWPSModelNameProperty]); 518 EXPECT_EQ(kModelNumber, vendor_stringmap[kVendorWPSModelNumberProperty]); 519 EXPECT_EQ(kDeviceName, vendor_stringmap[kVendorWPSDeviceNameProperty]); 520 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorOUIListProperty)); 521 } 522 { 523 vector<uint8_t> ies; 524 vector<uint8_t> wps; 525 const string kManufacturer("manufacturer"); 526 const string kModelName("modelname"); 527 AddWPSElement(IEEE_80211::kWPSElementManufacturer, kManufacturer, &wps); 528 wps.resize(wps.size() - 1); // Insert a non-ASCII character in the WPS. 529 wps.push_back(0x80); 530 AddWPSElement(IEEE_80211::kWPSElementModelName, kModelName, &wps); 531 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, 532 IEEE_80211::kOUIMicrosoftWPS, wps, &ies); 533 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 534 WiFiEndpoint::VendorInformation vendor_information; 535 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 536 nullptr, nullptr); 537 EXPECT_EQ("", vendor_information.wps_manufacturer); 538 EXPECT_EQ(kModelName, vendor_information.wps_model_name); 539 } 540 } 541 542 TEST_F(WiFiEndpointTest, ParseWPACapabilities) { 543 { 544 vector<uint8_t> ies; 545 vector<uint8_t> rsn; 546 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, IEEE_80211::kOUIMicrosoftWPA, 547 rsn, &ies); 548 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies); 549 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 550 WiFiEndpoint::VendorInformation vendor_information; 551 bool ieee80211w_required = false; 552 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 553 &ieee80211w_required, nullptr); 554 EXPECT_FALSE(ieee80211w_required); 555 } 556 { 557 vector<uint8_t> ies; 558 vector<uint8_t> rsn = MakeRSNProperties( 559 2, 3, ~IEEE_80211::kRSNCapabilityFrameProtectionRequired); 560 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, IEEE_80211::kOUIMicrosoftWPA, 561 rsn, &ies); 562 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies); 563 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 564 WiFiEndpoint::VendorInformation vendor_information; 565 bool ieee80211w_required = false; 566 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 567 &ieee80211w_required, nullptr); 568 EXPECT_FALSE(ieee80211w_required); 569 } 570 { 571 vector<uint8_t> ies; 572 vector<uint8_t> rsn = MakeRSNProperties( 573 2, 3, IEEE_80211::kRSNCapabilityFrameProtectionRequired); 574 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, IEEE_80211::kOUIMicrosoftWPA, 575 rsn, &ies); 576 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 577 WiFiEndpoint::VendorInformation vendor_information; 578 bool ieee80211w_required = false; 579 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 580 &ieee80211w_required, nullptr); 581 EXPECT_TRUE(ieee80211w_required); 582 } 583 { 584 vector<uint8_t> ies; 585 vector<uint8_t> rsn = MakeRSNProperties( 586 8, 2, IEEE_80211::kRSNCapabilityFrameProtectionRequired); 587 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies); 588 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 589 WiFiEndpoint::VendorInformation vendor_information; 590 bool ieee80211w_required = false; 591 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 592 &ieee80211w_required, nullptr); 593 EXPECT_TRUE(ieee80211w_required); 594 } 595 { 596 vector<uint8_t> ies; 597 vector<uint8_t> rsn = MakeRSNProperties( 598 8, 2, IEEE_80211::kRSNCapabilityFrameProtectionRequired); 599 rsn.resize(rsn.size() + 1); 600 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies); 601 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 602 WiFiEndpoint::VendorInformation vendor_information; 603 bool ieee80211w_required = false; 604 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 605 &ieee80211w_required, nullptr); 606 EXPECT_TRUE(ieee80211w_required); 607 } 608 { 609 vector<uint8_t> ies; 610 vector<uint8_t> rsn = MakeRSNProperties( 611 8, 2, IEEE_80211::kRSNCapabilityFrameProtectionRequired); 612 rsn.resize(rsn.size() - 1); 613 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies); 614 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 615 WiFiEndpoint::VendorInformation vendor_information; 616 bool ieee80211w_required = false; 617 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 618 &ieee80211w_required, nullptr); 619 EXPECT_FALSE(ieee80211w_required); 620 } 621 { 622 vector<uint8_t> ies; 623 vector<uint8_t> rsn0 = MakeRSNProperties( 624 1, 1, IEEE_80211::kRSNCapabilityFrameProtectionRequired); 625 AddIEWithData(IEEE_80211::kElemIdRSN, rsn0, &ies); 626 vector<uint8_t> rsn1 = MakeRSNProperties(1, 1, 0); 627 AddIEWithData(IEEE_80211::kElemIdRSN, rsn1, &ies); 628 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 629 WiFiEndpoint::VendorInformation vendor_information; 630 bool ieee80211w_required = false; 631 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 632 &ieee80211w_required, nullptr); 633 EXPECT_TRUE(ieee80211w_required); 634 } 635 } 636 637 TEST_F(WiFiEndpointTest, ParseCountryCode) { 638 { 639 vector<uint8_t> ies; 640 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 641 WiFiEndpoint::VendorInformation vendor_information; 642 string country_code; 643 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 644 nullptr, &country_code); 645 EXPECT_TRUE(country_code.empty()); 646 } 647 { 648 const string kCountryCode("G"); 649 const vector<uint8_t> kCountryCodeAsVector( 650 kCountryCode.begin(), kCountryCode.end()); 651 vector<uint8_t> ies; 652 AddIEWithData(IEEE_80211::kElemIdCountry, kCountryCodeAsVector, &ies); 653 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 654 WiFiEndpoint::VendorInformation vendor_information; 655 string country_code; 656 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 657 nullptr, &country_code); 658 EXPECT_TRUE(country_code.empty()); 659 } 660 { 661 const string kCountryCode("GO"); 662 const vector<uint8_t> kCountryCodeAsVector( 663 kCountryCode.begin(), kCountryCode.end()); 664 vector<uint8_t> ies; 665 AddIEWithData(IEEE_80211::kElemIdCountry, kCountryCodeAsVector, &ies); 666 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 667 WiFiEndpoint::VendorInformation vendor_information; 668 string country_code; 669 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 670 nullptr, &country_code); 671 EXPECT_EQ(kCountryCode, country_code); 672 } 673 { 674 const string kCountryCode("GOO"); 675 const vector<uint8_t> kCountryCodeAsVector( 676 kCountryCode.begin(), kCountryCode.end()); 677 vector<uint8_t> ies; 678 AddIEWithData(IEEE_80211::kElemIdCountry, kCountryCodeAsVector, &ies); 679 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef; 680 WiFiEndpoint::VendorInformation vendor_information; 681 string country_code; 682 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information, 683 nullptr, &country_code); 684 EXPECT_EQ(string(kCountryCode, 0, 2), country_code); 685 } 686 } 687 688 TEST_F(WiFiEndpointTest, PropertiesChangedNone) { 689 WiFiEndpointRefPtr endpoint = 690 MakeOpenEndpoint(nullptr, wifi(), "ssid", "00:00:00:00:00:01"); 691 EXPECT_EQ(kModeManaged, endpoint->network_mode()); 692 EXPECT_EQ(kSecurityNone, endpoint->security_mode()); 693 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0); 694 KeyValueStore no_changed_properties; 695 endpoint->PropertiesChanged(no_changed_properties); 696 EXPECT_EQ(kModeManaged, endpoint->network_mode()); 697 EXPECT_EQ(kSecurityNone, endpoint->security_mode()); 698 } 699 700 TEST_F(WiFiEndpointTest, PropertiesChangedStrength) { 701 WiFiEndpointRefPtr endpoint = 702 MakeOpenEndpoint(nullptr, wifi(), "ssid", "00:00:00:00:00:01"); 703 KeyValueStore changed_properties; 704 int16_t signal_strength = 10; 705 706 EXPECT_NE(signal_strength, endpoint->signal_strength()); 707 changed_properties.SetInt16(WPASupplicant::kBSSPropertySignal, 708 signal_strength); 709 710 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)); 711 endpoint->PropertiesChanged(changed_properties); 712 EXPECT_EQ(signal_strength, endpoint->signal_strength()); 713 } 714 715 TEST_F(WiFiEndpointTest, PropertiesChangedNetworkMode) { 716 WiFiEndpointRefPtr endpoint = 717 MakeOpenEndpoint(nullptr, wifi(), "ssid", "00:00:00:00:00:01"); 718 EXPECT_EQ(kModeManaged, endpoint->network_mode()); 719 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1); 720 KeyValueStore changed_properties; 721 changed_properties.SetString(WPASupplicant::kBSSPropertyMode, 722 WPASupplicant::kNetworkModeAdHoc); 723 endpoint->PropertiesChanged(changed_properties); 724 EXPECT_EQ(kModeAdhoc, endpoint->network_mode()); 725 } 726 727 TEST_F(WiFiEndpointTest, PropertiesChangedSecurityMode) { 728 WiFiEndpointRefPtr endpoint = 729 MakeOpenEndpoint(nullptr, wifi(), "ssid", "00:00:00:00:00:01"); 730 EXPECT_EQ(kSecurityNone, endpoint->security_mode()); 731 732 // Upgrade to WEP if privacy flag is added. 733 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1); 734 endpoint->PropertiesChanged(make_privacy_args(true)); 735 Mock::VerifyAndClearExpectations(wifi().get()); 736 EXPECT_EQ(kSecurityWep, endpoint->security_mode()); 737 738 // Make sure we don't downgrade if no interesting arguments arrive. 739 KeyValueStore no_changed_properties; 740 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0); 741 endpoint->PropertiesChanged(no_changed_properties); 742 Mock::VerifyAndClearExpectations(wifi().get()); 743 EXPECT_EQ(kSecurityWep, endpoint->security_mode()); 744 745 // Another upgrade to 802.1x. 746 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1); 747 endpoint->PropertiesChanged(make_security_args("RSN", "something-eap")); 748 Mock::VerifyAndClearExpectations(wifi().get()); 749 EXPECT_EQ(kSecurity8021x, endpoint->security_mode()); 750 751 // Add WPA-PSK, however this is trumped by RSN 802.1x above, so we don't 752 // change our security nor do we notify anyone. 753 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0); 754 endpoint->PropertiesChanged(make_security_args("WPA", "something-psk")); 755 Mock::VerifyAndClearExpectations(wifi().get()); 756 EXPECT_EQ(kSecurity8021x, endpoint->security_mode()); 757 758 // If nothing changes, we should stay the same. 759 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0); 760 endpoint->PropertiesChanged(no_changed_properties); 761 Mock::VerifyAndClearExpectations(wifi().get()); 762 EXPECT_EQ(kSecurity8021x, endpoint->security_mode()); 763 764 // However, if the BSS updates to no longer support 802.1x, we degrade 765 // to WPA. 766 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1); 767 endpoint->PropertiesChanged(make_security_args("RSN", "")); 768 Mock::VerifyAndClearExpectations(wifi().get()); 769 EXPECT_EQ(kSecurityWpa, endpoint->security_mode()); 770 771 // Losing WPA brings us back to WEP (since the privacy flag hasn't changed). 772 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1); 773 endpoint->PropertiesChanged(make_security_args("WPA", "")); 774 Mock::VerifyAndClearExpectations(wifi().get()); 775 EXPECT_EQ(kSecurityWep, endpoint->security_mode()); 776 777 // From WEP to open security. 778 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1); 779 endpoint->PropertiesChanged(make_privacy_args(false)); 780 Mock::VerifyAndClearExpectations(wifi().get()); 781 EXPECT_EQ(kSecurityNone, endpoint->security_mode()); 782 } 783 784 TEST_F(WiFiEndpointTest, HasRsnWpaProperties) { 785 { 786 WiFiEndpointRefPtr endpoint = MakeEndpoint( 787 nullptr, wifi(), "ssid", "00:00:00:00:00:01", false, false); 788 EXPECT_FALSE(endpoint->has_wpa_property()); 789 EXPECT_FALSE(endpoint->has_rsn_property()); 790 } 791 { 792 WiFiEndpointRefPtr endpoint = 793 MakeEndpoint(nullptr, wifi(), "ssid", "00:00:00:00:00:01", true, false); 794 EXPECT_TRUE(endpoint->has_wpa_property()); 795 EXPECT_FALSE(endpoint->has_rsn_property()); 796 } 797 { 798 WiFiEndpointRefPtr endpoint = 799 MakeEndpoint(nullptr, wifi(), "ssid", "00:00:00:00:00:01", false, true); 800 EXPECT_FALSE(endpoint->has_wpa_property()); 801 EXPECT_TRUE(endpoint->has_rsn_property()); 802 } 803 { 804 // Both can be true. 805 WiFiEndpointRefPtr endpoint = 806 MakeEndpoint(nullptr, wifi(), "ssid", "00:00:00:00:00:01", true, true); 807 EXPECT_TRUE(endpoint->has_wpa_property()); 808 EXPECT_TRUE(endpoint->has_rsn_property()); 809 } 810 } 811 812 TEST_F(WiFiEndpointTest, HasTetheringSignature) { 813 { 814 WiFiEndpointRefPtr endpoint = MakeEndpoint( 815 nullptr, wifi(), "ssid", "02:1a:11:00:00:01", false, false); 816 EXPECT_TRUE(endpoint->has_tethering_signature()); 817 } 818 { 819 WiFiEndpointRefPtr endpoint = MakeEndpoint( 820 nullptr, wifi(), "ssid", "02:1a:10:00:00:01", false, false); 821 EXPECT_FALSE(endpoint->has_tethering_signature()); 822 endpoint->vendor_information_.oui_set.insert(Tethering::kIosOui); 823 endpoint->CheckForTetheringSignature(); 824 EXPECT_TRUE(endpoint->has_tethering_signature()); 825 } 826 { 827 WiFiEndpointRefPtr endpoint = MakeEndpoint( 828 nullptr, wifi(), "ssid", "04:1a:10:00:00:01", false, false); 829 EXPECT_FALSE(endpoint->has_tethering_signature()); 830 endpoint->vendor_information_.oui_set.insert(Tethering::kIosOui); 831 endpoint->CheckForTetheringSignature(); 832 EXPECT_FALSE(endpoint->has_tethering_signature()); 833 } 834 } 835 836 } // namespace shill 837