blob: 397e54b0d0f3451f08046cac5cdbe78649242d15 [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(
mukesh agrawal923f14f2012-06-04 16:46:08 -0700186 "", kOkEndpointBssId, kOkEndpointFrequency, kOkEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800187 good_endpoint = MakeEndpoint(
mukesh agrawal923f14f2012-06-04 16:46:08 -0700188 "", kGoodEndpointBssId, kGoodEndpointFrequency, kGoodEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800189 bad_endpoint = MakeEndpoint(
mukesh agrawal923f14f2012-06-04 16:46:08 -0700190 "", kBadEndpointBssId, kBadEndpointFrequency, kBadEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800191 }
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;
mukesh agrawal923f14f2012-06-04 16:46:08 -0700200 static const char *kOkEndpointBssId;
201 static const char *kGoodEndpointBssId;
202 static const char *kBadEndpointBssId;
mukesh agrawale1d90e92012-02-15 17:36:08 -0800203 // Can't be both static and const (because initialization requires a
204 // function call). So choose to be just const.
205 const uint8 kOkEndpointStrength;
206 const uint8 kBadEndpointStrength;
207 const uint8 kGoodEndpointStrength;
208 WiFiEndpointRefPtr ok_endpoint;
209 WiFiEndpointRefPtr bad_endpoint;
210 WiFiEndpointRefPtr good_endpoint;
211 WiFiServiceRefPtr service;
212 ServiceMockAdaptor &adaptor;
213};
214
mukesh agrawal923f14f2012-06-04 16:46:08 -0700215const char *WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId =
216 "00:00:00:00:00:01";
217const char *WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId =
218 "00:00:00:00:00:02";
219const char *WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId =
220 "00:00:00:00:00:03";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800221
Chris Masone34af2182011-08-22 11:59:36 -0700222TEST_F(WiFiServiceTest, StorageId) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800223 vector<uint8_t> ssid(5);
Chris Masone34af2182011-08-22 11:59:36 -0700224 ssid.push_back(0xff);
Chris Masone9d779932011-08-25 16:33:41 -0700225
Chris Masone2176a882011-09-14 22:29:15 -0700226 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
227 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800228 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700229 manager(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700230 wifi(),
Chris Masone9d779932011-08-25 16:33:41 -0700231 ssid,
232 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800233 flimflam::kSecurityNone,
234 false);
Chris Masone9d779932011-08-25 16:33:41 -0700235 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700236 for (uint i = 0; i < id.length(); ++i) {
237 EXPECT_TRUE(id[i] == '_' ||
238 isxdigit(id[i]) ||
239 (isalpha(id[i]) && islower(id[i])));
240 }
Chris Masone34af2182011-08-22 11:59:36 -0700241 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
242 EXPECT_NE(mac_pos, string::npos);
243 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
244}
245
Gaurav Shahda6218a2011-11-11 12:09:33 -0800246// Make sure the passphrase is registered as a write only property
247// by reading and comparing all string properties returned on the store.
248TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
249 vector<uint8_t> ssid(5);
250 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
251 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800252 metrics(),
Gaurav Shahda6218a2011-11-11 12:09:33 -0800253 manager(),
254 wifi(),
255 ssid,
256 flimflam::kModeManaged,
257 flimflam::kSecurityWpa,
258 false);
259 ReadablePropertyConstIterator<string> it =
260 (wifi_service->store()).GetStringPropertiesIter();
261 for( ; !it.AtEnd(); it.Advance())
262 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
263}
264
Thieu Lef7709452011-11-15 01:13:19 +0000265// Make sure setting the passphrase via D-Bus Service.SetProperty validates
266// the passphrase.
267TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
268 // We only spot check two password cases here to make sure the
269 // SetProperty code path does validation. We're not going to exhaustively
270 // test for all types of passwords.
271 vector<uint8_t> ssid(5);
272 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
273 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800274 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000275 manager(),
276 wifi(),
277 ssid,
278 flimflam::kModeManaged,
279 flimflam::kSecurityWep,
280 false);
281 Error error;
282 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
283 flimflam::kPassphraseProperty, "0:abcde", &error));
284 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
285 flimflam::kPassphraseProperty, "invalid", &error));
286 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
287}
288
289TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
290 vector<uint8_t> ssid(5);
291 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
292 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800293 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000294 manager(),
295 wifi(),
296 ssid,
297 flimflam::kModeManaged,
298 flimflam::kSecurityNone,
299 false);
300 Error error;
301 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
302 flimflam::kPassphraseProperty, "invalid", &error));
303 EXPECT_EQ(Error::kNotSupported, error.type());
304}
305
mukesh agrawald835b202011-10-07 15:26:47 -0700306TEST_F(WiFiServiceTest, NonUTF8SSID) {
307 vector<uint8_t> ssid;
308
309 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
310 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
311 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800312 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700313 manager(),
314 wifi(),
315 ssid,
316 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800317 flimflam::kSecurityNone,
318 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700319 map<string, ::DBus::Variant> properties;
320 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
321 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
322}
323
Gaurav Shahda6218a2011-11-11 12:09:33 -0800324MATCHER(WPASecurityArgs, "") {
325 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
326 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
327}
328
Gaurav Shah10109f22011-11-11 20:16:22 -0800329MATCHER(EAPSecurityArgs, "") {
330 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
331 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath);
332}
333
Paul Stewarte2d7c502012-07-16 16:35:10 -0700334MATCHER_P(FrequencyArg, has_arg, "") {
335 return has_arg ==
336 ContainsKey(arg, wpa_supplicant::kNetworkPropertyFrequency);
337}
338
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700339TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800340 vector<uint8_t> ssid(5);
mukesh agrawal6e277772011-09-29 15:04:23 -0700341 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
342 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800343 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700344 manager(),
345 wifi(),
346 ssid,
347 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800348 flimflam::kSecurityWpa,
349 false);
mukesh agrawal6e277772011-09-29 15:04:23 -0700350 EXPECT_CALL(*wifi(),
351 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700352 Error error;
353 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500354 wifi_service->Connect(NULL);
mukesh agrawal6e277772011-09-29 15:04:23 -0700355}
356
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700357TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800358 vector<uint8_t> ssid(5);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700359 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
360 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800361 metrics(),
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700362 manager(),
363 wifi(),
364 ssid,
365 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800366 flimflam::kSecurityRsn,
367 false);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700368 EXPECT_CALL(*wifi(),
369 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700370 Error error;
371 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500372 wifi_service->Connect(NULL);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700373}
374
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800375TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800376 vector<uint8_t> ssid(5);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800377 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
378 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800379 metrics(),
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800380 manager(),
381 wifi(),
382 ssid,
383 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800384 flimflam::kSecurityPsk,
385 false);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800386 EXPECT_CALL(*wifi(),
387 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700388 Error error;
389 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500390 wifi_service->Connect(NULL);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800391}
392
Gaurav Shah10109f22011-11-11 20:16:22 -0800393TEST_F(WiFiServiceTest, ConnectTask8021x) {
394 vector<uint8_t> ssid(5);
395 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
396 dispatcher(),
397 metrics(),
398 manager(),
399 wifi(),
400 ssid,
401 flimflam::kModeManaged,
402 flimflam::kSecurity8021x,
403 false);
404 Service::EapCredentials eap;
405 eap.identity = "identity";
Wade Guthrie005bd342012-05-02 09:37:07 -0700406 eap.password = "mumble";
Gaurav Shah10109f22011-11-11 20:16:22 -0800407 wifi_service->set_eap(eap);
408 EXPECT_CALL(*wifi(),
409 ConnectTo(wifi_service.get(), EAPSecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500410 wifi_service->Connect(NULL);
Gaurav Shah10109f22011-11-11 20:16:22 -0800411}
412
Paul Stewarte2d7c502012-07-16 16:35:10 -0700413TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) {
414 vector<uint8_t> ssid(1, 'a');
415 WiFiEndpointRefPtr endpoint_nofreq =
416 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
417 WiFiEndpointRefPtr endpoint_freq =
418 MakeEndpoint("a", "00:00:00:00:00:02", 2412, 0);
419
420 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
421 dispatcher(),
422 metrics(),
423 manager(),
424 wifi(),
425 ssid,
426 flimflam::kModeManaged,
427 flimflam::kSecurityNone,
428 false);
429 wifi_service->AddEndpoint(endpoint_freq);
430 EXPECT_CALL(*wifi(),
431 ConnectTo(wifi_service.get(), FrequencyArg(false)));
432 wifi_service->Connect(NULL);
433
434 wifi_service = new WiFiService(control_interface(),
435 dispatcher(),
436 metrics(),
437 manager(),
438 wifi(),
439 ssid,
440 flimflam::kModeAdhoc,
441 flimflam::kSecurityNone,
442 false);
443 EXPECT_CALL(*wifi(),
444 ConnectTo(wifi_service.get(), FrequencyArg(false)));
445 wifi_service->Connect(NULL);
446
447 wifi_service = new WiFiService(control_interface(),
448 dispatcher(),
449 metrics(),
450 manager(),
451 wifi(),
452 ssid,
453 flimflam::kModeAdhoc,
454 flimflam::kSecurityNone,
455 false);
456 wifi_service->AddEndpoint(endpoint_nofreq);
457 EXPECT_CALL(*wifi(),
458 ConnectTo(wifi_service.get(), FrequencyArg(false)));
459 wifi_service->Connect(NULL);
460
461 wifi_service = new WiFiService(control_interface(),
462 dispatcher(),
463 metrics(),
464 manager(),
465 wifi(),
466 ssid,
467 flimflam::kModeAdhoc,
468 flimflam::kSecurityNone,
469 false);
470 wifi_service->AddEndpoint(endpoint_freq);
471 EXPECT_CALL(*wifi(),
472 ConnectTo(wifi_service.get(), FrequencyArg(true)));
473 wifi_service->Connect(NULL);
474}
475
Thieu Lef4cbda92011-11-10 23:41:24 +0000476MATCHER(WEPSecurityArgsKeyIndex0, "") {
477 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
478 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
479 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
480 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
481 reader().get_uint32() == 0);
482}
483
484MATCHER(WEPSecurityArgsKeyIndex1, "") {
485 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
486 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
487 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
488 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
489 reader().get_uint32() == 1);
490}
491
492MATCHER(WEPSecurityArgsKeyIndex2, "") {
493 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
494 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
495 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
496 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
497 reader().get_uint32() == 2);
498}
499
500MATCHER(WEPSecurityArgsKeyIndex3, "") {
501 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
502 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
503 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
504 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
505 reader().get_uint32() == 3);
506}
507
508TEST_F(WiFiServiceTest, ConnectTaskWEP) {
509 vector<uint8_t> ssid(5);
510 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
511 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800512 metrics(),
Thieu Lef4cbda92011-11-10 23:41:24 +0000513 manager(),
514 wifi(),
515 ssid,
516 flimflam::kModeManaged,
517 flimflam::kSecurityWep,
518 false);
519 Error error;
520 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
521 EXPECT_CALL(*wifi(),
522 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500523 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000524
525 wifi_service->SetPassphrase("abcdefghijklm", &error);
526 EXPECT_CALL(*wifi(),
527 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500528 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000529
530 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
531 EXPECT_CALL(*wifi(),
532 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500533 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000534
535 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
536 EXPECT_CALL(*wifi(),
537 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500538 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000539
540 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
541 EXPECT_CALL(*wifi(),
542 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500543 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000544}
545
Gaurav Shah29d68882012-01-30 19:06:42 -0800546
547MATCHER(DynamicWEPArgs, "") {
548 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
549 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
550 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
551}
552
553// Dynamic WEP + 802.1x.
554TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
555 vector<uint8_t> ssid(5);
556 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
557 dispatcher(),
558 metrics(),
559 manager(),
560 wifi(),
561 ssid,
562 flimflam::kModeManaged,
563 flimflam::kSecurityWep,
564 false);
565
566 Service::EapCredentials eap;
567 eap.key_management = "IEEE8021X";
568 eap.identity = "something";
Wade Guthrie005bd342012-05-02 09:37:07 -0700569 eap.password = "mumble";
Gaurav Shah29d68882012-01-30 19:06:42 -0800570 wifi_service->set_eap(eap);
571 EXPECT_CALL(*wifi(),
572 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500573 wifi_service->Connect(NULL);
Gaurav Shah29d68882012-01-30 19:06:42 -0800574}
575
Paul Stewartd08f4432011-11-04 07:48:20 -0700576TEST_F(WiFiServiceTest, LoadHidden) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800577 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700578 ssid.push_back(0xff);
579
580 WiFiServiceRefPtr service = new WiFiService(control_interface(),
581 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800582 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700583 manager(),
584 wifi(),
585 ssid,
586 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800587 flimflam::kSecurityNone,
588 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700589 ASSERT_FALSE(service->hidden_ssid_);
590 NiceMock<MockStore> mock_store;
591 const string storage_id = service->GetStorageIdentifier();
592 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
593 .WillRepeatedly(Return(true));
594 EXPECT_CALL(mock_store, GetBool(_, _, _))
595 .WillRepeatedly(Return(false));
596 EXPECT_CALL(mock_store,
597 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
598 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
599 EXPECT_TRUE(service->Load(&mock_store));
600 EXPECT_TRUE(service->hidden_ssid_);
601}
602
603TEST_F(WiFiServiceSecurityTest, WPAMapping) {
604 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
605 flimflam::kSecurityPsk));
606 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
607 flimflam::kSecurityPsk));
608 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
609 flimflam::kSecurityPsk));
610 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
611 flimflam::kSecurityWep));
612 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
613 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800614 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
615 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700616}
617
618TEST_F(WiFiServiceSecurityTest, LoadMapping) {
619 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
620 flimflam::kSecurityPsk,
621 true));
622 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
623 flimflam::kSecurityRsn,
624 true));
625 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
626 flimflam::kSecurityWpa,
627 false));
628 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
629 flimflam::kSecurityPsk,
630 true));
631 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
632 flimflam::kSecurityWpa,
633 true));
634 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
635 flimflam::kSecurityRsn,
636 false));
637 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
638 flimflam::kSecurityWep,
639 true));
640 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
641 flimflam::kSecurityPsk,
642 false));
643}
644
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800645TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
646 vector<uint8_t> ssid(5);
647 ssid.push_back(0xff);
648
649 WiFiServiceRefPtr service = new WiFiService(control_interface(),
650 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800651 metrics(),
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800652 manager(),
653 wifi(),
654 ssid,
655 flimflam::kModeManaged,
656 flimflam::kSecurityPsk,
657 false);
658 NiceMock<MockStore> mock_store;
659 const string storage_id = service->GetStorageIdentifier();
660 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
661 .WillRepeatedly(Return(true));
662 EXPECT_CALL(mock_store, GetBool(_, _, _))
663 .WillRepeatedly(Return(false));
664 const string passphrase = "passphrase";
665 EXPECT_CALL(mock_store,
666 GetCryptedString(StrEq(storage_id),
667 WiFiService::kStoragePassphrase, _))
668 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
669 EXPECT_CALL(mock_store,
670 GetCryptedString(StrEq(storage_id),
671 StrNe(WiFiService::kStoragePassphrase), _))
672 .WillRepeatedly(Return(false));
673 EXPECT_TRUE(service->need_passphrase_);
674 EXPECT_TRUE(service->Load(&mock_store));
675 EXPECT_EQ(passphrase, service->passphrase_);
676 EXPECT_TRUE(service->connectable());
677 EXPECT_FALSE(service->need_passphrase_);
678 service->Unload();
679 EXPECT_EQ(string(""), service->passphrase_);
680 EXPECT_FALSE(service->connectable());
681 EXPECT_TRUE(service->need_passphrase_);
682}
683
Paul Stewart66c86002012-01-30 18:00:52 -0800684TEST_F(WiFiServiceTest, UnloadAndClearCacheWep) {
685 vector<uint8_t> ssid(1, 'a');
686 WiFiServiceRefPtr service = new WiFiService(control_interface(),
687 dispatcher(),
688 metrics(),
689 manager(),
690 wifi(),
691 ssid,
692 flimflam::kModeManaged,
693 flimflam::kSecurityWep,
694 false);
695 // A WEP network does not incur cached credentials.
696 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(0);
697 service->Unload();
698}
699
700TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
701 vector<uint8_t> ssid(1, 'a');
702 WiFiServiceRefPtr service = new WiFiService(control_interface(),
703 dispatcher(),
704 metrics(),
705 manager(),
706 wifi(),
707 ssid,
708 flimflam::kModeManaged,
709 flimflam::kSecurity8021x,
710 false);
711 // An 802.1x network should clear its cached credentials.
712 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(1);
713 service->Unload();
714}
715
Paul Stewart0756db92012-01-27 08:34:47 -0800716TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewarta41e38d2011-11-11 07:47:29 -0800717 vector<uint8_t> ssid(5);
718 ssid.push_back(0xff);
719
720 WiFiServiceRefPtr service = new WiFiService(control_interface(),
721 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800722 metrics(),
Paul Stewarta41e38d2011-11-11 07:47:29 -0800723 manager(),
724 wifi(),
725 ssid,
726 flimflam::kModeManaged,
727 flimflam::kSecurityNone,
728 false);
729 const string storage_id = service->GetStorageIdentifier();
730 string address;
731 string mode;
732 string security;
733 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
734 &security));
735 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
736 EXPECT_EQ(flimflam::kModeManaged, mode);
737 EXPECT_EQ(flimflam::kSecurityNone, security);
738}
739
Paul Stewart0756db92012-01-27 08:34:47 -0800740TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
741 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
742 // which needs to be dealt with specially in the parser.
743 vector<uint8_t> ssid(5);
744 ssid.push_back(0xff);
745
746 WiFiServiceRefPtr service = new WiFiService(control_interface(),
747 dispatcher(),
748 metrics(),
749 manager(),
750 wifi(),
751 ssid,
752 flimflam::kModeManaged,
753 flimflam::kSecurity8021x,
754 false);
755 const string storage_id = service->GetStorageIdentifier();
756 string address;
757 string mode;
758 string security;
759 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
760 &security));
761 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
762 EXPECT_EQ(flimflam::kModeManaged, mode);
763 EXPECT_EQ(flimflam::kSecurity8021x, security);
764}
765
mukesh agrawal29c13a12011-11-24 00:09:19 +0000766TEST_F(WiFiServiceTest, Connectable) {
767 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800768 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000769
770 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -0800771 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000772
773 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800774 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000775
776 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800777 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000778
779 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800780 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000781
782 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -0800783 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
784 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
785 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000786
787 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800788 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
789
790 Service::EapCredentials eap;
791 // Empty EAP credentials should not make a 802.1x network connectable.
792 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
793
794 eap.identity = "something";
795 // If client certificate is being used, a private key must exist.
796 eap.client_cert = "some client cert";
797 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
798 eap.private_key = "some private key";
799 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
800
801 // Identity is always required.
802 eap.identity.clear();
803 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
804
805 eap.identity = "something";
806 // For non EAP-TLS types, a password is required.
807 eap.eap = "Non-TLS";
808 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
809 eap.password = "some password";
810 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -0800811 // Dynamic WEP + 802.1X should be connectable under the same conditions.
812 eap.key_management = "IEEE8021X";
813 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000814}
815
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000816TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800817 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000818 vector<uint8_t> ssid(1, 'a');
819 WiFiServiceRefPtr service = new WiFiService(control_interface(),
820 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800821 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000822 manager(),
823 wifi(),
824 ssid,
825 flimflam::kModeManaged,
826 flimflam::kSecurityNone,
827 false);
828 EXPECT_CALL(*wifi(), IsIdle())
829 .WillRepeatedly(Return(true));
830 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800831 EXPECT_FALSE(service->IsAutoConnectable(&reason));
832 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000833
mukesh agrawalbf14e942012-03-02 14:36:34 -0800834 reason = "";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800835 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000836 service->AddEndpoint(endpoint);
837 EXPECT_CALL(*wifi(), IsIdle())
838 .WillRepeatedly(Return(true));
839 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800840 EXPECT_TRUE(service->IsAutoConnectable(&reason));
841 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000842
843 // WiFi only supports connecting to one Service at a time. So, to
844 // avoid disrupting connectivity, we only allow auto-connection to
845 // a WiFiService when the corresponding WiFi is idle.
846 EXPECT_CALL(*wifi(), IsIdle())
847 .WillRepeatedly(Return(false));
848 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800849 EXPECT_FALSE(service->IsAutoConnectable(&reason));
850 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000851}
852
853TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800854 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000855 vector<uint8_t> ssid(1, 'a');
856 WiFiServiceRefPtr service = new WiFiService(control_interface(),
857 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800858 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000859 manager(),
860 wifi(),
861 ssid,
862 flimflam::kModeManaged,
863 flimflam::kSecurityNone,
864 false);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800865 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000866 EXPECT_CALL(*wifi(), ConnectTo(_, _))
867 .Times(0);
868 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500869 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000870
mukesh agrawale1d90e92012-02-15 17:36:08 -0800871 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000872 service->AddEndpoint(endpoint);
873 EXPECT_CALL(*wifi(), IsIdle())
874 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -0800875 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000876 EXPECT_CALL(*wifi(), ConnectTo(_, _));
877 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500878 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -0800879
880 Error error;
881 service->Disconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500882 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -0800883 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000884}
885
Gaurav Shah10109f22011-11-11 20:16:22 -0800886TEST_F(WiFiServiceTest, Populate8021x) {
887 vector<uint8_t> ssid(1, 'a');
888 WiFiServiceRefPtr service = new WiFiService(control_interface(),
889 dispatcher(),
890 metrics(),
891 manager(),
892 wifi(),
893 ssid,
894 flimflam::kModeManaged,
895 flimflam::kSecurityNone,
896 false);
897 Service::EapCredentials eap;
898 eap.identity = "testidentity";
Paul Stewart20550982012-04-16 12:16:11 -0700899 eap.pin = "xxxx";
Gaurav Shah10109f22011-11-11 20:16:22 -0800900 service->set_eap(eap);
901 map<string, ::DBus::Variant> params;
902 service->Populate8021xProperties(&params);
903 // Test that only non-empty 802.1x properties are populated.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700904 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapIdentity));
905 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
906 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
907
Paul Stewart20550982012-04-16 12:16:11 -0700908 // Test that CA path is set by default.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700909 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
910
Paul Stewart20550982012-04-16 12:16:11 -0700911 // Test that hardware-backed security arguments are not set.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700912 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
913 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
914 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
Paul Stewart20550982012-04-16 12:16:11 -0700915}
916
917TEST_F(WiFiServiceTest, Populate8021xNoSystemCAs) {
918 vector<uint8_t> ssid(1, 'a');
919 WiFiServiceRefPtr service = new WiFiService(control_interface(),
920 dispatcher(),
921 metrics(),
922 manager(),
923 wifi(),
924 ssid,
925 flimflam::kModeManaged,
926 flimflam::kSecurityNone,
927 false);
928 Service::EapCredentials eap;
929 eap.identity = "testidentity";
930 eap.use_system_cas = false;
931 service->set_eap(eap);
932 map<string, ::DBus::Variant> params;
933 service->Populate8021xProperties(&params);
934 // Test that CA path is not set if use_system_cas is explicitly false.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700935 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
Paul Stewart20550982012-04-16 12:16:11 -0700936}
937
938TEST_F(WiFiServiceTest, Populate8021xUsingHardwareAuth) {
939 vector<uint8_t> ssid(1, 'a');
940 WiFiServiceRefPtr service = new WiFiService(control_interface(),
941 dispatcher(),
942 metrics(),
943 manager(),
944 wifi(),
945 ssid,
946 flimflam::kModeManaged,
947 flimflam::kSecurityNone,
948 false);
949 Service::EapCredentials eap;
950 eap.identity = "testidentity";
951 eap.key_id = "key_id";
952 eap.pin = "xxxx";
953 service->set_eap(eap);
954 map<string, ::DBus::Variant> params;
955 service->Populate8021xProperties(&params);
956 // Test that EAP engine parameters set if key_id is set.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700957 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
958 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
959 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
960 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
961}
962
963TEST_F(WiFiServiceTest, Populate8021xNSS) {
964 vector<uint8_t> ssid(1, 'a');
965 WiFiServiceRefPtr service = new WiFiService(control_interface(),
966 dispatcher(),
967 metrics(),
968 manager(),
969 wifi(),
970 ssid,
971 flimflam::kModeManaged,
972 flimflam::kSecurityNone,
973 false);
974 Service::EapCredentials eap;
975 eap.ca_cert_nss = "nss_nickname";
976 service->set_eap(eap);
977 MockNSS nss;
978 service->nss_ = &nss;
979
980 const string kNSSCertfile("/tmp/nss-cert");
981 FilePath nss_cert(kNSSCertfile);
982 vector<char> ssid_in_chars(ssid.begin(), ssid.end());
983 EXPECT_CALL(nss, GetDERCertfile(eap.ca_cert_nss, ssid_in_chars))
984 .WillOnce(Return(nss_cert));
985
986 map<string, ::DBus::Variant> params;
987 service->Populate8021xProperties(&params);
988 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
989 if (ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert)) {
990 EXPECT_EQ(kNSSCertfile, params[wpa_supplicant::kNetworkPropertyEapCaCert]
991 .reader().get_string());
992 }
Gaurav Shah10109f22011-11-11 20:16:22 -0800993}
994
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800995TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
996 vector<uint8_t> ssid(1, 'a');
997 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
998 dispatcher(),
999 metrics(),
1000 manager(),
1001 wifi(),
1002 ssid,
1003 flimflam::kModeManaged,
1004 flimflam::kSecurityWep,
1005 false);
1006
1007 EXPECT_EQ("", wifi_service->passphrase_);
1008
1009 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001010 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001011 wifi_service->mutable_store(),
1012 flimflam::kPassphraseProperty,
1013 DBusAdaptor::StringToVariant("0:abcde"),
1014 &error));
1015 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
1016
1017 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
1018 flimflam::kPassphraseProperty,
1019 &error));
1020 EXPECT_EQ("", wifi_service->passphrase_);
1021}
1022
mukesh agrawale1d90e92012-02-15 17:36:08 -08001023TEST_F(WiFiServiceTest, SignalToStrength) {
1024 // Verify that our mapping is sane, in the sense that it preserves ordering.
1025 // We break the test into two domains, because we assume that positive
1026 // values aren't actually in dBm.
1027 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
1028 int16 current_mapped = WiFiService::SignalToStrength(i);
1029 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1030 EXPECT_LE(current_mapped, next_mapped)
1031 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001032 EXPECT_GE(current_mapped, Service::kStrengthMin);
1033 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001034 }
1035 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
1036 int16 current_mapped = WiFiService::SignalToStrength(i);
1037 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1038 EXPECT_LE(current_mapped, next_mapped)
1039 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001040 EXPECT_GE(current_mapped, Service::kStrengthMin);
1041 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001042 }
1043}
1044
1045TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
1046 // If the chosen signal values don't map to distinct strength
1047 // values, then we can't expect our other tests to pass. So verify
1048 // their distinctness.
1049 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
1050 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
1051 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
1052}
1053
1054TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
1055 // Initial endpoint updates values.
1056 EXPECT_CALL(adaptor, EmitUint16Changed(
1057 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001058 EXPECT_CALL(adaptor, EmitStringChanged(
1059 flimflam::kWifiBSsid, kOkEndpointBssId));
1060 EXPECT_CALL(adaptor, EmitUint8Changed(
mukesh agrawale1d90e92012-02-15 17:36:08 -08001061 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1062 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001063 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001064 Mock::VerifyAndClearExpectations(&adaptor);
1065
1066 // Endpoint with stronger signal updates values.
1067 EXPECT_CALL(adaptor, EmitUint16Changed(
1068 flimflam::kWifiFrequency, kGoodEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001069 EXPECT_CALL(adaptor, EmitStringChanged(
1070 flimflam::kWifiBSsid, kGoodEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001071 EXPECT_CALL(adaptor, EmitUint8Changed(
1072 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
1073 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001074 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001075 Mock::VerifyAndClearExpectations(&adaptor);
1076
1077 // Endpoint with lower signal does not change values.
1078 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001079 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001080 EXPECT_CALL(adaptor,
1081 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1082 service->AddEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001083 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001084 Mock::VerifyAndClearExpectations(&adaptor);
1085
1086 // Removing non-optimal endpoint does not change values.
1087 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001088 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001089 EXPECT_CALL(adaptor,
1090 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1091 service->RemoveEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001092 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001093 Mock::VerifyAndClearExpectations(&adaptor);
1094
1095 // Removing optimal endpoint updates values.
1096 EXPECT_CALL(adaptor, EmitUint16Changed(
1097 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001098 EXPECT_CALL(adaptor, EmitStringChanged(
1099 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001100 EXPECT_CALL(adaptor, EmitUint8Changed(
1101 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1102 service->RemoveEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001103 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001104 Mock::VerifyAndClearExpectations(&adaptor);
1105
1106 // Removing last endpoint updates values (and doesn't crash).
1107 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001108 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001109 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1110 service->RemoveEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001111 EXPECT_EQ(0, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001112 Mock::VerifyAndClearExpectations(&adaptor);
1113}
1114
1115TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1116 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001117 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001118 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1119 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1120 service->AddEndpoint(bad_endpoint);
1121 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001122 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001123 Mock::VerifyAndClearExpectations(&adaptor);
1124
1125 // Setting current endpoint forces adoption of its values, even if it
1126 // doesn't have the highest signal.
1127 EXPECT_CALL(adaptor, EmitUint16Changed(
1128 flimflam::kWifiFrequency, kBadEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001129 EXPECT_CALL(adaptor, EmitStringChanged(
1130 flimflam::kWifiBSsid, kBadEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001131 EXPECT_CALL(adaptor, EmitUint8Changed(
1132 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
1133 service->NotifyCurrentEndpoint(bad_endpoint);
1134 Mock::VerifyAndClearExpectations(&adaptor);
1135
1136 // Adding a better endpoint doesn't matter, when current endpoint is set.
1137 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001138 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001139 EXPECT_CALL(adaptor,
1140 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1141 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001142 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001143 Mock::VerifyAndClearExpectations(&adaptor);
1144
1145 // Removing a better endpoint doesn't matter, when current endpoint is set.
1146 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001147 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001148 EXPECT_CALL(adaptor,
1149 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1150 service->RemoveEndpoint(good_endpoint);
1151 Mock::VerifyAndClearExpectations(&adaptor);
1152
1153 // Removing the current endpoint is safe and sane.
1154 EXPECT_CALL(adaptor, EmitUint16Changed(
1155 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001156 EXPECT_CALL(adaptor, EmitStringChanged(
1157 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001158 EXPECT_CALL(adaptor, EmitUint8Changed(
1159 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1160 service->RemoveEndpoint(bad_endpoint);
1161 Mock::VerifyAndClearExpectations(&adaptor);
1162
1163 // Clearing the current endpoint (without removing it) is also safe and sane.
1164 service->NotifyCurrentEndpoint(ok_endpoint);
1165 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001166 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001167 EXPECT_CALL(adaptor,
1168 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1169 service->NotifyCurrentEndpoint(NULL);
1170 Mock::VerifyAndClearExpectations(&adaptor);
1171}
1172
1173TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1174 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001175 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001176 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1177 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1178 service->AddEndpoint(ok_endpoint);
1179 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001180 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001181 Mock::VerifyAndClearExpectations(&adaptor);
1182
1183 // Updating sub-optimal Endpoint doesn't update Service.
1184 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001185 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001186 EXPECT_CALL(adaptor,
1187 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1188 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
1189 service->NotifyEndpointUpdated(*ok_endpoint);
1190 Mock::VerifyAndClearExpectations(&adaptor);
1191
1192 // Updating optimal Endpoint updates appropriate Service property.
1193 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001194 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001195 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1196 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
1197 service->NotifyEndpointUpdated(*good_endpoint);
1198 Mock::VerifyAndClearExpectations(&adaptor);
1199
1200 // Change in optimal Endpoint updates Service properties.
1201 EXPECT_CALL(adaptor, EmitUint16Changed(
1202 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001203 EXPECT_CALL(adaptor, EmitStringChanged(
1204 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001205 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1206 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
1207 service->NotifyEndpointUpdated(*ok_endpoint);
1208 Mock::VerifyAndClearExpectations(&adaptor);
1209}
1210
Chris Masone34af2182011-08-22 11:59:36 -07001211} // namespace shill