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:
WiFiEndpointTest()54 WiFiEndpointTest() : wifi_(
55 new NiceMock<MockWiFi>(
56 control_interface(),
57 dispatcher(),
58 metrics(),
59 manager(),
60 "wifi",
61 "aabbccddeeff", // fake mac
62 0)) {}
~WiFiEndpointTest()63 virtual ~WiFiEndpointTest() {}
64
65 protected:
make_string_vector1(const string & str1)66 vector<string> make_string_vector1(const string& str1) {
67 vector<string> strvec;
68 strvec.push_back(str1);
69 return strvec;
70 }
71
make_string_vector2(const string & str1,const string & str2)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
make_key_management_args(vector<string> key_management_method_strings)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
make_privacy_args(bool is_private)87 KeyValueStore make_privacy_args(bool is_private) {
88 KeyValueStore props;
89 props.SetBool(WPASupplicant::kPropertyPrivacy, is_private);
90 return props;
91 }
92
make_security_args(const string & security_protocol,const string & key_management_method)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
ParseSecurity(const KeyValueStore & properties)107 const char* ParseSecurity(
108 const KeyValueStore& properties) {
109 WiFiEndpoint::SecurityFlags security_flags;
110 return WiFiEndpoint::ParseSecurity(properties, &security_flags);
111 }
112
AddIEWithData(uint8_t type,vector<uint8_t> data,vector<uint8_t> * ies)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
AddIE(uint8_t type,vector<uint8_t> * ies)119 void AddIE(uint8_t type, vector<uint8_t>* ies) {
120 AddIEWithData(type, vector<uint8_t>(1), ies);
121 }
122
AddVendorIE(uint32_t oui,uint8_t vendor_type,const vector<uint8_t> & data,vector<uint8_t> * ies)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
AddWPSElement(uint16_t type,const string & value,vector<uint8_t> * wps)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
MakeBSSPropertiesWithIEs(const vector<uint8_t> & ies)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).
MakeRSNProperties(uint16_t pairwise_count,uint16_t authkey_count,uint16_t capabilities)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
ParseIEs(const KeyValueStore & properties,Metrics::WiFiNetworkPhyMode * phy_mode,WiFiEndpoint::VendorInformation * vendor_information,bool * ieee80211w_required,std::string * country_code)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
SetVendorInformation(const WiFiEndpointRefPtr & endpoint,const WiFiEndpoint::VendorInformation & vendor_information)187 void SetVendorInformation(
188 const WiFiEndpointRefPtr& endpoint,
189 const WiFiEndpoint::VendorInformation& vendor_information) {
190 endpoint->vendor_information_ = vendor_information;
191 }
192
MakeEndpoint(ControlInterface * control_interface,const WiFiRefPtr & wifi,const std::string & ssid,const std::string & bssid,bool has_wpa_property,bool has_rsn_property)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
MakeOpenEndpoint(ControlInterface * control_interface,const WiFiRefPtr & wifi,const std::string & ssid,const std::string & bssid)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
wifi()214 scoped_refptr<MockWiFi> wifi() { return wifi_; }
215
216 private:
217 scoped_refptr<MockWiFi> wifi_;
218 };
219
TEST_F(WiFiEndpointTest,ParseKeyManagementMethodsEAP)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
TEST_F(WiFiEndpointTest,ParseKeyManagementMethodsPSK)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
TEST_F(WiFiEndpointTest,ParseKeyManagementMethodsEAPAndPSK)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
TEST_F(WiFiEndpointTest,ParseSecurityRSN802_1x)254 TEST_F(WiFiEndpointTest, ParseSecurityRSN802_1x) {
255 EXPECT_STREQ(kSecurity8021x,
256 ParseSecurity(make_security_args("RSN", "something-eap")));
257 }
258
TEST_F(WiFiEndpointTest,ParseSecurityWPA802_1x)259 TEST_F(WiFiEndpointTest, ParseSecurityWPA802_1x) {
260 EXPECT_STREQ(kSecurity8021x,
261 ParseSecurity(make_security_args("WPA", "something-eap")));
262 }
263
TEST_F(WiFiEndpointTest,ParseSecurityRSNPSK)264 TEST_F(WiFiEndpointTest, ParseSecurityRSNPSK) {
265 EXPECT_STREQ(kSecurityRsn,
266 ParseSecurity(make_security_args("RSN", "something-psk")));
267 }
268
TEST_F(WiFiEndpointTest,ParseSecurityWPAPSK)269 TEST_F(WiFiEndpointTest, ParseSecurityWPAPSK) {
270 EXPECT_STREQ(kSecurityWpa,
271 ParseSecurity(make_security_args("WPA", "something-psk")));
272 }
273
TEST_F(WiFiEndpointTest,ParseSecurityWEP)274 TEST_F(WiFiEndpointTest, ParseSecurityWEP) {
275 EXPECT_STREQ(kSecurityWep, ParseSecurity(make_privacy_args(true)));
276 }
277
TEST_F(WiFiEndpointTest,ParseSecurityNone)278 TEST_F(WiFiEndpointTest, ParseSecurityNone) {
279 KeyValueStore top_params;
280 EXPECT_STREQ(kSecurityNone, ParseSecurity(top_params));
281 }
282
TEST_F(WiFiEndpointTest,SSIDAndBSSIDString)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
TEST_F(WiFiEndpointTest,SSIDWithNull)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
TEST_F(WiFiEndpointTest,DeterminePhyModeFromFrequency)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
TEST_F(WiFiEndpointTest,ParseIEs)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
TEST_F(WiFiEndpointTest,ParseVendorIEs)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
TEST_F(WiFiEndpointTest,ParseWPACapabilities)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
TEST_F(WiFiEndpointTest,ParseCountryCode)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
TEST_F(WiFiEndpointTest,PropertiesChangedNone)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
TEST_F(WiFiEndpointTest,PropertiesChangedStrength)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
TEST_F(WiFiEndpointTest,PropertiesChangedNetworkMode)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
TEST_F(WiFiEndpointTest,PropertiesChangedSecurityMode)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
TEST_F(WiFiEndpointTest,HasRsnWpaProperties)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
TEST_F(WiFiEndpointTest,HasTetheringSignature)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