blob: 389c71745d0a626b8a8f65511fca0a6caaf3bb67 [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"
Paul Stewartecf4cd12012-04-17 11:08:39 -070020#include "shill/mock_nss.h"
Chris Masone34af2182011-08-22 11:59:36 -070021#include "shill/mock_service.h"
22#include "shill/mock_store.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070023#include "shill/mock_wifi.h"
Chris Masone34af2182011-08-22 11:59:36 -070024#include "shill/property_store_unittest.h"
mukesh agrawal8a3188d2011-12-01 20:56:44 +000025#include "shill/refptr_types.h"
26#include "shill/wifi_endpoint.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070027#include "shill/wpa_supplicant.h"
Chris Masone34af2182011-08-22 11:59:36 -070028
mukesh agrawald835b202011-10-07 15:26:47 -070029using std::map;
Chris Masone34af2182011-08-22 11:59:36 -070030using std::string;
31using std::vector;
Paul Stewartd08f4432011-11-04 07:48:20 -070032using ::testing::_;
mukesh agrawale1d90e92012-02-15 17:36:08 -080033using ::testing::AnyNumber;
Paul Stewartd08f4432011-11-04 07:48:20 -070034using ::testing::DoAll;
mukesh agrawale1d90e92012-02-15 17:36:08 -080035using ::testing::Mock;
mukesh agrawal6e277772011-09-29 15:04:23 -070036using ::testing::NiceMock;
Paul Stewartd08f4432011-11-04 07:48:20 -070037using ::testing::Return;
38using ::testing::SetArgumentPointee;
39using ::testing::StrEq;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080040using ::testing::StrNe;
Chris Masone34af2182011-08-22 11:59:36 -070041
mukesh agrawalb20776f2012-02-10 16:00:36 -080042namespace shill {
43
Chris Masone34af2182011-08-22 11:59:36 -070044class WiFiServiceTest : public PropertyStoreTest {
45 public:
mukesh agrawal6e277772011-09-29 15:04:23 -070046 WiFiServiceTest() : wifi_(
47 new NiceMock<MockWiFi>(
48 control_interface(),
49 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080050 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -070051 manager(),
52 "wifi",
53 fake_mac,
54 0)) {}
Chris Masone34af2182011-08-22 11:59:36 -070055 virtual ~WiFiServiceTest() {}
mukesh agrawal6e277772011-09-29 15:04:23 -070056
57 protected:
58 static const char fake_mac[];
mukesh agrawale1d90e92012-02-15 17:36:08 -080059
Gaurav Shah10109f22011-11-11 20:16:22 -080060 bool CheckConnectable(const std::string &security, const char *passphrase,
61 Service::EapCredentials *eap) {
mukesh agrawal29c13a12011-11-24 00:09:19 +000062 Error error;
63 vector<uint8_t> ssid(1, 'a');
64 WiFiServiceRefPtr service = new WiFiService(control_interface(),
65 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080066 metrics(),
mukesh agrawal29c13a12011-11-24 00:09:19 +000067 manager(),
68 wifi(),
69 ssid,
70 flimflam::kModeManaged,
71 security,
72 false);
73 if (passphrase)
74 service->SetPassphrase(passphrase, &error);
Gaurav Shah10109f22011-11-11 20:16:22 -080075 if (eap) {
76 service->set_eap(*eap);
77 }
mukesh agrawal29c13a12011-11-24 00:09:19 +000078 return service->connectable();
79 }
mukesh agrawale1d90e92012-02-15 17:36:08 -080080 WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid,
81 uint16 frequency, int16 signal_dbm) {
82 return WiFiEndpoint::MakeOpenEndpoint(
83 NULL, NULL, ssid, bssid, frequency, signal_dbm);
84 }
85 WiFiService *MakeGenericService() {
86 return new WiFiService(control_interface(),
87 dispatcher(),
88 metrics(),
89 manager(),
90 wifi(),
91 vector<uint8_t>(),
92 flimflam::kModeManaged,
93 flimflam::kSecurityWep,
94 false);
95 }
96 ServiceMockAdaptor *GetAdaptor(WiFiService *service) {
97 return dynamic_cast<ServiceMockAdaptor *>(service->adaptor());
mukesh agrawal8a3188d2011-12-01 20:56:44 +000098 }
mukesh agrawal6e277772011-09-29 15:04:23 -070099 scoped_refptr<MockWiFi> wifi() { return wifi_; }
100
101 private:
102 scoped_refptr<MockWiFi> wifi_;
Chris Masone34af2182011-08-22 11:59:36 -0700103};
104
mukesh agrawal6e277772011-09-29 15:04:23 -0700105// static
106const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
107
Paul Stewartd08f4432011-11-04 07:48:20 -0700108class WiFiServiceSecurityTest : public WiFiServiceTest {
109 public:
110 WiFiServiceRefPtr CreateServiceWithSecurity(const string &security) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800111 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700112 ssid.push_back(0xff);
113
114 return new WiFiService(control_interface(),
115 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800116 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700117 manager(),
118 wifi(),
119 ssid,
120 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800121 security,
122 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700123 }
124
125 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
126 const string &security) {
127 string id = wifi_service->GetStorageIdentifier();
128 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
129 EXPECT_NE(mac_pos, string::npos);
130 size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
131 EXPECT_NE(mode_pos, string::npos);
132 return id.find(string(security), mode_pos) != string::npos;
133 }
134
135 // Test that a service that is created with security |from_security|
136 // gets by default a storage identifier with |to_security| as its
137 // security component.
138 bool TestStorageMapping(const string &from_security,
139 const string &to_security) {
140 WiFiServiceRefPtr wifi_service = CreateServiceWithSecurity(from_security);
141 return TestStorageSecurityIs(wifi_service, to_security);
142 }
143
144 // Test whether a service of type |service_security| can load from a
145 // storage interface containing an entry for |storage_security|.
146 // Make sure the result meets |expectation|. If |expectation| is
147 // true, also make sure the service storage identifier changes to
148 // match |storage_security|.
149 bool TestLoadMapping(const string &service_security,
150 const string &storage_security,
151 bool expectation) {
152 WiFiServiceRefPtr wifi_service =
153 CreateServiceWithSecurity(service_security);
154 NiceMock<MockStore> mock_store;
155 const string storage_id =
156 wifi_service->GetStorageIdentifierForSecurity(storage_security);
157 EXPECT_CALL(mock_store, ContainsGroup(_))
158 .WillRepeatedly(Return(false));
159 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
160 .WillRepeatedly(Return(true));
161 bool is_loadable = wifi_service->IsLoadableFrom(&mock_store);
162 EXPECT_EQ(expectation, is_loadable);
163 bool is_loaded = wifi_service->Load(&mock_store);
164 EXPECT_EQ(expectation, is_loaded);
165
166 if (expectation != is_loadable || expectation != is_loaded) {
167 return false;
168 } else if (!expectation) {
169 return true;
170 } else {
171 return TestStorageSecurityIs(wifi_service, storage_security);
172 }
173 }
174};
175
mukesh agrawale1d90e92012-02-15 17:36:08 -0800176class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
177 public:
178 WiFiServiceUpdateFromEndpointsTest()
179 : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
180 kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
181 kGoodEndpointStrength(
182 WiFiService::SignalToStrength(kGoodEndpointSignal)),
183 service(MakeGenericService()),
184 adaptor(*GetAdaptor(service)) {
185 ok_endpoint = MakeEndpoint(
186 "", "00:00:00:00:01", kOkEndpointFrequency, kOkEndpointSignal);
187 good_endpoint = MakeEndpoint(
188 "", "00:00:00:00:02", kGoodEndpointFrequency, kGoodEndpointSignal);
189 bad_endpoint = MakeEndpoint(
190 "", "00:00:00:00:03", kBadEndpointFrequency, kBadEndpointSignal);
191 }
192
193 protected:
194 static const uint16 kOkEndpointFrequency = 2422;
195 static const uint16 kBadEndpointFrequency = 2417;
196 static const uint16 kGoodEndpointFrequency = 2412;
197 static const int16 kOkEndpointSignal = -50;
198 static const int16 kBadEndpointSignal = -75;
199 static const int16 kGoodEndpointSignal = -25;
200 // Can't be both static and const (because initialization requires a
201 // function call). So choose to be just const.
202 const uint8 kOkEndpointStrength;
203 const uint8 kBadEndpointStrength;
204 const uint8 kGoodEndpointStrength;
205 WiFiEndpointRefPtr ok_endpoint;
206 WiFiEndpointRefPtr bad_endpoint;
207 WiFiEndpointRefPtr good_endpoint;
208 WiFiServiceRefPtr service;
209 ServiceMockAdaptor &adaptor;
210};
211
212
Chris Masone34af2182011-08-22 11:59:36 -0700213TEST_F(WiFiServiceTest, StorageId) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800214 vector<uint8_t> ssid(5);
Chris Masone34af2182011-08-22 11:59:36 -0700215 ssid.push_back(0xff);
Chris Masone9d779932011-08-25 16:33:41 -0700216
Chris Masone2176a882011-09-14 22:29:15 -0700217 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
218 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800219 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700220 manager(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700221 wifi(),
Chris Masone9d779932011-08-25 16:33:41 -0700222 ssid,
223 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800224 flimflam::kSecurityNone,
225 false);
Chris Masone9d779932011-08-25 16:33:41 -0700226 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700227 for (uint i = 0; i < id.length(); ++i) {
228 EXPECT_TRUE(id[i] == '_' ||
229 isxdigit(id[i]) ||
230 (isalpha(id[i]) && islower(id[i])));
231 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700232 EXPECT_TRUE(wifi_service->TechnologyIs(Technology::kWifi));
Chris Masone34af2182011-08-22 11:59:36 -0700233 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
234 EXPECT_NE(mac_pos, string::npos);
235 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
236}
237
Gaurav Shahda6218a2011-11-11 12:09:33 -0800238// Make sure the passphrase is registered as a write only property
239// by reading and comparing all string properties returned on the store.
240TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
241 vector<uint8_t> ssid(5);
242 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
243 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800244 metrics(),
Gaurav Shahda6218a2011-11-11 12:09:33 -0800245 manager(),
246 wifi(),
247 ssid,
248 flimflam::kModeManaged,
249 flimflam::kSecurityWpa,
250 false);
251 ReadablePropertyConstIterator<string> it =
252 (wifi_service->store()).GetStringPropertiesIter();
253 for( ; !it.AtEnd(); it.Advance())
254 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
255}
256
Thieu Lef7709452011-11-15 01:13:19 +0000257// Make sure setting the passphrase via D-Bus Service.SetProperty validates
258// the passphrase.
259TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
260 // We only spot check two password cases here to make sure the
261 // SetProperty code path does validation. We're not going to exhaustively
262 // test for all types of passwords.
263 vector<uint8_t> ssid(5);
264 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
265 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800266 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000267 manager(),
268 wifi(),
269 ssid,
270 flimflam::kModeManaged,
271 flimflam::kSecurityWep,
272 false);
273 Error error;
274 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
275 flimflam::kPassphraseProperty, "0:abcde", &error));
276 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
277 flimflam::kPassphraseProperty, "invalid", &error));
278 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
279}
280
281TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
282 vector<uint8_t> ssid(5);
283 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
284 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800285 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000286 manager(),
287 wifi(),
288 ssid,
289 flimflam::kModeManaged,
290 flimflam::kSecurityNone,
291 false);
292 Error error;
293 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
294 flimflam::kPassphraseProperty, "invalid", &error));
295 EXPECT_EQ(Error::kNotSupported, error.type());
296}
297
mukesh agrawald835b202011-10-07 15:26:47 -0700298TEST_F(WiFiServiceTest, NonUTF8SSID) {
299 vector<uint8_t> ssid;
300
301 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
302 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
303 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800304 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700305 manager(),
306 wifi(),
307 ssid,
308 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800309 flimflam::kSecurityNone,
310 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700311 map<string, ::DBus::Variant> properties;
312 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
313 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
314}
315
Gaurav Shahda6218a2011-11-11 12:09:33 -0800316MATCHER(WPASecurityArgs, "") {
317 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
318 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
319}
320
Gaurav Shah10109f22011-11-11 20:16:22 -0800321MATCHER(EAPSecurityArgs, "") {
322 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
323 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath);
324}
325
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700326TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800327 vector<uint8_t> ssid(5);
mukesh agrawal6e277772011-09-29 15:04:23 -0700328 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
329 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800330 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700331 manager(),
332 wifi(),
333 ssid,
334 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800335 flimflam::kSecurityWpa,
336 false);
mukesh agrawal6e277772011-09-29 15:04:23 -0700337 EXPECT_CALL(*wifi(),
338 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700339 Error error;
340 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500341 wifi_service->Connect(NULL);
mukesh agrawal6e277772011-09-29 15:04:23 -0700342}
343
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700344TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800345 vector<uint8_t> ssid(5);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700346 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
347 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800348 metrics(),
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700349 manager(),
350 wifi(),
351 ssid,
352 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800353 flimflam::kSecurityRsn,
354 false);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700355 EXPECT_CALL(*wifi(),
356 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700357 Error error;
358 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500359 wifi_service->Connect(NULL);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700360}
361
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800362TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800363 vector<uint8_t> ssid(5);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800364 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
365 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800366 metrics(),
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800367 manager(),
368 wifi(),
369 ssid,
370 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800371 flimflam::kSecurityPsk,
372 false);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800373 EXPECT_CALL(*wifi(),
374 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700375 Error error;
376 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500377 wifi_service->Connect(NULL);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800378}
379
Gaurav Shah10109f22011-11-11 20:16:22 -0800380TEST_F(WiFiServiceTest, ConnectTask8021x) {
381 vector<uint8_t> ssid(5);
382 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
383 dispatcher(),
384 metrics(),
385 manager(),
386 wifi(),
387 ssid,
388 flimflam::kModeManaged,
389 flimflam::kSecurity8021x,
390 false);
391 Service::EapCredentials eap;
392 eap.identity = "identity";
Wade Guthrie005bd342012-05-02 09:37:07 -0700393 eap.password = "mumble";
Gaurav Shah10109f22011-11-11 20:16:22 -0800394 wifi_service->set_eap(eap);
395 EXPECT_CALL(*wifi(),
396 ConnectTo(wifi_service.get(), EAPSecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500397 wifi_service->Connect(NULL);
Gaurav Shah10109f22011-11-11 20:16:22 -0800398}
399
Thieu Lef4cbda92011-11-10 23:41:24 +0000400MATCHER(WEPSecurityArgsKeyIndex0, "") {
401 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
402 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
403 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
404 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
405 reader().get_uint32() == 0);
406}
407
408MATCHER(WEPSecurityArgsKeyIndex1, "") {
409 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
410 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
411 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
412 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
413 reader().get_uint32() == 1);
414}
415
416MATCHER(WEPSecurityArgsKeyIndex2, "") {
417 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
418 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
419 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
420 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
421 reader().get_uint32() == 2);
422}
423
424MATCHER(WEPSecurityArgsKeyIndex3, "") {
425 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
426 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
427 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
428 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
429 reader().get_uint32() == 3);
430}
431
432TEST_F(WiFiServiceTest, ConnectTaskWEP) {
433 vector<uint8_t> ssid(5);
434 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
435 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800436 metrics(),
Thieu Lef4cbda92011-11-10 23:41:24 +0000437 manager(),
438 wifi(),
439 ssid,
440 flimflam::kModeManaged,
441 flimflam::kSecurityWep,
442 false);
443 Error error;
444 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
445 EXPECT_CALL(*wifi(),
446 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500447 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000448
449 wifi_service->SetPassphrase("abcdefghijklm", &error);
450 EXPECT_CALL(*wifi(),
451 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500452 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000453
454 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
455 EXPECT_CALL(*wifi(),
456 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500457 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000458
459 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
460 EXPECT_CALL(*wifi(),
461 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500462 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000463
464 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
465 EXPECT_CALL(*wifi(),
466 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500467 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000468}
469
Gaurav Shah29d68882012-01-30 19:06:42 -0800470
471MATCHER(DynamicWEPArgs, "") {
472 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
473 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
474 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
475}
476
477// Dynamic WEP + 802.1x.
478TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
479 vector<uint8_t> ssid(5);
480 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
481 dispatcher(),
482 metrics(),
483 manager(),
484 wifi(),
485 ssid,
486 flimflam::kModeManaged,
487 flimflam::kSecurityWep,
488 false);
489
490 Service::EapCredentials eap;
491 eap.key_management = "IEEE8021X";
492 eap.identity = "something";
Wade Guthrie005bd342012-05-02 09:37:07 -0700493 eap.password = "mumble";
Gaurav Shah29d68882012-01-30 19:06:42 -0800494 wifi_service->set_eap(eap);
495 EXPECT_CALL(*wifi(),
496 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500497 wifi_service->Connect(NULL);
Gaurav Shah29d68882012-01-30 19:06:42 -0800498}
499
Paul Stewartd08f4432011-11-04 07:48:20 -0700500TEST_F(WiFiServiceTest, LoadHidden) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800501 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700502 ssid.push_back(0xff);
503
504 WiFiServiceRefPtr service = new WiFiService(control_interface(),
505 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800506 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700507 manager(),
508 wifi(),
509 ssid,
510 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800511 flimflam::kSecurityNone,
512 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700513 ASSERT_FALSE(service->hidden_ssid_);
514 NiceMock<MockStore> mock_store;
515 const string storage_id = service->GetStorageIdentifier();
516 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
517 .WillRepeatedly(Return(true));
518 EXPECT_CALL(mock_store, GetBool(_, _, _))
519 .WillRepeatedly(Return(false));
520 EXPECT_CALL(mock_store,
521 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
522 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
523 EXPECT_TRUE(service->Load(&mock_store));
524 EXPECT_TRUE(service->hidden_ssid_);
525}
526
527TEST_F(WiFiServiceSecurityTest, WPAMapping) {
528 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
529 flimflam::kSecurityPsk));
530 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
531 flimflam::kSecurityPsk));
532 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
533 flimflam::kSecurityPsk));
534 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
535 flimflam::kSecurityWep));
536 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
537 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800538 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
539 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700540}
541
542TEST_F(WiFiServiceSecurityTest, LoadMapping) {
543 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
544 flimflam::kSecurityPsk,
545 true));
546 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
547 flimflam::kSecurityRsn,
548 true));
549 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
550 flimflam::kSecurityWpa,
551 false));
552 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
553 flimflam::kSecurityPsk,
554 true));
555 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
556 flimflam::kSecurityWpa,
557 true));
558 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
559 flimflam::kSecurityRsn,
560 false));
561 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
562 flimflam::kSecurityWep,
563 true));
564 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
565 flimflam::kSecurityPsk,
566 false));
567}
568
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800569TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
570 vector<uint8_t> ssid(5);
571 ssid.push_back(0xff);
572
573 WiFiServiceRefPtr service = new WiFiService(control_interface(),
574 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800575 metrics(),
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800576 manager(),
577 wifi(),
578 ssid,
579 flimflam::kModeManaged,
580 flimflam::kSecurityPsk,
581 false);
582 NiceMock<MockStore> mock_store;
583 const string storage_id = service->GetStorageIdentifier();
584 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
585 .WillRepeatedly(Return(true));
586 EXPECT_CALL(mock_store, GetBool(_, _, _))
587 .WillRepeatedly(Return(false));
588 const string passphrase = "passphrase";
589 EXPECT_CALL(mock_store,
590 GetCryptedString(StrEq(storage_id),
591 WiFiService::kStoragePassphrase, _))
592 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
593 EXPECT_CALL(mock_store,
594 GetCryptedString(StrEq(storage_id),
595 StrNe(WiFiService::kStoragePassphrase), _))
596 .WillRepeatedly(Return(false));
597 EXPECT_TRUE(service->need_passphrase_);
598 EXPECT_TRUE(service->Load(&mock_store));
599 EXPECT_EQ(passphrase, service->passphrase_);
600 EXPECT_TRUE(service->connectable());
601 EXPECT_FALSE(service->need_passphrase_);
602 service->Unload();
603 EXPECT_EQ(string(""), service->passphrase_);
604 EXPECT_FALSE(service->connectable());
605 EXPECT_TRUE(service->need_passphrase_);
606}
607
Paul Stewart66c86002012-01-30 18:00:52 -0800608TEST_F(WiFiServiceTest, UnloadAndClearCacheWep) {
609 vector<uint8_t> ssid(1, 'a');
610 WiFiServiceRefPtr service = new WiFiService(control_interface(),
611 dispatcher(),
612 metrics(),
613 manager(),
614 wifi(),
615 ssid,
616 flimflam::kModeManaged,
617 flimflam::kSecurityWep,
618 false);
619 // A WEP network does not incur cached credentials.
620 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(0);
621 service->Unload();
622}
623
624TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
625 vector<uint8_t> ssid(1, 'a');
626 WiFiServiceRefPtr service = new WiFiService(control_interface(),
627 dispatcher(),
628 metrics(),
629 manager(),
630 wifi(),
631 ssid,
632 flimflam::kModeManaged,
633 flimflam::kSecurity8021x,
634 false);
635 // An 802.1x network should clear its cached credentials.
636 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(1);
637 service->Unload();
638}
639
Paul Stewart0756db92012-01-27 08:34:47 -0800640TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewarta41e38d2011-11-11 07:47:29 -0800641 vector<uint8_t> ssid(5);
642 ssid.push_back(0xff);
643
644 WiFiServiceRefPtr service = new WiFiService(control_interface(),
645 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800646 metrics(),
Paul Stewarta41e38d2011-11-11 07:47:29 -0800647 manager(),
648 wifi(),
649 ssid,
650 flimflam::kModeManaged,
651 flimflam::kSecurityNone,
652 false);
653 const string storage_id = service->GetStorageIdentifier();
654 string address;
655 string mode;
656 string security;
657 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
658 &security));
659 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
660 EXPECT_EQ(flimflam::kModeManaged, mode);
661 EXPECT_EQ(flimflam::kSecurityNone, security);
662}
663
Paul Stewart0756db92012-01-27 08:34:47 -0800664TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
665 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
666 // which needs to be dealt with specially in the parser.
667 vector<uint8_t> ssid(5);
668 ssid.push_back(0xff);
669
670 WiFiServiceRefPtr service = new WiFiService(control_interface(),
671 dispatcher(),
672 metrics(),
673 manager(),
674 wifi(),
675 ssid,
676 flimflam::kModeManaged,
677 flimflam::kSecurity8021x,
678 false);
679 const string storage_id = service->GetStorageIdentifier();
680 string address;
681 string mode;
682 string security;
683 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
684 &security));
685 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
686 EXPECT_EQ(flimflam::kModeManaged, mode);
687 EXPECT_EQ(flimflam::kSecurity8021x, security);
688}
689
mukesh agrawal29c13a12011-11-24 00:09:19 +0000690TEST_F(WiFiServiceTest, Connectable) {
691 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800692 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000693
694 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -0800695 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000696
697 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800698 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000699
700 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800701 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000702
703 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800704 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000705
706 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -0800707 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
708 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
709 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000710
711 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800712 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
713
714 Service::EapCredentials eap;
715 // Empty EAP credentials should not make a 802.1x network connectable.
716 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
717
718 eap.identity = "something";
719 // If client certificate is being used, a private key must exist.
720 eap.client_cert = "some client cert";
721 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
722 eap.private_key = "some private key";
723 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
724
725 // Identity is always required.
726 eap.identity.clear();
727 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
728
729 eap.identity = "something";
730 // For non EAP-TLS types, a password is required.
731 eap.eap = "Non-TLS";
732 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
733 eap.password = "some password";
734 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -0800735 // Dynamic WEP + 802.1X should be connectable under the same conditions.
736 eap.key_management = "IEEE8021X";
737 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000738}
739
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000740TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800741 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000742 vector<uint8_t> ssid(1, 'a');
743 WiFiServiceRefPtr service = new WiFiService(control_interface(),
744 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800745 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000746 manager(),
747 wifi(),
748 ssid,
749 flimflam::kModeManaged,
750 flimflam::kSecurityNone,
751 false);
752 EXPECT_CALL(*wifi(), IsIdle())
753 .WillRepeatedly(Return(true));
754 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800755 EXPECT_FALSE(service->IsAutoConnectable(&reason));
756 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000757
mukesh agrawalbf14e942012-03-02 14:36:34 -0800758 reason = "";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800759 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000760 service->AddEndpoint(endpoint);
761 EXPECT_CALL(*wifi(), IsIdle())
762 .WillRepeatedly(Return(true));
763 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800764 EXPECT_TRUE(service->IsAutoConnectable(&reason));
765 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000766
767 // WiFi only supports connecting to one Service at a time. So, to
768 // avoid disrupting connectivity, we only allow auto-connection to
769 // a WiFiService when the corresponding WiFi is idle.
770 EXPECT_CALL(*wifi(), IsIdle())
771 .WillRepeatedly(Return(false));
772 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800773 EXPECT_FALSE(service->IsAutoConnectable(&reason));
774 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000775}
776
777TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800778 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000779 vector<uint8_t> ssid(1, 'a');
780 WiFiServiceRefPtr service = new WiFiService(control_interface(),
781 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800782 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000783 manager(),
784 wifi(),
785 ssid,
786 flimflam::kModeManaged,
787 flimflam::kSecurityNone,
788 false);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800789 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000790 EXPECT_CALL(*wifi(), ConnectTo(_, _))
791 .Times(0);
792 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500793 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000794
mukesh agrawale1d90e92012-02-15 17:36:08 -0800795 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000796 service->AddEndpoint(endpoint);
797 EXPECT_CALL(*wifi(), IsIdle())
798 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -0800799 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000800 EXPECT_CALL(*wifi(), ConnectTo(_, _));
801 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500802 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -0800803
804 Error error;
805 service->Disconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500806 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -0800807 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000808}
809
Gaurav Shah10109f22011-11-11 20:16:22 -0800810TEST_F(WiFiServiceTest, Populate8021x) {
811 vector<uint8_t> ssid(1, 'a');
812 WiFiServiceRefPtr service = new WiFiService(control_interface(),
813 dispatcher(),
814 metrics(),
815 manager(),
816 wifi(),
817 ssid,
818 flimflam::kModeManaged,
819 flimflam::kSecurityNone,
820 false);
821 Service::EapCredentials eap;
822 eap.identity = "testidentity";
Paul Stewart20550982012-04-16 12:16:11 -0700823 eap.pin = "xxxx";
Gaurav Shah10109f22011-11-11 20:16:22 -0800824 service->set_eap(eap);
825 map<string, ::DBus::Variant> params;
826 service->Populate8021xProperties(&params);
827 // Test that only non-empty 802.1x properties are populated.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700828 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapIdentity));
829 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
830 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
831
Paul Stewart20550982012-04-16 12:16:11 -0700832 // Test that CA path is set by default.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700833 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
834
Paul Stewart20550982012-04-16 12:16:11 -0700835 // Test that hardware-backed security arguments are not set.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700836 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
837 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
838 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
Paul Stewart20550982012-04-16 12:16:11 -0700839}
840
841TEST_F(WiFiServiceTest, Populate8021xNoSystemCAs) {
842 vector<uint8_t> ssid(1, 'a');
843 WiFiServiceRefPtr service = new WiFiService(control_interface(),
844 dispatcher(),
845 metrics(),
846 manager(),
847 wifi(),
848 ssid,
849 flimflam::kModeManaged,
850 flimflam::kSecurityNone,
851 false);
852 Service::EapCredentials eap;
853 eap.identity = "testidentity";
854 eap.use_system_cas = false;
855 service->set_eap(eap);
856 map<string, ::DBus::Variant> params;
857 service->Populate8021xProperties(&params);
858 // Test that CA path is not set if use_system_cas is explicitly false.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700859 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
Paul Stewart20550982012-04-16 12:16:11 -0700860}
861
862TEST_F(WiFiServiceTest, Populate8021xUsingHardwareAuth) {
863 vector<uint8_t> ssid(1, 'a');
864 WiFiServiceRefPtr service = new WiFiService(control_interface(),
865 dispatcher(),
866 metrics(),
867 manager(),
868 wifi(),
869 ssid,
870 flimflam::kModeManaged,
871 flimflam::kSecurityNone,
872 false);
873 Service::EapCredentials eap;
874 eap.identity = "testidentity";
875 eap.key_id = "key_id";
876 eap.pin = "xxxx";
877 service->set_eap(eap);
878 map<string, ::DBus::Variant> params;
879 service->Populate8021xProperties(&params);
880 // Test that EAP engine parameters set if key_id is set.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700881 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
882 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
883 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
884 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
885}
886
887TEST_F(WiFiServiceTest, Populate8021xNSS) {
888 vector<uint8_t> ssid(1, 'a');
889 WiFiServiceRefPtr service = new WiFiService(control_interface(),
890 dispatcher(),
891 metrics(),
892 manager(),
893 wifi(),
894 ssid,
895 flimflam::kModeManaged,
896 flimflam::kSecurityNone,
897 false);
898 Service::EapCredentials eap;
899 eap.ca_cert_nss = "nss_nickname";
900 service->set_eap(eap);
901 MockNSS nss;
902 service->nss_ = &nss;
903
904 const string kNSSCertfile("/tmp/nss-cert");
905 FilePath nss_cert(kNSSCertfile);
906 vector<char> ssid_in_chars(ssid.begin(), ssid.end());
907 EXPECT_CALL(nss, GetDERCertfile(eap.ca_cert_nss, ssid_in_chars))
908 .WillOnce(Return(nss_cert));
909
910 map<string, ::DBus::Variant> params;
911 service->Populate8021xProperties(&params);
912 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
913 if (ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert)) {
914 EXPECT_EQ(kNSSCertfile, params[wpa_supplicant::kNetworkPropertyEapCaCert]
915 .reader().get_string());
916 }
Gaurav Shah10109f22011-11-11 20:16:22 -0800917}
918
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800919TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
920 vector<uint8_t> ssid(1, 'a');
921 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
922 dispatcher(),
923 metrics(),
924 manager(),
925 wifi(),
926 ssid,
927 flimflam::kModeManaged,
928 flimflam::kSecurityWep,
929 false);
930
931 EXPECT_EQ("", wifi_service->passphrase_);
932
933 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800934 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800935 wifi_service->mutable_store(),
936 flimflam::kPassphraseProperty,
937 DBusAdaptor::StringToVariant("0:abcde"),
938 &error));
939 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
940
941 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
942 flimflam::kPassphraseProperty,
943 &error));
944 EXPECT_EQ("", wifi_service->passphrase_);
945}
946
mukesh agrawale1d90e92012-02-15 17:36:08 -0800947TEST_F(WiFiServiceTest, SignalToStrength) {
948 // Verify that our mapping is sane, in the sense that it preserves ordering.
949 // We break the test into two domains, because we assume that positive
950 // values aren't actually in dBm.
951 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
952 int16 current_mapped = WiFiService::SignalToStrength(i);
953 int16 next_mapped = WiFiService::SignalToStrength(i+1);
954 EXPECT_LE(current_mapped, next_mapped)
955 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -0800956 EXPECT_GE(current_mapped, Service::kStrengthMin);
957 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800958 }
959 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
960 int16 current_mapped = WiFiService::SignalToStrength(i);
961 int16 next_mapped = WiFiService::SignalToStrength(i+1);
962 EXPECT_LE(current_mapped, next_mapped)
963 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -0800964 EXPECT_GE(current_mapped, Service::kStrengthMin);
965 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800966 }
967}
968
969TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
970 // If the chosen signal values don't map to distinct strength
971 // values, then we can't expect our other tests to pass. So verify
972 // their distinctness.
973 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
974 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
975 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
976}
977
978TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
979 // Initial endpoint updates values.
980 EXPECT_CALL(adaptor, EmitUint16Changed(
981 flimflam::kWifiFrequency, kOkEndpointFrequency));
982 EXPECT_CALL(adaptor,EmitUint8Changed(
983 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
984 service->AddEndpoint(ok_endpoint);
985 Mock::VerifyAndClearExpectations(&adaptor);
986
987 // Endpoint with stronger signal updates values.
988 EXPECT_CALL(adaptor, EmitUint16Changed(
989 flimflam::kWifiFrequency, kGoodEndpointFrequency));
990 EXPECT_CALL(adaptor, EmitUint8Changed(
991 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
992 service->AddEndpoint(good_endpoint);
993 Mock::VerifyAndClearExpectations(&adaptor);
994
995 // Endpoint with lower signal does not change values.
996 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
997 EXPECT_CALL(adaptor,
998 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
999 service->AddEndpoint(bad_endpoint);
1000 Mock::VerifyAndClearExpectations(&adaptor);
1001
1002 // Removing non-optimal endpoint does not change values.
1003 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1004 EXPECT_CALL(adaptor,
1005 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1006 service->RemoveEndpoint(bad_endpoint);
1007 Mock::VerifyAndClearExpectations(&adaptor);
1008
1009 // Removing optimal endpoint updates values.
1010 EXPECT_CALL(adaptor, EmitUint16Changed(
1011 flimflam::kWifiFrequency, kOkEndpointFrequency));
1012 EXPECT_CALL(adaptor, EmitUint8Changed(
1013 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1014 service->RemoveEndpoint(good_endpoint);
1015 Mock::VerifyAndClearExpectations(&adaptor);
1016
1017 // Removing last endpoint updates values (and doesn't crash).
1018 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
1019 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1020 service->RemoveEndpoint(ok_endpoint);
1021 Mock::VerifyAndClearExpectations(&adaptor);
1022}
1023
1024TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1025 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1026 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1027 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1028 service->AddEndpoint(bad_endpoint);
1029 service->AddEndpoint(ok_endpoint);
1030 Mock::VerifyAndClearExpectations(&adaptor);
1031
1032 // Setting current endpoint forces adoption of its values, even if it
1033 // doesn't have the highest signal.
1034 EXPECT_CALL(adaptor, EmitUint16Changed(
1035 flimflam::kWifiFrequency, kBadEndpointFrequency));
1036 EXPECT_CALL(adaptor, EmitUint8Changed(
1037 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
1038 service->NotifyCurrentEndpoint(bad_endpoint);
1039 Mock::VerifyAndClearExpectations(&adaptor);
1040
1041 // Adding a better endpoint doesn't matter, when current endpoint is set.
1042 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1043 EXPECT_CALL(adaptor,
1044 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1045 service->AddEndpoint(good_endpoint);
1046 Mock::VerifyAndClearExpectations(&adaptor);
1047
1048 // Removing a better endpoint doesn't matter, when current endpoint is set.
1049 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1050 EXPECT_CALL(adaptor,
1051 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1052 service->RemoveEndpoint(good_endpoint);
1053 Mock::VerifyAndClearExpectations(&adaptor);
1054
1055 // Removing the current endpoint is safe and sane.
1056 EXPECT_CALL(adaptor, EmitUint16Changed(
1057 flimflam::kWifiFrequency, kOkEndpointFrequency));
1058 EXPECT_CALL(adaptor, EmitUint8Changed(
1059 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1060 service->RemoveEndpoint(bad_endpoint);
1061 Mock::VerifyAndClearExpectations(&adaptor);
1062
1063 // Clearing the current endpoint (without removing it) is also safe and sane.
1064 service->NotifyCurrentEndpoint(ok_endpoint);
1065 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1066 EXPECT_CALL(adaptor,
1067 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1068 service->NotifyCurrentEndpoint(NULL);
1069 Mock::VerifyAndClearExpectations(&adaptor);
1070}
1071
1072TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1073 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1074 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1075 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1076 service->AddEndpoint(ok_endpoint);
1077 service->AddEndpoint(good_endpoint);
1078 Mock::VerifyAndClearExpectations(&adaptor);
1079
1080 // Updating sub-optimal Endpoint doesn't update Service.
1081 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1082 EXPECT_CALL(adaptor,
1083 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1084 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
1085 service->NotifyEndpointUpdated(*ok_endpoint);
1086 Mock::VerifyAndClearExpectations(&adaptor);
1087
1088 // Updating optimal Endpoint updates appropriate Service property.
1089 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1090 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1091 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
1092 service->NotifyEndpointUpdated(*good_endpoint);
1093 Mock::VerifyAndClearExpectations(&adaptor);
1094
1095 // Change in optimal Endpoint updates Service properties.
1096 EXPECT_CALL(adaptor, EmitUint16Changed(
1097 flimflam::kWifiFrequency, kOkEndpointFrequency));
1098 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1099 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
1100 service->NotifyEndpointUpdated(*ok_endpoint);
1101 Mock::VerifyAndClearExpectations(&adaptor);
1102}
1103
Chris Masone34af2182011-08-22 11:59:36 -07001104} // namespace shill