blob: 5f226acd32dc9aeb5a4485c758098c14931b8b19 [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>
Chris Masone34af2182011-08-22 11:59:36 -07008#include <string>
9#include <vector>
10
11#include <base/string_util.h>
12#include <chromeos/dbus/service_constants.h>
13#include <gmock/gmock.h>
14#include <gtest/gtest.h>
15
Paul Stewart26b327e2011-10-19 11:38:09 -070016#include "shill/event_dispatcher.h"
Chris Masone34af2182011-08-22 11:59:36 -070017#include "shill/manager.h"
18#include "shill/mock_adaptors.h"
19#include "shill/mock_control.h"
20#include "shill/mock_service.h"
21#include "shill/mock_store.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070022#include "shill/mock_wifi.h"
Chris Masone34af2182011-08-22 11:59:36 -070023#include "shill/property_store_unittest.h"
mukesh agrawal8a3188d2011-12-01 20:56:44 +000024#include "shill/refptr_types.h"
25#include "shill/wifi_endpoint.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070026#include "shill/wpa_supplicant.h"
Chris Masone34af2182011-08-22 11:59:36 -070027
mukesh agrawald835b202011-10-07 15:26:47 -070028using std::map;
Chris Masone34af2182011-08-22 11:59:36 -070029using std::string;
30using std::vector;
31
32namespace shill {
Paul Stewartd08f4432011-11-04 07:48:20 -070033using ::testing::_;
34using ::testing::DoAll;
mukesh agrawal6e277772011-09-29 15:04:23 -070035using ::testing::NiceMock;
Paul Stewartd08f4432011-11-04 07:48:20 -070036using ::testing::Return;
37using ::testing::SetArgumentPointee;
38using ::testing::StrEq;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080039using ::testing::StrNe;
Chris Masone34af2182011-08-22 11:59:36 -070040
41class WiFiServiceTest : public PropertyStoreTest {
42 public:
mukesh agrawal6e277772011-09-29 15:04:23 -070043 WiFiServiceTest() : wifi_(
44 new NiceMock<MockWiFi>(
45 control_interface(),
46 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080047 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -070048 manager(),
49 "wifi",
50 fake_mac,
51 0)) {}
Chris Masone34af2182011-08-22 11:59:36 -070052 virtual ~WiFiServiceTest() {}
mukesh agrawal6e277772011-09-29 15:04:23 -070053
54 protected:
55 static const char fake_mac[];
mukesh agrawal29c13a12011-11-24 00:09:19 +000056 bool CheckConnectable(const std::string &security, const char *passphrase) {
57 Error error;
58 vector<uint8_t> ssid(1, 'a');
59 WiFiServiceRefPtr service = new WiFiService(control_interface(),
60 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080061 metrics(),
mukesh agrawal29c13a12011-11-24 00:09:19 +000062 manager(),
63 wifi(),
64 ssid,
65 flimflam::kModeManaged,
66 security,
67 false);
68 if (passphrase)
69 service->SetPassphrase(passphrase, &error);
70 return service->connectable();
71 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +000072 WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid) {
73 return WiFiEndpoint::MakeOpenEndpoint(ssid, bssid);
74 }
mukesh agrawal6e277772011-09-29 15:04:23 -070075 scoped_refptr<MockWiFi> wifi() { return wifi_; }
76
77 private:
78 scoped_refptr<MockWiFi> wifi_;
Chris Masone34af2182011-08-22 11:59:36 -070079};
80
mukesh agrawal6e277772011-09-29 15:04:23 -070081// static
82const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
83
Paul Stewartd08f4432011-11-04 07:48:20 -070084class WiFiServiceSecurityTest : public WiFiServiceTest {
85 public:
86 WiFiServiceRefPtr CreateServiceWithSecurity(const string &security) {
Gaurav Shahda6218a2011-11-11 12:09:33 -080087 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -070088 ssid.push_back(0xff);
89
90 return new WiFiService(control_interface(),
91 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080092 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -070093 manager(),
94 wifi(),
95 ssid,
96 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -080097 security,
98 false);
Paul Stewartd08f4432011-11-04 07:48:20 -070099 }
100
101 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
102 const string &security) {
103 string id = wifi_service->GetStorageIdentifier();
104 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
105 EXPECT_NE(mac_pos, string::npos);
106 size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
107 EXPECT_NE(mode_pos, string::npos);
108 return id.find(string(security), mode_pos) != string::npos;
109 }
110
111 // Test that a service that is created with security |from_security|
112 // gets by default a storage identifier with |to_security| as its
113 // security component.
114 bool TestStorageMapping(const string &from_security,
115 const string &to_security) {
116 WiFiServiceRefPtr wifi_service = CreateServiceWithSecurity(from_security);
117 return TestStorageSecurityIs(wifi_service, to_security);
118 }
119
120 // Test whether a service of type |service_security| can load from a
121 // storage interface containing an entry for |storage_security|.
122 // Make sure the result meets |expectation|. If |expectation| is
123 // true, also make sure the service storage identifier changes to
124 // match |storage_security|.
125 bool TestLoadMapping(const string &service_security,
126 const string &storage_security,
127 bool expectation) {
128 WiFiServiceRefPtr wifi_service =
129 CreateServiceWithSecurity(service_security);
130 NiceMock<MockStore> mock_store;
131 const string storage_id =
132 wifi_service->GetStorageIdentifierForSecurity(storage_security);
133 EXPECT_CALL(mock_store, ContainsGroup(_))
134 .WillRepeatedly(Return(false));
135 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
136 .WillRepeatedly(Return(true));
137 bool is_loadable = wifi_service->IsLoadableFrom(&mock_store);
138 EXPECT_EQ(expectation, is_loadable);
139 bool is_loaded = wifi_service->Load(&mock_store);
140 EXPECT_EQ(expectation, is_loaded);
141
142 if (expectation != is_loadable || expectation != is_loaded) {
143 return false;
144 } else if (!expectation) {
145 return true;
146 } else {
147 return TestStorageSecurityIs(wifi_service, storage_security);
148 }
149 }
150};
151
Chris Masone34af2182011-08-22 11:59:36 -0700152TEST_F(WiFiServiceTest, StorageId) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800153 vector<uint8_t> ssid(5);
Chris Masone34af2182011-08-22 11:59:36 -0700154 ssid.push_back(0xff);
Chris Masone9d779932011-08-25 16:33:41 -0700155
Chris Masone2176a882011-09-14 22:29:15 -0700156 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
157 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800158 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700159 manager(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700160 wifi(),
Chris Masone9d779932011-08-25 16:33:41 -0700161 ssid,
162 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800163 flimflam::kSecurityNone,
164 false);
Chris Masone9d779932011-08-25 16:33:41 -0700165 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700166 for (uint i = 0; i < id.length(); ++i) {
167 EXPECT_TRUE(id[i] == '_' ||
168 isxdigit(id[i]) ||
169 (isalpha(id[i]) && islower(id[i])));
170 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700171 EXPECT_TRUE(wifi_service->TechnologyIs(Technology::kWifi));
Chris Masone34af2182011-08-22 11:59:36 -0700172 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
173 EXPECT_NE(mac_pos, string::npos);
174 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
175}
176
Gaurav Shahda6218a2011-11-11 12:09:33 -0800177// Make sure the passphrase is registered as a write only property
178// by reading and comparing all string properties returned on the store.
179TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
180 vector<uint8_t> ssid(5);
181 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
182 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800183 metrics(),
Gaurav Shahda6218a2011-11-11 12:09:33 -0800184 manager(),
185 wifi(),
186 ssid,
187 flimflam::kModeManaged,
188 flimflam::kSecurityWpa,
189 false);
190 ReadablePropertyConstIterator<string> it =
191 (wifi_service->store()).GetStringPropertiesIter();
192 for( ; !it.AtEnd(); it.Advance())
193 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
194}
195
Thieu Lef7709452011-11-15 01:13:19 +0000196// Make sure setting the passphrase via D-Bus Service.SetProperty validates
197// the passphrase.
198TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
199 // We only spot check two password cases here to make sure the
200 // SetProperty code path does validation. We're not going to exhaustively
201 // test for all types of passwords.
202 vector<uint8_t> ssid(5);
203 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
204 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800205 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000206 manager(),
207 wifi(),
208 ssid,
209 flimflam::kModeManaged,
210 flimflam::kSecurityWep,
211 false);
212 Error error;
213 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
214 flimflam::kPassphraseProperty, "0:abcde", &error));
215 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
216 flimflam::kPassphraseProperty, "invalid", &error));
217 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
218}
219
220TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
221 vector<uint8_t> ssid(5);
222 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
223 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800224 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000225 manager(),
226 wifi(),
227 ssid,
228 flimflam::kModeManaged,
229 flimflam::kSecurityNone,
230 false);
231 Error error;
232 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
233 flimflam::kPassphraseProperty, "invalid", &error));
234 EXPECT_EQ(Error::kNotSupported, error.type());
235}
236
mukesh agrawald835b202011-10-07 15:26:47 -0700237TEST_F(WiFiServiceTest, NonUTF8SSID) {
238 vector<uint8_t> ssid;
239
240 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
241 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
242 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800243 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700244 manager(),
245 wifi(),
246 ssid,
247 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800248 flimflam::kSecurityNone,
249 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700250 map<string, ::DBus::Variant> properties;
251 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
252 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
253}
254
Gaurav Shahda6218a2011-11-11 12:09:33 -0800255MATCHER(WPASecurityArgs, "") {
256 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
257 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
258}
259
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700260TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800261 vector<uint8_t> ssid(5);
mukesh agrawal6e277772011-09-29 15:04:23 -0700262 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
263 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800264 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700265 manager(),
266 wifi(),
267 ssid,
268 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800269 flimflam::kSecurityWpa,
270 false);
mukesh agrawal6e277772011-09-29 15:04:23 -0700271 EXPECT_CALL(*wifi(),
272 ConnectTo(wifi_service.get(), WPASecurityArgs()));
273 wifi_service->ConnectTask();
274}
275
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700276TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800277 vector<uint8_t> ssid(5);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700278 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
279 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800280 metrics(),
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700281 manager(),
282 wifi(),
283 ssid,
284 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800285 flimflam::kSecurityRsn,
286 false);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700287 EXPECT_CALL(*wifi(),
288 ConnectTo(wifi_service.get(), WPASecurityArgs()));
289 wifi_service->ConnectTask();
290}
291
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800292TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800293 vector<uint8_t> ssid(5);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800294 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
295 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800296 metrics(),
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800297 manager(),
298 wifi(),
299 ssid,
300 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800301 flimflam::kSecurityPsk,
302 false);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800303 EXPECT_CALL(*wifi(),
304 ConnectTo(wifi_service.get(), WPASecurityArgs()));
305 wifi_service->ConnectTask();
306}
307
Thieu Lef4cbda92011-11-10 23:41:24 +0000308MATCHER(WEPSecurityArgsKeyIndex0, "") {
309 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
310 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
311 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
312 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
313 reader().get_uint32() == 0);
314}
315
316MATCHER(WEPSecurityArgsKeyIndex1, "") {
317 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
318 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
319 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
320 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
321 reader().get_uint32() == 1);
322}
323
324MATCHER(WEPSecurityArgsKeyIndex2, "") {
325 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
326 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
327 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
328 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
329 reader().get_uint32() == 2);
330}
331
332MATCHER(WEPSecurityArgsKeyIndex3, "") {
333 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
334 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
335 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
336 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
337 reader().get_uint32() == 3);
338}
339
340TEST_F(WiFiServiceTest, ConnectTaskWEP) {
341 vector<uint8_t> ssid(5);
342 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
343 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800344 metrics(),
Thieu Lef4cbda92011-11-10 23:41:24 +0000345 manager(),
346 wifi(),
347 ssid,
348 flimflam::kModeManaged,
349 flimflam::kSecurityWep,
350 false);
351 Error error;
352 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
353 EXPECT_CALL(*wifi(),
354 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
355 wifi_service->ConnectTask();
356
357 wifi_service->SetPassphrase("abcdefghijklm", &error);
358 EXPECT_CALL(*wifi(),
359 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
360 wifi_service->ConnectTask();
361
362 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
363 EXPECT_CALL(*wifi(),
364 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
365 wifi_service->ConnectTask();
366
367 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
368 EXPECT_CALL(*wifi(),
369 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
370 wifi_service->ConnectTask();
371
372 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
373 EXPECT_CALL(*wifi(),
374 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
375 wifi_service->ConnectTask();
376}
377
Paul Stewartd08f4432011-11-04 07:48:20 -0700378TEST_F(WiFiServiceTest, LoadHidden) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800379 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700380 ssid.push_back(0xff);
381
382 WiFiServiceRefPtr service = new WiFiService(control_interface(),
383 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800384 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700385 manager(),
386 wifi(),
387 ssid,
388 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800389 flimflam::kSecurityNone,
390 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700391 ASSERT_FALSE(service->hidden_ssid_);
392 NiceMock<MockStore> mock_store;
393 const string storage_id = service->GetStorageIdentifier();
394 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
395 .WillRepeatedly(Return(true));
396 EXPECT_CALL(mock_store, GetBool(_, _, _))
397 .WillRepeatedly(Return(false));
398 EXPECT_CALL(mock_store,
399 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
400 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
401 EXPECT_TRUE(service->Load(&mock_store));
402 EXPECT_TRUE(service->hidden_ssid_);
403}
404
405TEST_F(WiFiServiceSecurityTest, WPAMapping) {
406 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
407 flimflam::kSecurityPsk));
408 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
409 flimflam::kSecurityPsk));
410 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
411 flimflam::kSecurityPsk));
412 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
413 flimflam::kSecurityWep));
414 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
415 flimflam::kSecurityNone));
416 // TODO(pstew): 802.1x is in a NOTIMPLEMENTED block in wifi_service.cc
417 // EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
418 // flimflam::kSecurity8021x));
419}
420
421TEST_F(WiFiServiceSecurityTest, LoadMapping) {
422 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
423 flimflam::kSecurityPsk,
424 true));
425 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
426 flimflam::kSecurityRsn,
427 true));
428 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
429 flimflam::kSecurityWpa,
430 false));
431 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
432 flimflam::kSecurityPsk,
433 true));
434 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
435 flimflam::kSecurityWpa,
436 true));
437 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
438 flimflam::kSecurityRsn,
439 false));
440 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
441 flimflam::kSecurityWep,
442 true));
443 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
444 flimflam::kSecurityPsk,
445 false));
446}
447
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800448TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
449 vector<uint8_t> ssid(5);
450 ssid.push_back(0xff);
451
452 WiFiServiceRefPtr service = new WiFiService(control_interface(),
453 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800454 metrics(),
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800455 manager(),
456 wifi(),
457 ssid,
458 flimflam::kModeManaged,
459 flimflam::kSecurityPsk,
460 false);
461 NiceMock<MockStore> mock_store;
462 const string storage_id = service->GetStorageIdentifier();
463 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
464 .WillRepeatedly(Return(true));
465 EXPECT_CALL(mock_store, GetBool(_, _, _))
466 .WillRepeatedly(Return(false));
467 const string passphrase = "passphrase";
468 EXPECT_CALL(mock_store,
469 GetCryptedString(StrEq(storage_id),
470 WiFiService::kStoragePassphrase, _))
471 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
472 EXPECT_CALL(mock_store,
473 GetCryptedString(StrEq(storage_id),
474 StrNe(WiFiService::kStoragePassphrase), _))
475 .WillRepeatedly(Return(false));
476 EXPECT_TRUE(service->need_passphrase_);
477 EXPECT_TRUE(service->Load(&mock_store));
478 EXPECT_EQ(passphrase, service->passphrase_);
479 EXPECT_TRUE(service->connectable());
480 EXPECT_FALSE(service->need_passphrase_);
481 service->Unload();
482 EXPECT_EQ(string(""), service->passphrase_);
483 EXPECT_FALSE(service->connectable());
484 EXPECT_TRUE(service->need_passphrase_);
485}
486
Paul Stewarta41e38d2011-11-11 07:47:29 -0800487TEST_F(WiFiServiceTest, ParseStorageIdentifier) {
488 vector<uint8_t> ssid(5);
489 ssid.push_back(0xff);
490
491 WiFiServiceRefPtr service = new WiFiService(control_interface(),
492 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800493 metrics(),
Paul Stewarta41e38d2011-11-11 07:47:29 -0800494 manager(),
495 wifi(),
496 ssid,
497 flimflam::kModeManaged,
498 flimflam::kSecurityNone,
499 false);
500 const string storage_id = service->GetStorageIdentifier();
501 string address;
502 string mode;
503 string security;
504 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
505 &security));
506 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
507 EXPECT_EQ(flimflam::kModeManaged, mode);
508 EXPECT_EQ(flimflam::kSecurityNone, security);
509}
510
mukesh agrawal29c13a12011-11-24 00:09:19 +0000511TEST_F(WiFiServiceTest, Connectable) {
512 // Open network should be connectable.
513 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL));
514
515 // Open network should remain connectable if we try to set a password on it.
516 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde"));
517
518 // WEP network with passphrase set should be connectable.
519 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde"));
520
521 // WEP network without passphrase set should NOT be connectable.
522 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL));
523
524 // A bad passphrase should not make a WEP network connectable.
525 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a"));
526
527 // Similar to WEP, for WPA.
528 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh"));
529 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL));
530 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a"));
531
532 // Unconfigured 802.1x should NOT be connectable.
533 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL));
534}
535
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000536TEST_F(WiFiServiceTest, IsAutoConnectable) {
537 vector<uint8_t> ssid(1, 'a');
538 WiFiServiceRefPtr service = new WiFiService(control_interface(),
539 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800540 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000541 manager(),
542 wifi(),
543 ssid,
544 flimflam::kModeManaged,
545 flimflam::kSecurityNone,
546 false);
547 EXPECT_CALL(*wifi(), IsIdle())
548 .WillRepeatedly(Return(true));
549 EXPECT_FALSE(service->HasEndpoints());
550 EXPECT_FALSE(service->IsAutoConnectable());
551
552 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01");
553 service->AddEndpoint(endpoint);
554 EXPECT_CALL(*wifi(), IsIdle())
555 .WillRepeatedly(Return(true));
556 EXPECT_TRUE(service->HasEndpoints());
557 EXPECT_TRUE(service->IsAutoConnectable());
558
559 // WiFi only supports connecting to one Service at a time. So, to
560 // avoid disrupting connectivity, we only allow auto-connection to
561 // a WiFiService when the corresponding WiFi is idle.
562 EXPECT_CALL(*wifi(), IsIdle())
563 .WillRepeatedly(Return(false));
564 EXPECT_TRUE(service->HasEndpoints());
565 EXPECT_FALSE(service->IsAutoConnectable());
566}
567
568TEST_F(WiFiServiceTest, AutoConnect) {
569 vector<uint8_t> ssid(1, 'a');
570 WiFiServiceRefPtr service = new WiFiService(control_interface(),
571 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800572 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000573 manager(),
574 wifi(),
575 ssid,
576 flimflam::kModeManaged,
577 flimflam::kSecurityNone,
578 false);
579 EXPECT_FALSE(service->IsAutoConnectable());
580 EXPECT_CALL(*wifi(), ConnectTo(_, _))
581 .Times(0);
582 service->AutoConnect();
583
584 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01");
585 service->AddEndpoint(endpoint);
586 EXPECT_CALL(*wifi(), IsIdle())
587 .WillRepeatedly(Return(true));
588 EXPECT_TRUE(service->IsAutoConnectable());
589 EXPECT_CALL(*wifi(), ConnectTo(_, _));
590 service->AutoConnect();
mukesh agrawaladb68482012-01-17 16:31:51 -0800591
592 Error error;
593 service->Disconnect(&error);
594 EXPECT_FALSE(service->IsAutoConnectable());
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000595}
596
Chris Masone34af2182011-08-22 11:59:36 -0700597} // namespace shill