blob: d581cb689e79fea4988a982f20fbc15a0f6213cc [file] [log] [blame]
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone34af2182011-08-22 11:59:36 -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_service.h"
6
mukesh agrawald835b202011-10-07 15:26:47 -07007#include <map>
Paul Stewart85aea152013-01-22 09:31:56 -08008#include <set>
Chris Masone34af2182011-08-22 11:59:36 -07009#include <string>
10#include <vector>
11
Paul Stewart85aea152013-01-22 09:31:56 -080012#include <base/stringprintf.h>
Paul Stewart71a4d3b2013-01-18 18:12:56 -080013#include <base/string_number_conversions.h>
Chris Masone34af2182011-08-22 11:59:36 -070014#include <base/string_util.h>
15#include <chromeos/dbus/service_constants.h>
16#include <gmock/gmock.h>
17#include <gtest/gtest.h>
18
Paul Stewart26b327e2011-10-19 11:38:09 -070019#include "shill/event_dispatcher.h"
Chris Masone34af2182011-08-22 11:59:36 -070020#include "shill/manager.h"
21#include "shill/mock_adaptors.h"
22#include "shill/mock_control.h"
Paul Stewart71a4d3b2013-01-18 18:12:56 -080023#include "shill/mock_log.h"
Paul Stewartecf4cd12012-04-17 11:08:39 -070024#include "shill/mock_nss.h"
Christopher Wiley1ce658d2012-10-10 10:02:03 -070025#include "shill/mock_profile.h"
Chris Masone34af2182011-08-22 11:59:36 -070026#include "shill/mock_service.h"
27#include "shill/mock_store.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070028#include "shill/mock_wifi.h"
Chris Masone34af2182011-08-22 11:59:36 -070029#include "shill/property_store_unittest.h"
mukesh agrawal8a3188d2011-12-01 20:56:44 +000030#include "shill/refptr_types.h"
31#include "shill/wifi_endpoint.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070032#include "shill/wpa_supplicant.h"
Chris Masone34af2182011-08-22 11:59:36 -070033
mukesh agrawald835b202011-10-07 15:26:47 -070034using std::map;
Paul Stewart85aea152013-01-22 09:31:56 -080035using std::set;
Chris Masone34af2182011-08-22 11:59:36 -070036using std::string;
37using std::vector;
Paul Stewartd08f4432011-11-04 07:48:20 -070038using ::testing::_;
mukesh agrawale1d90e92012-02-15 17:36:08 -080039using ::testing::AnyNumber;
Paul Stewartd08f4432011-11-04 07:48:20 -070040using ::testing::DoAll;
Paul Stewart71a4d3b2013-01-18 18:12:56 -080041using ::testing::EndsWith;
mukesh agrawale1d90e92012-02-15 17:36:08 -080042using ::testing::Mock;
mukesh agrawal6e277772011-09-29 15:04:23 -070043using ::testing::NiceMock;
Paul Stewartd08f4432011-11-04 07:48:20 -070044using ::testing::Return;
45using ::testing::SetArgumentPointee;
46using ::testing::StrEq;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080047using ::testing::StrNe;
Paul Stewart85aea152013-01-22 09:31:56 -080048using ::testing::StrictMock;
Chris Masone34af2182011-08-22 11:59:36 -070049
mukesh agrawalb20776f2012-02-10 16:00:36 -080050namespace shill {
51
Chris Masone34af2182011-08-22 11:59:36 -070052class WiFiServiceTest : public PropertyStoreTest {
53 public:
mukesh agrawal6e277772011-09-29 15:04:23 -070054 WiFiServiceTest() : wifi_(
55 new NiceMock<MockWiFi>(
56 control_interface(),
57 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080058 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -070059 manager(),
60 "wifi",
61 fake_mac,
62 0)) {}
Chris Masone34af2182011-08-22 11:59:36 -070063 virtual ~WiFiServiceTest() {}
mukesh agrawal6e277772011-09-29 15:04:23 -070064
65 protected:
66 static const char fake_mac[];
mukesh agrawale1d90e92012-02-15 17:36:08 -080067
Gaurav Shah10109f22011-11-11 20:16:22 -080068 bool CheckConnectable(const std::string &security, const char *passphrase,
69 Service::EapCredentials *eap) {
mukesh agrawal29c13a12011-11-24 00:09:19 +000070 Error error;
71 vector<uint8_t> ssid(1, 'a');
72 WiFiServiceRefPtr service = new WiFiService(control_interface(),
73 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080074 metrics(),
mukesh agrawal29c13a12011-11-24 00:09:19 +000075 manager(),
76 wifi(),
77 ssid,
78 flimflam::kModeManaged,
79 security,
80 false);
81 if (passphrase)
82 service->SetPassphrase(passphrase, &error);
Gaurav Shah10109f22011-11-11 20:16:22 -080083 if (eap) {
84 service->set_eap(*eap);
85 }
mukesh agrawal29c13a12011-11-24 00:09:19 +000086 return service->connectable();
87 }
mukesh agrawale1d90e92012-02-15 17:36:08 -080088 WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid,
89 uint16 frequency, int16 signal_dbm) {
90 return WiFiEndpoint::MakeOpenEndpoint(
91 NULL, NULL, ssid, bssid, frequency, signal_dbm);
92 }
93 WiFiService *MakeGenericService() {
94 return new WiFiService(control_interface(),
95 dispatcher(),
96 metrics(),
97 manager(),
98 wifi(),
99 vector<uint8_t>(),
100 flimflam::kModeManaged,
101 flimflam::kSecurityWep,
102 false);
103 }
104 ServiceMockAdaptor *GetAdaptor(WiFiService *service) {
105 return dynamic_cast<ServiceMockAdaptor *>(service->adaptor());
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000106 }
mukesh agrawal6e277772011-09-29 15:04:23 -0700107 scoped_refptr<MockWiFi> wifi() { return wifi_; }
108
109 private:
110 scoped_refptr<MockWiFi> wifi_;
Chris Masone34af2182011-08-22 11:59:36 -0700111};
112
mukesh agrawal6e277772011-09-29 15:04:23 -0700113// static
114const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
115
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800116MATCHER_P3(ContainsWiFiProperties, ssid, mode, security, "") {
117 string hex_ssid = base::HexEncode(ssid.data(), ssid.size());
118 return
119 arg.ContainsString(WiFiService::kStorageType) &&
120 arg.GetString(WiFiService::kStorageType) == flimflam::kTypeWifi &&
121 arg.ContainsString(WiFiService::kStorageSSID) &&
122 arg.GetString(WiFiService::kStorageSSID) == hex_ssid &&
123 arg.ContainsString(WiFiService::kStorageMode) &&
124 arg.GetString(WiFiService::kStorageMode) == mode &&
125 arg.ContainsString(WiFiService::kStorageSecurityClass) &&
126 arg.GetString(WiFiService::kStorageSecurityClass) == security;
127}
128
Paul Stewartd08f4432011-11-04 07:48:20 -0700129class WiFiServiceSecurityTest : public WiFiServiceTest {
130 public:
131 WiFiServiceRefPtr CreateServiceWithSecurity(const string &security) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800132 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700133 ssid.push_back(0xff);
134
135 return new WiFiService(control_interface(),
136 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800137 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700138 manager(),
139 wifi(),
140 ssid,
141 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800142 security,
143 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700144 }
145
146 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
147 const string &security) {
148 string id = wifi_service->GetStorageIdentifier();
149 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
150 EXPECT_NE(mac_pos, string::npos);
151 size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
152 EXPECT_NE(mode_pos, string::npos);
153 return id.find(string(security), mode_pos) != string::npos;
154 }
155
156 // Test that a service that is created with security |from_security|
157 // gets by default a storage identifier with |to_security| as its
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800158 // security component, and that when saved, it sets the Security
159 // property in to |to_security| as well.
Paul Stewartd08f4432011-11-04 07:48:20 -0700160 bool TestStorageMapping(const string &from_security,
161 const string &to_security) {
162 WiFiServiceRefPtr wifi_service = CreateServiceWithSecurity(from_security);
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800163 NiceMock<MockStore> mock_store;
164 EXPECT_CALL(mock_store, SetString(_, _, _)).WillRepeatedly(Return(true));
165 EXPECT_CALL(mock_store,
166 SetString(_, WiFiService::kStorageSecurity, from_security))
167 .Times(1);
168 EXPECT_CALL(mock_store,
169 SetString(_, WiFiService::kStorageSecurityClass, to_security))
170 .Times(1);
171 wifi_service->Save(&mock_store);
Paul Stewartd08f4432011-11-04 07:48:20 -0700172 return TestStorageSecurityIs(wifi_service, to_security);
173 }
174
175 // Test whether a service of type |service_security| can load from a
176 // storage interface containing an entry for |storage_security|.
177 // Make sure the result meets |expectation|. If |expectation| is
178 // true, also make sure the service storage identifier changes to
179 // match |storage_security|.
180 bool TestLoadMapping(const string &service_security,
181 const string &storage_security,
182 bool expectation) {
183 WiFiServiceRefPtr wifi_service =
184 CreateServiceWithSecurity(service_security);
185 NiceMock<MockStore> mock_store;
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800186 EXPECT_CALL(mock_store, GetGroupsWithProperties(_))
187 .WillRepeatedly(Return(set<string>()));
188 const string kStorageId = "storage_id";
189 EXPECT_CALL(mock_store, ContainsGroup(kStorageId))
Paul Stewartd08f4432011-11-04 07:48:20 -0700190 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800191 set<string> groups;
192 groups.insert(kStorageId);
193 EXPECT_CALL(mock_store, GetGroupsWithProperties(
194 ContainsWiFiProperties(wifi_service->ssid(),
195 flimflam::kModeManaged,
196 storage_security)))
197 .WillRepeatedly(Return(groups));
Paul Stewartd08f4432011-11-04 07:48:20 -0700198 bool is_loadable = wifi_service->IsLoadableFrom(&mock_store);
199 EXPECT_EQ(expectation, is_loadable);
200 bool is_loaded = wifi_service->Load(&mock_store);
201 EXPECT_EQ(expectation, is_loaded);
202
203 if (expectation != is_loadable || expectation != is_loaded) {
204 return false;
205 } else if (!expectation) {
206 return true;
207 } else {
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800208 return wifi_service->GetStorageIdentifier() == kStorageId;
Paul Stewartd08f4432011-11-04 07:48:20 -0700209 }
210 }
211};
212
mukesh agrawale1d90e92012-02-15 17:36:08 -0800213class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
214 public:
215 WiFiServiceUpdateFromEndpointsTest()
216 : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
217 kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
218 kGoodEndpointStrength(
219 WiFiService::SignalToStrength(kGoodEndpointSignal)),
220 service(MakeGenericService()),
221 adaptor(*GetAdaptor(service)) {
222 ok_endpoint = MakeEndpoint(
mukesh agrawal923f14f2012-06-04 16:46:08 -0700223 "", kOkEndpointBssId, kOkEndpointFrequency, kOkEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800224 good_endpoint = MakeEndpoint(
mukesh agrawal923f14f2012-06-04 16:46:08 -0700225 "", kGoodEndpointBssId, kGoodEndpointFrequency, kGoodEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800226 bad_endpoint = MakeEndpoint(
mukesh agrawal923f14f2012-06-04 16:46:08 -0700227 "", kBadEndpointBssId, kBadEndpointFrequency, kBadEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800228 }
229
230 protected:
231 static const uint16 kOkEndpointFrequency = 2422;
232 static const uint16 kBadEndpointFrequency = 2417;
233 static const uint16 kGoodEndpointFrequency = 2412;
234 static const int16 kOkEndpointSignal = -50;
235 static const int16 kBadEndpointSignal = -75;
236 static const int16 kGoodEndpointSignal = -25;
mukesh agrawal923f14f2012-06-04 16:46:08 -0700237 static const char *kOkEndpointBssId;
238 static const char *kGoodEndpointBssId;
239 static const char *kBadEndpointBssId;
mukesh agrawale1d90e92012-02-15 17:36:08 -0800240 // Can't be both static and const (because initialization requires a
241 // function call). So choose to be just const.
242 const uint8 kOkEndpointStrength;
243 const uint8 kBadEndpointStrength;
244 const uint8 kGoodEndpointStrength;
245 WiFiEndpointRefPtr ok_endpoint;
246 WiFiEndpointRefPtr bad_endpoint;
247 WiFiEndpointRefPtr good_endpoint;
248 WiFiServiceRefPtr service;
249 ServiceMockAdaptor &adaptor;
250};
251
mukesh agrawal923f14f2012-06-04 16:46:08 -0700252const char *WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId =
253 "00:00:00:00:00:01";
254const char *WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId =
255 "00:00:00:00:00:02";
256const char *WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId =
257 "00:00:00:00:00:03";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800258
Paul Stewart85aea152013-01-22 09:31:56 -0800259class WiFiServiceFixupStorageTest : public WiFiServiceTest {
260 protected:
261 void AddGroup(string group_name) {
262 groups_.insert(group_name);
263 }
264
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800265 void AddServiceEntry(bool has_type, bool has_mode, bool has_security,
266 bool has_security_class) {
Paul Stewart85aea152013-01-22 09:31:56 -0800267 int index = groups_.size();
268 string id = base::StringPrintf("%s_%d_%d_%s_%s", flimflam::kTypeWifi,
269 index, index, flimflam::kModeManaged,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800270 flimflam::kSecurityWpa);
Paul Stewart85aea152013-01-22 09:31:56 -0800271 AddGroup(id);
272 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageType, _))
273 .WillOnce(Return(has_type));
274 if (!has_type) {
275 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageType,
276 flimflam::kTypeWifi));
277 }
278 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageMode, _))
279 .WillOnce(Return(has_mode));
280 if (!has_mode) {
281 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageMode,
282 flimflam::kModeManaged));
283 }
284 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurity, _))
285 .WillOnce(Return(has_security));
286 if (!has_security) {
287 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurity,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800288 flimflam::kSecurityWpa));
289 }
290 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurityClass, _))
291 .WillOnce(Return(has_security_class));
292 if (!has_security_class) {
293 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurityClass,
294 flimflam::kSecurityPsk));
Paul Stewart85aea152013-01-22 09:31:56 -0800295 }
296 }
297
298 bool FixupServiceEntries() {
299 EXPECT_CALL(store_, GetGroups()).WillOnce(Return(groups_));
300 return WiFiService::FixupServiceEntries(&store_);
301 }
302
303 private:
304 StrictMock<MockStore> store_;
305 set<string> groups_;
306};
307
Chris Masone34af2182011-08-22 11:59:36 -0700308TEST_F(WiFiServiceTest, StorageId) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800309 vector<uint8_t> ssid(5);
Chris Masone34af2182011-08-22 11:59:36 -0700310 ssid.push_back(0xff);
Chris Masone9d779932011-08-25 16:33:41 -0700311
Chris Masone2176a882011-09-14 22:29:15 -0700312 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
313 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800314 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700315 manager(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700316 wifi(),
Chris Masone9d779932011-08-25 16:33:41 -0700317 ssid,
318 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800319 flimflam::kSecurityNone,
320 false);
Chris Masone9d779932011-08-25 16:33:41 -0700321 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700322 for (uint i = 0; i < id.length(); ++i) {
323 EXPECT_TRUE(id[i] == '_' ||
324 isxdigit(id[i]) ||
325 (isalpha(id[i]) && islower(id[i])));
326 }
Chris Masone34af2182011-08-22 11:59:36 -0700327 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
328 EXPECT_NE(mac_pos, string::npos);
329 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
330}
331
Gaurav Shahda6218a2011-11-11 12:09:33 -0800332// Make sure the passphrase is registered as a write only property
333// by reading and comparing all string properties returned on the store.
334TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
335 vector<uint8_t> ssid(5);
336 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
337 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800338 metrics(),
Gaurav Shahda6218a2011-11-11 12:09:33 -0800339 manager(),
340 wifi(),
341 ssid,
342 flimflam::kModeManaged,
343 flimflam::kSecurityWpa,
344 false);
345 ReadablePropertyConstIterator<string> it =
346 (wifi_service->store()).GetStringPropertiesIter();
347 for( ; !it.AtEnd(); it.Advance())
348 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
349}
350
Thieu Lef7709452011-11-15 01:13:19 +0000351// Make sure setting the passphrase via D-Bus Service.SetProperty validates
352// the passphrase.
353TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
354 // We only spot check two password cases here to make sure the
355 // SetProperty code path does validation. We're not going to exhaustively
356 // test for all types of passwords.
357 vector<uint8_t> ssid(5);
358 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
359 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800360 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000361 manager(),
362 wifi(),
363 ssid,
364 flimflam::kModeManaged,
365 flimflam::kSecurityWep,
366 false);
367 Error error;
368 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
369 flimflam::kPassphraseProperty, "0:abcde", &error));
370 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
371 flimflam::kPassphraseProperty, "invalid", &error));
372 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
373}
374
375TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
376 vector<uint8_t> ssid(5);
377 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
378 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800379 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000380 manager(),
381 wifi(),
382 ssid,
383 flimflam::kModeManaged,
384 flimflam::kSecurityNone,
385 false);
386 Error error;
387 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
388 flimflam::kPassphraseProperty, "invalid", &error));
389 EXPECT_EQ(Error::kNotSupported, error.type());
390}
391
mukesh agrawald835b202011-10-07 15:26:47 -0700392TEST_F(WiFiServiceTest, NonUTF8SSID) {
393 vector<uint8_t> ssid;
394
395 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
396 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
397 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800398 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700399 manager(),
400 wifi(),
401 ssid,
402 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800403 flimflam::kSecurityNone,
404 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700405 map<string, ::DBus::Variant> properties;
406 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
407 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
408}
409
Gaurav Shahda6218a2011-11-11 12:09:33 -0800410MATCHER(WPASecurityArgs, "") {
411 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
412 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
413}
414
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800415MATCHER(WPA80211wSecurityArgs, "") {
416 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
417 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey) &&
418 ContainsKey(arg, wpa_supplicant::kNetworkPropertyIeee80211w);
419}
420
Gaurav Shah10109f22011-11-11 20:16:22 -0800421MATCHER(EAPSecurityArgs, "") {
422 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
423 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath);
424}
425
Paul Stewarte2d7c502012-07-16 16:35:10 -0700426MATCHER_P(FrequencyArg, has_arg, "") {
427 return has_arg ==
428 ContainsKey(arg, wpa_supplicant::kNetworkPropertyFrequency);
429}
430
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700431TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800432 vector<uint8_t> ssid(5);
mukesh agrawal6e277772011-09-29 15:04:23 -0700433 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
434 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800435 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700436 manager(),
437 wifi(),
438 ssid,
439 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800440 flimflam::kSecurityWpa,
441 false);
mukesh agrawal6e277772011-09-29 15:04:23 -0700442 EXPECT_CALL(*wifi(),
443 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700444 Error error;
445 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500446 wifi_service->Connect(NULL);
mukesh agrawal6e277772011-09-29 15:04:23 -0700447}
448
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700449TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800450 vector<uint8_t> ssid(5);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700451 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
452 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800453 metrics(),
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700454 manager(),
455 wifi(),
456 ssid,
457 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800458 flimflam::kSecurityRsn,
459 false);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700460 EXPECT_CALL(*wifi(),
461 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700462 Error error;
463 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500464 wifi_service->Connect(NULL);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700465}
466
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700467TEST_F(WiFiServiceTest, ConnectConditions) {
468 Error error;
469 vector<uint8_t> ssid(5);
470 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
471 dispatcher(),
472 metrics(),
473 manager(),
474 wifi(),
475 ssid,
476 flimflam::kModeManaged,
477 flimflam::kSecurityNone,
478 false);
479 scoped_refptr<MockProfile> mock_profile(
480 new NiceMock<MockProfile>(control_interface(), manager()));
481 wifi_service->set_profile(mock_profile);
482 // With nothing else going on, the service should attempt to connect.
483 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), _));
484 wifi_service->Connect(&error);
485 Mock::VerifyAndClearExpectations(wifi());
486
487 // But if we're already "connecting" or "connected" then we shouldn't attempt
488 // again.
489 EXPECT_CALL(*wifi(),
490 ConnectTo(wifi_service.get(), _)).Times(0);
491 wifi_service->SetState(Service::kStateAssociating);
492 wifi_service->Connect(&error);
493 wifi_service->SetState(Service::kStateConfiguring);
494 wifi_service->Connect(&error);
495 wifi_service->SetState(Service::kStateConnected);
496 wifi_service->Connect(&error);
497 wifi_service->SetState(Service::kStatePortal);
498 wifi_service->Connect(&error);
499 wifi_service->SetState(Service::kStateOnline);
500 wifi_service->Connect(&error);
501 Mock::VerifyAndClearExpectations(wifi());
502}
503
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800504TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800505 vector<uint8_t> ssid(5);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800506 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
507 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800508 metrics(),
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800509 manager(),
510 wifi(),
511 ssid,
512 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800513 flimflam::kSecurityPsk,
514 false);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800515 EXPECT_CALL(*wifi(),
516 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700517 Error error;
518 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500519 wifi_service->Connect(NULL);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800520}
521
Gaurav Shah10109f22011-11-11 20:16:22 -0800522TEST_F(WiFiServiceTest, ConnectTask8021x) {
523 vector<uint8_t> ssid(5);
524 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
525 dispatcher(),
526 metrics(),
527 manager(),
528 wifi(),
529 ssid,
530 flimflam::kModeManaged,
531 flimflam::kSecurity8021x,
532 false);
533 Service::EapCredentials eap;
534 eap.identity = "identity";
Wade Guthrie005bd342012-05-02 09:37:07 -0700535 eap.password = "mumble";
Gaurav Shah10109f22011-11-11 20:16:22 -0800536 wifi_service->set_eap(eap);
537 EXPECT_CALL(*wifi(),
538 ConnectTo(wifi_service.get(), EAPSecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500539 wifi_service->Connect(NULL);
Gaurav Shah10109f22011-11-11 20:16:22 -0800540}
541
Paul Stewarte2d7c502012-07-16 16:35:10 -0700542TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) {
543 vector<uint8_t> ssid(1, 'a');
544 WiFiEndpointRefPtr endpoint_nofreq =
545 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
546 WiFiEndpointRefPtr endpoint_freq =
547 MakeEndpoint("a", "00:00:00:00:00:02", 2412, 0);
548
549 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
550 dispatcher(),
551 metrics(),
552 manager(),
553 wifi(),
554 ssid,
555 flimflam::kModeManaged,
556 flimflam::kSecurityNone,
557 false);
558 wifi_service->AddEndpoint(endpoint_freq);
559 EXPECT_CALL(*wifi(),
560 ConnectTo(wifi_service.get(), FrequencyArg(false)));
561 wifi_service->Connect(NULL);
562
563 wifi_service = new WiFiService(control_interface(),
564 dispatcher(),
565 metrics(),
566 manager(),
567 wifi(),
568 ssid,
569 flimflam::kModeAdhoc,
570 flimflam::kSecurityNone,
571 false);
572 EXPECT_CALL(*wifi(),
573 ConnectTo(wifi_service.get(), FrequencyArg(false)));
574 wifi_service->Connect(NULL);
575
576 wifi_service = new WiFiService(control_interface(),
577 dispatcher(),
578 metrics(),
579 manager(),
580 wifi(),
581 ssid,
582 flimflam::kModeAdhoc,
583 flimflam::kSecurityNone,
584 false);
585 wifi_service->AddEndpoint(endpoint_nofreq);
586 EXPECT_CALL(*wifi(),
587 ConnectTo(wifi_service.get(), FrequencyArg(false)));
588 wifi_service->Connect(NULL);
589
590 wifi_service = new WiFiService(control_interface(),
591 dispatcher(),
592 metrics(),
593 manager(),
594 wifi(),
595 ssid,
596 flimflam::kModeAdhoc,
597 flimflam::kSecurityNone,
598 false);
599 wifi_service->AddEndpoint(endpoint_freq);
600 EXPECT_CALL(*wifi(),
601 ConnectTo(wifi_service.get(), FrequencyArg(true)));
602 wifi_service->Connect(NULL);
603}
604
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800605TEST_F(WiFiServiceTest, ConnectTaskWPA80211w) {
606 vector<uint8_t> ssid(1, 'a');
607 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
608 dispatcher(),
609 metrics(),
610 manager(),
611 wifi(),
612 ssid,
613 flimflam::kModeManaged,
614 flimflam::kSecurityPsk,
615 false);
616 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
617 endpoint->ieee80211w_required_ = true;
618 wifi_service->AddEndpoint(endpoint);
619 Error error;
620 wifi_service->SetPassphrase("0:mumblemumblem", &error);
621 EXPECT_CALL(*wifi(),
622 ConnectTo(wifi_service.get(), WPA80211wSecurityArgs()));
623 wifi_service->Connect(NULL);
624}
625
Thieu Lef4cbda92011-11-10 23:41:24 +0000626MATCHER(WEPSecurityArgsKeyIndex0, "") {
627 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
628 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
629 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
630 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
631 reader().get_uint32() == 0);
632}
633
634MATCHER(WEPSecurityArgsKeyIndex1, "") {
635 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
636 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
637 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
638 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
639 reader().get_uint32() == 1);
640}
641
642MATCHER(WEPSecurityArgsKeyIndex2, "") {
643 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
644 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
645 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
646 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
647 reader().get_uint32() == 2);
648}
649
650MATCHER(WEPSecurityArgsKeyIndex3, "") {
651 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
652 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
653 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
654 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
655 reader().get_uint32() == 3);
656}
657
658TEST_F(WiFiServiceTest, ConnectTaskWEP) {
659 vector<uint8_t> ssid(5);
660 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
661 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800662 metrics(),
Thieu Lef4cbda92011-11-10 23:41:24 +0000663 manager(),
664 wifi(),
665 ssid,
666 flimflam::kModeManaged,
667 flimflam::kSecurityWep,
668 false);
669 Error error;
670 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
671 EXPECT_CALL(*wifi(),
672 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500673 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000674
675 wifi_service->SetPassphrase("abcdefghijklm", &error);
676 EXPECT_CALL(*wifi(),
677 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500678 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000679
680 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
681 EXPECT_CALL(*wifi(),
682 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500683 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000684
685 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
686 EXPECT_CALL(*wifi(),
687 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500688 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000689
690 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
691 EXPECT_CALL(*wifi(),
692 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500693 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000694}
695
Gaurav Shah29d68882012-01-30 19:06:42 -0800696
697MATCHER(DynamicWEPArgs, "") {
698 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
699 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
700 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
701}
702
703// Dynamic WEP + 802.1x.
704TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
705 vector<uint8_t> ssid(5);
706 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
707 dispatcher(),
708 metrics(),
709 manager(),
710 wifi(),
711 ssid,
712 flimflam::kModeManaged,
713 flimflam::kSecurityWep,
714 false);
715
716 Service::EapCredentials eap;
717 eap.key_management = "IEEE8021X";
718 eap.identity = "something";
Wade Guthrie005bd342012-05-02 09:37:07 -0700719 eap.password = "mumble";
Gaurav Shah29d68882012-01-30 19:06:42 -0800720 wifi_service->set_eap(eap);
721 EXPECT_CALL(*wifi(),
722 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500723 wifi_service->Connect(NULL);
Gaurav Shah29d68882012-01-30 19:06:42 -0800724}
725
Paul Stewart835934a2012-12-06 19:27:09 -0800726TEST_F(WiFiServiceTest, SetPassphraseRemovesCachedCredentials) {
727 vector<uint8_t> ssid(5);
728 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
729 dispatcher(),
730 metrics(),
731 manager(),
732 wifi(),
733 ssid,
734 flimflam::kModeManaged,
735 flimflam::kSecurityRsn,
736 false);
737
738 const string kPassphrase = "abcdefgh";
739
740 {
741 Error error;
742 // A changed passphrase should trigger cache removal.
743 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
744 wifi_service->SetPassphrase(kPassphrase, &error);
745 Mock::VerifyAndClearExpectations(wifi());
746 EXPECT_TRUE(error.IsSuccess());
747 }
748
749 {
750 Error error;
751 // An unchanged passphrase should not trigger cache removal.
752 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
753 wifi_service->SetPassphrase(kPassphrase, &error);
754 Mock::VerifyAndClearExpectations(wifi());
755 EXPECT_TRUE(error.IsSuccess());
756 }
757
758 {
759 Error error;
760 // A modified passphrase should trigger cache removal.
761 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
762 wifi_service->SetPassphrase(kPassphrase + "X", &error);
763 Mock::VerifyAndClearExpectations(wifi());
764 EXPECT_TRUE(error.IsSuccess());
765 }
766
767 {
768 Error error;
769 // A cleared passphrase should also trigger cache removal.
770 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
771 wifi_service->ClearPassphrase(&error);
772 Mock::VerifyAndClearExpectations(wifi());
773 EXPECT_TRUE(error.IsSuccess());
774 }
775
776 {
777 Error error;
778 // An invalid passphrase should not trigger cache removal.
779 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
780 wifi_service->SetPassphrase("", &error);
781 Mock::VerifyAndClearExpectations(wifi());
782 EXPECT_FALSE(error.IsSuccess());
783 }
784
785 {
786 // Any change to EAP parameters (including a null one) will trigger cache
787 // removal. This is a lot less granular than the passphrase checks above.
788 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
789 wifi_service->set_eap(Service::EapCredentials());
790 Mock::VerifyAndClearExpectations(wifi());
791 }
792}
793
Paul Stewartd08f4432011-11-04 07:48:20 -0700794TEST_F(WiFiServiceTest, LoadHidden) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800795 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700796 ssid.push_back(0xff);
797
798 WiFiServiceRefPtr service = new WiFiService(control_interface(),
799 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800800 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700801 manager(),
802 wifi(),
803 ssid,
804 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800805 flimflam::kSecurityNone,
806 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700807 ASSERT_FALSE(service->hidden_ssid_);
808 NiceMock<MockStore> mock_store;
809 const string storage_id = service->GetStorageIdentifier();
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800810 set<string> groups;
811 groups.insert(storage_id);
Paul Stewartd08f4432011-11-04 07:48:20 -0700812 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
813 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800814 EXPECT_CALL(mock_store, GetGroupsWithProperties(
815 ContainsWiFiProperties(
816 ssid, flimflam::kModeManaged, flimflam::kSecurityNone)))
817 .WillRepeatedly(Return(groups));
Paul Stewartd08f4432011-11-04 07:48:20 -0700818 EXPECT_CALL(mock_store, GetBool(_, _, _))
819 .WillRepeatedly(Return(false));
820 EXPECT_CALL(mock_store,
821 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
822 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
823 EXPECT_TRUE(service->Load(&mock_store));
824 EXPECT_TRUE(service->hidden_ssid_);
825}
826
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800827TEST_F(WiFiServiceTest, LoadMultipleMatchingGroups) {
828 vector<uint8_t> ssid(1, 'a');
829 WiFiServiceRefPtr service = new WiFiService(control_interface(),
830 dispatcher(),
831 metrics(),
832 manager(),
833 wifi(),
834 ssid,
835 flimflam::kModeManaged,
836 flimflam::kSecurityNone,
837 false);
838 set<string> groups;
839 groups.insert("id0");
840 groups.insert("id1");
841 // Make sure we retain the first matched group in the same way that
842 // WiFiService::Load() will.
843 string first_group = *groups.begin();
844
845 NiceMock<MockStore> mock_store;
846 EXPECT_CALL(mock_store, GetGroupsWithProperties(
847 ContainsWiFiProperties(
848 ssid, flimflam::kModeManaged, flimflam::kSecurityNone)))
849 .WillRepeatedly(Return(groups));
850 EXPECT_CALL(mock_store, ContainsGroup(first_group))
851 .WillRepeatedly(Return(true));
852 EXPECT_CALL(mock_store, ContainsGroup(StrNe(first_group))).Times(0);
853 EXPECT_CALL(mock_store, GetBool(first_group, _, _))
854 .WillRepeatedly(Return(false));
855 EXPECT_CALL(mock_store, GetBool(StrNe(first_group), _, _)).Times(0);
856 ScopedMockLog log;
857 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
858 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
859 EndsWith("choosing the first.")));
860 EXPECT_TRUE(service->Load(&mock_store));
861}
862
Paul Stewartd08f4432011-11-04 07:48:20 -0700863TEST_F(WiFiServiceSecurityTest, WPAMapping) {
864 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
865 flimflam::kSecurityPsk));
866 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
867 flimflam::kSecurityPsk));
868 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
869 flimflam::kSecurityPsk));
870 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
871 flimflam::kSecurityWep));
872 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
873 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800874 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
875 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700876}
877
878TEST_F(WiFiServiceSecurityTest, LoadMapping) {
879 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
880 flimflam::kSecurityPsk,
881 true));
882 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
883 flimflam::kSecurityRsn,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800884 false));
Paul Stewartd08f4432011-11-04 07:48:20 -0700885 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
886 flimflam::kSecurityWpa,
887 false));
888 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
889 flimflam::kSecurityPsk,
890 true));
891 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
892 flimflam::kSecurityWpa,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800893 false));
Paul Stewartd08f4432011-11-04 07:48:20 -0700894 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
895 flimflam::kSecurityRsn,
896 false));
897 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
898 flimflam::kSecurityWep,
899 true));
900 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
901 flimflam::kSecurityPsk,
902 false));
903}
904
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800905TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
906 vector<uint8_t> ssid(5);
907 ssid.push_back(0xff);
908
909 WiFiServiceRefPtr service = new WiFiService(control_interface(),
910 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800911 metrics(),
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800912 manager(),
913 wifi(),
914 ssid,
915 flimflam::kModeManaged,
916 flimflam::kSecurityPsk,
917 false);
918 NiceMock<MockStore> mock_store;
919 const string storage_id = service->GetStorageIdentifier();
920 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
921 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800922 set<string> groups;
923 groups.insert(storage_id);
924 EXPECT_CALL(mock_store, GetGroupsWithProperties(
925 ContainsWiFiProperties(
926 ssid, flimflam::kModeManaged, flimflam::kSecurityPsk)))
927 .WillRepeatedly(Return(groups));
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800928 EXPECT_CALL(mock_store, GetBool(_, _, _))
929 .WillRepeatedly(Return(false));
930 const string passphrase = "passphrase";
931 EXPECT_CALL(mock_store,
932 GetCryptedString(StrEq(storage_id),
933 WiFiService::kStoragePassphrase, _))
934 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
935 EXPECT_CALL(mock_store,
936 GetCryptedString(StrEq(storage_id),
937 StrNe(WiFiService::kStoragePassphrase), _))
938 .WillRepeatedly(Return(false));
939 EXPECT_TRUE(service->need_passphrase_);
940 EXPECT_TRUE(service->Load(&mock_store));
941 EXPECT_EQ(passphrase, service->passphrase_);
942 EXPECT_TRUE(service->connectable());
943 EXPECT_FALSE(service->need_passphrase_);
944 service->Unload();
945 EXPECT_EQ(string(""), service->passphrase_);
946 EXPECT_FALSE(service->connectable());
947 EXPECT_TRUE(service->need_passphrase_);
948}
949
Christopher Wiley27b47232012-11-02 13:13:00 -0700950TEST_F(WiFiServiceTest, ConfigureMakesConnectable) {
951 string guid("legit_guid");
952 KeyValueStore args;
953 args.SetString(flimflam::kEapIdentityProperty, "legit_identity");
954 args.SetString(flimflam::kEapPasswordProperty, "legit_password");
955 args.SetString(flimflam::kEAPEAPProperty, "PEAP");
956 args.SetString(flimflam::kGuidProperty, guid);
957 Error error;
958 vector<uint8_t> ssid(5);
959 ssid.push_back(0xff);
960
961 WiFiServiceRefPtr service = new WiFiService(control_interface(),
962 dispatcher(),
963 metrics(),
964 manager(),
965 wifi(),
966 ssid,
967 flimflam::kModeManaged,
968 flimflam::kSecurity8021x,
969 false);
970 // Hack the GUID in so that we don't have to mess about with WiFi to regsiter
971 // our service. This way, Manager will handle the lookup itself.
972 service->set_guid(guid);
973 manager()->RegisterService(service);
974 EXPECT_FALSE(service->connectable());
975 EXPECT_EQ(service.get(), manager()->GetService(args, &error).get());
976 EXPECT_TRUE(error.IsSuccess());
977 EXPECT_TRUE(service->connectable());
978}
979
Paul Stewart835934a2012-12-06 19:27:09 -0800980TEST_F(WiFiServiceTest, UnloadAndClearCacheWEP) {
Paul Stewart66c86002012-01-30 18:00:52 -0800981 vector<uint8_t> ssid(1, 'a');
982 WiFiServiceRefPtr service = new WiFiService(control_interface(),
983 dispatcher(),
984 metrics(),
985 manager(),
986 wifi(),
987 ssid,
988 flimflam::kModeManaged,
989 flimflam::kSecurityWep,
990 false);
Paul Stewart835934a2012-12-06 19:27:09 -0800991 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
992 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -0800993 service->Unload();
994}
995
996TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
997 vector<uint8_t> ssid(1, 'a');
998 WiFiServiceRefPtr service = new WiFiService(control_interface(),
999 dispatcher(),
1000 metrics(),
1001 manager(),
1002 wifi(),
1003 ssid,
1004 flimflam::kModeManaged,
1005 flimflam::kSecurity8021x,
1006 false);
Paul Stewart835934a2012-12-06 19:27:09 -08001007 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
1008 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -08001009 service->Unload();
1010}
1011
Paul Stewart0756db92012-01-27 08:34:47 -08001012TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewarta41e38d2011-11-11 07:47:29 -08001013 vector<uint8_t> ssid(5);
1014 ssid.push_back(0xff);
1015
1016 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1017 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001018 metrics(),
Paul Stewarta41e38d2011-11-11 07:47:29 -08001019 manager(),
1020 wifi(),
1021 ssid,
1022 flimflam::kModeManaged,
1023 flimflam::kSecurityNone,
1024 false);
1025 const string storage_id = service->GetStorageIdentifier();
1026 string address;
1027 string mode;
1028 string security;
1029 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
1030 &security));
1031 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
1032 EXPECT_EQ(flimflam::kModeManaged, mode);
1033 EXPECT_EQ(flimflam::kSecurityNone, security);
1034}
1035
Paul Stewart0756db92012-01-27 08:34:47 -08001036TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
1037 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
1038 // which needs to be dealt with specially in the parser.
1039 vector<uint8_t> ssid(5);
1040 ssid.push_back(0xff);
1041
1042 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1043 dispatcher(),
1044 metrics(),
1045 manager(),
1046 wifi(),
1047 ssid,
1048 flimflam::kModeManaged,
1049 flimflam::kSecurity8021x,
1050 false);
1051 const string storage_id = service->GetStorageIdentifier();
1052 string address;
1053 string mode;
1054 string security;
1055 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
1056 &security));
1057 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
1058 EXPECT_EQ(flimflam::kModeManaged, mode);
1059 EXPECT_EQ(flimflam::kSecurity8021x, security);
1060}
1061
Paul Stewart85aea152013-01-22 09:31:56 -08001062TEST_F(WiFiServiceFixupStorageTest, FixedEntries) {
1063 const string kNonWiFiId = "vpn_foo";
1064 const string kUnparsableWiFiId = "wifi_foo";
1065
1066 AddGroup(kNonWiFiId);
1067 AddGroup(kUnparsableWiFiId);
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001068 AddServiceEntry(true, true, true, true);
1069 AddServiceEntry(false, false, false, false);
1070 AddServiceEntry(true, true, true, true);
1071 AddServiceEntry(false, false, false, false);
Paul Stewart85aea152013-01-22 09:31:56 -08001072 EXPECT_TRUE(FixupServiceEntries());
1073}
1074
1075TEST_F(WiFiServiceFixupStorageTest, NoFixedEntries) {
1076 const string kNonWiFiId = "vpn_foo";
1077 const string kUnparsableWiFiId = "wifi_foo";
1078
1079 AddGroup(kNonWiFiId);
1080 AddGroup(kUnparsableWiFiId);
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001081 AddServiceEntry(true, true, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001082 EXPECT_FALSE(FixupServiceEntries());
1083}
1084
1085TEST_F(WiFiServiceFixupStorageTest, MissingTypeProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001086 AddServiceEntry(false, true, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001087 EXPECT_TRUE(FixupServiceEntries());
1088}
1089
1090TEST_F(WiFiServiceFixupStorageTest, MissingModeProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001091 AddServiceEntry(true, false, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001092 EXPECT_TRUE(FixupServiceEntries());
1093}
1094
1095TEST_F(WiFiServiceFixupStorageTest, MissingSecurityProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001096 AddServiceEntry(true, true, false, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001097 EXPECT_TRUE(FixupServiceEntries());
1098}
1099
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001100TEST_F(WiFiServiceFixupStorageTest, MissingSecurityClassProperty) {
1101 AddServiceEntry(true, true, true, false);
1102 EXPECT_TRUE(FixupServiceEntries());
1103}
Paul Stewart85aea152013-01-22 09:31:56 -08001104
mukesh agrawal29c13a12011-11-24 00:09:19 +00001105TEST_F(WiFiServiceTest, Connectable) {
1106 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001107 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001108
1109 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -08001110 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001111
1112 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001113 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001114
1115 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001116 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001117
1118 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001119 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001120
1121 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -08001122 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
1123 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
1124 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001125
1126 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001127 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
1128
1129 Service::EapCredentials eap;
1130 // Empty EAP credentials should not make a 802.1x network connectable.
1131 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1132
1133 eap.identity = "something";
1134 // If client certificate is being used, a private key must exist.
1135 eap.client_cert = "some client cert";
1136 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1137 eap.private_key = "some private key";
1138 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1139
1140 // Identity is always required.
1141 eap.identity.clear();
1142 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1143
1144 eap.identity = "something";
1145 // For non EAP-TLS types, a password is required.
1146 eap.eap = "Non-TLS";
1147 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1148 eap.password = "some password";
1149 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -08001150 // Dynamic WEP + 802.1X should be connectable under the same conditions.
1151 eap.key_management = "IEEE8021X";
1152 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001153}
1154
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001155TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001156 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001157 vector<uint8_t> ssid(1, 'a');
1158 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1159 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001160 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001161 manager(),
1162 wifi(),
1163 ssid,
1164 flimflam::kModeManaged,
1165 flimflam::kSecurityNone,
1166 false);
1167 EXPECT_CALL(*wifi(), IsIdle())
1168 .WillRepeatedly(Return(true));
1169 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001170 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1171 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001172
mukesh agrawalbf14e942012-03-02 14:36:34 -08001173 reason = "";
mukesh agrawale1d90e92012-02-15 17:36:08 -08001174 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001175 service->AddEndpoint(endpoint);
1176 EXPECT_CALL(*wifi(), IsIdle())
1177 .WillRepeatedly(Return(true));
1178 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001179 EXPECT_TRUE(service->IsAutoConnectable(&reason));
1180 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001181
1182 // WiFi only supports connecting to one Service at a time. So, to
1183 // avoid disrupting connectivity, we only allow auto-connection to
1184 // a WiFiService when the corresponding WiFi is idle.
1185 EXPECT_CALL(*wifi(), IsIdle())
1186 .WillRepeatedly(Return(false));
1187 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001188 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1189 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001190}
1191
1192TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001193 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001194 vector<uint8_t> ssid(1, 'a');
1195 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1196 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001197 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001198 manager(),
1199 wifi(),
1200 ssid,
1201 flimflam::kModeManaged,
1202 flimflam::kSecurityNone,
1203 false);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001204 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001205 EXPECT_CALL(*wifi(), ConnectTo(_, _))
1206 .Times(0);
1207 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001208 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001209
mukesh agrawale1d90e92012-02-15 17:36:08 -08001210 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001211 service->AddEndpoint(endpoint);
1212 EXPECT_CALL(*wifi(), IsIdle())
1213 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -08001214 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001215 EXPECT_CALL(*wifi(), ConnectTo(_, _));
1216 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001217 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -08001218
1219 Error error;
Christopher Wileyabd3b502012-09-26 13:08:52 -07001220 service->UserInitiatedDisconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001221 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -08001222 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001223}
1224
Gaurav Shah10109f22011-11-11 20:16:22 -08001225TEST_F(WiFiServiceTest, Populate8021x) {
1226 vector<uint8_t> ssid(1, 'a');
1227 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1228 dispatcher(),
1229 metrics(),
1230 manager(),
1231 wifi(),
1232 ssid,
1233 flimflam::kModeManaged,
1234 flimflam::kSecurityNone,
1235 false);
1236 Service::EapCredentials eap;
1237 eap.identity = "testidentity";
Paul Stewart20550982012-04-16 12:16:11 -07001238 eap.pin = "xxxx";
Gaurav Shah10109f22011-11-11 20:16:22 -08001239 service->set_eap(eap);
1240 map<string, ::DBus::Variant> params;
1241 service->Populate8021xProperties(&params);
1242 // Test that only non-empty 802.1x properties are populated.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001243 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapIdentity));
1244 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
1245 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
1246
Paul Stewart20550982012-04-16 12:16:11 -07001247 // Test that CA path is set by default.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001248 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
1249
Paul Stewart20550982012-04-16 12:16:11 -07001250 // Test that hardware-backed security arguments are not set.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001251 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
1252 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
1253 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
Paul Stewart20550982012-04-16 12:16:11 -07001254}
1255
1256TEST_F(WiFiServiceTest, Populate8021xNoSystemCAs) {
1257 vector<uint8_t> ssid(1, 'a');
1258 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1259 dispatcher(),
1260 metrics(),
1261 manager(),
1262 wifi(),
1263 ssid,
1264 flimflam::kModeManaged,
1265 flimflam::kSecurityNone,
1266 false);
1267 Service::EapCredentials eap;
1268 eap.identity = "testidentity";
1269 eap.use_system_cas = false;
1270 service->set_eap(eap);
1271 map<string, ::DBus::Variant> params;
1272 service->Populate8021xProperties(&params);
1273 // Test that CA path is not set if use_system_cas is explicitly false.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001274 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
Paul Stewart20550982012-04-16 12:16:11 -07001275}
1276
1277TEST_F(WiFiServiceTest, Populate8021xUsingHardwareAuth) {
1278 vector<uint8_t> ssid(1, 'a');
1279 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1280 dispatcher(),
1281 metrics(),
1282 manager(),
1283 wifi(),
1284 ssid,
1285 flimflam::kModeManaged,
1286 flimflam::kSecurityNone,
1287 false);
1288 Service::EapCredentials eap;
1289 eap.identity = "testidentity";
1290 eap.key_id = "key_id";
1291 eap.pin = "xxxx";
1292 service->set_eap(eap);
1293 map<string, ::DBus::Variant> params;
1294 service->Populate8021xProperties(&params);
1295 // Test that EAP engine parameters set if key_id is set.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001296 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
1297 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
1298 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
1299 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
1300}
1301
1302TEST_F(WiFiServiceTest, Populate8021xNSS) {
1303 vector<uint8_t> ssid(1, 'a');
1304 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1305 dispatcher(),
1306 metrics(),
1307 manager(),
1308 wifi(),
1309 ssid,
1310 flimflam::kModeManaged,
1311 flimflam::kSecurityNone,
1312 false);
1313 Service::EapCredentials eap;
1314 eap.ca_cert_nss = "nss_nickname";
1315 service->set_eap(eap);
1316 MockNSS nss;
1317 service->nss_ = &nss;
1318
1319 const string kNSSCertfile("/tmp/nss-cert");
1320 FilePath nss_cert(kNSSCertfile);
1321 vector<char> ssid_in_chars(ssid.begin(), ssid.end());
1322 EXPECT_CALL(nss, GetDERCertfile(eap.ca_cert_nss, ssid_in_chars))
1323 .WillOnce(Return(nss_cert));
1324
1325 map<string, ::DBus::Variant> params;
1326 service->Populate8021xProperties(&params);
1327 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
1328 if (ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert)) {
1329 EXPECT_EQ(kNSSCertfile, params[wpa_supplicant::kNetworkPropertyEapCaCert]
1330 .reader().get_string());
1331 }
Gaurav Shah10109f22011-11-11 20:16:22 -08001332}
1333
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001334TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
1335 vector<uint8_t> ssid(1, 'a');
1336 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
1337 dispatcher(),
1338 metrics(),
1339 manager(),
1340 wifi(),
1341 ssid,
1342 flimflam::kModeManaged,
1343 flimflam::kSecurityWep,
1344 false);
1345
1346 EXPECT_EQ("", wifi_service->passphrase_);
1347
1348 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001349 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001350 wifi_service->mutable_store(),
1351 flimflam::kPassphraseProperty,
1352 DBusAdaptor::StringToVariant("0:abcde"),
1353 &error));
1354 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
1355
1356 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
1357 flimflam::kPassphraseProperty,
1358 &error));
1359 EXPECT_EQ("", wifi_service->passphrase_);
1360}
1361
mukesh agrawale1d90e92012-02-15 17:36:08 -08001362TEST_F(WiFiServiceTest, SignalToStrength) {
1363 // Verify that our mapping is sane, in the sense that it preserves ordering.
1364 // We break the test into two domains, because we assume that positive
1365 // values aren't actually in dBm.
1366 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
1367 int16 current_mapped = WiFiService::SignalToStrength(i);
1368 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1369 EXPECT_LE(current_mapped, next_mapped)
1370 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001371 EXPECT_GE(current_mapped, Service::kStrengthMin);
1372 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001373 }
1374 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
1375 int16 current_mapped = WiFiService::SignalToStrength(i);
1376 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1377 EXPECT_LE(current_mapped, next_mapped)
1378 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001379 EXPECT_GE(current_mapped, Service::kStrengthMin);
1380 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001381 }
1382}
1383
1384TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
1385 // If the chosen signal values don't map to distinct strength
1386 // values, then we can't expect our other tests to pass. So verify
1387 // their distinctness.
1388 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
1389 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
1390 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
1391}
1392
1393TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
1394 // Initial endpoint updates values.
1395 EXPECT_CALL(adaptor, EmitUint16Changed(
1396 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001397 EXPECT_CALL(adaptor, EmitStringChanged(
1398 flimflam::kWifiBSsid, kOkEndpointBssId));
1399 EXPECT_CALL(adaptor, EmitUint8Changed(
mukesh agrawale1d90e92012-02-15 17:36:08 -08001400 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1401 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001402 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001403 Mock::VerifyAndClearExpectations(&adaptor);
1404
1405 // Endpoint with stronger signal updates values.
1406 EXPECT_CALL(adaptor, EmitUint16Changed(
1407 flimflam::kWifiFrequency, kGoodEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001408 EXPECT_CALL(adaptor, EmitStringChanged(
1409 flimflam::kWifiBSsid, kGoodEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001410 EXPECT_CALL(adaptor, EmitUint8Changed(
1411 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
1412 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001413 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001414 Mock::VerifyAndClearExpectations(&adaptor);
1415
1416 // Endpoint with lower signal does not change values.
1417 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001418 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001419 EXPECT_CALL(adaptor,
1420 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1421 service->AddEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001422 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001423 Mock::VerifyAndClearExpectations(&adaptor);
1424
1425 // Removing non-optimal endpoint does not change values.
1426 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001427 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001428 EXPECT_CALL(adaptor,
1429 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1430 service->RemoveEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001431 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001432 Mock::VerifyAndClearExpectations(&adaptor);
1433
1434 // Removing optimal endpoint updates values.
1435 EXPECT_CALL(adaptor, EmitUint16Changed(
1436 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001437 EXPECT_CALL(adaptor, EmitStringChanged(
1438 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001439 EXPECT_CALL(adaptor, EmitUint8Changed(
1440 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1441 service->RemoveEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001442 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001443 Mock::VerifyAndClearExpectations(&adaptor);
1444
1445 // Removing last endpoint updates values (and doesn't crash).
1446 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001447 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001448 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1449 service->RemoveEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001450 EXPECT_EQ(0, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001451 Mock::VerifyAndClearExpectations(&adaptor);
1452}
1453
1454TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1455 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001456 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001457 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1458 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1459 service->AddEndpoint(bad_endpoint);
1460 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001461 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001462 Mock::VerifyAndClearExpectations(&adaptor);
1463
1464 // Setting current endpoint forces adoption of its values, even if it
1465 // doesn't have the highest signal.
1466 EXPECT_CALL(adaptor, EmitUint16Changed(
1467 flimflam::kWifiFrequency, kBadEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001468 EXPECT_CALL(adaptor, EmitStringChanged(
1469 flimflam::kWifiBSsid, kBadEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001470 EXPECT_CALL(adaptor, EmitUint8Changed(
1471 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
1472 service->NotifyCurrentEndpoint(bad_endpoint);
1473 Mock::VerifyAndClearExpectations(&adaptor);
1474
1475 // Adding a better endpoint doesn't matter, when current endpoint is set.
1476 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001477 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001478 EXPECT_CALL(adaptor,
1479 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1480 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001481 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001482 Mock::VerifyAndClearExpectations(&adaptor);
1483
1484 // Removing a better endpoint doesn't matter, when current endpoint is set.
1485 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001486 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001487 EXPECT_CALL(adaptor,
1488 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1489 service->RemoveEndpoint(good_endpoint);
1490 Mock::VerifyAndClearExpectations(&adaptor);
1491
1492 // Removing the current endpoint is safe and sane.
1493 EXPECT_CALL(adaptor, EmitUint16Changed(
1494 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001495 EXPECT_CALL(adaptor, EmitStringChanged(
1496 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001497 EXPECT_CALL(adaptor, EmitUint8Changed(
1498 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1499 service->RemoveEndpoint(bad_endpoint);
1500 Mock::VerifyAndClearExpectations(&adaptor);
1501
1502 // Clearing the current endpoint (without removing it) is also safe and sane.
1503 service->NotifyCurrentEndpoint(ok_endpoint);
1504 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001505 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001506 EXPECT_CALL(adaptor,
1507 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1508 service->NotifyCurrentEndpoint(NULL);
1509 Mock::VerifyAndClearExpectations(&adaptor);
1510}
1511
1512TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1513 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001514 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001515 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1516 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1517 service->AddEndpoint(ok_endpoint);
1518 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001519 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001520 Mock::VerifyAndClearExpectations(&adaptor);
1521
1522 // Updating sub-optimal Endpoint doesn't update Service.
1523 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001524 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001525 EXPECT_CALL(adaptor,
1526 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1527 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
1528 service->NotifyEndpointUpdated(*ok_endpoint);
1529 Mock::VerifyAndClearExpectations(&adaptor);
1530
1531 // Updating optimal Endpoint updates appropriate Service property.
1532 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001533 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001534 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1535 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
1536 service->NotifyEndpointUpdated(*good_endpoint);
1537 Mock::VerifyAndClearExpectations(&adaptor);
1538
1539 // Change in optimal Endpoint updates Service properties.
1540 EXPECT_CALL(adaptor, EmitUint16Changed(
1541 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001542 EXPECT_CALL(adaptor, EmitStringChanged(
1543 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001544 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1545 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
1546 service->NotifyEndpointUpdated(*ok_endpoint);
1547 Mock::VerifyAndClearExpectations(&adaptor);
1548}
1549
Paul Stewarta5e7d5f2013-01-09 18:06:15 -08001550TEST_F(WiFiServiceUpdateFromEndpointsTest, Ieee80211w) {
1551 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1552 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1553 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1554 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1555 service->AddEndpoint(ok_endpoint);
1556 EXPECT_FALSE(service->ieee80211w_required());
1557 good_endpoint->ieee80211w_required_ = true;
1558 service->AddEndpoint(good_endpoint);
1559 EXPECT_TRUE(service->ieee80211w_required());
1560 service->RemoveEndpoint(good_endpoint);
1561 EXPECT_TRUE(service->ieee80211w_required());
1562}
1563
Chris Masone34af2182011-08-22 11:59:36 -07001564} // namespace shill