blob: 4299e3e267e8ba4c1958a9ba0fa47a04f0e1b88b [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 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700241 EXPECT_TRUE(wifi_service->TechnologyIs(Technology::kWifi));
Chris Masone34af2182011-08-22 11:59:36 -0700242 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
243 EXPECT_NE(mac_pos, string::npos);
244 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
245}
246
Gaurav Shahda6218a2011-11-11 12:09:33 -0800247// Make sure the passphrase is registered as a write only property
248// by reading and comparing all string properties returned on the store.
249TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
250 vector<uint8_t> ssid(5);
251 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
252 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800253 metrics(),
Gaurav Shahda6218a2011-11-11 12:09:33 -0800254 manager(),
255 wifi(),
256 ssid,
257 flimflam::kModeManaged,
258 flimflam::kSecurityWpa,
259 false);
260 ReadablePropertyConstIterator<string> it =
261 (wifi_service->store()).GetStringPropertiesIter();
262 for( ; !it.AtEnd(); it.Advance())
263 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
264}
265
Thieu Lef7709452011-11-15 01:13:19 +0000266// Make sure setting the passphrase via D-Bus Service.SetProperty validates
267// the passphrase.
268TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
269 // We only spot check two password cases here to make sure the
270 // SetProperty code path does validation. We're not going to exhaustively
271 // test for all types of passwords.
272 vector<uint8_t> ssid(5);
273 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
274 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800275 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000276 manager(),
277 wifi(),
278 ssid,
279 flimflam::kModeManaged,
280 flimflam::kSecurityWep,
281 false);
282 Error error;
283 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
284 flimflam::kPassphraseProperty, "0:abcde", &error));
285 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
286 flimflam::kPassphraseProperty, "invalid", &error));
287 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
288}
289
290TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
291 vector<uint8_t> ssid(5);
292 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
293 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800294 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000295 manager(),
296 wifi(),
297 ssid,
298 flimflam::kModeManaged,
299 flimflam::kSecurityNone,
300 false);
301 Error error;
302 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
303 flimflam::kPassphraseProperty, "invalid", &error));
304 EXPECT_EQ(Error::kNotSupported, error.type());
305}
306
mukesh agrawald835b202011-10-07 15:26:47 -0700307TEST_F(WiFiServiceTest, NonUTF8SSID) {
308 vector<uint8_t> ssid;
309
310 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
311 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
312 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800313 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700314 manager(),
315 wifi(),
316 ssid,
317 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800318 flimflam::kSecurityNone,
319 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700320 map<string, ::DBus::Variant> properties;
321 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
322 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
323}
324
Gaurav Shahda6218a2011-11-11 12:09:33 -0800325MATCHER(WPASecurityArgs, "") {
326 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
327 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
328}
329
Gaurav Shah10109f22011-11-11 20:16:22 -0800330MATCHER(EAPSecurityArgs, "") {
331 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
332 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath);
333}
334
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700335TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800336 vector<uint8_t> ssid(5);
mukesh agrawal6e277772011-09-29 15:04:23 -0700337 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
338 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800339 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700340 manager(),
341 wifi(),
342 ssid,
343 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800344 flimflam::kSecurityWpa,
345 false);
mukesh agrawal6e277772011-09-29 15:04:23 -0700346 EXPECT_CALL(*wifi(),
347 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700348 Error error;
349 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500350 wifi_service->Connect(NULL);
mukesh agrawal6e277772011-09-29 15:04:23 -0700351}
352
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700353TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800354 vector<uint8_t> ssid(5);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700355 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
356 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800357 metrics(),
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700358 manager(),
359 wifi(),
360 ssid,
361 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800362 flimflam::kSecurityRsn,
363 false);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700364 EXPECT_CALL(*wifi(),
365 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700366 Error error;
367 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500368 wifi_service->Connect(NULL);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700369}
370
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800371TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800372 vector<uint8_t> ssid(5);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800373 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
374 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800375 metrics(),
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800376 manager(),
377 wifi(),
378 ssid,
379 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800380 flimflam::kSecurityPsk,
381 false);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800382 EXPECT_CALL(*wifi(),
383 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700384 Error error;
385 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500386 wifi_service->Connect(NULL);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800387}
388
Gaurav Shah10109f22011-11-11 20:16:22 -0800389TEST_F(WiFiServiceTest, ConnectTask8021x) {
390 vector<uint8_t> ssid(5);
391 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
392 dispatcher(),
393 metrics(),
394 manager(),
395 wifi(),
396 ssid,
397 flimflam::kModeManaged,
398 flimflam::kSecurity8021x,
399 false);
400 Service::EapCredentials eap;
401 eap.identity = "identity";
Wade Guthrie005bd342012-05-02 09:37:07 -0700402 eap.password = "mumble";
Gaurav Shah10109f22011-11-11 20:16:22 -0800403 wifi_service->set_eap(eap);
404 EXPECT_CALL(*wifi(),
405 ConnectTo(wifi_service.get(), EAPSecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500406 wifi_service->Connect(NULL);
Gaurav Shah10109f22011-11-11 20:16:22 -0800407}
408
Thieu Lef4cbda92011-11-10 23:41:24 +0000409MATCHER(WEPSecurityArgsKeyIndex0, "") {
410 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
411 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
412 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
413 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
414 reader().get_uint32() == 0);
415}
416
417MATCHER(WEPSecurityArgsKeyIndex1, "") {
418 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
419 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
420 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
421 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
422 reader().get_uint32() == 1);
423}
424
425MATCHER(WEPSecurityArgsKeyIndex2, "") {
426 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
427 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
428 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
429 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
430 reader().get_uint32() == 2);
431}
432
433MATCHER(WEPSecurityArgsKeyIndex3, "") {
434 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
435 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
436 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
437 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
438 reader().get_uint32() == 3);
439}
440
441TEST_F(WiFiServiceTest, ConnectTaskWEP) {
442 vector<uint8_t> ssid(5);
443 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
444 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800445 metrics(),
Thieu Lef4cbda92011-11-10 23:41:24 +0000446 manager(),
447 wifi(),
448 ssid,
449 flimflam::kModeManaged,
450 flimflam::kSecurityWep,
451 false);
452 Error error;
453 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
454 EXPECT_CALL(*wifi(),
455 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500456 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000457
458 wifi_service->SetPassphrase("abcdefghijklm", &error);
459 EXPECT_CALL(*wifi(),
460 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500461 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000462
463 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
464 EXPECT_CALL(*wifi(),
465 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500466 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000467
468 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
469 EXPECT_CALL(*wifi(),
470 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500471 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000472
473 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
474 EXPECT_CALL(*wifi(),
475 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500476 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000477}
478
Gaurav Shah29d68882012-01-30 19:06:42 -0800479
480MATCHER(DynamicWEPArgs, "") {
481 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
482 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
483 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
484}
485
486// Dynamic WEP + 802.1x.
487TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
488 vector<uint8_t> ssid(5);
489 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
490 dispatcher(),
491 metrics(),
492 manager(),
493 wifi(),
494 ssid,
495 flimflam::kModeManaged,
496 flimflam::kSecurityWep,
497 false);
498
499 Service::EapCredentials eap;
500 eap.key_management = "IEEE8021X";
501 eap.identity = "something";
Wade Guthrie005bd342012-05-02 09:37:07 -0700502 eap.password = "mumble";
Gaurav Shah29d68882012-01-30 19:06:42 -0800503 wifi_service->set_eap(eap);
504 EXPECT_CALL(*wifi(),
505 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500506 wifi_service->Connect(NULL);
Gaurav Shah29d68882012-01-30 19:06:42 -0800507}
508
Paul Stewartd08f4432011-11-04 07:48:20 -0700509TEST_F(WiFiServiceTest, LoadHidden) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800510 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700511 ssid.push_back(0xff);
512
513 WiFiServiceRefPtr service = new WiFiService(control_interface(),
514 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800515 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700516 manager(),
517 wifi(),
518 ssid,
519 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800520 flimflam::kSecurityNone,
521 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700522 ASSERT_FALSE(service->hidden_ssid_);
523 NiceMock<MockStore> mock_store;
524 const string storage_id = service->GetStorageIdentifier();
525 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
526 .WillRepeatedly(Return(true));
527 EXPECT_CALL(mock_store, GetBool(_, _, _))
528 .WillRepeatedly(Return(false));
529 EXPECT_CALL(mock_store,
530 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
531 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
532 EXPECT_TRUE(service->Load(&mock_store));
533 EXPECT_TRUE(service->hidden_ssid_);
534}
535
536TEST_F(WiFiServiceSecurityTest, WPAMapping) {
537 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
538 flimflam::kSecurityPsk));
539 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
540 flimflam::kSecurityPsk));
541 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
542 flimflam::kSecurityPsk));
543 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
544 flimflam::kSecurityWep));
545 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
546 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800547 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
548 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700549}
550
551TEST_F(WiFiServiceSecurityTest, LoadMapping) {
552 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
553 flimflam::kSecurityPsk,
554 true));
555 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
556 flimflam::kSecurityRsn,
557 true));
558 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
559 flimflam::kSecurityWpa,
560 false));
561 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
562 flimflam::kSecurityPsk,
563 true));
564 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
565 flimflam::kSecurityWpa,
566 true));
567 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
568 flimflam::kSecurityRsn,
569 false));
570 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
571 flimflam::kSecurityWep,
572 true));
573 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
574 flimflam::kSecurityPsk,
575 false));
576}
577
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800578TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
579 vector<uint8_t> ssid(5);
580 ssid.push_back(0xff);
581
582 WiFiServiceRefPtr service = new WiFiService(control_interface(),
583 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800584 metrics(),
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800585 manager(),
586 wifi(),
587 ssid,
588 flimflam::kModeManaged,
589 flimflam::kSecurityPsk,
590 false);
591 NiceMock<MockStore> mock_store;
592 const string storage_id = service->GetStorageIdentifier();
593 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
594 .WillRepeatedly(Return(true));
595 EXPECT_CALL(mock_store, GetBool(_, _, _))
596 .WillRepeatedly(Return(false));
597 const string passphrase = "passphrase";
598 EXPECT_CALL(mock_store,
599 GetCryptedString(StrEq(storage_id),
600 WiFiService::kStoragePassphrase, _))
601 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
602 EXPECT_CALL(mock_store,
603 GetCryptedString(StrEq(storage_id),
604 StrNe(WiFiService::kStoragePassphrase), _))
605 .WillRepeatedly(Return(false));
606 EXPECT_TRUE(service->need_passphrase_);
607 EXPECT_TRUE(service->Load(&mock_store));
608 EXPECT_EQ(passphrase, service->passphrase_);
609 EXPECT_TRUE(service->connectable());
610 EXPECT_FALSE(service->need_passphrase_);
611 service->Unload();
612 EXPECT_EQ(string(""), service->passphrase_);
613 EXPECT_FALSE(service->connectable());
614 EXPECT_TRUE(service->need_passphrase_);
615}
616
Paul Stewart66c86002012-01-30 18:00:52 -0800617TEST_F(WiFiServiceTest, UnloadAndClearCacheWep) {
618 vector<uint8_t> ssid(1, 'a');
619 WiFiServiceRefPtr service = new WiFiService(control_interface(),
620 dispatcher(),
621 metrics(),
622 manager(),
623 wifi(),
624 ssid,
625 flimflam::kModeManaged,
626 flimflam::kSecurityWep,
627 false);
628 // A WEP network does not incur cached credentials.
629 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(0);
630 service->Unload();
631}
632
633TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
634 vector<uint8_t> ssid(1, 'a');
635 WiFiServiceRefPtr service = new WiFiService(control_interface(),
636 dispatcher(),
637 metrics(),
638 manager(),
639 wifi(),
640 ssid,
641 flimflam::kModeManaged,
642 flimflam::kSecurity8021x,
643 false);
644 // An 802.1x network should clear its cached credentials.
645 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(1);
646 service->Unload();
647}
648
Paul Stewart0756db92012-01-27 08:34:47 -0800649TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewarta41e38d2011-11-11 07:47:29 -0800650 vector<uint8_t> ssid(5);
651 ssid.push_back(0xff);
652
653 WiFiServiceRefPtr service = new WiFiService(control_interface(),
654 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800655 metrics(),
Paul Stewarta41e38d2011-11-11 07:47:29 -0800656 manager(),
657 wifi(),
658 ssid,
659 flimflam::kModeManaged,
660 flimflam::kSecurityNone,
661 false);
662 const string storage_id = service->GetStorageIdentifier();
663 string address;
664 string mode;
665 string security;
666 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
667 &security));
668 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
669 EXPECT_EQ(flimflam::kModeManaged, mode);
670 EXPECT_EQ(flimflam::kSecurityNone, security);
671}
672
Paul Stewart0756db92012-01-27 08:34:47 -0800673TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
674 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
675 // which needs to be dealt with specially in the parser.
676 vector<uint8_t> ssid(5);
677 ssid.push_back(0xff);
678
679 WiFiServiceRefPtr service = new WiFiService(control_interface(),
680 dispatcher(),
681 metrics(),
682 manager(),
683 wifi(),
684 ssid,
685 flimflam::kModeManaged,
686 flimflam::kSecurity8021x,
687 false);
688 const string storage_id = service->GetStorageIdentifier();
689 string address;
690 string mode;
691 string security;
692 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
693 &security));
694 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
695 EXPECT_EQ(flimflam::kModeManaged, mode);
696 EXPECT_EQ(flimflam::kSecurity8021x, security);
697}
698
mukesh agrawal29c13a12011-11-24 00:09:19 +0000699TEST_F(WiFiServiceTest, Connectable) {
700 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800701 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000702
703 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -0800704 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000705
706 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800707 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000708
709 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800710 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000711
712 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800713 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000714
715 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -0800716 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
717 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
718 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000719
720 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800721 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
722
723 Service::EapCredentials eap;
724 // Empty EAP credentials should not make a 802.1x network connectable.
725 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
726
727 eap.identity = "something";
728 // If client certificate is being used, a private key must exist.
729 eap.client_cert = "some client cert";
730 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
731 eap.private_key = "some private key";
732 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
733
734 // Identity is always required.
735 eap.identity.clear();
736 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
737
738 eap.identity = "something";
739 // For non EAP-TLS types, a password is required.
740 eap.eap = "Non-TLS";
741 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
742 eap.password = "some password";
743 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -0800744 // Dynamic WEP + 802.1X should be connectable under the same conditions.
745 eap.key_management = "IEEE8021X";
746 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000747}
748
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000749TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800750 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000751 vector<uint8_t> ssid(1, 'a');
752 WiFiServiceRefPtr service = new WiFiService(control_interface(),
753 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800754 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000755 manager(),
756 wifi(),
757 ssid,
758 flimflam::kModeManaged,
759 flimflam::kSecurityNone,
760 false);
761 EXPECT_CALL(*wifi(), IsIdle())
762 .WillRepeatedly(Return(true));
763 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800764 EXPECT_FALSE(service->IsAutoConnectable(&reason));
765 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000766
mukesh agrawalbf14e942012-03-02 14:36:34 -0800767 reason = "";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800768 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000769 service->AddEndpoint(endpoint);
770 EXPECT_CALL(*wifi(), IsIdle())
771 .WillRepeatedly(Return(true));
772 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800773 EXPECT_TRUE(service->IsAutoConnectable(&reason));
774 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000775
776 // WiFi only supports connecting to one Service at a time. So, to
777 // avoid disrupting connectivity, we only allow auto-connection to
778 // a WiFiService when the corresponding WiFi is idle.
779 EXPECT_CALL(*wifi(), IsIdle())
780 .WillRepeatedly(Return(false));
781 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800782 EXPECT_FALSE(service->IsAutoConnectable(&reason));
783 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000784}
785
786TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800787 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000788 vector<uint8_t> ssid(1, 'a');
789 WiFiServiceRefPtr service = new WiFiService(control_interface(),
790 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800791 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000792 manager(),
793 wifi(),
794 ssid,
795 flimflam::kModeManaged,
796 flimflam::kSecurityNone,
797 false);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800798 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000799 EXPECT_CALL(*wifi(), ConnectTo(_, _))
800 .Times(0);
801 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500802 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000803
mukesh agrawale1d90e92012-02-15 17:36:08 -0800804 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000805 service->AddEndpoint(endpoint);
806 EXPECT_CALL(*wifi(), IsIdle())
807 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -0800808 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000809 EXPECT_CALL(*wifi(), ConnectTo(_, _));
810 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500811 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -0800812
813 Error error;
814 service->Disconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500815 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -0800816 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000817}
818
Gaurav Shah10109f22011-11-11 20:16:22 -0800819TEST_F(WiFiServiceTest, Populate8021x) {
820 vector<uint8_t> ssid(1, 'a');
821 WiFiServiceRefPtr service = new WiFiService(control_interface(),
822 dispatcher(),
823 metrics(),
824 manager(),
825 wifi(),
826 ssid,
827 flimflam::kModeManaged,
828 flimflam::kSecurityNone,
829 false);
830 Service::EapCredentials eap;
831 eap.identity = "testidentity";
Paul Stewart20550982012-04-16 12:16:11 -0700832 eap.pin = "xxxx";
Gaurav Shah10109f22011-11-11 20:16:22 -0800833 service->set_eap(eap);
834 map<string, ::DBus::Variant> params;
835 service->Populate8021xProperties(&params);
836 // Test that only non-empty 802.1x properties are populated.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700837 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapIdentity));
838 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
839 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
840
Paul Stewart20550982012-04-16 12:16:11 -0700841 // Test that CA path is set by default.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700842 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
843
Paul Stewart20550982012-04-16 12:16:11 -0700844 // Test that hardware-backed security arguments are not set.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700845 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
846 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
847 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
Paul Stewart20550982012-04-16 12:16:11 -0700848}
849
850TEST_F(WiFiServiceTest, Populate8021xNoSystemCAs) {
851 vector<uint8_t> ssid(1, 'a');
852 WiFiServiceRefPtr service = new WiFiService(control_interface(),
853 dispatcher(),
854 metrics(),
855 manager(),
856 wifi(),
857 ssid,
858 flimflam::kModeManaged,
859 flimflam::kSecurityNone,
860 false);
861 Service::EapCredentials eap;
862 eap.identity = "testidentity";
863 eap.use_system_cas = false;
864 service->set_eap(eap);
865 map<string, ::DBus::Variant> params;
866 service->Populate8021xProperties(&params);
867 // Test that CA path is not set if use_system_cas is explicitly false.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700868 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
Paul Stewart20550982012-04-16 12:16:11 -0700869}
870
871TEST_F(WiFiServiceTest, Populate8021xUsingHardwareAuth) {
872 vector<uint8_t> ssid(1, 'a');
873 WiFiServiceRefPtr service = new WiFiService(control_interface(),
874 dispatcher(),
875 metrics(),
876 manager(),
877 wifi(),
878 ssid,
879 flimflam::kModeManaged,
880 flimflam::kSecurityNone,
881 false);
882 Service::EapCredentials eap;
883 eap.identity = "testidentity";
884 eap.key_id = "key_id";
885 eap.pin = "xxxx";
886 service->set_eap(eap);
887 map<string, ::DBus::Variant> params;
888 service->Populate8021xProperties(&params);
889 // Test that EAP engine parameters set if key_id is set.
Paul Stewartecf4cd12012-04-17 11:08:39 -0700890 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
891 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
892 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
893 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
894}
895
896TEST_F(WiFiServiceTest, Populate8021xNSS) {
897 vector<uint8_t> ssid(1, 'a');
898 WiFiServiceRefPtr service = new WiFiService(control_interface(),
899 dispatcher(),
900 metrics(),
901 manager(),
902 wifi(),
903 ssid,
904 flimflam::kModeManaged,
905 flimflam::kSecurityNone,
906 false);
907 Service::EapCredentials eap;
908 eap.ca_cert_nss = "nss_nickname";
909 service->set_eap(eap);
910 MockNSS nss;
911 service->nss_ = &nss;
912
913 const string kNSSCertfile("/tmp/nss-cert");
914 FilePath nss_cert(kNSSCertfile);
915 vector<char> ssid_in_chars(ssid.begin(), ssid.end());
916 EXPECT_CALL(nss, GetDERCertfile(eap.ca_cert_nss, ssid_in_chars))
917 .WillOnce(Return(nss_cert));
918
919 map<string, ::DBus::Variant> params;
920 service->Populate8021xProperties(&params);
921 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
922 if (ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert)) {
923 EXPECT_EQ(kNSSCertfile, params[wpa_supplicant::kNetworkPropertyEapCaCert]
924 .reader().get_string());
925 }
Gaurav Shah10109f22011-11-11 20:16:22 -0800926}
927
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800928TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
929 vector<uint8_t> ssid(1, 'a');
930 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
931 dispatcher(),
932 metrics(),
933 manager(),
934 wifi(),
935 ssid,
936 flimflam::kModeManaged,
937 flimflam::kSecurityWep,
938 false);
939
940 EXPECT_EQ("", wifi_service->passphrase_);
941
942 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800943 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800944 wifi_service->mutable_store(),
945 flimflam::kPassphraseProperty,
946 DBusAdaptor::StringToVariant("0:abcde"),
947 &error));
948 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
949
950 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
951 flimflam::kPassphraseProperty,
952 &error));
953 EXPECT_EQ("", wifi_service->passphrase_);
954}
955
mukesh agrawale1d90e92012-02-15 17:36:08 -0800956TEST_F(WiFiServiceTest, SignalToStrength) {
957 // Verify that our mapping is sane, in the sense that it preserves ordering.
958 // We break the test into two domains, because we assume that positive
959 // values aren't actually in dBm.
960 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
961 int16 current_mapped = WiFiService::SignalToStrength(i);
962 int16 next_mapped = WiFiService::SignalToStrength(i+1);
963 EXPECT_LE(current_mapped, next_mapped)
964 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -0800965 EXPECT_GE(current_mapped, Service::kStrengthMin);
966 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800967 }
968 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
969 int16 current_mapped = WiFiService::SignalToStrength(i);
970 int16 next_mapped = WiFiService::SignalToStrength(i+1);
971 EXPECT_LE(current_mapped, next_mapped)
972 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -0800973 EXPECT_GE(current_mapped, Service::kStrengthMin);
974 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800975 }
976}
977
978TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
979 // If the chosen signal values don't map to distinct strength
980 // values, then we can't expect our other tests to pass. So verify
981 // their distinctness.
982 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
983 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
984 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
985}
986
987TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
988 // Initial endpoint updates values.
989 EXPECT_CALL(adaptor, EmitUint16Changed(
990 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -0700991 EXPECT_CALL(adaptor, EmitStringChanged(
992 flimflam::kWifiBSsid, kOkEndpointBssId));
993 EXPECT_CALL(adaptor, EmitUint8Changed(
mukesh agrawale1d90e92012-02-15 17:36:08 -0800994 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
995 service->AddEndpoint(ok_endpoint);
996 Mock::VerifyAndClearExpectations(&adaptor);
997
998 // Endpoint with stronger signal updates values.
999 EXPECT_CALL(adaptor, EmitUint16Changed(
1000 flimflam::kWifiFrequency, kGoodEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001001 EXPECT_CALL(adaptor, EmitStringChanged(
1002 flimflam::kWifiBSsid, kGoodEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001003 EXPECT_CALL(adaptor, EmitUint8Changed(
1004 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
1005 service->AddEndpoint(good_endpoint);
1006 Mock::VerifyAndClearExpectations(&adaptor);
1007
1008 // Endpoint with lower signal does not change values.
1009 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001010 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001011 EXPECT_CALL(adaptor,
1012 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1013 service->AddEndpoint(bad_endpoint);
1014 Mock::VerifyAndClearExpectations(&adaptor);
1015
1016 // Removing non-optimal endpoint does not change values.
1017 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001018 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001019 EXPECT_CALL(adaptor,
1020 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1021 service->RemoveEndpoint(bad_endpoint);
1022 Mock::VerifyAndClearExpectations(&adaptor);
1023
1024 // Removing optimal endpoint updates values.
1025 EXPECT_CALL(adaptor, EmitUint16Changed(
1026 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001027 EXPECT_CALL(adaptor, EmitStringChanged(
1028 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001029 EXPECT_CALL(adaptor, EmitUint8Changed(
1030 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1031 service->RemoveEndpoint(good_endpoint);
1032 Mock::VerifyAndClearExpectations(&adaptor);
1033
1034 // Removing last endpoint updates values (and doesn't crash).
1035 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001036 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001037 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1038 service->RemoveEndpoint(ok_endpoint);
1039 Mock::VerifyAndClearExpectations(&adaptor);
1040}
1041
1042TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1043 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001044 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001045 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1046 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1047 service->AddEndpoint(bad_endpoint);
1048 service->AddEndpoint(ok_endpoint);
1049 Mock::VerifyAndClearExpectations(&adaptor);
1050
1051 // Setting current endpoint forces adoption of its values, even if it
1052 // doesn't have the highest signal.
1053 EXPECT_CALL(adaptor, EmitUint16Changed(
1054 flimflam::kWifiFrequency, kBadEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001055 EXPECT_CALL(adaptor, EmitStringChanged(
1056 flimflam::kWifiBSsid, kBadEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001057 EXPECT_CALL(adaptor, EmitUint8Changed(
1058 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
1059 service->NotifyCurrentEndpoint(bad_endpoint);
1060 Mock::VerifyAndClearExpectations(&adaptor);
1061
1062 // Adding a better endpoint doesn't matter, when current endpoint is set.
1063 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001064 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001065 EXPECT_CALL(adaptor,
1066 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1067 service->AddEndpoint(good_endpoint);
1068 Mock::VerifyAndClearExpectations(&adaptor);
1069
1070 // Removing a better endpoint doesn't matter, when current endpoint is set.
1071 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001072 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001073 EXPECT_CALL(adaptor,
1074 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1075 service->RemoveEndpoint(good_endpoint);
1076 Mock::VerifyAndClearExpectations(&adaptor);
1077
1078 // Removing the current endpoint is safe and sane.
1079 EXPECT_CALL(adaptor, EmitUint16Changed(
1080 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001081 EXPECT_CALL(adaptor, EmitStringChanged(
1082 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001083 EXPECT_CALL(adaptor, EmitUint8Changed(
1084 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1085 service->RemoveEndpoint(bad_endpoint);
1086 Mock::VerifyAndClearExpectations(&adaptor);
1087
1088 // Clearing the current endpoint (without removing it) is also safe and sane.
1089 service->NotifyCurrentEndpoint(ok_endpoint);
1090 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001091 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001092 EXPECT_CALL(adaptor,
1093 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1094 service->NotifyCurrentEndpoint(NULL);
1095 Mock::VerifyAndClearExpectations(&adaptor);
1096}
1097
1098TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1099 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001100 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001101 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1102 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1103 service->AddEndpoint(ok_endpoint);
1104 service->AddEndpoint(good_endpoint);
1105 Mock::VerifyAndClearExpectations(&adaptor);
1106
1107 // Updating sub-optimal Endpoint doesn't update Service.
1108 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001109 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001110 EXPECT_CALL(adaptor,
1111 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1112 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
1113 service->NotifyEndpointUpdated(*ok_endpoint);
1114 Mock::VerifyAndClearExpectations(&adaptor);
1115
1116 // Updating optimal Endpoint updates appropriate Service property.
1117 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001118 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001119 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1120 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
1121 service->NotifyEndpointUpdated(*good_endpoint);
1122 Mock::VerifyAndClearExpectations(&adaptor);
1123
1124 // Change in optimal Endpoint updates Service properties.
1125 EXPECT_CALL(adaptor, EmitUint16Changed(
1126 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001127 EXPECT_CALL(adaptor, EmitStringChanged(
1128 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001129 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1130 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
1131 service->NotifyEndpointUpdated(*ok_endpoint);
1132 Mock::VerifyAndClearExpectations(&adaptor);
1133}
1134
Chris Masone34af2182011-08-22 11:59:36 -07001135} // namespace shill