blob: b6190ddf395b3835821dcdec561b62f25a732294 [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()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500339 wifi_service->Connect(NULL);
mukesh agrawal6e277772011-09-29 15:04:23 -0700340}
341
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700342TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800343 vector<uint8_t> ssid(5);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700344 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
345 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800346 metrics(),
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700347 manager(),
348 wifi(),
349 ssid,
350 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800351 flimflam::kSecurityRsn,
352 false);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700353 EXPECT_CALL(*wifi(),
354 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500355 wifi_service->Connect(NULL);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700356}
357
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800358TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800359 vector<uint8_t> ssid(5);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800360 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
361 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800362 metrics(),
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800363 manager(),
364 wifi(),
365 ssid,
366 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800367 flimflam::kSecurityPsk,
368 false);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800369 EXPECT_CALL(*wifi(),
370 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500371 wifi_service->Connect(NULL);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800372}
373
Gaurav Shah10109f22011-11-11 20:16:22 -0800374TEST_F(WiFiServiceTest, ConnectTask8021x) {
375 vector<uint8_t> ssid(5);
376 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
377 dispatcher(),
378 metrics(),
379 manager(),
380 wifi(),
381 ssid,
382 flimflam::kModeManaged,
383 flimflam::kSecurity8021x,
384 false);
385 Service::EapCredentials eap;
386 eap.identity = "identity";
387 wifi_service->set_eap(eap);
388 EXPECT_CALL(*wifi(),
389 ConnectTo(wifi_service.get(), EAPSecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500390 wifi_service->Connect(NULL);
Gaurav Shah10109f22011-11-11 20:16:22 -0800391}
392
Thieu Lef4cbda92011-11-10 23:41:24 +0000393MATCHER(WEPSecurityArgsKeyIndex0, "") {
394 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
395 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
396 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
397 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
398 reader().get_uint32() == 0);
399}
400
401MATCHER(WEPSecurityArgsKeyIndex1, "") {
402 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
403 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
404 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
405 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
406 reader().get_uint32() == 1);
407}
408
409MATCHER(WEPSecurityArgsKeyIndex2, "") {
410 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
411 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
412 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
413 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
414 reader().get_uint32() == 2);
415}
416
417MATCHER(WEPSecurityArgsKeyIndex3, "") {
418 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
419 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
420 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
421 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
422 reader().get_uint32() == 3);
423}
424
425TEST_F(WiFiServiceTest, ConnectTaskWEP) {
426 vector<uint8_t> ssid(5);
427 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
428 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800429 metrics(),
Thieu Lef4cbda92011-11-10 23:41:24 +0000430 manager(),
431 wifi(),
432 ssid,
433 flimflam::kModeManaged,
434 flimflam::kSecurityWep,
435 false);
436 Error error;
437 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
438 EXPECT_CALL(*wifi(),
439 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500440 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000441
442 wifi_service->SetPassphrase("abcdefghijklm", &error);
443 EXPECT_CALL(*wifi(),
444 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500445 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000446
447 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
448 EXPECT_CALL(*wifi(),
449 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500450 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000451
452 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
453 EXPECT_CALL(*wifi(),
454 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500455 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000456
457 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
458 EXPECT_CALL(*wifi(),
459 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500460 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000461}
462
Gaurav Shah29d68882012-01-30 19:06:42 -0800463
464MATCHER(DynamicWEPArgs, "") {
465 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
466 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
467 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
468}
469
470// Dynamic WEP + 802.1x.
471TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
472 vector<uint8_t> ssid(5);
473 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
474 dispatcher(),
475 metrics(),
476 manager(),
477 wifi(),
478 ssid,
479 flimflam::kModeManaged,
480 flimflam::kSecurityWep,
481 false);
482
483 Service::EapCredentials eap;
484 eap.key_management = "IEEE8021X";
485 eap.identity = "something";
486 wifi_service->set_eap(eap);
487 EXPECT_CALL(*wifi(),
488 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500489 wifi_service->Connect(NULL);
Gaurav Shah29d68882012-01-30 19:06:42 -0800490}
491
Paul Stewartd08f4432011-11-04 07:48:20 -0700492TEST_F(WiFiServiceTest, LoadHidden) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800493 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700494 ssid.push_back(0xff);
495
496 WiFiServiceRefPtr service = new WiFiService(control_interface(),
497 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800498 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700499 manager(),
500 wifi(),
501 ssid,
502 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800503 flimflam::kSecurityNone,
504 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700505 ASSERT_FALSE(service->hidden_ssid_);
506 NiceMock<MockStore> mock_store;
507 const string storage_id = service->GetStorageIdentifier();
508 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
509 .WillRepeatedly(Return(true));
510 EXPECT_CALL(mock_store, GetBool(_, _, _))
511 .WillRepeatedly(Return(false));
512 EXPECT_CALL(mock_store,
513 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
514 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
515 EXPECT_TRUE(service->Load(&mock_store));
516 EXPECT_TRUE(service->hidden_ssid_);
517}
518
519TEST_F(WiFiServiceSecurityTest, WPAMapping) {
520 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
521 flimflam::kSecurityPsk));
522 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
523 flimflam::kSecurityPsk));
524 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
525 flimflam::kSecurityPsk));
526 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
527 flimflam::kSecurityWep));
528 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
529 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800530 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
531 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700532}
533
534TEST_F(WiFiServiceSecurityTest, LoadMapping) {
535 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
536 flimflam::kSecurityPsk,
537 true));
538 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
539 flimflam::kSecurityRsn,
540 true));
541 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
542 flimflam::kSecurityWpa,
543 false));
544 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
545 flimflam::kSecurityPsk,
546 true));
547 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
548 flimflam::kSecurityWpa,
549 true));
550 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
551 flimflam::kSecurityRsn,
552 false));
553 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
554 flimflam::kSecurityWep,
555 true));
556 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
557 flimflam::kSecurityPsk,
558 false));
559}
560
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800561TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
562 vector<uint8_t> ssid(5);
563 ssid.push_back(0xff);
564
565 WiFiServiceRefPtr service = new WiFiService(control_interface(),
566 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800567 metrics(),
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800568 manager(),
569 wifi(),
570 ssid,
571 flimflam::kModeManaged,
572 flimflam::kSecurityPsk,
573 false);
574 NiceMock<MockStore> mock_store;
575 const string storage_id = service->GetStorageIdentifier();
576 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
577 .WillRepeatedly(Return(true));
578 EXPECT_CALL(mock_store, GetBool(_, _, _))
579 .WillRepeatedly(Return(false));
580 const string passphrase = "passphrase";
581 EXPECT_CALL(mock_store,
582 GetCryptedString(StrEq(storage_id),
583 WiFiService::kStoragePassphrase, _))
584 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
585 EXPECT_CALL(mock_store,
586 GetCryptedString(StrEq(storage_id),
587 StrNe(WiFiService::kStoragePassphrase), _))
588 .WillRepeatedly(Return(false));
589 EXPECT_TRUE(service->need_passphrase_);
590 EXPECT_TRUE(service->Load(&mock_store));
591 EXPECT_EQ(passphrase, service->passphrase_);
592 EXPECT_TRUE(service->connectable());
593 EXPECT_FALSE(service->need_passphrase_);
594 service->Unload();
595 EXPECT_EQ(string(""), service->passphrase_);
596 EXPECT_FALSE(service->connectable());
597 EXPECT_TRUE(service->need_passphrase_);
598}
599
Paul Stewart66c86002012-01-30 18:00:52 -0800600TEST_F(WiFiServiceTest, UnloadAndClearCacheWep) {
601 vector<uint8_t> ssid(1, 'a');
602 WiFiServiceRefPtr service = new WiFiService(control_interface(),
603 dispatcher(),
604 metrics(),
605 manager(),
606 wifi(),
607 ssid,
608 flimflam::kModeManaged,
609 flimflam::kSecurityWep,
610 false);
611 // A WEP network does not incur cached credentials.
612 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(0);
613 service->Unload();
614}
615
616TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
617 vector<uint8_t> ssid(1, 'a');
618 WiFiServiceRefPtr service = new WiFiService(control_interface(),
619 dispatcher(),
620 metrics(),
621 manager(),
622 wifi(),
623 ssid,
624 flimflam::kModeManaged,
625 flimflam::kSecurity8021x,
626 false);
627 // An 802.1x network should clear its cached credentials.
628 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(1);
629 service->Unload();
630}
631
Paul Stewart0756db92012-01-27 08:34:47 -0800632TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewarta41e38d2011-11-11 07:47:29 -0800633 vector<uint8_t> ssid(5);
634 ssid.push_back(0xff);
635
636 WiFiServiceRefPtr service = new WiFiService(control_interface(),
637 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800638 metrics(),
Paul Stewarta41e38d2011-11-11 07:47:29 -0800639 manager(),
640 wifi(),
641 ssid,
642 flimflam::kModeManaged,
643 flimflam::kSecurityNone,
644 false);
645 const string storage_id = service->GetStorageIdentifier();
646 string address;
647 string mode;
648 string security;
649 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
650 &security));
651 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
652 EXPECT_EQ(flimflam::kModeManaged, mode);
653 EXPECT_EQ(flimflam::kSecurityNone, security);
654}
655
Paul Stewart0756db92012-01-27 08:34:47 -0800656TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
657 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
658 // which needs to be dealt with specially in the parser.
659 vector<uint8_t> ssid(5);
660 ssid.push_back(0xff);
661
662 WiFiServiceRefPtr service = new WiFiService(control_interface(),
663 dispatcher(),
664 metrics(),
665 manager(),
666 wifi(),
667 ssid,
668 flimflam::kModeManaged,
669 flimflam::kSecurity8021x,
670 false);
671 const string storage_id = service->GetStorageIdentifier();
672 string address;
673 string mode;
674 string security;
675 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
676 &security));
677 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
678 EXPECT_EQ(flimflam::kModeManaged, mode);
679 EXPECT_EQ(flimflam::kSecurity8021x, security);
680}
681
mukesh agrawal29c13a12011-11-24 00:09:19 +0000682TEST_F(WiFiServiceTest, Connectable) {
683 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800684 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000685
686 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -0800687 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000688
689 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800690 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000691
692 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800693 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000694
695 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800696 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000697
698 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -0800699 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
700 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
701 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000702
703 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800704 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
705
706 Service::EapCredentials eap;
707 // Empty EAP credentials should not make a 802.1x network connectable.
708 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
709
710 eap.identity = "something";
711 // If client certificate is being used, a private key must exist.
712 eap.client_cert = "some client cert";
713 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
714 eap.private_key = "some private key";
715 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
716
717 // Identity is always required.
718 eap.identity.clear();
719 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
720
721 eap.identity = "something";
722 // For non EAP-TLS types, a password is required.
723 eap.eap = "Non-TLS";
724 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
725 eap.password = "some password";
726 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -0800727 // Dynamic WEP + 802.1X should be connectable under the same conditions.
728 eap.key_management = "IEEE8021X";
729 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000730}
731
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000732TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800733 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000734 vector<uint8_t> ssid(1, 'a');
735 WiFiServiceRefPtr service = new WiFiService(control_interface(),
736 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800737 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000738 manager(),
739 wifi(),
740 ssid,
741 flimflam::kModeManaged,
742 flimflam::kSecurityNone,
743 false);
744 EXPECT_CALL(*wifi(), IsIdle())
745 .WillRepeatedly(Return(true));
746 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800747 EXPECT_FALSE(service->IsAutoConnectable(&reason));
748 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000749
mukesh agrawalbf14e942012-03-02 14:36:34 -0800750 reason = "";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800751 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000752 service->AddEndpoint(endpoint);
753 EXPECT_CALL(*wifi(), IsIdle())
754 .WillRepeatedly(Return(true));
755 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800756 EXPECT_TRUE(service->IsAutoConnectable(&reason));
757 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000758
759 // WiFi only supports connecting to one Service at a time. So, to
760 // avoid disrupting connectivity, we only allow auto-connection to
761 // a WiFiService when the corresponding WiFi is idle.
762 EXPECT_CALL(*wifi(), IsIdle())
763 .WillRepeatedly(Return(false));
764 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800765 EXPECT_FALSE(service->IsAutoConnectable(&reason));
766 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000767}
768
769TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800770 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000771 vector<uint8_t> ssid(1, 'a');
772 WiFiServiceRefPtr service = new WiFiService(control_interface(),
773 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800774 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000775 manager(),
776 wifi(),
777 ssid,
778 flimflam::kModeManaged,
779 flimflam::kSecurityNone,
780 false);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800781 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000782 EXPECT_CALL(*wifi(), ConnectTo(_, _))
783 .Times(0);
784 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500785 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000786
mukesh agrawale1d90e92012-02-15 17:36:08 -0800787 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000788 service->AddEndpoint(endpoint);
789 EXPECT_CALL(*wifi(), IsIdle())
790 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -0800791 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000792 EXPECT_CALL(*wifi(), ConnectTo(_, _));
793 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500794 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -0800795
796 Error error;
797 service->Disconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500798 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -0800799 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000800}
801
Gaurav Shah10109f22011-11-11 20:16:22 -0800802TEST_F(WiFiServiceTest, Populate8021x) {
803 vector<uint8_t> ssid(1, 'a');
804 WiFiServiceRefPtr service = new WiFiService(control_interface(),
805 dispatcher(),
806 metrics(),
807 manager(),
808 wifi(),
809 ssid,
810 flimflam::kModeManaged,
811 flimflam::kSecurityNone,
812 false);
813 Service::EapCredentials eap;
814 eap.identity = "testidentity";
Paul Stewart20550982012-04-16 12:16:11 -0700815 eap.pin = "xxxx";
Gaurav Shah10109f22011-11-11 20:16:22 -0800816 service->set_eap(eap);
817 map<string, ::DBus::Variant> params;
818 service->Populate8021xProperties(&params);
819 // Test that only non-empty 802.1x properties are populated.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700820 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapIdentity));
821 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
822 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
823
Paul Stewart20550982012-04-16 12:16:11 -0700824 // Test that CA path is set by default.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700825 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
826
Paul Stewart20550982012-04-16 12:16:11 -0700827 // Test that hardware-backed security arguments are not set.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700828 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
829 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
830 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
Paul Stewart20550982012-04-16 12:16:11 -0700831}
832
833TEST_F(WiFiServiceTest, Populate8021xNoSystemCAs) {
834 vector<uint8_t> ssid(1, 'a');
835 WiFiServiceRefPtr service = new WiFiService(control_interface(),
836 dispatcher(),
837 metrics(),
838 manager(),
839 wifi(),
840 ssid,
841 flimflam::kModeManaged,
842 flimflam::kSecurityNone,
843 false);
844 Service::EapCredentials eap;
845 eap.identity = "testidentity";
846 eap.use_system_cas = false;
847 service->set_eap(eap);
848 map<string, ::DBus::Variant> params;
849 service->Populate8021xProperties(&params);
850 // Test that CA path is not set if use_system_cas is explicitly false.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700851 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
Paul Stewart20550982012-04-16 12:16:11 -0700852}
853
854TEST_F(WiFiServiceTest, Populate8021xUsingHardwareAuth) {
855 vector<uint8_t> ssid(1, 'a');
856 WiFiServiceRefPtr service = new WiFiService(control_interface(),
857 dispatcher(),
858 metrics(),
859 manager(),
860 wifi(),
861 ssid,
862 flimflam::kModeManaged,
863 flimflam::kSecurityNone,
864 false);
865 Service::EapCredentials eap;
866 eap.identity = "testidentity";
867 eap.key_id = "key_id";
868 eap.pin = "xxxx";
869 service->set_eap(eap);
870 map<string, ::DBus::Variant> params;
871 service->Populate8021xProperties(&params);
872 // Test that EAP engine parameters set if key_id is set.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700873 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
874 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
875 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
876 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
877}
878
879TEST_F(WiFiServiceTest, Populate8021xNSS) {
880 vector<uint8_t> ssid(1, 'a');
881 WiFiServiceRefPtr service = new WiFiService(control_interface(),
882 dispatcher(),
883 metrics(),
884 manager(),
885 wifi(),
886 ssid,
887 flimflam::kModeManaged,
888 flimflam::kSecurityNone,
889 false);
890 Service::EapCredentials eap;
891 eap.ca_cert_nss = "nss_nickname";
892 service->set_eap(eap);
893 MockNSS nss;
894 service->nss_ = &nss;
895
896 const string kNSSCertfile("/tmp/nss-cert");
897 FilePath nss_cert(kNSSCertfile);
898 vector<char> ssid_in_chars(ssid.begin(), ssid.end());
899 EXPECT_CALL(nss, GetDERCertfile(eap.ca_cert_nss, ssid_in_chars))
900 .WillOnce(Return(nss_cert));
901
902 map<string, ::DBus::Variant> params;
903 service->Populate8021xProperties(&params);
904 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
905 if (ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert)) {
906 EXPECT_EQ(kNSSCertfile, params[wpa_supplicant::kNetworkPropertyEapCaCert]
907 .reader().get_string());
908 }
Gaurav Shah10109f22011-11-11 20:16:22 -0800909}
910
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800911TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
912 vector<uint8_t> ssid(1, 'a');
913 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
914 dispatcher(),
915 metrics(),
916 manager(),
917 wifi(),
918 ssid,
919 flimflam::kModeManaged,
920 flimflam::kSecurityWep,
921 false);
922
923 EXPECT_EQ("", wifi_service->passphrase_);
924
925 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800926 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800927 wifi_service->mutable_store(),
928 flimflam::kPassphraseProperty,
929 DBusAdaptor::StringToVariant("0:abcde"),
930 &error));
931 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
932
933 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
934 flimflam::kPassphraseProperty,
935 &error));
936 EXPECT_EQ("", wifi_service->passphrase_);
937}
938
mukesh agrawale1d90e92012-02-15 17:36:08 -0800939TEST_F(WiFiServiceTest, SignalToStrength) {
940 // Verify that our mapping is sane, in the sense that it preserves ordering.
941 // We break the test into two domains, because we assume that positive
942 // values aren't actually in dBm.
943 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
944 int16 current_mapped = WiFiService::SignalToStrength(i);
945 int16 next_mapped = WiFiService::SignalToStrength(i+1);
946 EXPECT_LE(current_mapped, next_mapped)
947 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -0800948 EXPECT_GE(current_mapped, Service::kStrengthMin);
949 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800950 }
951 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++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}
960
961TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
962 // If the chosen signal values don't map to distinct strength
963 // values, then we can't expect our other tests to pass. So verify
964 // their distinctness.
965 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
966 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
967 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
968}
969
970TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
971 // Initial endpoint updates values.
972 EXPECT_CALL(adaptor, EmitUint16Changed(
973 flimflam::kWifiFrequency, kOkEndpointFrequency));
974 EXPECT_CALL(adaptor,EmitUint8Changed(
975 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
976 service->AddEndpoint(ok_endpoint);
977 Mock::VerifyAndClearExpectations(&adaptor);
978
979 // Endpoint with stronger signal updates values.
980 EXPECT_CALL(adaptor, EmitUint16Changed(
981 flimflam::kWifiFrequency, kGoodEndpointFrequency));
982 EXPECT_CALL(adaptor, EmitUint8Changed(
983 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
984 service->AddEndpoint(good_endpoint);
985 Mock::VerifyAndClearExpectations(&adaptor);
986
987 // Endpoint with lower signal does not change values.
988 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
989 EXPECT_CALL(adaptor,
990 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
991 service->AddEndpoint(bad_endpoint);
992 Mock::VerifyAndClearExpectations(&adaptor);
993
994 // Removing non-optimal endpoint does not change values.
995 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
996 EXPECT_CALL(adaptor,
997 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
998 service->RemoveEndpoint(bad_endpoint);
999 Mock::VerifyAndClearExpectations(&adaptor);
1000
1001 // Removing optimal endpoint updates values.
1002 EXPECT_CALL(adaptor, EmitUint16Changed(
1003 flimflam::kWifiFrequency, kOkEndpointFrequency));
1004 EXPECT_CALL(adaptor, EmitUint8Changed(
1005 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1006 service->RemoveEndpoint(good_endpoint);
1007 Mock::VerifyAndClearExpectations(&adaptor);
1008
1009 // Removing last endpoint updates values (and doesn't crash).
1010 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
1011 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1012 service->RemoveEndpoint(ok_endpoint);
1013 Mock::VerifyAndClearExpectations(&adaptor);
1014}
1015
1016TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1017 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1018 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1019 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1020 service->AddEndpoint(bad_endpoint);
1021 service->AddEndpoint(ok_endpoint);
1022 Mock::VerifyAndClearExpectations(&adaptor);
1023
1024 // Setting current endpoint forces adoption of its values, even if it
1025 // doesn't have the highest signal.
1026 EXPECT_CALL(adaptor, EmitUint16Changed(
1027 flimflam::kWifiFrequency, kBadEndpointFrequency));
1028 EXPECT_CALL(adaptor, EmitUint8Changed(
1029 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
1030 service->NotifyCurrentEndpoint(bad_endpoint);
1031 Mock::VerifyAndClearExpectations(&adaptor);
1032
1033 // Adding a better endpoint doesn't matter, when current endpoint is set.
1034 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1035 EXPECT_CALL(adaptor,
1036 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1037 service->AddEndpoint(good_endpoint);
1038 Mock::VerifyAndClearExpectations(&adaptor);
1039
1040 // Removing a better endpoint doesn't matter, when current endpoint is set.
1041 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1042 EXPECT_CALL(adaptor,
1043 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1044 service->RemoveEndpoint(good_endpoint);
1045 Mock::VerifyAndClearExpectations(&adaptor);
1046
1047 // Removing the current endpoint is safe and sane.
1048 EXPECT_CALL(adaptor, EmitUint16Changed(
1049 flimflam::kWifiFrequency, kOkEndpointFrequency));
1050 EXPECT_CALL(adaptor, EmitUint8Changed(
1051 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1052 service->RemoveEndpoint(bad_endpoint);
1053 Mock::VerifyAndClearExpectations(&adaptor);
1054
1055 // Clearing the current endpoint (without removing it) is also safe and sane.
1056 service->NotifyCurrentEndpoint(ok_endpoint);
1057 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1058 EXPECT_CALL(adaptor,
1059 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1060 service->NotifyCurrentEndpoint(NULL);
1061 Mock::VerifyAndClearExpectations(&adaptor);
1062}
1063
1064TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1065 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1066 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1067 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1068 service->AddEndpoint(ok_endpoint);
1069 service->AddEndpoint(good_endpoint);
1070 Mock::VerifyAndClearExpectations(&adaptor);
1071
1072 // Updating sub-optimal Endpoint doesn't update Service.
1073 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1074 EXPECT_CALL(adaptor,
1075 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1076 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
1077 service->NotifyEndpointUpdated(*ok_endpoint);
1078 Mock::VerifyAndClearExpectations(&adaptor);
1079
1080 // Updating optimal Endpoint updates appropriate Service property.
1081 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
1082 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1083 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
1084 service->NotifyEndpointUpdated(*good_endpoint);
1085 Mock::VerifyAndClearExpectations(&adaptor);
1086
1087 // Change in optimal Endpoint updates Service properties.
1088 EXPECT_CALL(adaptor, EmitUint16Changed(
1089 flimflam::kWifiFrequency, kOkEndpointFrequency));
1090 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1091 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
1092 service->NotifyEndpointUpdated(*ok_endpoint);
1093 Mock::VerifyAndClearExpectations(&adaptor);
1094}
1095
Chris Masone34af2182011-08-22 11:59:36 -07001096} // namespace shill