blob: 219d7e8b20d1cc3ce817479301ee7a212ae8da2f [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[];
Gaurav Shah10109f22011-11-11 20:16:22 -080056 bool CheckConnectable(const std::string &security, const char *passphrase,
57 Service::EapCredentials *eap) {
mukesh agrawal29c13a12011-11-24 00:09:19 +000058 Error error;
59 vector<uint8_t> ssid(1, 'a');
60 WiFiServiceRefPtr service = new WiFiService(control_interface(),
61 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080062 metrics(),
mukesh agrawal29c13a12011-11-24 00:09:19 +000063 manager(),
64 wifi(),
65 ssid,
66 flimflam::kModeManaged,
67 security,
68 false);
69 if (passphrase)
70 service->SetPassphrase(passphrase, &error);
Gaurav Shah10109f22011-11-11 20:16:22 -080071 if (eap) {
72 service->set_eap(*eap);
73 }
mukesh agrawal29c13a12011-11-24 00:09:19 +000074 return service->connectable();
75 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +000076 WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid) {
77 return WiFiEndpoint::MakeOpenEndpoint(ssid, bssid);
78 }
mukesh agrawal6e277772011-09-29 15:04:23 -070079 scoped_refptr<MockWiFi> wifi() { return wifi_; }
80
81 private:
82 scoped_refptr<MockWiFi> wifi_;
Chris Masone34af2182011-08-22 11:59:36 -070083};
84
mukesh agrawal6e277772011-09-29 15:04:23 -070085// static
86const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
87
Paul Stewartd08f4432011-11-04 07:48:20 -070088class WiFiServiceSecurityTest : public WiFiServiceTest {
89 public:
90 WiFiServiceRefPtr CreateServiceWithSecurity(const string &security) {
Gaurav Shahda6218a2011-11-11 12:09:33 -080091 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -070092 ssid.push_back(0xff);
93
94 return new WiFiService(control_interface(),
95 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080096 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -070097 manager(),
98 wifi(),
99 ssid,
100 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800101 security,
102 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700103 }
104
105 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
106 const string &security) {
107 string id = wifi_service->GetStorageIdentifier();
108 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
109 EXPECT_NE(mac_pos, string::npos);
110 size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
111 EXPECT_NE(mode_pos, string::npos);
112 return id.find(string(security), mode_pos) != string::npos;
113 }
114
115 // Test that a service that is created with security |from_security|
116 // gets by default a storage identifier with |to_security| as its
117 // security component.
118 bool TestStorageMapping(const string &from_security,
119 const string &to_security) {
120 WiFiServiceRefPtr wifi_service = CreateServiceWithSecurity(from_security);
121 return TestStorageSecurityIs(wifi_service, to_security);
122 }
123
124 // Test whether a service of type |service_security| can load from a
125 // storage interface containing an entry for |storage_security|.
126 // Make sure the result meets |expectation|. If |expectation| is
127 // true, also make sure the service storage identifier changes to
128 // match |storage_security|.
129 bool TestLoadMapping(const string &service_security,
130 const string &storage_security,
131 bool expectation) {
132 WiFiServiceRefPtr wifi_service =
133 CreateServiceWithSecurity(service_security);
134 NiceMock<MockStore> mock_store;
135 const string storage_id =
136 wifi_service->GetStorageIdentifierForSecurity(storage_security);
137 EXPECT_CALL(mock_store, ContainsGroup(_))
138 .WillRepeatedly(Return(false));
139 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
140 .WillRepeatedly(Return(true));
141 bool is_loadable = wifi_service->IsLoadableFrom(&mock_store);
142 EXPECT_EQ(expectation, is_loadable);
143 bool is_loaded = wifi_service->Load(&mock_store);
144 EXPECT_EQ(expectation, is_loaded);
145
146 if (expectation != is_loadable || expectation != is_loaded) {
147 return false;
148 } else if (!expectation) {
149 return true;
150 } else {
151 return TestStorageSecurityIs(wifi_service, storage_security);
152 }
153 }
154};
155
Chris Masone34af2182011-08-22 11:59:36 -0700156TEST_F(WiFiServiceTest, StorageId) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800157 vector<uint8_t> ssid(5);
Chris Masone34af2182011-08-22 11:59:36 -0700158 ssid.push_back(0xff);
Chris Masone9d779932011-08-25 16:33:41 -0700159
Chris Masone2176a882011-09-14 22:29:15 -0700160 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
161 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800162 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700163 manager(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700164 wifi(),
Chris Masone9d779932011-08-25 16:33:41 -0700165 ssid,
166 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800167 flimflam::kSecurityNone,
168 false);
Chris Masone9d779932011-08-25 16:33:41 -0700169 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700170 for (uint i = 0; i < id.length(); ++i) {
171 EXPECT_TRUE(id[i] == '_' ||
172 isxdigit(id[i]) ||
173 (isalpha(id[i]) && islower(id[i])));
174 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700175 EXPECT_TRUE(wifi_service->TechnologyIs(Technology::kWifi));
Chris Masone34af2182011-08-22 11:59:36 -0700176 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
177 EXPECT_NE(mac_pos, string::npos);
178 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
179}
180
Gaurav Shahda6218a2011-11-11 12:09:33 -0800181// Make sure the passphrase is registered as a write only property
182// by reading and comparing all string properties returned on the store.
183TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
184 vector<uint8_t> ssid(5);
185 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
186 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800187 metrics(),
Gaurav Shahda6218a2011-11-11 12:09:33 -0800188 manager(),
189 wifi(),
190 ssid,
191 flimflam::kModeManaged,
192 flimflam::kSecurityWpa,
193 false);
194 ReadablePropertyConstIterator<string> it =
195 (wifi_service->store()).GetStringPropertiesIter();
196 for( ; !it.AtEnd(); it.Advance())
197 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
198}
199
Thieu Lef7709452011-11-15 01:13:19 +0000200// Make sure setting the passphrase via D-Bus Service.SetProperty validates
201// the passphrase.
202TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
203 // We only spot check two password cases here to make sure the
204 // SetProperty code path does validation. We're not going to exhaustively
205 // test for all types of passwords.
206 vector<uint8_t> ssid(5);
207 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
208 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800209 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000210 manager(),
211 wifi(),
212 ssid,
213 flimflam::kModeManaged,
214 flimflam::kSecurityWep,
215 false);
216 Error error;
217 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
218 flimflam::kPassphraseProperty, "0:abcde", &error));
219 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
220 flimflam::kPassphraseProperty, "invalid", &error));
221 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
222}
223
224TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
225 vector<uint8_t> ssid(5);
226 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
227 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800228 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000229 manager(),
230 wifi(),
231 ssid,
232 flimflam::kModeManaged,
233 flimflam::kSecurityNone,
234 false);
235 Error error;
236 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
237 flimflam::kPassphraseProperty, "invalid", &error));
238 EXPECT_EQ(Error::kNotSupported, error.type());
239}
240
mukesh agrawald835b202011-10-07 15:26:47 -0700241TEST_F(WiFiServiceTest, NonUTF8SSID) {
242 vector<uint8_t> ssid;
243
244 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
245 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
246 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800247 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700248 manager(),
249 wifi(),
250 ssid,
251 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800252 flimflam::kSecurityNone,
253 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700254 map<string, ::DBus::Variant> properties;
255 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
256 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
257}
258
Gaurav Shahda6218a2011-11-11 12:09:33 -0800259MATCHER(WPASecurityArgs, "") {
260 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
261 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
262}
263
Gaurav Shah10109f22011-11-11 20:16:22 -0800264MATCHER(EAPSecurityArgs, "") {
265 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
266 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath);
267}
268
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700269TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800270 vector<uint8_t> ssid(5);
mukesh agrawal6e277772011-09-29 15:04:23 -0700271 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
272 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800273 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700274 manager(),
275 wifi(),
276 ssid,
277 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800278 flimflam::kSecurityWpa,
279 false);
mukesh agrawal6e277772011-09-29 15:04:23 -0700280 EXPECT_CALL(*wifi(),
281 ConnectTo(wifi_service.get(), WPASecurityArgs()));
282 wifi_service->ConnectTask();
283}
284
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700285TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800286 vector<uint8_t> ssid(5);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700287 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
288 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800289 metrics(),
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700290 manager(),
291 wifi(),
292 ssid,
293 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800294 flimflam::kSecurityRsn,
295 false);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700296 EXPECT_CALL(*wifi(),
297 ConnectTo(wifi_service.get(), WPASecurityArgs()));
298 wifi_service->ConnectTask();
299}
300
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800301TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800302 vector<uint8_t> ssid(5);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800303 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
304 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800305 metrics(),
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800306 manager(),
307 wifi(),
308 ssid,
309 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800310 flimflam::kSecurityPsk,
311 false);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800312 EXPECT_CALL(*wifi(),
313 ConnectTo(wifi_service.get(), WPASecurityArgs()));
314 wifi_service->ConnectTask();
315}
316
Gaurav Shah10109f22011-11-11 20:16:22 -0800317TEST_F(WiFiServiceTest, ConnectTask8021x) {
318 vector<uint8_t> ssid(5);
319 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
320 dispatcher(),
321 metrics(),
322 manager(),
323 wifi(),
324 ssid,
325 flimflam::kModeManaged,
326 flimflam::kSecurity8021x,
327 false);
328 Service::EapCredentials eap;
329 eap.identity = "identity";
330 wifi_service->set_eap(eap);
331 EXPECT_CALL(*wifi(),
332 ConnectTo(wifi_service.get(), EAPSecurityArgs()));
333 wifi_service->ConnectTask();
334}
335
Thieu Lef4cbda92011-11-10 23:41:24 +0000336MATCHER(WEPSecurityArgsKeyIndex0, "") {
337 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
338 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
339 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
340 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
341 reader().get_uint32() == 0);
342}
343
344MATCHER(WEPSecurityArgsKeyIndex1, "") {
345 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
346 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
347 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
348 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
349 reader().get_uint32() == 1);
350}
351
352MATCHER(WEPSecurityArgsKeyIndex2, "") {
353 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
354 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
355 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
356 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
357 reader().get_uint32() == 2);
358}
359
360MATCHER(WEPSecurityArgsKeyIndex3, "") {
361 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
362 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
363 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
364 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
365 reader().get_uint32() == 3);
366}
367
368TEST_F(WiFiServiceTest, ConnectTaskWEP) {
369 vector<uint8_t> ssid(5);
370 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
371 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800372 metrics(),
Thieu Lef4cbda92011-11-10 23:41:24 +0000373 manager(),
374 wifi(),
375 ssid,
376 flimflam::kModeManaged,
377 flimflam::kSecurityWep,
378 false);
379 Error error;
380 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
381 EXPECT_CALL(*wifi(),
382 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
383 wifi_service->ConnectTask();
384
385 wifi_service->SetPassphrase("abcdefghijklm", &error);
386 EXPECT_CALL(*wifi(),
387 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
388 wifi_service->ConnectTask();
389
390 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
391 EXPECT_CALL(*wifi(),
392 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
393 wifi_service->ConnectTask();
394
395 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
396 EXPECT_CALL(*wifi(),
397 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
398 wifi_service->ConnectTask();
399
400 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
401 EXPECT_CALL(*wifi(),
402 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
403 wifi_service->ConnectTask();
404}
405
Gaurav Shah29d68882012-01-30 19:06:42 -0800406
407MATCHER(DynamicWEPArgs, "") {
408 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
409 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
410 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
411}
412
413// Dynamic WEP + 802.1x.
414TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
415 vector<uint8_t> ssid(5);
416 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
417 dispatcher(),
418 metrics(),
419 manager(),
420 wifi(),
421 ssid,
422 flimflam::kModeManaged,
423 flimflam::kSecurityWep,
424 false);
425
426 Service::EapCredentials eap;
427 eap.key_management = "IEEE8021X";
428 eap.identity = "something";
429 wifi_service->set_eap(eap);
430 EXPECT_CALL(*wifi(),
431 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
432 wifi_service->ConnectTask();
433}
434
Paul Stewartd08f4432011-11-04 07:48:20 -0700435TEST_F(WiFiServiceTest, LoadHidden) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800436 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700437 ssid.push_back(0xff);
438
439 WiFiServiceRefPtr service = new WiFiService(control_interface(),
440 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800441 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700442 manager(),
443 wifi(),
444 ssid,
445 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800446 flimflam::kSecurityNone,
447 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700448 ASSERT_FALSE(service->hidden_ssid_);
449 NiceMock<MockStore> mock_store;
450 const string storage_id = service->GetStorageIdentifier();
451 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
452 .WillRepeatedly(Return(true));
453 EXPECT_CALL(mock_store, GetBool(_, _, _))
454 .WillRepeatedly(Return(false));
455 EXPECT_CALL(mock_store,
456 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
457 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
458 EXPECT_TRUE(service->Load(&mock_store));
459 EXPECT_TRUE(service->hidden_ssid_);
460}
461
462TEST_F(WiFiServiceSecurityTest, WPAMapping) {
463 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
464 flimflam::kSecurityPsk));
465 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
466 flimflam::kSecurityPsk));
467 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
468 flimflam::kSecurityPsk));
469 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
470 flimflam::kSecurityWep));
471 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
472 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800473 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
474 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700475}
476
477TEST_F(WiFiServiceSecurityTest, LoadMapping) {
478 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
479 flimflam::kSecurityPsk,
480 true));
481 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
482 flimflam::kSecurityRsn,
483 true));
484 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
485 flimflam::kSecurityWpa,
486 false));
487 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
488 flimflam::kSecurityPsk,
489 true));
490 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
491 flimflam::kSecurityWpa,
492 true));
493 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
494 flimflam::kSecurityRsn,
495 false));
496 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
497 flimflam::kSecurityWep,
498 true));
499 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
500 flimflam::kSecurityPsk,
501 false));
502}
503
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800504TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
505 vector<uint8_t> ssid(5);
506 ssid.push_back(0xff);
507
508 WiFiServiceRefPtr service = new WiFiService(control_interface(),
509 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800510 metrics(),
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800511 manager(),
512 wifi(),
513 ssid,
514 flimflam::kModeManaged,
515 flimflam::kSecurityPsk,
516 false);
517 NiceMock<MockStore> mock_store;
518 const string storage_id = service->GetStorageIdentifier();
519 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
520 .WillRepeatedly(Return(true));
521 EXPECT_CALL(mock_store, GetBool(_, _, _))
522 .WillRepeatedly(Return(false));
523 const string passphrase = "passphrase";
524 EXPECT_CALL(mock_store,
525 GetCryptedString(StrEq(storage_id),
526 WiFiService::kStoragePassphrase, _))
527 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
528 EXPECT_CALL(mock_store,
529 GetCryptedString(StrEq(storage_id),
530 StrNe(WiFiService::kStoragePassphrase), _))
531 .WillRepeatedly(Return(false));
532 EXPECT_TRUE(service->need_passphrase_);
533 EXPECT_TRUE(service->Load(&mock_store));
534 EXPECT_EQ(passphrase, service->passphrase_);
535 EXPECT_TRUE(service->connectable());
536 EXPECT_FALSE(service->need_passphrase_);
537 service->Unload();
538 EXPECT_EQ(string(""), service->passphrase_);
539 EXPECT_FALSE(service->connectable());
540 EXPECT_TRUE(service->need_passphrase_);
541}
542
Paul Stewart0756db92012-01-27 08:34:47 -0800543TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewarta41e38d2011-11-11 07:47:29 -0800544 vector<uint8_t> ssid(5);
545 ssid.push_back(0xff);
546
547 WiFiServiceRefPtr service = new WiFiService(control_interface(),
548 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800549 metrics(),
Paul Stewarta41e38d2011-11-11 07:47:29 -0800550 manager(),
551 wifi(),
552 ssid,
553 flimflam::kModeManaged,
554 flimflam::kSecurityNone,
555 false);
556 const string storage_id = service->GetStorageIdentifier();
557 string address;
558 string mode;
559 string security;
560 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
561 &security));
562 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
563 EXPECT_EQ(flimflam::kModeManaged, mode);
564 EXPECT_EQ(flimflam::kSecurityNone, security);
565}
566
Paul Stewart0756db92012-01-27 08:34:47 -0800567TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
568 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
569 // which needs to be dealt with specially in the parser.
570 vector<uint8_t> ssid(5);
571 ssid.push_back(0xff);
572
573 WiFiServiceRefPtr service = new WiFiService(control_interface(),
574 dispatcher(),
575 metrics(),
576 manager(),
577 wifi(),
578 ssid,
579 flimflam::kModeManaged,
580 flimflam::kSecurity8021x,
581 false);
582 const string storage_id = service->GetStorageIdentifier();
583 string address;
584 string mode;
585 string security;
586 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
587 &security));
588 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
589 EXPECT_EQ(flimflam::kModeManaged, mode);
590 EXPECT_EQ(flimflam::kSecurity8021x, security);
591}
592
mukesh agrawal29c13a12011-11-24 00:09:19 +0000593TEST_F(WiFiServiceTest, Connectable) {
594 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800595 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000596
597 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -0800598 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000599
600 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800601 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000602
603 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800604 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000605
606 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800607 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000608
609 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -0800610 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
611 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
612 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000613
614 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800615 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
616
617 Service::EapCredentials eap;
618 // Empty EAP credentials should not make a 802.1x network connectable.
619 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
620
621 eap.identity = "something";
622 // If client certificate is being used, a private key must exist.
623 eap.client_cert = "some client cert";
624 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
625 eap.private_key = "some private key";
626 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
627
628 // Identity is always required.
629 eap.identity.clear();
630 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
631
632 eap.identity = "something";
633 // For non EAP-TLS types, a password is required.
634 eap.eap = "Non-TLS";
635 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
636 eap.password = "some password";
637 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -0800638 // Dynamic WEP + 802.1X should be connectable under the same conditions.
639 eap.key_management = "IEEE8021X";
640 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000641}
642
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000643TEST_F(WiFiServiceTest, IsAutoConnectable) {
644 vector<uint8_t> ssid(1, 'a');
645 WiFiServiceRefPtr service = new WiFiService(control_interface(),
646 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800647 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000648 manager(),
649 wifi(),
650 ssid,
651 flimflam::kModeManaged,
652 flimflam::kSecurityNone,
653 false);
654 EXPECT_CALL(*wifi(), IsIdle())
655 .WillRepeatedly(Return(true));
656 EXPECT_FALSE(service->HasEndpoints());
657 EXPECT_FALSE(service->IsAutoConnectable());
658
659 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01");
660 service->AddEndpoint(endpoint);
661 EXPECT_CALL(*wifi(), IsIdle())
662 .WillRepeatedly(Return(true));
663 EXPECT_TRUE(service->HasEndpoints());
664 EXPECT_TRUE(service->IsAutoConnectable());
665
666 // WiFi only supports connecting to one Service at a time. So, to
667 // avoid disrupting connectivity, we only allow auto-connection to
668 // a WiFiService when the corresponding WiFi is idle.
669 EXPECT_CALL(*wifi(), IsIdle())
670 .WillRepeatedly(Return(false));
671 EXPECT_TRUE(service->HasEndpoints());
672 EXPECT_FALSE(service->IsAutoConnectable());
673}
674
675TEST_F(WiFiServiceTest, AutoConnect) {
676 vector<uint8_t> ssid(1, 'a');
677 WiFiServiceRefPtr service = new WiFiService(control_interface(),
678 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800679 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000680 manager(),
681 wifi(),
682 ssid,
683 flimflam::kModeManaged,
684 flimflam::kSecurityNone,
685 false);
686 EXPECT_FALSE(service->IsAutoConnectable());
687 EXPECT_CALL(*wifi(), ConnectTo(_, _))
688 .Times(0);
689 service->AutoConnect();
690
691 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01");
692 service->AddEndpoint(endpoint);
693 EXPECT_CALL(*wifi(), IsIdle())
694 .WillRepeatedly(Return(true));
695 EXPECT_TRUE(service->IsAutoConnectable());
696 EXPECT_CALL(*wifi(), ConnectTo(_, _));
697 service->AutoConnect();
mukesh agrawaladb68482012-01-17 16:31:51 -0800698
699 Error error;
700 service->Disconnect(&error);
701 EXPECT_FALSE(service->IsAutoConnectable());
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000702}
703
Gaurav Shah10109f22011-11-11 20:16:22 -0800704TEST_F(WiFiServiceTest, Populate8021x) {
705 vector<uint8_t> ssid(1, 'a');
706 WiFiServiceRefPtr service = new WiFiService(control_interface(),
707 dispatcher(),
708 metrics(),
709 manager(),
710 wifi(),
711 ssid,
712 flimflam::kModeManaged,
713 flimflam::kSecurityNone,
714 false);
715 Service::EapCredentials eap;
716 eap.identity = "testidentity";
717 service->set_eap(eap);
718 map<string, ::DBus::Variant> params;
719 service->Populate8021xProperties(&params);
720 // Test that only non-empty 802.1x properties are populated.
721 EXPECT_TRUE(ContainsKey(params,
722 wpa_supplicant::kNetworkPropertyEapIdentity));
723 EXPECT_FALSE(ContainsKey(params,
724 wpa_supplicant::kNetworkPropertyEapKeyId));
725}
726
Chris Masone34af2182011-08-22 11:59:36 -0700727} // namespace shill