blob: eb795062b0f0ba7c6eb11fc5650271057d8d9692 [file] [log] [blame]
mukesh agrawal16bc1b82012-02-09 18:38:26 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
mukesh agrawal6e277772011-09-29 15:04:23 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/wifi_endpoint.h"
6
7#include <map>
8#include <set>
9#include <string>
10#include <vector>
11
Eric Shienbrood3e20a232012-02-16 11:35:56 -050012#include <base/stl_util.h>
mukesh agrawal6e277772011-09-29 15:04:23 -070013#include <chromeos/dbus/service_constants.h>
mukesh agrawalb20776f2012-02-10 16:00:36 -080014#include <gmock/gmock.h>
mukesh agrawal6e277772011-09-29 15:04:23 -070015#include <gtest/gtest.h>
16
Thieu Le1df7f4e2012-02-10 15:21:45 -080017#include "shill/ieee80211.h"
Paul Stewart72b2fdc2012-06-02 08:58:51 -070018#include "shill/mock_log.h"
mukesh agrawalb20776f2012-02-10 16:00:36 -080019#include "shill/mock_wifi.h"
20#include "shill/property_store_unittest.h"
mukesh agrawal16bc1b82012-02-09 18:38:26 -080021#include "shill/refptr_types.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070022#include "shill/wpa_supplicant.h"
23
24using std::map;
25using std::set;
26using std::string;
27using std::vector;
mukesh agrawalb20776f2012-02-10 16:00:36 -080028using ::testing::_;
Paul Stewartaffc0552013-03-25 07:50:15 -070029using ::testing::HasSubstr;
30using ::testing::Mock;
mukesh agrawalb20776f2012-02-10 16:00:36 -080031using ::testing::NiceMock;
mukesh agrawal6e277772011-09-29 15:04:23 -070032
33namespace shill {
34
mukesh agrawalb20776f2012-02-10 16:00:36 -080035class WiFiEndpointTest : public PropertyStoreTest {
mukesh agrawal6e277772011-09-29 15:04:23 -070036 public:
mukesh agrawalb20776f2012-02-10 16:00:36 -080037 WiFiEndpointTest() : wifi_(
38 new NiceMock<MockWiFi>(
39 control_interface(),
40 dispatcher(),
41 metrics(),
42 manager(),
43 "wifi",
44 "aabbccddeeff", // fake mac
45 0)) {}
mukesh agrawal6e277772011-09-29 15:04:23 -070046 virtual ~WiFiEndpointTest() {}
47
48 protected:
49 vector<string> make_string_vector1(const string &str1) {
50 vector<string> strvec;
51 strvec.push_back(str1);
52 return strvec;
53 }
54
55 vector<string> make_string_vector2(const string &str1, const string &str2) {
56 vector<string> strvec;
57 strvec.push_back(str1);
58 strvec.push_back(str2);
59 return strvec;
60 }
61
62 map<string, ::DBus::Variant> make_key_management_args(
63 vector<string> key_management_method_strings) {
64 map<string, ::DBus::Variant> args;
65 ::DBus::MessageIter writer;
66 writer =
Paul Stewart0654ece2013-03-26 15:21:26 -070067 args[WPASupplicant::kSecurityMethodPropertyKeyManagement].writer();
mukesh agrawal6e277772011-09-29 15:04:23 -070068 writer << key_management_method_strings;
69 return args;
70 }
71
Paul Stewartaffc0552013-03-25 07:50:15 -070072 map<string, ::DBus::Variant> make_privacy_args(bool is_private) {
73 map<string, ::DBus::Variant> props;
74 props[WPASupplicant::kPropertyPrivacy].writer().append_bool(is_private);
75 return props;
76 }
77
mukesh agrawal6e277772011-09-29 15:04:23 -070078 map<string, ::DBus::Variant> make_security_args(
79 const string &security_protocol,
80 const string &key_management_method) {
81 map<string, ::DBus::Variant> args;
82 ::DBus::MessageIter writer;
83 writer = args[security_protocol].writer();
Paul Stewartaffc0552013-03-25 07:50:15 -070084 vector<string> key_management_method_vector;
85 if (!key_management_method.empty()) {
86 key_management_method_vector = make_string_vector1(key_management_method);
87 }
88 writer << make_key_management_args(key_management_method_vector);
mukesh agrawal6e277772011-09-29 15:04:23 -070089 return args;
90 }
91
92 const char *ParseSecurity(
93 const map<string, ::DBus::Variant> &properties) {
Paul Stewartaffc0552013-03-25 07:50:15 -070094 WiFiEndpoint::SecurityFlags security_flags;
95 return WiFiEndpoint::ParseSecurity(properties, &security_flags);
mukesh agrawal6e277772011-09-29 15:04:23 -070096 }
Thieu Le1df7f4e2012-02-10 15:21:45 -080097
Paul Stewarta5e7d5f2013-01-09 18:06:15 -080098 void AddIEWithData(uint8_t type, vector<uint8_t> data, vector<uint8_t> *ies) {
Thieu Le1df7f4e2012-02-10 15:21:45 -080099 ies->push_back(type); // type
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800100 ies->push_back(data.size()); // length
101 ies->insert(ies->end(), data.begin(), data.end());
102 }
103
104 void AddIE(uint8_t type, vector<uint8_t> *ies) {
105 AddIEWithData(type, vector<uint8_t>(1), ies);
Thieu Le1df7f4e2012-02-10 15:21:45 -0800106 }
mukesh agrawalb20776f2012-02-10 16:00:36 -0800107
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700108 void AddVendorIE(uint32_t oui, uint8_t vendor_type,
109 const vector<uint8_t> &data,
110 vector<uint8_t> *ies) {
111 ies->push_back(IEEE_80211::kElemIdVendor); // type
112 ies->push_back(4 + data.size()); // length
113 ies->push_back((oui >> 16) & 0xff); // OUI MSByte
114 ies->push_back((oui >> 8) & 0xff); // OUI middle octet
115 ies->push_back(oui & 0xff); // OUI LSByte
116 ies->push_back(vendor_type); // OUI Type
117 ies->insert(ies->end(), data.begin(), data.end());
118 }
119
120 void AddWPSElement(uint16_t type, const string &value,
121 vector<uint8_t> *wps) {
122 wps->push_back(type >> 8); // type MSByte
123 wps->push_back(type); // type LSByte
124 CHECK(value.size() < kuint16max);
125 wps->push_back((value.size() >> 8) & 0xff); // length MSByte
126 wps->push_back(value.size() & 0xff); // length LSByte
127 wps->insert(wps->end(), value.begin(), value.end());
128 }
129
130 map<string, ::DBus::Variant> MakeBSSPropertiesWithIEs(
131 const vector<uint8_t> &ies) {
132 map<string, ::DBus::Variant> properties;
133 ::DBus::MessageIter writer =
Paul Stewart0654ece2013-03-26 15:21:26 -0700134 properties[WPASupplicant::kBSSPropertyIEs].writer();
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700135 writer << ies;
136 return properties;
137 }
138
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800139 // Creates the RSN properties string (which still requires an information
140 // element prefix).
141 vector<uint8_t> MakeRSNProperties(uint16 pairwise_count,
142 uint16 authkey_count,
143 uint16 capabilities) {
144 vector<uint8_t> rsn(IEEE_80211::kRSNIECipherCountOffset +
145 IEEE_80211::kRSNIECipherCountLen * 2 +
146 IEEE_80211::kRSNIESelectorLen *
147 (pairwise_count + authkey_count) +
148 IEEE_80211::kRSNIECapabilitiesLen);
149
150 // Set both cipher counts in little endian.
151 rsn[IEEE_80211::kRSNIECipherCountOffset] = pairwise_count & 0xff;
152 rsn[IEEE_80211::kRSNIECipherCountOffset + 1] = pairwise_count >> 8;
153 size_t authkey_offset = IEEE_80211::kRSNIECipherCountOffset +
154 IEEE_80211::kRSNIECipherCountLen +
155 pairwise_count * IEEE_80211::kRSNIESelectorLen;
156 rsn[authkey_offset] = authkey_count & 0xff;
157 rsn[authkey_offset + 1] = authkey_count >> 8;
158
159 // Set the little-endian capabilities field.
160 size_t capabilities_offset = rsn.size() - 2;
161 rsn[capabilities_offset] = capabilities & 0xff;
162 rsn[capabilities_offset + 1] = capabilities >> 8;
163
164 return rsn;
165 }
166
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700167 bool ParseIEs(const std::map<std::string, ::DBus::Variant> &properties,
168 Metrics::WiFiNetworkPhyMode *phy_mode,
169 WiFiEndpoint::VendorInformation *vendor_information,
170 bool *ieee80211w_required, std::string *country_code) {
171 return WiFiEndpoint::ParseIEs(properties, phy_mode, vendor_information,
172 ieee80211w_required, country_code);
173 }
174
175 void SetVendorInformation(
176 const WiFiEndpointRefPtr &endpoint,
177 const WiFiEndpoint::VendorInformation &vendor_information) {
178 endpoint->vendor_information_ = vendor_information;
179 }
180
mukesh agrawal43970a22013-02-15 16:00:07 -0800181 WiFiEndpoint *MakeEndpoint(ProxyFactory *proxy_factory,
182 const WiFiRefPtr &wifi,
183 const std::string &ssid,
184 const std::string &bssid,
185 bool has_wpa_property,
186 bool has_rsn_property) {
187 return WiFiEndpoint::MakeEndpoint(
188 proxy_factory, wifi, ssid, bssid,
Paul Stewart0654ece2013-03-26 15:21:26 -0700189 WPASupplicant::kNetworkModeInfrastructure, 0, 0, has_wpa_property,
mukesh agrawal43970a22013-02-15 16:00:07 -0800190 has_rsn_property);
191 }
192
mukesh agrawalb20776f2012-02-10 16:00:36 -0800193 WiFiEndpoint *MakeOpenEndpoint(ProxyFactory *proxy_factory,
194 const WiFiRefPtr &wifi,
195 const std::string &ssid,
196 const std::string &bssid) {
mukesh agrawale1d90e92012-02-15 17:36:08 -0800197 return WiFiEndpoint::MakeOpenEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800198 proxy_factory, wifi, ssid, bssid,
Paul Stewart0654ece2013-03-26 15:21:26 -0700199 WPASupplicant::kNetworkModeInfrastructure, 0, 0);
mukesh agrawalb20776f2012-02-10 16:00:36 -0800200 }
201
202 scoped_refptr<MockWiFi> wifi() { return wifi_; }
203
204 private:
205 scoped_refptr<MockWiFi> wifi_;
mukesh agrawal6e277772011-09-29 15:04:23 -0700206};
207
208TEST_F(WiFiEndpointTest, ParseKeyManagementMethodsEAP) {
209 set<WiFiEndpoint::KeyManagement> parsed_methods;
210 WiFiEndpoint::ParseKeyManagementMethods(
211 make_key_management_args(make_string_vector1("something-eap")),
212 &parsed_methods);
213 EXPECT_TRUE(
214 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagement802_1x));
215 EXPECT_FALSE(
216 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagementPSK));
217}
218
219TEST_F(WiFiEndpointTest, ParseKeyManagementMethodsPSK) {
220 set<WiFiEndpoint::KeyManagement> parsed_methods;
221 WiFiEndpoint::ParseKeyManagementMethods(
222 make_key_management_args(make_string_vector1("something-psk")),
223 &parsed_methods);
224 EXPECT_TRUE(
225 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagementPSK));
226 EXPECT_FALSE(
227 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagement802_1x));
228}
229
230TEST_F(WiFiEndpointTest, ParseKeyManagementMethodsEAPAndPSK) {
231 set<WiFiEndpoint::KeyManagement> parsed_methods;
232 WiFiEndpoint::ParseKeyManagementMethods(
233 make_key_management_args(
234 make_string_vector2("something-eap", "something-psk")),
235 &parsed_methods);
236 EXPECT_TRUE(
237 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagement802_1x));
238 EXPECT_TRUE(
239 ContainsKey(parsed_methods, WiFiEndpoint::kKeyManagementPSK));
240}
241
242TEST_F(WiFiEndpointTest, ParseSecurityRSN802_1x) {
243 EXPECT_STREQ(flimflam::kSecurity8021x,
244 ParseSecurity(make_security_args("RSN", "something-eap")));
245}
246
247TEST_F(WiFiEndpointTest, ParseSecurityWPA802_1x) {
248 EXPECT_STREQ(flimflam::kSecurity8021x,
249 ParseSecurity(make_security_args("WPA", "something-eap")));
250}
251
252TEST_F(WiFiEndpointTest, ParseSecurityRSNPSK) {
253 EXPECT_STREQ(flimflam::kSecurityRsn,
254 ParseSecurity(make_security_args("RSN", "something-psk")));
255}
256
257TEST_F(WiFiEndpointTest, ParseSecurityWPAPSK) {
258 EXPECT_STREQ(flimflam::kSecurityWpa,
259 ParseSecurity(make_security_args("WPA", "something-psk")));
260}
261
262TEST_F(WiFiEndpointTest, ParseSecurityWEP) {
Paul Stewartaffc0552013-03-25 07:50:15 -0700263 EXPECT_STREQ(flimflam::kSecurityWep, ParseSecurity(make_privacy_args(true)));
mukesh agrawal6e277772011-09-29 15:04:23 -0700264}
265
266TEST_F(WiFiEndpointTest, ParseSecurityNone) {
267 map<string, ::DBus::Variant> top_params;
268 EXPECT_STREQ(flimflam::kSecurityNone, ParseSecurity(top_params));
269}
270
mukesh agrawal16bc1b82012-02-09 18:38:26 -0800271TEST_F(WiFiEndpointTest, SSIDWithNull) {
272 WiFiEndpointRefPtr endpoint =
mukesh agrawalb20776f2012-02-10 16:00:36 -0800273 MakeOpenEndpoint(NULL, NULL, string(1, 0), "00:00:00:00:00:01");
mukesh agrawal16bc1b82012-02-09 18:38:26 -0800274 EXPECT_EQ("?", endpoint->ssid_string());
275}
276
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700277TEST_F(WiFiEndpointTest, DeterminePhyModeFromFrequency) {
Thieu Le1df7f4e2012-02-10 15:21:45 -0800278 {
279 map<string, ::DBus::Variant> properties;
280 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11a,
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700281 WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 3200));
Thieu Le1df7f4e2012-02-10 15:21:45 -0800282 }
283 {
284 map<string, ::DBus::Variant> properties;
285 vector<uint32_t> rates(1, 22000000);
286 ::DBus::MessageIter writer =
Paul Stewart0654ece2013-03-26 15:21:26 -0700287 properties[WPASupplicant::kBSSPropertyRates].writer();
Thieu Le1df7f4e2012-02-10 15:21:45 -0800288 writer << rates;
289 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11b,
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700290 WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 2400));
Thieu Le1df7f4e2012-02-10 15:21:45 -0800291 }
292 {
293 map<string, ::DBus::Variant> properties;
294 vector<uint32_t> rates(1, 54000000);
295 ::DBus::MessageIter writer =
Paul Stewart0654ece2013-03-26 15:21:26 -0700296 properties[WPASupplicant::kBSSPropertyRates].writer();
Thieu Le1df7f4e2012-02-10 15:21:45 -0800297 writer << rates;
298 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11g,
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700299 WiFiEndpoint::DeterminePhyModeFromFrequency(properties, 2400));
300 }
301}
302
303TEST_F(WiFiEndpointTest, ParseIEs) {
304 {
305 vector<uint8_t> ies;
306 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
307 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700308 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
309 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700310 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, phy_mode);
311 }
312 {
313 vector<uint8_t> ies;
314 AddIE(IEEE_80211::kElemIdErp, &ies);
315 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
316 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700317 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
318 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700319 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11g, phy_mode);
320 }
321 {
322 vector<uint8_t> ies;
323 AddIE(IEEE_80211::kElemIdHTCap, &ies);
324 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
325 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700326 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
327 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700328 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, phy_mode);
329 }
330 {
331 vector<uint8_t> ies;
332 AddIE(IEEE_80211::kElemIdHTInfo, &ies);
333 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
334 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700335 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
336 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700337 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, phy_mode);
338 }
339 {
340 vector<uint8_t> ies;
341 AddIE(IEEE_80211::kElemIdErp, &ies);
342 AddIE(IEEE_80211::kElemIdHTCap, &ies);
343 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
344 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700345 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
346 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700347 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, phy_mode);
348 }
349}
350
351TEST_F(WiFiEndpointTest, ParseVendorIEs) {
352 {
353 ScopedMockLog log;
354 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
355 HasSubstr("no room in IE for OUI and type field.")))
356 .Times(1);
357 vector<uint8_t> ies;
358 AddIE(IEEE_80211::kElemIdVendor, &ies);
359 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
360 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700361 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
362 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700363 }
364 {
365 vector<uint8_t> ies;
366 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
367 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700368 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
369 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700370 EXPECT_EQ("", vendor_information.wps_manufacturer);
371 EXPECT_EQ("", vendor_information.wps_model_name);
372 EXPECT_EQ("", vendor_information.wps_model_number);
373 EXPECT_EQ("", vendor_information.wps_device_name);
374 EXPECT_EQ(0, vendor_information.oui_list.size());
375 }
376 {
377 ScopedMockLog log;
378 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
379 HasSubstr("IE extends past containing PDU"))).Times(1);
380 vector<uint8_t> ies;
381 AddVendorIE(0, 0, vector<uint8_t>(), &ies);
382 ies.resize(ies.size() - 1); // Cause an underrun in the data.
383 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
384 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700385 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
386 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700387 }
388 {
389 vector<uint8_t> ies;
390 const uint32_t kVendorOUI = 0xaabbcc;
391 AddVendorIE(kVendorOUI, 0, vector<uint8_t>(), &ies);
392 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, 0, vector<uint8_t>(), &ies);
393 AddVendorIE(IEEE_80211::kOUIVendorEpigram, 0, vector<uint8_t>(), &ies);
394 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
395 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700396 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
397 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700398 EXPECT_EQ("", vendor_information.wps_manufacturer);
399 EXPECT_EQ("", vendor_information.wps_model_name);
400 EXPECT_EQ("", vendor_information.wps_model_number);
401 EXPECT_EQ("", vendor_information.wps_device_name);
402 EXPECT_EQ(1, vendor_information.oui_list.size());
403 EXPECT_FALSE(vendor_information.oui_list.find(kVendorOUI) ==
404 vendor_information.oui_list.end());
405
406 WiFiEndpointRefPtr endpoint =
407 MakeOpenEndpoint(NULL, NULL, string(1, 0), "00:00:00:00:00:01");
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700408 SetVendorInformation(endpoint, vendor_information);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700409 map<string, string> vendor_stringmap(endpoint->GetVendorInformation());
410 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSManufacturerProperty));
411 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSModelNameProperty));
412 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSModelNumberProperty));
413 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorWPSDeviceNameProperty));
414 EXPECT_EQ("aa-bb-cc", vendor_stringmap[kVendorOUIListProperty]);
415 }
416 {
417 ScopedMockLog log;
418 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
419 HasSubstr("WPS element extends past containing PDU")))
420 .Times(1);
421 vector<uint8_t> ies;
422 vector<uint8_t> wps;
423 AddWPSElement(IEEE_80211::kWPSElementManufacturer, "foo", &wps);
424 wps.resize(wps.size() - 1); // Cause an underrun in the data.
425 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft,
426 IEEE_80211::kOUIMicrosoftWPS, wps, &ies);
427 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
428 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700429 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
430 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700431 EXPECT_EQ("", vendor_information.wps_manufacturer);
432 }
433 {
434 vector<uint8_t> ies;
435 vector<uint8_t> wps;
436 const string kManufacturer("manufacturer");
437 const string kModelName("modelname");
438 const string kModelNumber("modelnumber");
439 const string kDeviceName("devicename");
440 AddWPSElement(IEEE_80211::kWPSElementManufacturer, kManufacturer, &wps);
441 AddWPSElement(IEEE_80211::kWPSElementModelName, kModelName, &wps);
442 AddWPSElement(IEEE_80211::kWPSElementModelNumber, kModelNumber, &wps);
443 AddWPSElement(IEEE_80211::kWPSElementDeviceName, kDeviceName, &wps);
444 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft,
445 IEEE_80211::kOUIMicrosoftWPS, wps, &ies);
446 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
447 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700448 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
449 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700450 EXPECT_EQ(kManufacturer, vendor_information.wps_manufacturer);
451 EXPECT_EQ(kModelName, vendor_information.wps_model_name);
452 EXPECT_EQ(kModelNumber, vendor_information.wps_model_number);
453 EXPECT_EQ(kDeviceName, vendor_information.wps_device_name);
454
455 WiFiEndpointRefPtr endpoint =
456 MakeOpenEndpoint(NULL, NULL, string(1, 0), "00:00:00:00:00:01");
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700457 SetVendorInformation(endpoint, vendor_information);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700458 map<string, string> vendor_stringmap(endpoint->GetVendorInformation());
459 EXPECT_EQ(kManufacturer, vendor_stringmap[kVendorWPSManufacturerProperty]);
460 EXPECT_EQ(kModelName, vendor_stringmap[kVendorWPSModelNameProperty]);
461 EXPECT_EQ(kModelNumber, vendor_stringmap[kVendorWPSModelNumberProperty]);
462 EXPECT_EQ(kDeviceName, vendor_stringmap[kVendorWPSDeviceNameProperty]);
463 EXPECT_FALSE(ContainsKey(vendor_stringmap, kVendorOUIListProperty));
464 }
465 {
466 vector<uint8_t> ies;
467 vector<uint8_t> wps;
468 const string kManufacturer("manufacturer");
469 const string kModelName("modelname");
470 AddWPSElement(IEEE_80211::kWPSElementManufacturer, kManufacturer, &wps);
471 wps.resize(wps.size() - 1); // Insert a non-ASCII character in the WPS.
472 wps.push_back(0x80);
473 AddWPSElement(IEEE_80211::kWPSElementModelName, kModelName, &wps);
474 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft,
475 IEEE_80211::kOUIMicrosoftWPS, wps, &ies);
476 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
477 WiFiEndpoint::VendorInformation vendor_information;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700478 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
479 NULL, NULL);
Paul Stewart72b2fdc2012-06-02 08:58:51 -0700480 EXPECT_EQ("", vendor_information.wps_manufacturer);
481 EXPECT_EQ(kModelName, vendor_information.wps_model_name);
Thieu Le1df7f4e2012-02-10 15:21:45 -0800482 }
483}
484
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800485TEST_F(WiFiEndpointTest, ParseWPACapabilities) {
486 {
487 vector<uint8_t> ies;
488 vector<uint8_t> rsn;
489 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, IEEE_80211::kOUIMicrosoftWPA,
490 rsn, &ies);
491 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
492 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
493 WiFiEndpoint::VendorInformation vendor_information;
494 bool ieee80211w_required = false;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700495 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
496 &ieee80211w_required, NULL);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800497 EXPECT_FALSE(ieee80211w_required);
498 }
499 {
500 vector<uint8_t> ies;
501 vector<uint8_t> rsn = MakeRSNProperties(
502 2, 3, ~IEEE_80211::kRSNCapabilityFrameProtectionRequired);
503 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, IEEE_80211::kOUIMicrosoftWPA,
504 rsn, &ies);
505 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
506 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
507 WiFiEndpoint::VendorInformation vendor_information;
508 bool ieee80211w_required = false;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700509 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
510 &ieee80211w_required, NULL);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800511 EXPECT_FALSE(ieee80211w_required);
512 }
513 {
514 vector<uint8_t> ies;
515 vector<uint8_t> rsn = MakeRSNProperties(
516 2, 3, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
517 AddVendorIE(IEEE_80211::kOUIVendorMicrosoft, IEEE_80211::kOUIMicrosoftWPA,
518 rsn, &ies);
519 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
520 WiFiEndpoint::VendorInformation vendor_information;
521 bool ieee80211w_required = false;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700522 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
523 &ieee80211w_required, NULL);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800524 EXPECT_TRUE(ieee80211w_required);
525 }
526 {
527 vector<uint8_t> ies;
528 vector<uint8_t> rsn = MakeRSNProperties(
529 8, 2, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
530 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
531 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
532 WiFiEndpoint::VendorInformation vendor_information;
533 bool ieee80211w_required = false;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700534 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
535 &ieee80211w_required, NULL);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800536 EXPECT_TRUE(ieee80211w_required);
537 }
538 {
539 vector<uint8_t> ies;
540 vector<uint8_t> rsn = MakeRSNProperties(
541 8, 2, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
542 rsn.resize(rsn.size() + 1);
543 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
544 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
545 WiFiEndpoint::VendorInformation vendor_information;
546 bool ieee80211w_required = false;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700547 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
548 &ieee80211w_required, NULL);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800549 EXPECT_TRUE(ieee80211w_required);
550 }
551 {
552 vector<uint8_t> ies;
553 vector<uint8_t> rsn = MakeRSNProperties(
554 8, 2, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
555 rsn.resize(rsn.size() - 1);
556 AddIEWithData(IEEE_80211::kElemIdRSN, rsn, &ies);
557 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
558 WiFiEndpoint::VendorInformation vendor_information;
559 bool ieee80211w_required = false;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700560 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
561 &ieee80211w_required, NULL);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800562 EXPECT_FALSE(ieee80211w_required);
563 }
564 {
565 vector<uint8_t> ies;
566 vector<uint8_t> rsn0 = MakeRSNProperties(
567 1, 1, IEEE_80211::kRSNCapabilityFrameProtectionRequired);
568 AddIEWithData(IEEE_80211::kElemIdRSN, rsn0, &ies);
569 vector<uint8_t> rsn1 = MakeRSNProperties(1, 1, 0);
570 AddIEWithData(IEEE_80211::kElemIdRSN, rsn1, &ies);
571 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
572 WiFiEndpoint::VendorInformation vendor_information;
573 bool ieee80211w_required = false;
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700574 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
575 &ieee80211w_required, NULL);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800576 EXPECT_TRUE(ieee80211w_required);
577 }
578}
579
Paul Stewartbdbd3c32013-04-17 09:47:21 -0700580TEST_F(WiFiEndpointTest, ParseCountryCode) {
581 {
582 vector<uint8_t> ies;
583 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
584 WiFiEndpoint::VendorInformation vendor_information;
585 string country_code;
586 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
587 NULL, &country_code);
588 EXPECT_TRUE(country_code.empty());
589 }
590 {
591 const string kCountryCode("G");
592 const vector<uint8_t> kCountryCodeAsVector(
593 kCountryCode.begin(), kCountryCode.end());
594 vector<uint8_t> ies;
595 AddIEWithData(IEEE_80211::kElemIdCountry, kCountryCodeAsVector, &ies);
596 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
597 WiFiEndpoint::VendorInformation vendor_information;
598 string country_code;
599 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
600 NULL, &country_code);
601 EXPECT_TRUE(country_code.empty());
602 }
603 {
604 const string kCountryCode("GO");
605 const vector<uint8_t> kCountryCodeAsVector(
606 kCountryCode.begin(), kCountryCode.end());
607 vector<uint8_t> ies;
608 AddIEWithData(IEEE_80211::kElemIdCountry, kCountryCodeAsVector, &ies);
609 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
610 WiFiEndpoint::VendorInformation vendor_information;
611 string country_code;
612 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
613 NULL, &country_code);
614 EXPECT_EQ(kCountryCode, country_code);
615 }
616 {
617 const string kCountryCode("GOO");
618 const vector<uint8_t> kCountryCodeAsVector(
619 kCountryCode.begin(), kCountryCode.end());
620 vector<uint8_t> ies;
621 AddIEWithData(IEEE_80211::kElemIdCountry, kCountryCodeAsVector, &ies);
622 Metrics::WiFiNetworkPhyMode phy_mode = Metrics::kWiFiNetworkPhyModeUndef;
623 WiFiEndpoint::VendorInformation vendor_information;
624 string country_code;
625 ParseIEs(MakeBSSPropertiesWithIEs(ies), &phy_mode, &vendor_information,
626 NULL, &country_code);
627 EXPECT_EQ(string(kCountryCode, 0, 2), country_code);
628 }
629}
630
Paul Stewartaffc0552013-03-25 07:50:15 -0700631TEST_F(WiFiEndpointTest, PropertiesChangedNone) {
632 WiFiEndpointRefPtr endpoint =
633 MakeOpenEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01");
634 EXPECT_EQ(flimflam::kModeManaged, endpoint->network_mode());
635 EXPECT_EQ(flimflam::kSecurityNone, endpoint->security_mode());
636 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0);
637 map<string, ::DBus::Variant> no_changed_properties;
638 endpoint->PropertiesChanged(no_changed_properties);
639 EXPECT_EQ(flimflam::kModeManaged, endpoint->network_mode());
640 EXPECT_EQ(flimflam::kSecurityNone, endpoint->security_mode());
641}
642
643TEST_F(WiFiEndpointTest, PropertiesChangedStrength) {
mukesh agrawalb20776f2012-02-10 16:00:36 -0800644 WiFiEndpointRefPtr endpoint =
645 MakeOpenEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01");
646 map<string, ::DBus::Variant> changed_properties;
mukesh agrawalb20776f2012-02-10 16:00:36 -0800647 int16_t signal_strength = 10;
648
649 EXPECT_NE(signal_strength, endpoint->signal_strength());
Paul Stewartaffc0552013-03-25 07:50:15 -0700650 ::DBus::MessageIter writer =
Paul Stewart0654ece2013-03-26 15:21:26 -0700651 changed_properties[WPASupplicant::kBSSPropertySignal].writer();
mukesh agrawalb20776f2012-02-10 16:00:36 -0800652 writer << signal_strength;
653
654 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_));
655 endpoint->PropertiesChanged(changed_properties);
656 EXPECT_EQ(signal_strength, endpoint->signal_strength());
657}
658
Paul Stewartaffc0552013-03-25 07:50:15 -0700659TEST_F(WiFiEndpointTest, PropertiesChangedNetworkMode) {
660 WiFiEndpointRefPtr endpoint =
661 MakeOpenEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01");
662 EXPECT_EQ(flimflam::kModeManaged, endpoint->network_mode());
663 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
664 map<string, ::DBus::Variant> changed_properties;
665 ::DBus::MessageIter writer =
666 changed_properties[WPASupplicant::kBSSPropertyMode].writer();
667 writer << string(WPASupplicant::kNetworkModeAdHoc);
668 endpoint->PropertiesChanged(changed_properties);
669 EXPECT_EQ(flimflam::kModeAdhoc, endpoint->network_mode());
670}
671
672TEST_F(WiFiEndpointTest, PropertiesChangedSecurityMode) {
673 WiFiEndpointRefPtr endpoint =
674 MakeOpenEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01");
675 EXPECT_EQ(flimflam::kSecurityNone, endpoint->security_mode());
676
677 // Upgrade to WEP if privacy flag is added.
678 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
679 endpoint->PropertiesChanged(make_privacy_args(true));
680 Mock::VerifyAndClearExpectations(wifi());
681 EXPECT_EQ(flimflam::kSecurityWep, endpoint->security_mode());
682
683 // Make sure we don't downgrade if no interesting arguments arrive.
684 map<string, ::DBus::Variant> no_changed_properties;
685 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0);
686 endpoint->PropertiesChanged(no_changed_properties);
687 Mock::VerifyAndClearExpectations(wifi());
688 EXPECT_EQ(flimflam::kSecurityWep, endpoint->security_mode());
689
690 // Another upgrade to 802.1x.
691 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
692 endpoint->PropertiesChanged(make_security_args("RSN", "something-eap"));
693 Mock::VerifyAndClearExpectations(wifi());
694 EXPECT_EQ(flimflam::kSecurity8021x, endpoint->security_mode());
695
696 // Add WPA-PSK, however this is trumped by RSN 802.1x above, so we don't
697 // change our security nor do we notify anyone.
698 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0);
699 endpoint->PropertiesChanged(make_security_args("WPA", "something-psk"));
700 Mock::VerifyAndClearExpectations(wifi());
701 EXPECT_EQ(flimflam::kSecurity8021x, endpoint->security_mode());
702
703 // If nothing changes, we should stay the same.
704 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(0);
705 endpoint->PropertiesChanged(no_changed_properties);
706 Mock::VerifyAndClearExpectations(wifi());
707 EXPECT_EQ(flimflam::kSecurity8021x, endpoint->security_mode());
708
709 // However, if the BSS updates to no longer support 802.1x, we degrade
710 // to WPA.
711 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
712 endpoint->PropertiesChanged(make_security_args("RSN", ""));
713 Mock::VerifyAndClearExpectations(wifi());
714 EXPECT_EQ(flimflam::kSecurityWpa, endpoint->security_mode());
715
716 // Losing WPA brings us back to WEP (since the privacy flag hasn't changed).
717 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
718 endpoint->PropertiesChanged(make_security_args("WPA", ""));
719 Mock::VerifyAndClearExpectations(wifi());
720 EXPECT_EQ(flimflam::kSecurityWep, endpoint->security_mode());
721
722 // From WEP to open security.
723 EXPECT_CALL(*wifi(), NotifyEndpointChanged(_)).Times(1);
724 endpoint->PropertiesChanged(make_privacy_args(false));
725 Mock::VerifyAndClearExpectations(wifi());
726 EXPECT_EQ(flimflam::kSecurityNone, endpoint->security_mode());
727}
728
mukesh agrawal43970a22013-02-15 16:00:07 -0800729TEST_F(WiFiEndpointTest, HasRsnWpaProperties) {
730 {
731 WiFiEndpointRefPtr endpoint =
732 MakeEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01", false, false);
733 EXPECT_FALSE(endpoint->has_wpa_property());
734 EXPECT_FALSE(endpoint->has_rsn_property());
735 }
736 {
737 WiFiEndpointRefPtr endpoint =
738 MakeEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01", true, false);
739 EXPECT_TRUE(endpoint->has_wpa_property());
740 EXPECT_FALSE(endpoint->has_rsn_property());
741 }
742 {
743 WiFiEndpointRefPtr endpoint =
744 MakeEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01", false, true);
745 EXPECT_FALSE(endpoint->has_wpa_property());
746 EXPECT_TRUE(endpoint->has_rsn_property());
747 }
748 {
749 // Both can be true.
750 WiFiEndpointRefPtr endpoint =
751 MakeEndpoint(NULL, wifi(), "ssid", "00:00:00:00:00:01", true, true);
752 EXPECT_TRUE(endpoint->has_wpa_property());
753 EXPECT_TRUE(endpoint->has_rsn_property());
754 }
755}
756
mukesh agrawal6e277772011-09-29 15:04:23 -0700757} // namespace shill