blob: 59cecf3361cd673c44421a7b9a6f4d8212962b91 [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>
Paul Stewart85aea152013-01-22 09:31:56 -08008#include <set>
Chris Masone34af2182011-08-22 11:59:36 -07009#include <string>
10#include <vector>
11
Paul Stewart85aea152013-01-22 09:31:56 -080012#include <base/stringprintf.h>
Paul Stewart71a4d3b2013-01-18 18:12:56 -080013#include <base/string_number_conversions.h>
Chris Masone34af2182011-08-22 11:59:36 -070014#include <base/string_util.h>
15#include <chromeos/dbus/service_constants.h>
16#include <gmock/gmock.h>
17#include <gtest/gtest.h>
18
Paul Stewart26b327e2011-10-19 11:38:09 -070019#include "shill/event_dispatcher.h"
Chris Masone34af2182011-08-22 11:59:36 -070020#include "shill/manager.h"
21#include "shill/mock_adaptors.h"
22#include "shill/mock_control.h"
Paul Stewart71a4d3b2013-01-18 18:12:56 -080023#include "shill/mock_log.h"
Paul Stewartecf4cd12012-04-17 11:08:39 -070024#include "shill/mock_nss.h"
Christopher Wiley1ce658d2012-10-10 10:02:03 -070025#include "shill/mock_profile.h"
Chris Masone34af2182011-08-22 11:59:36 -070026#include "shill/mock_service.h"
27#include "shill/mock_store.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070028#include "shill/mock_wifi.h"
Paul Stewart3c504012013-01-17 17:49:58 -080029#include "shill/mock_wifi_provider.h"
Chris Masone34af2182011-08-22 11:59:36 -070030#include "shill/property_store_unittest.h"
mukesh agrawal8a3188d2011-12-01 20:56:44 +000031#include "shill/refptr_types.h"
32#include "shill/wifi_endpoint.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070033#include "shill/wpa_supplicant.h"
Chris Masone34af2182011-08-22 11:59:36 -070034
mukesh agrawald835b202011-10-07 15:26:47 -070035using std::map;
Paul Stewart85aea152013-01-22 09:31:56 -080036using std::set;
Chris Masone34af2182011-08-22 11:59:36 -070037using std::string;
38using std::vector;
Paul Stewartd08f4432011-11-04 07:48:20 -070039using ::testing::_;
mukesh agrawale1d90e92012-02-15 17:36:08 -080040using ::testing::AnyNumber;
Paul Stewartd08f4432011-11-04 07:48:20 -070041using ::testing::DoAll;
Paul Stewart71a4d3b2013-01-18 18:12:56 -080042using ::testing::EndsWith;
Paul Stewart3c504012013-01-17 17:49:58 -080043using ::testing::HasSubstr;
mukesh agrawale1d90e92012-02-15 17:36:08 -080044using ::testing::Mock;
mukesh agrawal6e277772011-09-29 15:04:23 -070045using ::testing::NiceMock;
Paul Stewartd08f4432011-11-04 07:48:20 -070046using ::testing::Return;
47using ::testing::SetArgumentPointee;
48using ::testing::StrEq;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080049using ::testing::StrNe;
Paul Stewart85aea152013-01-22 09:31:56 -080050using ::testing::StrictMock;
Chris Masone34af2182011-08-22 11:59:36 -070051
mukesh agrawalb20776f2012-02-10 16:00:36 -080052namespace shill {
53
Chris Masone34af2182011-08-22 11:59:36 -070054class WiFiServiceTest : public PropertyStoreTest {
55 public:
Paul Stewart3c504012013-01-17 17:49:58 -080056 WiFiServiceTest()
57 : wifi_(new NiceMock<MockWiFi>(
58 control_interface(),
59 dispatcher(),
60 metrics(),
61 manager(),
62 "wifi",
63 fake_mac,
64 0)),
65 simple_ssid_(1, 'a'),
66 simple_ssid_string_("a") {}
Chris Masone34af2182011-08-22 11:59:36 -070067 virtual ~WiFiServiceTest() {}
mukesh agrawal6e277772011-09-29 15:04:23 -070068
69 protected:
70 static const char fake_mac[];
mukesh agrawale1d90e92012-02-15 17:36:08 -080071
Gaurav Shah10109f22011-11-11 20:16:22 -080072 bool CheckConnectable(const std::string &security, const char *passphrase,
73 Service::EapCredentials *eap) {
mukesh agrawal29c13a12011-11-24 00:09:19 +000074 Error error;
Paul Stewart3c504012013-01-17 17:49:58 -080075 WiFiServiceRefPtr service = MakeSimpleService(security);
mukesh agrawal29c13a12011-11-24 00:09:19 +000076 if (passphrase)
77 service->SetPassphrase(passphrase, &error);
Gaurav Shah10109f22011-11-11 20:16:22 -080078 if (eap) {
79 service->set_eap(*eap);
80 }
mukesh agrawal29c13a12011-11-24 00:09:19 +000081 return service->connectable();
82 }
mukesh agrawale1d90e92012-02-15 17:36:08 -080083 WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid,
84 uint16 frequency, int16 signal_dbm) {
85 return WiFiEndpoint::MakeOpenEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -080086 NULL, wifi(), ssid, bssid, wpa_supplicant::kNetworkModeInfrastructure,
87 frequency, signal_dbm);
mukesh agrawale1d90e92012-02-15 17:36:08 -080088 }
Paul Stewart3c504012013-01-17 17:49:58 -080089 WiFiServiceRefPtr MakeSimpleService(const string &security) {
mukesh agrawale1d90e92012-02-15 17:36:08 -080090 return new WiFiService(control_interface(),
91 dispatcher(),
92 metrics(),
93 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -080094 &provider_,
95 simple_ssid_,
mukesh agrawale1d90e92012-02-15 17:36:08 -080096 flimflam::kModeManaged,
Paul Stewart3c504012013-01-17 17:49:58 -080097 security,
mukesh agrawale1d90e92012-02-15 17:36:08 -080098 false);
99 }
Paul Stewart3c504012013-01-17 17:49:58 -0800100 WiFiServiceRefPtr MakeGenericService() {
101 return MakeSimpleService(flimflam::kSecurityWep);
102 }
103 void SetWiFiForService(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
104 service->wifi_ = wifi;
105 }
106 WiFiServiceRefPtr MakeServiceWithWiFi(const string &security) {
107 WiFiServiceRefPtr service = MakeSimpleService(security);
108 SetWiFiForService(service, wifi_);
109 return service;
110 }
mukesh agrawale1d90e92012-02-15 17:36:08 -0800111 ServiceMockAdaptor *GetAdaptor(WiFiService *service) {
112 return dynamic_cast<ServiceMockAdaptor *>(service->adaptor());
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000113 }
Paul Stewart3c504012013-01-17 17:49:58 -0800114 Error::Type TestConfigurePassphrase(const string &security,
115 const char *passphrase) {
116 WiFiServiceRefPtr service = MakeSimpleService(security);
117 KeyValueStore args;
118 if (passphrase) {
119 args.SetString(flimflam::kPassphraseProperty, passphrase);
120 }
121 Error error;
122 service->Configure(args, &error);
123 return error.type();
124 }
mukesh agrawal6e277772011-09-29 15:04:23 -0700125 scoped_refptr<MockWiFi> wifi() { return wifi_; }
Paul Stewart3c504012013-01-17 17:49:58 -0800126 MockWiFiProvider *provider() { return &provider_; }
127 string GetAnyDeviceAddress() { return WiFiService::kAnyDeviceAddress; }
128 const vector<uint8_t> &simple_ssid() { return simple_ssid_; }
129 const string &simple_ssid_string() { return simple_ssid_string_; }
mukesh agrawal6e277772011-09-29 15:04:23 -0700130
131 private:
132 scoped_refptr<MockWiFi> wifi_;
Paul Stewart3c504012013-01-17 17:49:58 -0800133 MockWiFiProvider provider_;
134 const vector<uint8_t> simple_ssid_;
135 const string simple_ssid_string_;
Chris Masone34af2182011-08-22 11:59:36 -0700136};
137
mukesh agrawal6e277772011-09-29 15:04:23 -0700138// static
139const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
140
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800141MATCHER_P3(ContainsWiFiProperties, ssid, mode, security, "") {
142 string hex_ssid = base::HexEncode(ssid.data(), ssid.size());
143 return
144 arg.ContainsString(WiFiService::kStorageType) &&
145 arg.GetString(WiFiService::kStorageType) == flimflam::kTypeWifi &&
146 arg.ContainsString(WiFiService::kStorageSSID) &&
147 arg.GetString(WiFiService::kStorageSSID) == hex_ssid &&
148 arg.ContainsString(WiFiService::kStorageMode) &&
149 arg.GetString(WiFiService::kStorageMode) == mode &&
150 arg.ContainsString(WiFiService::kStorageSecurityClass) &&
151 arg.GetString(WiFiService::kStorageSecurityClass) == security;
152}
153
Paul Stewartd08f4432011-11-04 07:48:20 -0700154class WiFiServiceSecurityTest : public WiFiServiceTest {
155 public:
Paul Stewartd08f4432011-11-04 07:48:20 -0700156 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
157 const string &security) {
158 string id = wifi_service->GetStorageIdentifier();
Paul Stewart3c504012013-01-17 17:49:58 -0800159 size_t mac_pos = id.find(StringToLowerASCII(GetAnyDeviceAddress()));
Paul Stewartd08f4432011-11-04 07:48:20 -0700160 EXPECT_NE(mac_pos, string::npos);
161 size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
162 EXPECT_NE(mode_pos, string::npos);
163 return id.find(string(security), mode_pos) != string::npos;
164 }
165
166 // Test that a service that is created with security |from_security|
167 // gets by default a storage identifier with |to_security| as its
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800168 // security component, and that when saved, it sets the Security
169 // property in to |to_security| as well.
Paul Stewartd08f4432011-11-04 07:48:20 -0700170 bool TestStorageMapping(const string &from_security,
171 const string &to_security) {
Paul Stewart3c504012013-01-17 17:49:58 -0800172 WiFiServiceRefPtr wifi_service = MakeSimpleService(from_security);
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800173 NiceMock<MockStore> mock_store;
174 EXPECT_CALL(mock_store, SetString(_, _, _)).WillRepeatedly(Return(true));
175 EXPECT_CALL(mock_store,
176 SetString(_, WiFiService::kStorageSecurity, from_security))
177 .Times(1);
178 EXPECT_CALL(mock_store,
179 SetString(_, WiFiService::kStorageSecurityClass, to_security))
180 .Times(1);
181 wifi_service->Save(&mock_store);
Paul Stewartd08f4432011-11-04 07:48:20 -0700182 return TestStorageSecurityIs(wifi_service, to_security);
183 }
184
185 // Test whether a service of type |service_security| can load from a
186 // storage interface containing an entry for |storage_security|.
187 // Make sure the result meets |expectation|. If |expectation| is
188 // true, also make sure the service storage identifier changes to
189 // match |storage_security|.
190 bool TestLoadMapping(const string &service_security,
191 const string &storage_security,
192 bool expectation) {
Paul Stewart3c504012013-01-17 17:49:58 -0800193 WiFiServiceRefPtr wifi_service = MakeSimpleService(service_security);
Paul Stewartd08f4432011-11-04 07:48:20 -0700194 NiceMock<MockStore> mock_store;
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800195 EXPECT_CALL(mock_store, GetGroupsWithProperties(_))
196 .WillRepeatedly(Return(set<string>()));
197 const string kStorageId = "storage_id";
198 EXPECT_CALL(mock_store, ContainsGroup(kStorageId))
Paul Stewartd08f4432011-11-04 07:48:20 -0700199 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800200 set<string> groups;
201 groups.insert(kStorageId);
202 EXPECT_CALL(mock_store, GetGroupsWithProperties(
203 ContainsWiFiProperties(wifi_service->ssid(),
204 flimflam::kModeManaged,
205 storage_security)))
206 .WillRepeatedly(Return(groups));
Paul Stewartd08f4432011-11-04 07:48:20 -0700207 bool is_loadable = wifi_service->IsLoadableFrom(&mock_store);
208 EXPECT_EQ(expectation, is_loadable);
209 bool is_loaded = wifi_service->Load(&mock_store);
210 EXPECT_EQ(expectation, is_loaded);
211
212 if (expectation != is_loadable || expectation != is_loaded) {
213 return false;
214 } else if (!expectation) {
215 return true;
216 } else {
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800217 return wifi_service->GetStorageIdentifier() == kStorageId;
Paul Stewartd08f4432011-11-04 07:48:20 -0700218 }
219 }
220};
221
mukesh agrawale1d90e92012-02-15 17:36:08 -0800222class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
223 public:
224 WiFiServiceUpdateFromEndpointsTest()
225 : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
226 kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
227 kGoodEndpointStrength(
228 WiFiService::SignalToStrength(kGoodEndpointSignal)),
229 service(MakeGenericService()),
230 adaptor(*GetAdaptor(service)) {
231 ok_endpoint = MakeEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800232 simple_ssid_string(), kOkEndpointBssId, kOkEndpointFrequency,
233 kOkEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800234 good_endpoint = MakeEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800235 simple_ssid_string(), kGoodEndpointBssId, kGoodEndpointFrequency,
236 kGoodEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800237 bad_endpoint = MakeEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800238 simple_ssid_string(), kBadEndpointBssId, kBadEndpointFrequency,
239 kBadEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800240 }
241
242 protected:
243 static const uint16 kOkEndpointFrequency = 2422;
244 static const uint16 kBadEndpointFrequency = 2417;
245 static const uint16 kGoodEndpointFrequency = 2412;
246 static const int16 kOkEndpointSignal = -50;
247 static const int16 kBadEndpointSignal = -75;
248 static const int16 kGoodEndpointSignal = -25;
mukesh agrawal923f14f2012-06-04 16:46:08 -0700249 static const char *kOkEndpointBssId;
250 static const char *kGoodEndpointBssId;
251 static const char *kBadEndpointBssId;
mukesh agrawale1d90e92012-02-15 17:36:08 -0800252 // Can't be both static and const (because initialization requires a
253 // function call). So choose to be just const.
254 const uint8 kOkEndpointStrength;
255 const uint8 kBadEndpointStrength;
256 const uint8 kGoodEndpointStrength;
257 WiFiEndpointRefPtr ok_endpoint;
258 WiFiEndpointRefPtr bad_endpoint;
259 WiFiEndpointRefPtr good_endpoint;
260 WiFiServiceRefPtr service;
261 ServiceMockAdaptor &adaptor;
262};
263
mukesh agrawal923f14f2012-06-04 16:46:08 -0700264const char *WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId =
265 "00:00:00:00:00:01";
266const char *WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId =
267 "00:00:00:00:00:02";
268const char *WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId =
269 "00:00:00:00:00:03";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800270
Paul Stewart85aea152013-01-22 09:31:56 -0800271class WiFiServiceFixupStorageTest : public WiFiServiceTest {
272 protected:
273 void AddGroup(string group_name) {
274 groups_.insert(group_name);
275 }
276
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800277 void AddServiceEntry(bool has_type, bool has_mode, bool has_security,
278 bool has_security_class) {
Paul Stewart85aea152013-01-22 09:31:56 -0800279 int index = groups_.size();
280 string id = base::StringPrintf("%s_%d_%d_%s_%s", flimflam::kTypeWifi,
281 index, index, flimflam::kModeManaged,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800282 flimflam::kSecurityWpa);
Paul Stewart85aea152013-01-22 09:31:56 -0800283 AddGroup(id);
284 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageType, _))
285 .WillOnce(Return(has_type));
286 if (!has_type) {
287 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageType,
288 flimflam::kTypeWifi));
289 }
290 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageMode, _))
291 .WillOnce(Return(has_mode));
292 if (!has_mode) {
293 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageMode,
294 flimflam::kModeManaged));
295 }
296 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurity, _))
297 .WillOnce(Return(has_security));
298 if (!has_security) {
299 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurity,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800300 flimflam::kSecurityWpa));
301 }
302 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurityClass, _))
303 .WillOnce(Return(has_security_class));
304 if (!has_security_class) {
305 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurityClass,
306 flimflam::kSecurityPsk));
Paul Stewart85aea152013-01-22 09:31:56 -0800307 }
308 }
309
310 bool FixupServiceEntries() {
311 EXPECT_CALL(store_, GetGroups()).WillOnce(Return(groups_));
312 return WiFiService::FixupServiceEntries(&store_);
313 }
314
315 private:
316 StrictMock<MockStore> store_;
317 set<string> groups_;
318};
319
Chris Masone34af2182011-08-22 11:59:36 -0700320TEST_F(WiFiServiceTest, StorageId) {
Paul Stewart3c504012013-01-17 17:49:58 -0800321 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityNone);
Chris Masone9d779932011-08-25 16:33:41 -0700322 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700323 for (uint i = 0; i < id.length(); ++i) {
324 EXPECT_TRUE(id[i] == '_' ||
325 isxdigit(id[i]) ||
326 (isalpha(id[i]) && islower(id[i])));
327 }
Paul Stewart3c504012013-01-17 17:49:58 -0800328 size_t mac_pos = id.find(StringToLowerASCII(GetAnyDeviceAddress()));
Chris Masone34af2182011-08-22 11:59:36 -0700329 EXPECT_NE(mac_pos, string::npos);
330 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
331}
332
Gaurav Shahda6218a2011-11-11 12:09:33 -0800333// Make sure the passphrase is registered as a write only property
334// by reading and comparing all string properties returned on the store.
335TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
Paul Stewart3c504012013-01-17 17:49:58 -0800336 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWpa);
Gaurav Shahda6218a2011-11-11 12:09:33 -0800337 ReadablePropertyConstIterator<string> it =
338 (wifi_service->store()).GetStringPropertiesIter();
339 for( ; !it.AtEnd(); it.Advance())
340 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
341}
342
Thieu Lef7709452011-11-15 01:13:19 +0000343// Make sure setting the passphrase via D-Bus Service.SetProperty validates
344// the passphrase.
345TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
346 // We only spot check two password cases here to make sure the
347 // SetProperty code path does validation. We're not going to exhaustively
348 // test for all types of passwords.
Paul Stewart3c504012013-01-17 17:49:58 -0800349 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWep);
Thieu Lef7709452011-11-15 01:13:19 +0000350 Error error;
351 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
352 flimflam::kPassphraseProperty, "0:abcde", &error));
353 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
354 flimflam::kPassphraseProperty, "invalid", &error));
355 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
356}
357
358TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
Paul Stewart3c504012013-01-17 17:49:58 -0800359 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityNone);
Thieu Lef7709452011-11-15 01:13:19 +0000360 Error error;
361 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
362 flimflam::kPassphraseProperty, "invalid", &error));
363 EXPECT_EQ(Error::kNotSupported, error.type());
364}
365
mukesh agrawald835b202011-10-07 15:26:47 -0700366TEST_F(WiFiServiceTest, NonUTF8SSID) {
367 vector<uint8_t> ssid;
368
369 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
370 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
371 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800372 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700373 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800374 provider(),
mukesh agrawald835b202011-10-07 15:26:47 -0700375 ssid,
376 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800377 flimflam::kSecurityNone,
378 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700379 map<string, ::DBus::Variant> properties;
380 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
381 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
382}
383
Gaurav Shahda6218a2011-11-11 12:09:33 -0800384MATCHER(WPASecurityArgs, "") {
385 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
386 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
387}
388
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800389MATCHER(WPA80211wSecurityArgs, "") {
390 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
391 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey) &&
392 ContainsKey(arg, wpa_supplicant::kNetworkPropertyIeee80211w);
393}
394
Gaurav Shah10109f22011-11-11 20:16:22 -0800395MATCHER(EAPSecurityArgs, "") {
396 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
397 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath);
398}
399
Paul Stewarte2d7c502012-07-16 16:35:10 -0700400MATCHER_P(FrequencyArg, has_arg, "") {
401 return has_arg ==
402 ContainsKey(arg, wpa_supplicant::kNetworkPropertyFrequency);
403}
404
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700405TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Paul Stewart3c504012013-01-17 17:49:58 -0800406 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWpa);
mukesh agrawal6e277772011-09-29 15:04:23 -0700407 EXPECT_CALL(*wifi(),
408 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700409 Error error;
410 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500411 wifi_service->Connect(NULL);
mukesh agrawal6e277772011-09-29 15:04:23 -0700412}
413
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700414TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Paul Stewart3c504012013-01-17 17:49:58 -0800415 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityRsn);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700416 EXPECT_CALL(*wifi(),
417 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700418 Error error;
419 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500420 wifi_service->Connect(NULL);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700421}
422
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700423TEST_F(WiFiServiceTest, ConnectConditions) {
424 Error error;
Paul Stewart3c504012013-01-17 17:49:58 -0800425 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityNone);
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700426 scoped_refptr<MockProfile> mock_profile(
427 new NiceMock<MockProfile>(control_interface(), manager()));
428 wifi_service->set_profile(mock_profile);
429 // With nothing else going on, the service should attempt to connect.
430 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), _));
431 wifi_service->Connect(&error);
432 Mock::VerifyAndClearExpectations(wifi());
433
434 // But if we're already "connecting" or "connected" then we shouldn't attempt
435 // again.
436 EXPECT_CALL(*wifi(),
437 ConnectTo(wifi_service.get(), _)).Times(0);
438 wifi_service->SetState(Service::kStateAssociating);
439 wifi_service->Connect(&error);
440 wifi_service->SetState(Service::kStateConfiguring);
441 wifi_service->Connect(&error);
442 wifi_service->SetState(Service::kStateConnected);
443 wifi_service->Connect(&error);
444 wifi_service->SetState(Service::kStatePortal);
445 wifi_service->Connect(&error);
446 wifi_service->SetState(Service::kStateOnline);
447 wifi_service->Connect(&error);
448 Mock::VerifyAndClearExpectations(wifi());
449}
450
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800451TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Paul Stewart3c504012013-01-17 17:49:58 -0800452 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityPsk);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800453 EXPECT_CALL(*wifi(),
454 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700455 Error error;
456 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500457 wifi_service->Connect(NULL);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800458}
459
Gaurav Shah10109f22011-11-11 20:16:22 -0800460TEST_F(WiFiServiceTest, ConnectTask8021x) {
Paul Stewart3c504012013-01-17 17:49:58 -0800461 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
Gaurav Shah10109f22011-11-11 20:16:22 -0800462 Service::EapCredentials eap;
463 eap.identity = "identity";
Wade Guthrie005bd342012-05-02 09:37:07 -0700464 eap.password = "mumble";
Paul Stewart3c504012013-01-17 17:49:58 -0800465 service->set_eap(eap);
466 EXPECT_CALL(*wifi(), ConnectTo(service.get(), EAPSecurityArgs()));
467 service->Connect(NULL);
Gaurav Shah10109f22011-11-11 20:16:22 -0800468}
469
Paul Stewarte2d7c502012-07-16 16:35:10 -0700470TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) {
471 vector<uint8_t> ssid(1, 'a');
472 WiFiEndpointRefPtr endpoint_nofreq =
473 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
474 WiFiEndpointRefPtr endpoint_freq =
475 MakeEndpoint("a", "00:00:00:00:00:02", 2412, 0);
476
Paul Stewart3c504012013-01-17 17:49:58 -0800477 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityNone);
Paul Stewarte2d7c502012-07-16 16:35:10 -0700478 wifi_service->AddEndpoint(endpoint_freq);
479 EXPECT_CALL(*wifi(),
480 ConnectTo(wifi_service.get(), FrequencyArg(false)));
481 wifi_service->Connect(NULL);
482
483 wifi_service = new WiFiService(control_interface(),
484 dispatcher(),
485 metrics(),
486 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800487 provider(),
Paul Stewarte2d7c502012-07-16 16:35:10 -0700488 ssid,
489 flimflam::kModeAdhoc,
490 flimflam::kSecurityNone,
491 false);
492 EXPECT_CALL(*wifi(),
493 ConnectTo(wifi_service.get(), FrequencyArg(false)));
Paul Stewart3c504012013-01-17 17:49:58 -0800494 SetWiFiForService(wifi_service, wifi());
Paul Stewarte2d7c502012-07-16 16:35:10 -0700495 wifi_service->Connect(NULL);
496
497 wifi_service = new WiFiService(control_interface(),
498 dispatcher(),
499 metrics(),
500 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800501 provider(),
Paul Stewarte2d7c502012-07-16 16:35:10 -0700502 ssid,
503 flimflam::kModeAdhoc,
504 flimflam::kSecurityNone,
505 false);
506 wifi_service->AddEndpoint(endpoint_nofreq);
Paul Stewart3c504012013-01-17 17:49:58 -0800507 SetWiFiForService(wifi_service, wifi());
Paul Stewarte2d7c502012-07-16 16:35:10 -0700508 EXPECT_CALL(*wifi(),
509 ConnectTo(wifi_service.get(), FrequencyArg(false)));
510 wifi_service->Connect(NULL);
511
512 wifi_service = new WiFiService(control_interface(),
513 dispatcher(),
514 metrics(),
515 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800516 provider(),
Paul Stewarte2d7c502012-07-16 16:35:10 -0700517 ssid,
518 flimflam::kModeAdhoc,
519 flimflam::kSecurityNone,
520 false);
521 wifi_service->AddEndpoint(endpoint_freq);
Paul Stewart3c504012013-01-17 17:49:58 -0800522 SetWiFiForService(wifi_service, wifi());
Paul Stewarte2d7c502012-07-16 16:35:10 -0700523 EXPECT_CALL(*wifi(),
524 ConnectTo(wifi_service.get(), FrequencyArg(true)));
525 wifi_service->Connect(NULL);
526}
527
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800528TEST_F(WiFiServiceTest, ConnectTaskWPA80211w) {
Paul Stewart3c504012013-01-17 17:49:58 -0800529 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityPsk);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800530 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
531 endpoint->ieee80211w_required_ = true;
532 wifi_service->AddEndpoint(endpoint);
533 Error error;
534 wifi_service->SetPassphrase("0:mumblemumblem", &error);
535 EXPECT_CALL(*wifi(),
536 ConnectTo(wifi_service.get(), WPA80211wSecurityArgs()));
537 wifi_service->Connect(NULL);
538}
539
Thieu Lef4cbda92011-11-10 23:41:24 +0000540MATCHER(WEPSecurityArgsKeyIndex0, "") {
541 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
542 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
543 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
544 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
545 reader().get_uint32() == 0);
546}
547
548MATCHER(WEPSecurityArgsKeyIndex1, "") {
549 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
550 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
551 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
552 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
553 reader().get_uint32() == 1);
554}
555
556MATCHER(WEPSecurityArgsKeyIndex2, "") {
557 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
558 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
559 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
560 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
561 reader().get_uint32() == 2);
562}
563
564MATCHER(WEPSecurityArgsKeyIndex3, "") {
565 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
566 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
567 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
568 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
569 reader().get_uint32() == 3);
570}
571
572TEST_F(WiFiServiceTest, ConnectTaskWEP) {
Paul Stewart3c504012013-01-17 17:49:58 -0800573 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWep);
Thieu Lef4cbda92011-11-10 23:41:24 +0000574 Error error;
575 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
576 EXPECT_CALL(*wifi(),
577 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500578 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000579
580 wifi_service->SetPassphrase("abcdefghijklm", &error);
581 EXPECT_CALL(*wifi(),
582 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500583 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000584
585 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
586 EXPECT_CALL(*wifi(),
587 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500588 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000589
590 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
591 EXPECT_CALL(*wifi(),
592 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500593 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000594
595 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
596 EXPECT_CALL(*wifi(),
597 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500598 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000599}
600
Gaurav Shah29d68882012-01-30 19:06:42 -0800601
602MATCHER(DynamicWEPArgs, "") {
603 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
604 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
605 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
606}
607
608// Dynamic WEP + 802.1x.
609TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
Paul Stewart3c504012013-01-17 17:49:58 -0800610 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWep);
Gaurav Shah29d68882012-01-30 19:06:42 -0800611
612 Service::EapCredentials eap;
613 eap.key_management = "IEEE8021X";
614 eap.identity = "something";
Wade Guthrie005bd342012-05-02 09:37:07 -0700615 eap.password = "mumble";
Gaurav Shah29d68882012-01-30 19:06:42 -0800616 wifi_service->set_eap(eap);
617 EXPECT_CALL(*wifi(),
618 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500619 wifi_service->Connect(NULL);
Gaurav Shah29d68882012-01-30 19:06:42 -0800620}
621
Paul Stewart835934a2012-12-06 19:27:09 -0800622TEST_F(WiFiServiceTest, SetPassphraseRemovesCachedCredentials) {
623 vector<uint8_t> ssid(5);
Paul Stewart3c504012013-01-17 17:49:58 -0800624 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityRsn);
Paul Stewart835934a2012-12-06 19:27:09 -0800625
626 const string kPassphrase = "abcdefgh";
627
628 {
629 Error error;
630 // A changed passphrase should trigger cache removal.
631 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
632 wifi_service->SetPassphrase(kPassphrase, &error);
633 Mock::VerifyAndClearExpectations(wifi());
634 EXPECT_TRUE(error.IsSuccess());
635 }
636
637 {
638 Error error;
639 // An unchanged passphrase should not trigger cache removal.
640 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
641 wifi_service->SetPassphrase(kPassphrase, &error);
642 Mock::VerifyAndClearExpectations(wifi());
643 EXPECT_TRUE(error.IsSuccess());
644 }
645
646 {
647 Error error;
648 // A modified passphrase should trigger cache removal.
649 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
650 wifi_service->SetPassphrase(kPassphrase + "X", &error);
651 Mock::VerifyAndClearExpectations(wifi());
652 EXPECT_TRUE(error.IsSuccess());
653 }
654
655 {
656 Error error;
657 // A cleared passphrase should also trigger cache removal.
658 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
659 wifi_service->ClearPassphrase(&error);
660 Mock::VerifyAndClearExpectations(wifi());
661 EXPECT_TRUE(error.IsSuccess());
662 }
663
664 {
665 Error error;
666 // An invalid passphrase should not trigger cache removal.
667 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
668 wifi_service->SetPassphrase("", &error);
669 Mock::VerifyAndClearExpectations(wifi());
670 EXPECT_FALSE(error.IsSuccess());
671 }
672
673 {
674 // Any change to EAP parameters (including a null one) will trigger cache
675 // removal. This is a lot less granular than the passphrase checks above.
676 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
677 wifi_service->set_eap(Service::EapCredentials());
678 Mock::VerifyAndClearExpectations(wifi());
679 }
680}
681
Paul Stewartd08f4432011-11-04 07:48:20 -0700682TEST_F(WiFiServiceTest, LoadHidden) {
Paul Stewart3c504012013-01-17 17:49:58 -0800683 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewartd08f4432011-11-04 07:48:20 -0700684 ASSERT_FALSE(service->hidden_ssid_);
685 NiceMock<MockStore> mock_store;
686 const string storage_id = service->GetStorageIdentifier();
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800687 set<string> groups;
688 groups.insert(storage_id);
Paul Stewartd08f4432011-11-04 07:48:20 -0700689 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
690 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800691 EXPECT_CALL(mock_store, GetGroupsWithProperties(
692 ContainsWiFiProperties(
Paul Stewart3c504012013-01-17 17:49:58 -0800693 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800694 .WillRepeatedly(Return(groups));
Paul Stewartd08f4432011-11-04 07:48:20 -0700695 EXPECT_CALL(mock_store, GetBool(_, _, _))
696 .WillRepeatedly(Return(false));
697 EXPECT_CALL(mock_store,
698 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
699 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
700 EXPECT_TRUE(service->Load(&mock_store));
701 EXPECT_TRUE(service->hidden_ssid_);
702}
703
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800704TEST_F(WiFiServiceTest, LoadMultipleMatchingGroups) {
Paul Stewart3c504012013-01-17 17:49:58 -0800705 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityNone);
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800706 set<string> groups;
707 groups.insert("id0");
708 groups.insert("id1");
709 // Make sure we retain the first matched group in the same way that
710 // WiFiService::Load() will.
711 string first_group = *groups.begin();
712
713 NiceMock<MockStore> mock_store;
714 EXPECT_CALL(mock_store, GetGroupsWithProperties(
715 ContainsWiFiProperties(
Paul Stewart3c504012013-01-17 17:49:58 -0800716 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800717 .WillRepeatedly(Return(groups));
718 EXPECT_CALL(mock_store, ContainsGroup(first_group))
719 .WillRepeatedly(Return(true));
720 EXPECT_CALL(mock_store, ContainsGroup(StrNe(first_group))).Times(0);
721 EXPECT_CALL(mock_store, GetBool(first_group, _, _))
722 .WillRepeatedly(Return(false));
723 EXPECT_CALL(mock_store, GetBool(StrNe(first_group), _, _)).Times(0);
724 ScopedMockLog log;
725 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
726 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
727 EndsWith("choosing the first.")));
728 EXPECT_TRUE(service->Load(&mock_store));
729}
730
Paul Stewartd08f4432011-11-04 07:48:20 -0700731TEST_F(WiFiServiceSecurityTest, WPAMapping) {
732 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
733 flimflam::kSecurityPsk));
734 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
735 flimflam::kSecurityPsk));
736 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
737 flimflam::kSecurityPsk));
738 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
739 flimflam::kSecurityWep));
740 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
741 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800742 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
743 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700744}
745
746TEST_F(WiFiServiceSecurityTest, LoadMapping) {
747 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
748 flimflam::kSecurityPsk,
749 true));
750 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
751 flimflam::kSecurityRsn,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800752 false));
Paul Stewartd08f4432011-11-04 07:48:20 -0700753 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
754 flimflam::kSecurityWpa,
755 false));
756 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
757 flimflam::kSecurityPsk,
758 true));
759 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
760 flimflam::kSecurityWpa,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800761 false));
Paul Stewartd08f4432011-11-04 07:48:20 -0700762 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
763 flimflam::kSecurityRsn,
764 false));
765 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
766 flimflam::kSecurityWep,
767 true));
768 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
769 flimflam::kSecurityPsk,
770 false));
771}
772
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800773TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
Paul Stewart3c504012013-01-17 17:49:58 -0800774 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityPsk);
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800775 NiceMock<MockStore> mock_store;
776 const string storage_id = service->GetStorageIdentifier();
777 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
778 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800779 set<string> groups;
780 groups.insert(storage_id);
781 EXPECT_CALL(mock_store, GetGroupsWithProperties(
782 ContainsWiFiProperties(
Paul Stewart3c504012013-01-17 17:49:58 -0800783 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityPsk)))
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800784 .WillRepeatedly(Return(groups));
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800785 EXPECT_CALL(mock_store, GetBool(_, _, _))
786 .WillRepeatedly(Return(false));
787 const string passphrase = "passphrase";
788 EXPECT_CALL(mock_store,
789 GetCryptedString(StrEq(storage_id),
790 WiFiService::kStoragePassphrase, _))
791 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
792 EXPECT_CALL(mock_store,
793 GetCryptedString(StrEq(storage_id),
794 StrNe(WiFiService::kStoragePassphrase), _))
795 .WillRepeatedly(Return(false));
796 EXPECT_TRUE(service->need_passphrase_);
797 EXPECT_TRUE(service->Load(&mock_store));
798 EXPECT_EQ(passphrase, service->passphrase_);
799 EXPECT_TRUE(service->connectable());
800 EXPECT_FALSE(service->need_passphrase_);
801 service->Unload();
802 EXPECT_EQ(string(""), service->passphrase_);
803 EXPECT_FALSE(service->connectable());
804 EXPECT_TRUE(service->need_passphrase_);
805}
806
Christopher Wiley27b47232012-11-02 13:13:00 -0700807TEST_F(WiFiServiceTest, ConfigureMakesConnectable) {
808 string guid("legit_guid");
809 KeyValueStore args;
810 args.SetString(flimflam::kEapIdentityProperty, "legit_identity");
811 args.SetString(flimflam::kEapPasswordProperty, "legit_password");
812 args.SetString(flimflam::kEAPEAPProperty, "PEAP");
813 args.SetString(flimflam::kGuidProperty, guid);
814 Error error;
Christopher Wiley27b47232012-11-02 13:13:00 -0700815
Paul Stewart3c504012013-01-17 17:49:58 -0800816 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
Christopher Wiley27b47232012-11-02 13:13:00 -0700817 // Hack the GUID in so that we don't have to mess about with WiFi to regsiter
818 // our service. This way, Manager will handle the lookup itself.
819 service->set_guid(guid);
820 manager()->RegisterService(service);
821 EXPECT_FALSE(service->connectable());
822 EXPECT_EQ(service.get(), manager()->GetService(args, &error).get());
823 EXPECT_TRUE(error.IsSuccess());
824 EXPECT_TRUE(service->connectable());
825}
826
Paul Stewart3c504012013-01-17 17:49:58 -0800827TEST_F(WiFiServiceTest, ConfigurePassphrase) {
828 EXPECT_EQ(Error::kNotSupported,
829 TestConfigurePassphrase(flimflam::kSecurityNone, ""));
830 EXPECT_EQ(Error::kNotSupported,
831 TestConfigurePassphrase(flimflam::kSecurityNone, "foo"));
832 EXPECT_EQ(Error::kSuccess,
833 TestConfigurePassphrase(flimflam::kSecurityWep, NULL));
834 EXPECT_EQ(Error::kInvalidPassphrase,
835 TestConfigurePassphrase(flimflam::kSecurityWep, ""));
836 EXPECT_EQ(Error::kInvalidPassphrase,
837 TestConfigurePassphrase(flimflam::kSecurityWep, "abcd"));
838 EXPECT_EQ(Error::kSuccess,
839 TestConfigurePassphrase(flimflam::kSecurityWep, "abcde"));
840 EXPECT_EQ(Error::kSuccess,
841 TestConfigurePassphrase(flimflam::kSecurityWep, "abcdefghijklm"));
842 EXPECT_EQ(Error::kSuccess,
843 TestConfigurePassphrase(flimflam::kSecurityWep, "0:abcdefghijklm"));
844 EXPECT_EQ(Error::kSuccess,
845 TestConfigurePassphrase(flimflam::kSecurityWep, "0102030405"));
846 EXPECT_EQ(Error::kInvalidPassphrase,
847 TestConfigurePassphrase(flimflam::kSecurityWep, "0x0102030405"));
848 EXPECT_EQ(Error::kInvalidPassphrase,
849 TestConfigurePassphrase(flimflam::kSecurityWep, "O102030405"));
850 EXPECT_EQ(Error::kInvalidPassphrase,
851 TestConfigurePassphrase(flimflam::kSecurityWep, "1:O102030405"));
852 EXPECT_EQ(Error::kInvalidPassphrase,
853 TestConfigurePassphrase(flimflam::kSecurityWep, "1:0xO102030405"));
854 EXPECT_EQ(Error::kInvalidPassphrase,
855 TestConfigurePassphrase(flimflam::kSecurityWep, "0xO102030405"));
856 EXPECT_EQ(Error::kSuccess,
857 TestConfigurePassphrase(flimflam::kSecurityWep,
858 "0102030405060708090a0b0c0d"));
859 EXPECT_EQ(Error::kSuccess,
860 TestConfigurePassphrase(flimflam::kSecurityWep,
861 "0102030405060708090A0B0C0D"));
862 EXPECT_EQ(Error::kSuccess,
863 TestConfigurePassphrase(flimflam::kSecurityWep,
864 "0:0102030405060708090a0b0c0d"));
865 EXPECT_EQ(Error::kSuccess,
866 TestConfigurePassphrase(flimflam::kSecurityWep,
867 "0:0x0102030405060708090a0b0c0d"));
868 EXPECT_EQ(Error::kSuccess,
869 TestConfigurePassphrase(flimflam::kSecurityWpa, NULL));
870 EXPECT_EQ(Error::kSuccess,
871 TestConfigurePassphrase(flimflam::kSecurityWpa, "secure password"));
872 EXPECT_EQ(Error::kInvalidPassphrase,
873 TestConfigurePassphrase(flimflam::kSecurityWpa, ""));
874 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
875 flimflam::kSecurityWpa,
876 string(IEEE_80211::kWPAAsciiMinLen, 'Z').c_str()));
877 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
878 flimflam::kSecurityWpa,
879 string(IEEE_80211::kWPAAsciiMaxLen, 'Z').c_str()));
880 // subtle: invalid length for hex key, but valid as ascii passphrase
881 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
882 flimflam::kSecurityWpa,
883 string(IEEE_80211::kWPAHexLen-1, '1').c_str()));
884 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
885 flimflam::kSecurityWpa,
886 string(IEEE_80211::kWPAHexLen, '1').c_str()));
887 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
888 flimflam::kSecurityWpa,
889 string(IEEE_80211::kWPAAsciiMinLen-1, 'Z').c_str()));
890 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
891 flimflam::kSecurityWpa,
892 string(IEEE_80211::kWPAAsciiMaxLen+1, 'Z').c_str()));
893 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
894 flimflam::kSecurityWpa,
895 string(IEEE_80211::kWPAHexLen+1, '1').c_str()));
896}
897
898TEST_F(WiFiServiceTest, ConfigureRedundantProperties) {
899 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
900 KeyValueStore args;
901 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
902 args.SetString(flimflam::kSSIDProperty, simple_ssid_string());
903 args.SetString(flimflam::kSecurityProperty, flimflam::kSecurityNone);
904 const string kGUID = "aguid";
905 args.SetString(flimflam::kGuidProperty, kGUID);
906
907 EXPECT_EQ("", service->guid());
908 Error error;
909 service->Configure(args, &error);
910 EXPECT_TRUE(error.IsSuccess());
911 EXPECT_EQ(kGUID, service->guid());
912}
913
914TEST_F(WiFiServiceTest, DisconnectWithWiFi) {
915 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityWep);
916 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
917 Error error;
918 service->Disconnect(&error);
919}
920
921TEST_F(WiFiServiceTest, DisconnectWithoutWiFi) {
922 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
923 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
924 Error error;
925 service->Disconnect(&error);
926 EXPECT_EQ(Error::kOperationFailed, error.type());
927}
928
929TEST_F(WiFiServiceTest, DisconnectWithoutWiFiWhileAssociating) {
930 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
931 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
932 service->SetState(Service::kStateAssociating);
933 ScopedMockLog log;
934 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
935 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
936 HasSubstr("WiFi endpoints do not (yet) exist.")));
937 Error error;
938 service->Disconnect(&error);
939 EXPECT_EQ(Error::kOperationFailed, error.type());
940}
941
Paul Stewart835934a2012-12-06 19:27:09 -0800942TEST_F(WiFiServiceTest, UnloadAndClearCacheWEP) {
Paul Stewart3c504012013-01-17 17:49:58 -0800943 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityWep);
Paul Stewart835934a2012-12-06 19:27:09 -0800944 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
945 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -0800946 service->Unload();
947}
948
949TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
Paul Stewart3c504012013-01-17 17:49:58 -0800950 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
Paul Stewart835934a2012-12-06 19:27:09 -0800951 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
952 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -0800953 service->Unload();
954}
955
Paul Stewart0756db92012-01-27 08:34:47 -0800956TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewart3c504012013-01-17 17:49:58 -0800957 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewarta41e38d2011-11-11 07:47:29 -0800958 const string storage_id = service->GetStorageIdentifier();
959 string address;
960 string mode;
961 string security;
962 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
963 &security));
Paul Stewart3c504012013-01-17 17:49:58 -0800964 EXPECT_EQ(StringToLowerASCII(GetAnyDeviceAddress()), address);
Paul Stewarta41e38d2011-11-11 07:47:29 -0800965 EXPECT_EQ(flimflam::kModeManaged, mode);
966 EXPECT_EQ(flimflam::kSecurityNone, security);
967}
968
Paul Stewart0756db92012-01-27 08:34:47 -0800969TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
970 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
971 // which needs to be dealt with specially in the parser.
Paul Stewart3c504012013-01-17 17:49:58 -0800972 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
Paul Stewart0756db92012-01-27 08:34:47 -0800973 const string storage_id = service->GetStorageIdentifier();
974 string address;
975 string mode;
976 string security;
977 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
978 &security));
Paul Stewart3c504012013-01-17 17:49:58 -0800979 EXPECT_EQ(StringToLowerASCII(GetAnyDeviceAddress()), address);
Paul Stewart0756db92012-01-27 08:34:47 -0800980 EXPECT_EQ(flimflam::kModeManaged, mode);
981 EXPECT_EQ(flimflam::kSecurity8021x, security);
982}
983
Paul Stewart85aea152013-01-22 09:31:56 -0800984TEST_F(WiFiServiceFixupStorageTest, FixedEntries) {
985 const string kNonWiFiId = "vpn_foo";
986 const string kUnparsableWiFiId = "wifi_foo";
987
988 AddGroup(kNonWiFiId);
989 AddGroup(kUnparsableWiFiId);
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800990 AddServiceEntry(true, true, true, true);
991 AddServiceEntry(false, false, false, false);
992 AddServiceEntry(true, true, true, true);
993 AddServiceEntry(false, false, false, false);
Paul Stewart85aea152013-01-22 09:31:56 -0800994 EXPECT_TRUE(FixupServiceEntries());
995}
996
997TEST_F(WiFiServiceFixupStorageTest, NoFixedEntries) {
998 const string kNonWiFiId = "vpn_foo";
999 const string kUnparsableWiFiId = "wifi_foo";
1000
1001 AddGroup(kNonWiFiId);
1002 AddGroup(kUnparsableWiFiId);
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001003 AddServiceEntry(true, true, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001004 EXPECT_FALSE(FixupServiceEntries());
1005}
1006
1007TEST_F(WiFiServiceFixupStorageTest, MissingTypeProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001008 AddServiceEntry(false, true, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001009 EXPECT_TRUE(FixupServiceEntries());
1010}
1011
1012TEST_F(WiFiServiceFixupStorageTest, MissingModeProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001013 AddServiceEntry(true, false, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001014 EXPECT_TRUE(FixupServiceEntries());
1015}
1016
1017TEST_F(WiFiServiceFixupStorageTest, MissingSecurityProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001018 AddServiceEntry(true, true, false, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001019 EXPECT_TRUE(FixupServiceEntries());
1020}
1021
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001022TEST_F(WiFiServiceFixupStorageTest, MissingSecurityClassProperty) {
1023 AddServiceEntry(true, true, true, false);
1024 EXPECT_TRUE(FixupServiceEntries());
1025}
Paul Stewart85aea152013-01-22 09:31:56 -08001026
mukesh agrawal29c13a12011-11-24 00:09:19 +00001027TEST_F(WiFiServiceTest, Connectable) {
1028 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001029 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001030
1031 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -08001032 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001033
1034 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001035 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001036
1037 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001038 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001039
1040 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001041 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001042
1043 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -08001044 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
1045 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
1046 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001047
1048 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001049 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
1050
1051 Service::EapCredentials eap;
1052 // Empty EAP credentials should not make a 802.1x network connectable.
1053 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1054
1055 eap.identity = "something";
1056 // If client certificate is being used, a private key must exist.
1057 eap.client_cert = "some client cert";
1058 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1059 eap.private_key = "some private key";
1060 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1061
1062 // Identity is always required.
1063 eap.identity.clear();
1064 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1065
1066 eap.identity = "something";
1067 // For non EAP-TLS types, a password is required.
1068 eap.eap = "Non-TLS";
1069 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1070 eap.password = "some password";
1071 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -08001072 // Dynamic WEP + 802.1X should be connectable under the same conditions.
1073 eap.key_management = "IEEE8021X";
1074 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001075}
1076
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001077TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001078 const char *reason;
Paul Stewart3c504012013-01-17 17:49:58 -08001079 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001080 EXPECT_CALL(*wifi(), IsIdle())
1081 .WillRepeatedly(Return(true));
1082 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001083 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1084 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001085
mukesh agrawalbf14e942012-03-02 14:36:34 -08001086 reason = "";
mukesh agrawale1d90e92012-02-15 17:36:08 -08001087 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001088 service->AddEndpoint(endpoint);
1089 EXPECT_CALL(*wifi(), IsIdle())
1090 .WillRepeatedly(Return(true));
1091 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001092 EXPECT_TRUE(service->IsAutoConnectable(&reason));
1093 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001094
1095 // WiFi only supports connecting to one Service at a time. So, to
1096 // avoid disrupting connectivity, we only allow auto-connection to
1097 // a WiFiService when the corresponding WiFi is idle.
1098 EXPECT_CALL(*wifi(), IsIdle())
1099 .WillRepeatedly(Return(false));
1100 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001101 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1102 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001103}
1104
1105TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001106 const char *reason;
Paul Stewart3c504012013-01-17 17:49:58 -08001107 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001108 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001109 EXPECT_CALL(*wifi(), ConnectTo(_, _))
1110 .Times(0);
1111 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001112 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001113
mukesh agrawale1d90e92012-02-15 17:36:08 -08001114 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001115 service->AddEndpoint(endpoint);
1116 EXPECT_CALL(*wifi(), IsIdle())
1117 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -08001118 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001119 EXPECT_CALL(*wifi(), ConnectTo(_, _));
1120 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001121 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -08001122
1123 Error error;
Christopher Wileyabd3b502012-09-26 13:08:52 -07001124 service->UserInitiatedDisconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001125 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -08001126 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001127}
1128
Gaurav Shah10109f22011-11-11 20:16:22 -08001129TEST_F(WiFiServiceTest, Populate8021x) {
Paul Stewart3c504012013-01-17 17:49:58 -08001130 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Gaurav Shah10109f22011-11-11 20:16:22 -08001131 Service::EapCredentials eap;
1132 eap.identity = "testidentity";
Paul Stewart20550982012-04-16 12:16:11 -07001133 eap.pin = "xxxx";
Gaurav Shah10109f22011-11-11 20:16:22 -08001134 service->set_eap(eap);
1135 map<string, ::DBus::Variant> params;
1136 service->Populate8021xProperties(&params);
1137 // Test that only non-empty 802.1x properties are populated.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001138 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapIdentity));
1139 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
1140 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
1141
Paul Stewart20550982012-04-16 12:16:11 -07001142 // Test that CA path is set by default.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001143 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
1144
Paul Stewart20550982012-04-16 12:16:11 -07001145 // Test that hardware-backed security arguments are not set.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001146 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
1147 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
1148 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
Paul Stewart20550982012-04-16 12:16:11 -07001149}
1150
1151TEST_F(WiFiServiceTest, Populate8021xNoSystemCAs) {
Paul Stewart3c504012013-01-17 17:49:58 -08001152 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewart20550982012-04-16 12:16:11 -07001153 Service::EapCredentials eap;
1154 eap.identity = "testidentity";
1155 eap.use_system_cas = false;
1156 service->set_eap(eap);
1157 map<string, ::DBus::Variant> params;
1158 service->Populate8021xProperties(&params);
1159 // Test that CA path is not set if use_system_cas is explicitly false.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001160 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
Paul Stewart20550982012-04-16 12:16:11 -07001161}
1162
1163TEST_F(WiFiServiceTest, Populate8021xUsingHardwareAuth) {
Paul Stewart3c504012013-01-17 17:49:58 -08001164 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewart20550982012-04-16 12:16:11 -07001165 Service::EapCredentials eap;
1166 eap.identity = "testidentity";
1167 eap.key_id = "key_id";
1168 eap.pin = "xxxx";
1169 service->set_eap(eap);
1170 map<string, ::DBus::Variant> params;
1171 service->Populate8021xProperties(&params);
1172 // Test that EAP engine parameters set if key_id is set.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001173 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
1174 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
1175 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
1176 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
1177}
1178
1179TEST_F(WiFiServiceTest, Populate8021xNSS) {
1180 vector<uint8_t> ssid(1, 'a');
Paul Stewart3c504012013-01-17 17:49:58 -08001181 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewartecf4cd12012-04-17 11:08:39 -07001182 Service::EapCredentials eap;
1183 eap.ca_cert_nss = "nss_nickname";
1184 service->set_eap(eap);
1185 MockNSS nss;
1186 service->nss_ = &nss;
1187
1188 const string kNSSCertfile("/tmp/nss-cert");
1189 FilePath nss_cert(kNSSCertfile);
1190 vector<char> ssid_in_chars(ssid.begin(), ssid.end());
1191 EXPECT_CALL(nss, GetDERCertfile(eap.ca_cert_nss, ssid_in_chars))
1192 .WillOnce(Return(nss_cert));
1193
1194 map<string, ::DBus::Variant> params;
1195 service->Populate8021xProperties(&params);
1196 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
1197 if (ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert)) {
1198 EXPECT_EQ(kNSSCertfile, params[wpa_supplicant::kNetworkPropertyEapCaCert]
1199 .reader().get_string());
1200 }
Gaurav Shah10109f22011-11-11 20:16:22 -08001201}
1202
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001203TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
Paul Stewart3c504012013-01-17 17:49:58 -08001204 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWep);
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001205
1206 EXPECT_EQ("", wifi_service->passphrase_);
1207
1208 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001209 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001210 wifi_service->mutable_store(),
1211 flimflam::kPassphraseProperty,
1212 DBusAdaptor::StringToVariant("0:abcde"),
1213 &error));
1214 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
1215
1216 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
1217 flimflam::kPassphraseProperty,
1218 &error));
1219 EXPECT_EQ("", wifi_service->passphrase_);
1220}
1221
mukesh agrawale1d90e92012-02-15 17:36:08 -08001222TEST_F(WiFiServiceTest, SignalToStrength) {
1223 // Verify that our mapping is sane, in the sense that it preserves ordering.
1224 // We break the test into two domains, because we assume that positive
1225 // values aren't actually in dBm.
1226 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
1227 int16 current_mapped = WiFiService::SignalToStrength(i);
1228 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1229 EXPECT_LE(current_mapped, next_mapped)
1230 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001231 EXPECT_GE(current_mapped, Service::kStrengthMin);
1232 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001233 }
1234 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
1235 int16 current_mapped = WiFiService::SignalToStrength(i);
1236 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1237 EXPECT_LE(current_mapped, next_mapped)
1238 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001239 EXPECT_GE(current_mapped, Service::kStrengthMin);
1240 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001241 }
1242}
1243
1244TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
1245 // If the chosen signal values don't map to distinct strength
1246 // values, then we can't expect our other tests to pass. So verify
1247 // their distinctness.
1248 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
1249 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
1250 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
1251}
1252
1253TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
1254 // Initial endpoint updates values.
1255 EXPECT_CALL(adaptor, EmitUint16Changed(
1256 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001257 EXPECT_CALL(adaptor, EmitStringChanged(
1258 flimflam::kWifiBSsid, kOkEndpointBssId));
1259 EXPECT_CALL(adaptor, EmitUint8Changed(
mukesh agrawale1d90e92012-02-15 17:36:08 -08001260 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1261 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001262 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001263 Mock::VerifyAndClearExpectations(&adaptor);
1264
1265 // Endpoint with stronger signal updates values.
1266 EXPECT_CALL(adaptor, EmitUint16Changed(
1267 flimflam::kWifiFrequency, kGoodEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001268 EXPECT_CALL(adaptor, EmitStringChanged(
1269 flimflam::kWifiBSsid, kGoodEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001270 EXPECT_CALL(adaptor, EmitUint8Changed(
1271 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
1272 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001273 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001274 Mock::VerifyAndClearExpectations(&adaptor);
1275
1276 // Endpoint with lower signal does not change values.
1277 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001278 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001279 EXPECT_CALL(adaptor,
1280 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1281 service->AddEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001282 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001283 Mock::VerifyAndClearExpectations(&adaptor);
1284
1285 // Removing non-optimal endpoint does not change values.
1286 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001287 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001288 EXPECT_CALL(adaptor,
1289 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1290 service->RemoveEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001291 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001292 Mock::VerifyAndClearExpectations(&adaptor);
1293
1294 // Removing optimal endpoint updates values.
1295 EXPECT_CALL(adaptor, EmitUint16Changed(
1296 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001297 EXPECT_CALL(adaptor, EmitStringChanged(
1298 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001299 EXPECT_CALL(adaptor, EmitUint8Changed(
1300 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1301 service->RemoveEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001302 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001303 Mock::VerifyAndClearExpectations(&adaptor);
1304
1305 // Removing last endpoint updates values (and doesn't crash).
1306 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001307 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001308 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1309 service->RemoveEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001310 EXPECT_EQ(0, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001311 Mock::VerifyAndClearExpectations(&adaptor);
1312}
1313
1314TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1315 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001316 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001317 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1318 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1319 service->AddEndpoint(bad_endpoint);
1320 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001321 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001322 Mock::VerifyAndClearExpectations(&adaptor);
1323
1324 // Setting current endpoint forces adoption of its values, even if it
1325 // doesn't have the highest signal.
1326 EXPECT_CALL(adaptor, EmitUint16Changed(
1327 flimflam::kWifiFrequency, kBadEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001328 EXPECT_CALL(adaptor, EmitStringChanged(
1329 flimflam::kWifiBSsid, kBadEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001330 EXPECT_CALL(adaptor, EmitUint8Changed(
1331 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
1332 service->NotifyCurrentEndpoint(bad_endpoint);
1333 Mock::VerifyAndClearExpectations(&adaptor);
1334
1335 // Adding a better endpoint doesn't matter, when current endpoint is set.
1336 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001337 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001338 EXPECT_CALL(adaptor,
1339 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1340 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001341 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001342 Mock::VerifyAndClearExpectations(&adaptor);
1343
1344 // Removing a better endpoint doesn't matter, when current endpoint is set.
1345 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001346 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001347 EXPECT_CALL(adaptor,
1348 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1349 service->RemoveEndpoint(good_endpoint);
1350 Mock::VerifyAndClearExpectations(&adaptor);
1351
1352 // Removing the current endpoint is safe and sane.
1353 EXPECT_CALL(adaptor, EmitUint16Changed(
1354 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001355 EXPECT_CALL(adaptor, EmitStringChanged(
1356 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001357 EXPECT_CALL(adaptor, EmitUint8Changed(
1358 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1359 service->RemoveEndpoint(bad_endpoint);
1360 Mock::VerifyAndClearExpectations(&adaptor);
1361
1362 // Clearing the current endpoint (without removing it) is also safe and sane.
1363 service->NotifyCurrentEndpoint(ok_endpoint);
1364 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001365 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001366 EXPECT_CALL(adaptor,
1367 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1368 service->NotifyCurrentEndpoint(NULL);
1369 Mock::VerifyAndClearExpectations(&adaptor);
1370}
1371
1372TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1373 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001374 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001375 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1376 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1377 service->AddEndpoint(ok_endpoint);
1378 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001379 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001380 Mock::VerifyAndClearExpectations(&adaptor);
1381
1382 // Updating sub-optimal Endpoint doesn't update Service.
1383 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001384 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001385 EXPECT_CALL(adaptor,
1386 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1387 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
Paul Stewart3c504012013-01-17 17:49:58 -08001388 service->NotifyEndpointUpdated(ok_endpoint);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001389 Mock::VerifyAndClearExpectations(&adaptor);
1390
1391 // Updating optimal Endpoint updates appropriate Service property.
1392 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001393 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001394 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1395 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
Paul Stewart3c504012013-01-17 17:49:58 -08001396 service->NotifyEndpointUpdated(good_endpoint);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001397 Mock::VerifyAndClearExpectations(&adaptor);
1398
1399 // Change in optimal Endpoint updates Service properties.
1400 EXPECT_CALL(adaptor, EmitUint16Changed(
1401 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001402 EXPECT_CALL(adaptor, EmitStringChanged(
1403 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001404 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1405 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
Paul Stewart3c504012013-01-17 17:49:58 -08001406 service->NotifyEndpointUpdated(ok_endpoint);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001407 Mock::VerifyAndClearExpectations(&adaptor);
1408}
1409
Paul Stewarta5e7d5f2013-01-09 18:06:15 -08001410TEST_F(WiFiServiceUpdateFromEndpointsTest, Ieee80211w) {
1411 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1412 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1413 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1414 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1415 service->AddEndpoint(ok_endpoint);
1416 EXPECT_FALSE(service->ieee80211w_required());
1417 good_endpoint->ieee80211w_required_ = true;
1418 service->AddEndpoint(good_endpoint);
1419 EXPECT_TRUE(service->ieee80211w_required());
1420 service->RemoveEndpoint(good_endpoint);
1421 EXPECT_TRUE(service->ieee80211w_required());
1422}
1423
Chris Masone34af2182011-08-22 11:59:36 -07001424} // namespace shill