blob: 457a39a3afe72cece6556298e7944cd650c1ea14 [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"
Paul Stewart5baebb72013-03-14 11:43:29 -070022#include "shill/mock_certificate_file.h"
Chris Masone34af2182011-08-22 11:59:36 -070023#include "shill/mock_control.h"
Paul Stewart71a4d3b2013-01-18 18:12:56 -080024#include "shill/mock_log.h"
Paul Stewartecf4cd12012-04-17 11:08:39 -070025#include "shill/mock_nss.h"
Christopher Wiley1ce658d2012-10-10 10:02:03 -070026#include "shill/mock_profile.h"
Chris Masone34af2182011-08-22 11:59:36 -070027#include "shill/mock_service.h"
28#include "shill/mock_store.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070029#include "shill/mock_wifi.h"
Paul Stewart3c504012013-01-17 17:49:58 -080030#include "shill/mock_wifi_provider.h"
Chris Masone34af2182011-08-22 11:59:36 -070031#include "shill/property_store_unittest.h"
mukesh agrawal8a3188d2011-12-01 20:56:44 +000032#include "shill/refptr_types.h"
33#include "shill/wifi_endpoint.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070034#include "shill/wpa_supplicant.h"
Chris Masone34af2182011-08-22 11:59:36 -070035
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080036using base::FilePath;
mukesh agrawald835b202011-10-07 15:26:47 -070037using std::map;
Paul Stewart85aea152013-01-22 09:31:56 -080038using std::set;
Chris Masone34af2182011-08-22 11:59:36 -070039using std::string;
40using std::vector;
Paul Stewartd08f4432011-11-04 07:48:20 -070041using ::testing::_;
mukesh agrawale1d90e92012-02-15 17:36:08 -080042using ::testing::AnyNumber;
Paul Stewartd08f4432011-11-04 07:48:20 -070043using ::testing::DoAll;
Paul Stewart71a4d3b2013-01-18 18:12:56 -080044using ::testing::EndsWith;
Paul Stewart3c504012013-01-17 17:49:58 -080045using ::testing::HasSubstr;
mukesh agrawale1d90e92012-02-15 17:36:08 -080046using ::testing::Mock;
mukesh agrawal6e277772011-09-29 15:04:23 -070047using ::testing::NiceMock;
Paul Stewartd08f4432011-11-04 07:48:20 -070048using ::testing::Return;
49using ::testing::SetArgumentPointee;
50using ::testing::StrEq;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080051using ::testing::StrNe;
Paul Stewart85aea152013-01-22 09:31:56 -080052using ::testing::StrictMock;
Chris Masone34af2182011-08-22 11:59:36 -070053
mukesh agrawalb20776f2012-02-10 16:00:36 -080054namespace shill {
55
Chris Masone34af2182011-08-22 11:59:36 -070056class WiFiServiceTest : public PropertyStoreTest {
57 public:
Paul Stewart3c504012013-01-17 17:49:58 -080058 WiFiServiceTest()
59 : wifi_(new NiceMock<MockWiFi>(
60 control_interface(),
61 dispatcher(),
62 metrics(),
63 manager(),
64 "wifi",
65 fake_mac,
66 0)),
67 simple_ssid_(1, 'a'),
68 simple_ssid_string_("a") {}
Chris Masone34af2182011-08-22 11:59:36 -070069 virtual ~WiFiServiceTest() {}
mukesh agrawal6e277772011-09-29 15:04:23 -070070
71 protected:
72 static const char fake_mac[];
mukesh agrawale1d90e92012-02-15 17:36:08 -080073
Gaurav Shah10109f22011-11-11 20:16:22 -080074 bool CheckConnectable(const std::string &security, const char *passphrase,
75 Service::EapCredentials *eap) {
mukesh agrawal29c13a12011-11-24 00:09:19 +000076 Error error;
Paul Stewart3c504012013-01-17 17:49:58 -080077 WiFiServiceRefPtr service = MakeSimpleService(security);
mukesh agrawal29c13a12011-11-24 00:09:19 +000078 if (passphrase)
79 service->SetPassphrase(passphrase, &error);
Gaurav Shah10109f22011-11-11 20:16:22 -080080 if (eap) {
81 service->set_eap(*eap);
82 }
mukesh agrawal29c13a12011-11-24 00:09:19 +000083 return service->connectable();
84 }
mukesh agrawale1d90e92012-02-15 17:36:08 -080085 WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid,
mukesh agrawal43970a22013-02-15 16:00:07 -080086 uint16 frequency, int16 signal_dbm,
87 bool has_wpa_property, bool has_rsn_property) {
88 return WiFiEndpoint::MakeEndpoint(
89 NULL, wifi(), ssid, bssid, wpa_supplicant::kNetworkModeInfrastructure,
90 frequency, signal_dbm, has_wpa_property, has_rsn_property);
91 }
92 WiFiEndpoint *MakeOpenEndpoint(const string &ssid, const string &bssid,
93 uint16 frequency, int16 signal_dbm) {
mukesh agrawale1d90e92012-02-15 17:36:08 -080094 return WiFiEndpoint::MakeOpenEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -080095 NULL, wifi(), ssid, bssid, wpa_supplicant::kNetworkModeInfrastructure,
96 frequency, signal_dbm);
mukesh agrawale1d90e92012-02-15 17:36:08 -080097 }
Paul Stewart3c504012013-01-17 17:49:58 -080098 WiFiServiceRefPtr MakeSimpleService(const string &security) {
mukesh agrawale1d90e92012-02-15 17:36:08 -080099 return new WiFiService(control_interface(),
100 dispatcher(),
101 metrics(),
102 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800103 &provider_,
104 simple_ssid_,
mukesh agrawale1d90e92012-02-15 17:36:08 -0800105 flimflam::kModeManaged,
Paul Stewart3c504012013-01-17 17:49:58 -0800106 security,
mukesh agrawale1d90e92012-02-15 17:36:08 -0800107 false);
108 }
Paul Stewart3c504012013-01-17 17:49:58 -0800109 WiFiServiceRefPtr MakeGenericService() {
110 return MakeSimpleService(flimflam::kSecurityWep);
111 }
112 void SetWiFiForService(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
113 service->wifi_ = wifi;
114 }
115 WiFiServiceRefPtr MakeServiceWithWiFi(const string &security) {
116 WiFiServiceRefPtr service = MakeSimpleService(security);
117 SetWiFiForService(service, wifi_);
118 return service;
119 }
mukesh agrawale1d90e92012-02-15 17:36:08 -0800120 ServiceMockAdaptor *GetAdaptor(WiFiService *service) {
121 return dynamic_cast<ServiceMockAdaptor *>(service->adaptor());
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000122 }
Paul Stewart3c504012013-01-17 17:49:58 -0800123 Error::Type TestConfigurePassphrase(const string &security,
124 const char *passphrase) {
125 WiFiServiceRefPtr service = MakeSimpleService(security);
126 KeyValueStore args;
127 if (passphrase) {
128 args.SetString(flimflam::kPassphraseProperty, passphrase);
129 }
130 Error error;
131 service->Configure(args, &error);
132 return error.type();
133 }
mukesh agrawal6e277772011-09-29 15:04:23 -0700134 scoped_refptr<MockWiFi> wifi() { return wifi_; }
Paul Stewart3c504012013-01-17 17:49:58 -0800135 MockWiFiProvider *provider() { return &provider_; }
136 string GetAnyDeviceAddress() { return WiFiService::kAnyDeviceAddress; }
137 const vector<uint8_t> &simple_ssid() { return simple_ssid_; }
138 const string &simple_ssid_string() { return simple_ssid_string_; }
mukesh agrawal6e277772011-09-29 15:04:23 -0700139
140 private:
141 scoped_refptr<MockWiFi> wifi_;
Paul Stewart3c504012013-01-17 17:49:58 -0800142 MockWiFiProvider provider_;
143 const vector<uint8_t> simple_ssid_;
144 const string simple_ssid_string_;
Chris Masone34af2182011-08-22 11:59:36 -0700145};
146
mukesh agrawal6e277772011-09-29 15:04:23 -0700147// static
148const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
149
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800150MATCHER_P3(ContainsWiFiProperties, ssid, mode, security, "") {
151 string hex_ssid = base::HexEncode(ssid.data(), ssid.size());
152 return
153 arg.ContainsString(WiFiService::kStorageType) &&
154 arg.GetString(WiFiService::kStorageType) == flimflam::kTypeWifi &&
155 arg.ContainsString(WiFiService::kStorageSSID) &&
156 arg.GetString(WiFiService::kStorageSSID) == hex_ssid &&
157 arg.ContainsString(WiFiService::kStorageMode) &&
158 arg.GetString(WiFiService::kStorageMode) == mode &&
159 arg.ContainsString(WiFiService::kStorageSecurityClass) &&
160 arg.GetString(WiFiService::kStorageSecurityClass) == security;
161}
162
Paul Stewartd08f4432011-11-04 07:48:20 -0700163class WiFiServiceSecurityTest : public WiFiServiceTest {
164 public:
Paul Stewartd08f4432011-11-04 07:48:20 -0700165 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
166 const string &security) {
167 string id = wifi_service->GetStorageIdentifier();
Paul Stewart3c504012013-01-17 17:49:58 -0800168 size_t mac_pos = id.find(StringToLowerASCII(GetAnyDeviceAddress()));
Paul Stewartd08f4432011-11-04 07:48:20 -0700169 EXPECT_NE(mac_pos, string::npos);
170 size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
171 EXPECT_NE(mode_pos, string::npos);
172 return id.find(string(security), mode_pos) != string::npos;
173 }
174
175 // Test that a service that is created with security |from_security|
176 // gets by default a storage identifier with |to_security| as its
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800177 // security component, and that when saved, it sets the Security
178 // property in to |to_security| as well.
Paul Stewartd08f4432011-11-04 07:48:20 -0700179 bool TestStorageMapping(const string &from_security,
180 const string &to_security) {
Paul Stewart3c504012013-01-17 17:49:58 -0800181 WiFiServiceRefPtr wifi_service = MakeSimpleService(from_security);
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800182 NiceMock<MockStore> mock_store;
183 EXPECT_CALL(mock_store, SetString(_, _, _)).WillRepeatedly(Return(true));
184 EXPECT_CALL(mock_store,
185 SetString(_, WiFiService::kStorageSecurity, from_security))
186 .Times(1);
187 EXPECT_CALL(mock_store,
188 SetString(_, WiFiService::kStorageSecurityClass, to_security))
189 .Times(1);
190 wifi_service->Save(&mock_store);
Paul Stewartd08f4432011-11-04 07:48:20 -0700191 return TestStorageSecurityIs(wifi_service, to_security);
192 }
193
194 // Test whether a service of type |service_security| can load from a
195 // storage interface containing an entry for |storage_security|.
196 // Make sure the result meets |expectation|. If |expectation| is
197 // true, also make sure the service storage identifier changes to
198 // match |storage_security|.
199 bool TestLoadMapping(const string &service_security,
200 const string &storage_security,
201 bool expectation) {
Paul Stewart3c504012013-01-17 17:49:58 -0800202 WiFiServiceRefPtr wifi_service = MakeSimpleService(service_security);
Paul Stewartd08f4432011-11-04 07:48:20 -0700203 NiceMock<MockStore> mock_store;
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800204 EXPECT_CALL(mock_store, GetGroupsWithProperties(_))
205 .WillRepeatedly(Return(set<string>()));
206 const string kStorageId = "storage_id";
207 EXPECT_CALL(mock_store, ContainsGroup(kStorageId))
Paul Stewartd08f4432011-11-04 07:48:20 -0700208 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800209 set<string> groups;
210 groups.insert(kStorageId);
211 EXPECT_CALL(mock_store, GetGroupsWithProperties(
212 ContainsWiFiProperties(wifi_service->ssid(),
213 flimflam::kModeManaged,
214 storage_security)))
215 .WillRepeatedly(Return(groups));
Paul Stewartd08f4432011-11-04 07:48:20 -0700216 bool is_loadable = wifi_service->IsLoadableFrom(&mock_store);
217 EXPECT_EQ(expectation, is_loadable);
218 bool is_loaded = wifi_service->Load(&mock_store);
219 EXPECT_EQ(expectation, is_loaded);
220
221 if (expectation != is_loadable || expectation != is_loaded) {
222 return false;
223 } else if (!expectation) {
224 return true;
225 } else {
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800226 return wifi_service->GetStorageIdentifier() == kStorageId;
Paul Stewartd08f4432011-11-04 07:48:20 -0700227 }
228 }
229};
230
mukesh agrawale1d90e92012-02-15 17:36:08 -0800231class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
232 public:
233 WiFiServiceUpdateFromEndpointsTest()
234 : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
235 kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
236 kGoodEndpointStrength(
237 WiFiService::SignalToStrength(kGoodEndpointSignal)),
238 service(MakeGenericService()),
239 adaptor(*GetAdaptor(service)) {
mukesh agrawal43970a22013-02-15 16:00:07 -0800240 ok_endpoint = MakeOpenEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800241 simple_ssid_string(), kOkEndpointBssId, kOkEndpointFrequency,
242 kOkEndpointSignal);
mukesh agrawal43970a22013-02-15 16:00:07 -0800243 good_endpoint = MakeOpenEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800244 simple_ssid_string(), kGoodEndpointBssId, kGoodEndpointFrequency,
245 kGoodEndpointSignal);
mukesh agrawal43970a22013-02-15 16:00:07 -0800246 bad_endpoint = MakeOpenEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800247 simple_ssid_string(), kBadEndpointBssId, kBadEndpointFrequency,
248 kBadEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800249 }
250
251 protected:
252 static const uint16 kOkEndpointFrequency = 2422;
253 static const uint16 kBadEndpointFrequency = 2417;
254 static const uint16 kGoodEndpointFrequency = 2412;
255 static const int16 kOkEndpointSignal = -50;
256 static const int16 kBadEndpointSignal = -75;
257 static const int16 kGoodEndpointSignal = -25;
mukesh agrawal923f14f2012-06-04 16:46:08 -0700258 static const char *kOkEndpointBssId;
259 static const char *kGoodEndpointBssId;
260 static const char *kBadEndpointBssId;
mukesh agrawale1d90e92012-02-15 17:36:08 -0800261 // Can't be both static and const (because initialization requires a
262 // function call). So choose to be just const.
263 const uint8 kOkEndpointStrength;
264 const uint8 kBadEndpointStrength;
265 const uint8 kGoodEndpointStrength;
266 WiFiEndpointRefPtr ok_endpoint;
267 WiFiEndpointRefPtr bad_endpoint;
268 WiFiEndpointRefPtr good_endpoint;
269 WiFiServiceRefPtr service;
270 ServiceMockAdaptor &adaptor;
271};
272
mukesh agrawal923f14f2012-06-04 16:46:08 -0700273const char *WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId =
274 "00:00:00:00:00:01";
275const char *WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId =
276 "00:00:00:00:00:02";
277const char *WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId =
278 "00:00:00:00:00:03";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800279
Paul Stewart85aea152013-01-22 09:31:56 -0800280class WiFiServiceFixupStorageTest : public WiFiServiceTest {
281 protected:
282 void AddGroup(string group_name) {
283 groups_.insert(group_name);
284 }
285
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800286 void AddServiceEntry(bool has_type, bool has_mode, bool has_security,
287 bool has_security_class) {
Paul Stewart85aea152013-01-22 09:31:56 -0800288 int index = groups_.size();
289 string id = base::StringPrintf("%s_%d_%d_%s_%s", flimflam::kTypeWifi,
290 index, index, flimflam::kModeManaged,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800291 flimflam::kSecurityWpa);
Paul Stewart85aea152013-01-22 09:31:56 -0800292 AddGroup(id);
293 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageType, _))
294 .WillOnce(Return(has_type));
295 if (!has_type) {
296 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageType,
297 flimflam::kTypeWifi));
298 }
299 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageMode, _))
300 .WillOnce(Return(has_mode));
301 if (!has_mode) {
302 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageMode,
303 flimflam::kModeManaged));
304 }
305 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurity, _))
306 .WillOnce(Return(has_security));
307 if (!has_security) {
308 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurity,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800309 flimflam::kSecurityWpa));
310 }
311 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurityClass, _))
312 .WillOnce(Return(has_security_class));
313 if (!has_security_class) {
314 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurityClass,
315 flimflam::kSecurityPsk));
Paul Stewart85aea152013-01-22 09:31:56 -0800316 }
317 }
318
319 bool FixupServiceEntries() {
320 EXPECT_CALL(store_, GetGroups()).WillOnce(Return(groups_));
321 return WiFiService::FixupServiceEntries(&store_);
322 }
323
324 private:
325 StrictMock<MockStore> store_;
326 set<string> groups_;
327};
328
Chris Masone34af2182011-08-22 11:59:36 -0700329TEST_F(WiFiServiceTest, StorageId) {
Paul Stewart3c504012013-01-17 17:49:58 -0800330 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityNone);
Chris Masone9d779932011-08-25 16:33:41 -0700331 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700332 for (uint i = 0; i < id.length(); ++i) {
333 EXPECT_TRUE(id[i] == '_' ||
334 isxdigit(id[i]) ||
335 (isalpha(id[i]) && islower(id[i])));
336 }
Paul Stewart3c504012013-01-17 17:49:58 -0800337 size_t mac_pos = id.find(StringToLowerASCII(GetAnyDeviceAddress()));
Chris Masone34af2182011-08-22 11:59:36 -0700338 EXPECT_NE(mac_pos, string::npos);
339 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
340}
341
Gaurav Shahda6218a2011-11-11 12:09:33 -0800342// Make sure the passphrase is registered as a write only property
343// by reading and comparing all string properties returned on the store.
344TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
Paul Stewart3c504012013-01-17 17:49:58 -0800345 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWpa);
Gaurav Shahda6218a2011-11-11 12:09:33 -0800346 ReadablePropertyConstIterator<string> it =
347 (wifi_service->store()).GetStringPropertiesIter();
348 for( ; !it.AtEnd(); it.Advance())
349 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
350}
351
Thieu Lef7709452011-11-15 01:13:19 +0000352// Make sure setting the passphrase via D-Bus Service.SetProperty validates
353// the passphrase.
354TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
355 // We only spot check two password cases here to make sure the
356 // SetProperty code path does validation. We're not going to exhaustively
357 // test for all types of passwords.
Paul Stewart3c504012013-01-17 17:49:58 -0800358 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWep);
Thieu Lef7709452011-11-15 01:13:19 +0000359 Error error;
360 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
361 flimflam::kPassphraseProperty, "0:abcde", &error));
362 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
363 flimflam::kPassphraseProperty, "invalid", &error));
364 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
365}
366
367TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
Paul Stewart3c504012013-01-17 17:49:58 -0800368 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityNone);
Thieu Lef7709452011-11-15 01:13:19 +0000369 Error error;
370 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
371 flimflam::kPassphraseProperty, "invalid", &error));
372 EXPECT_EQ(Error::kNotSupported, error.type());
373}
374
mukesh agrawald835b202011-10-07 15:26:47 -0700375TEST_F(WiFiServiceTest, NonUTF8SSID) {
376 vector<uint8_t> ssid;
377
378 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
379 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
380 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800381 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700382 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800383 provider(),
mukesh agrawald835b202011-10-07 15:26:47 -0700384 ssid,
385 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800386 flimflam::kSecurityNone,
387 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700388 map<string, ::DBus::Variant> properties;
389 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
390 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
391}
392
Paul Stewart4108db92013-03-11 12:13:24 -0700393MATCHER(PSKSecurityArgs, "") {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800394 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
Paul Stewart4108db92013-03-11 12:13:24 -0700395 arg.find(wpa_supplicant::kPropertySecurityProtocol)->second.
396 reader().get_string() == string("WPA RSN") &&
Gaurav Shahda6218a2011-11-11 12:09:33 -0800397 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
398}
399
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800400MATCHER(WPA80211wSecurityArgs, "") {
401 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
402 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey) &&
403 ContainsKey(arg, wpa_supplicant::kNetworkPropertyIeee80211w);
404}
405
Gaurav Shah10109f22011-11-11 20:16:22 -0800406MATCHER(EAPSecurityArgs, "") {
407 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
408 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath);
409}
410
Paul Stewarte2d7c502012-07-16 16:35:10 -0700411MATCHER_P(FrequencyArg, has_arg, "") {
412 return has_arg ==
413 ContainsKey(arg, wpa_supplicant::kNetworkPropertyFrequency);
414}
415
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700416TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Paul Stewart3c504012013-01-17 17:49:58 -0800417 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWpa);
Paul Stewart4108db92013-03-11 12:13:24 -0700418 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), PSKSecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700419 Error error;
420 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500421 wifi_service->Connect(NULL);
mukesh agrawal6e277772011-09-29 15:04:23 -0700422}
423
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700424TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Paul Stewart3c504012013-01-17 17:49:58 -0800425 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityRsn);
Paul Stewart4108db92013-03-11 12:13:24 -0700426 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), PSKSecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700427 Error error;
428 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500429 wifi_service->Connect(NULL);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700430}
431
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700432TEST_F(WiFiServiceTest, ConnectConditions) {
433 Error error;
Paul Stewart3c504012013-01-17 17:49:58 -0800434 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityNone);
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700435 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800436 new NiceMock<MockProfile>(control_interface(), metrics(), manager()));
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700437 wifi_service->set_profile(mock_profile);
438 // With nothing else going on, the service should attempt to connect.
439 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), _));
440 wifi_service->Connect(&error);
441 Mock::VerifyAndClearExpectations(wifi());
442
443 // But if we're already "connecting" or "connected" then we shouldn't attempt
444 // again.
445 EXPECT_CALL(*wifi(),
446 ConnectTo(wifi_service.get(), _)).Times(0);
447 wifi_service->SetState(Service::kStateAssociating);
448 wifi_service->Connect(&error);
449 wifi_service->SetState(Service::kStateConfiguring);
450 wifi_service->Connect(&error);
451 wifi_service->SetState(Service::kStateConnected);
452 wifi_service->Connect(&error);
453 wifi_service->SetState(Service::kStatePortal);
454 wifi_service->Connect(&error);
455 wifi_service->SetState(Service::kStateOnline);
456 wifi_service->Connect(&error);
457 Mock::VerifyAndClearExpectations(wifi());
458}
459
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800460TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Paul Stewart3c504012013-01-17 17:49:58 -0800461 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityPsk);
Paul Stewart4108db92013-03-11 12:13:24 -0700462 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), PSKSecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700463 Error error;
464 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500465 wifi_service->Connect(NULL);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800466}
467
Gaurav Shah10109f22011-11-11 20:16:22 -0800468TEST_F(WiFiServiceTest, ConnectTask8021x) {
Paul Stewart3c504012013-01-17 17:49:58 -0800469 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
Gaurav Shah10109f22011-11-11 20:16:22 -0800470 Service::EapCredentials eap;
471 eap.identity = "identity";
Wade Guthrie005bd342012-05-02 09:37:07 -0700472 eap.password = "mumble";
Paul Stewart3c504012013-01-17 17:49:58 -0800473 service->set_eap(eap);
474 EXPECT_CALL(*wifi(), ConnectTo(service.get(), EAPSecurityArgs()));
475 service->Connect(NULL);
Gaurav Shah10109f22011-11-11 20:16:22 -0800476}
477
Paul Stewarte2d7c502012-07-16 16:35:10 -0700478TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) {
479 vector<uint8_t> ssid(1, 'a');
480 WiFiEndpointRefPtr endpoint_nofreq =
mukesh agrawal43970a22013-02-15 16:00:07 -0800481 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
Paul Stewarte2d7c502012-07-16 16:35:10 -0700482 WiFiEndpointRefPtr endpoint_freq =
mukesh agrawal43970a22013-02-15 16:00:07 -0800483 MakeOpenEndpoint("a", "00:00:00:00:00:02", 2412, 0);
Paul Stewarte2d7c502012-07-16 16:35:10 -0700484
Paul Stewart3c504012013-01-17 17:49:58 -0800485 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityNone);
Paul Stewarte2d7c502012-07-16 16:35:10 -0700486 wifi_service->AddEndpoint(endpoint_freq);
487 EXPECT_CALL(*wifi(),
488 ConnectTo(wifi_service.get(), FrequencyArg(false)));
489 wifi_service->Connect(NULL);
490
491 wifi_service = new WiFiService(control_interface(),
492 dispatcher(),
493 metrics(),
494 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800495 provider(),
Paul Stewarte2d7c502012-07-16 16:35:10 -0700496 ssid,
497 flimflam::kModeAdhoc,
498 flimflam::kSecurityNone,
499 false);
500 EXPECT_CALL(*wifi(),
501 ConnectTo(wifi_service.get(), FrequencyArg(false)));
Paul Stewart3c504012013-01-17 17:49:58 -0800502 SetWiFiForService(wifi_service, wifi());
Paul Stewarte2d7c502012-07-16 16:35:10 -0700503 wifi_service->Connect(NULL);
504
505 wifi_service = new WiFiService(control_interface(),
506 dispatcher(),
507 metrics(),
508 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800509 provider(),
Paul Stewarte2d7c502012-07-16 16:35:10 -0700510 ssid,
511 flimflam::kModeAdhoc,
512 flimflam::kSecurityNone,
513 false);
514 wifi_service->AddEndpoint(endpoint_nofreq);
Paul Stewart3c504012013-01-17 17:49:58 -0800515 SetWiFiForService(wifi_service, wifi());
Paul Stewarte2d7c502012-07-16 16:35:10 -0700516 EXPECT_CALL(*wifi(),
517 ConnectTo(wifi_service.get(), FrequencyArg(false)));
518 wifi_service->Connect(NULL);
519
520 wifi_service = new WiFiService(control_interface(),
521 dispatcher(),
522 metrics(),
523 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800524 provider(),
Paul Stewarte2d7c502012-07-16 16:35:10 -0700525 ssid,
526 flimflam::kModeAdhoc,
527 flimflam::kSecurityNone,
528 false);
529 wifi_service->AddEndpoint(endpoint_freq);
Paul Stewart3c504012013-01-17 17:49:58 -0800530 SetWiFiForService(wifi_service, wifi());
Paul Stewarte2d7c502012-07-16 16:35:10 -0700531 EXPECT_CALL(*wifi(),
532 ConnectTo(wifi_service.get(), FrequencyArg(true)));
533 wifi_service->Connect(NULL);
534}
535
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800536TEST_F(WiFiServiceTest, ConnectTaskWPA80211w) {
Paul Stewart3c504012013-01-17 17:49:58 -0800537 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityPsk);
mukesh agrawal43970a22013-02-15 16:00:07 -0800538 WiFiEndpointRefPtr endpoint =
539 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800540 endpoint->ieee80211w_required_ = true;
541 wifi_service->AddEndpoint(endpoint);
542 Error error;
543 wifi_service->SetPassphrase("0:mumblemumblem", &error);
544 EXPECT_CALL(*wifi(),
545 ConnectTo(wifi_service.get(), WPA80211wSecurityArgs()));
546 wifi_service->Connect(NULL);
547}
548
Thieu Lef4cbda92011-11-10 23:41:24 +0000549MATCHER(WEPSecurityArgsKeyIndex0, "") {
550 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
551 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
552 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
553 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
554 reader().get_uint32() == 0);
555}
556
557MATCHER(WEPSecurityArgsKeyIndex1, "") {
558 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
559 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
560 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
561 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
562 reader().get_uint32() == 1);
563}
564
565MATCHER(WEPSecurityArgsKeyIndex2, "") {
566 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
567 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
568 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
569 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
570 reader().get_uint32() == 2);
571}
572
573MATCHER(WEPSecurityArgsKeyIndex3, "") {
574 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
575 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
576 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
577 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
578 reader().get_uint32() == 3);
579}
580
581TEST_F(WiFiServiceTest, ConnectTaskWEP) {
Paul Stewart3c504012013-01-17 17:49:58 -0800582 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWep);
Thieu Lef4cbda92011-11-10 23:41:24 +0000583 Error error;
584 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
585 EXPECT_CALL(*wifi(),
586 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500587 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000588
589 wifi_service->SetPassphrase("abcdefghijklm", &error);
590 EXPECT_CALL(*wifi(),
591 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500592 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000593
594 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
595 EXPECT_CALL(*wifi(),
596 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500597 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000598
599 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
600 EXPECT_CALL(*wifi(),
601 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500602 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000603
604 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
605 EXPECT_CALL(*wifi(),
606 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500607 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000608}
609
Gaurav Shah29d68882012-01-30 19:06:42 -0800610
611MATCHER(DynamicWEPArgs, "") {
612 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
613 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
614 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
615}
616
617// Dynamic WEP + 802.1x.
618TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
Paul Stewart3c504012013-01-17 17:49:58 -0800619 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWep);
Gaurav Shah29d68882012-01-30 19:06:42 -0800620
621 Service::EapCredentials eap;
622 eap.key_management = "IEEE8021X";
623 eap.identity = "something";
Wade Guthrie005bd342012-05-02 09:37:07 -0700624 eap.password = "mumble";
Gaurav Shah29d68882012-01-30 19:06:42 -0800625 wifi_service->set_eap(eap);
626 EXPECT_CALL(*wifi(),
627 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500628 wifi_service->Connect(NULL);
Gaurav Shah29d68882012-01-30 19:06:42 -0800629}
630
Paul Stewart835934a2012-12-06 19:27:09 -0800631TEST_F(WiFiServiceTest, SetPassphraseRemovesCachedCredentials) {
632 vector<uint8_t> ssid(5);
Paul Stewart3c504012013-01-17 17:49:58 -0800633 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityRsn);
Paul Stewart835934a2012-12-06 19:27:09 -0800634
635 const string kPassphrase = "abcdefgh";
636
637 {
638 Error error;
639 // A changed passphrase should trigger cache removal.
640 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
641 wifi_service->SetPassphrase(kPassphrase, &error);
642 Mock::VerifyAndClearExpectations(wifi());
643 EXPECT_TRUE(error.IsSuccess());
644 }
645
646 {
647 Error error;
648 // An unchanged passphrase should not trigger cache removal.
649 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
650 wifi_service->SetPassphrase(kPassphrase, &error);
651 Mock::VerifyAndClearExpectations(wifi());
652 EXPECT_TRUE(error.IsSuccess());
653 }
654
655 {
656 Error error;
657 // A modified passphrase should trigger cache removal.
658 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
659 wifi_service->SetPassphrase(kPassphrase + "X", &error);
660 Mock::VerifyAndClearExpectations(wifi());
661 EXPECT_TRUE(error.IsSuccess());
662 }
663
664 {
665 Error error;
666 // A cleared passphrase should also trigger cache removal.
667 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
668 wifi_service->ClearPassphrase(&error);
669 Mock::VerifyAndClearExpectations(wifi());
670 EXPECT_TRUE(error.IsSuccess());
671 }
672
673 {
674 Error error;
675 // An invalid passphrase should not trigger cache removal.
676 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
677 wifi_service->SetPassphrase("", &error);
678 Mock::VerifyAndClearExpectations(wifi());
679 EXPECT_FALSE(error.IsSuccess());
680 }
681
682 {
683 // Any change to EAP parameters (including a null one) will trigger cache
684 // removal. This is a lot less granular than the passphrase checks above.
685 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
686 wifi_service->set_eap(Service::EapCredentials());
687 Mock::VerifyAndClearExpectations(wifi());
688 }
689}
690
Paul Stewartd08f4432011-11-04 07:48:20 -0700691TEST_F(WiFiServiceTest, LoadHidden) {
Paul Stewart3c504012013-01-17 17:49:58 -0800692 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewartd08f4432011-11-04 07:48:20 -0700693 ASSERT_FALSE(service->hidden_ssid_);
694 NiceMock<MockStore> mock_store;
695 const string storage_id = service->GetStorageIdentifier();
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800696 set<string> groups;
697 groups.insert(storage_id);
Paul Stewartd08f4432011-11-04 07:48:20 -0700698 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
699 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800700 EXPECT_CALL(mock_store, GetGroupsWithProperties(
701 ContainsWiFiProperties(
Paul Stewart3c504012013-01-17 17:49:58 -0800702 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800703 .WillRepeatedly(Return(groups));
Paul Stewartd08f4432011-11-04 07:48:20 -0700704 EXPECT_CALL(mock_store, GetBool(_, _, _))
705 .WillRepeatedly(Return(false));
706 EXPECT_CALL(mock_store,
707 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
708 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
709 EXPECT_TRUE(service->Load(&mock_store));
710 EXPECT_TRUE(service->hidden_ssid_);
711}
712
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800713TEST_F(WiFiServiceTest, LoadMultipleMatchingGroups) {
Paul Stewart3c504012013-01-17 17:49:58 -0800714 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityNone);
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800715 set<string> groups;
716 groups.insert("id0");
717 groups.insert("id1");
718 // Make sure we retain the first matched group in the same way that
719 // WiFiService::Load() will.
720 string first_group = *groups.begin();
721
722 NiceMock<MockStore> mock_store;
723 EXPECT_CALL(mock_store, GetGroupsWithProperties(
724 ContainsWiFiProperties(
Paul Stewart3c504012013-01-17 17:49:58 -0800725 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800726 .WillRepeatedly(Return(groups));
727 EXPECT_CALL(mock_store, ContainsGroup(first_group))
728 .WillRepeatedly(Return(true));
729 EXPECT_CALL(mock_store, ContainsGroup(StrNe(first_group))).Times(0);
730 EXPECT_CALL(mock_store, GetBool(first_group, _, _))
731 .WillRepeatedly(Return(false));
732 EXPECT_CALL(mock_store, GetBool(StrNe(first_group), _, _)).Times(0);
733 ScopedMockLog log;
734 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
735 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
736 EndsWith("choosing the first.")));
737 EXPECT_TRUE(service->Load(&mock_store));
738}
739
Paul Stewartd08f4432011-11-04 07:48:20 -0700740TEST_F(WiFiServiceSecurityTest, WPAMapping) {
741 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
742 flimflam::kSecurityPsk));
743 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
744 flimflam::kSecurityPsk));
745 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
746 flimflam::kSecurityPsk));
747 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
748 flimflam::kSecurityWep));
749 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
750 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800751 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
752 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700753}
754
755TEST_F(WiFiServiceSecurityTest, LoadMapping) {
756 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
757 flimflam::kSecurityPsk,
758 true));
759 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
760 flimflam::kSecurityRsn,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800761 false));
Paul Stewartd08f4432011-11-04 07:48:20 -0700762 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
763 flimflam::kSecurityWpa,
764 false));
765 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
766 flimflam::kSecurityPsk,
767 true));
768 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
769 flimflam::kSecurityWpa,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800770 false));
Paul Stewartd08f4432011-11-04 07:48:20 -0700771 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
772 flimflam::kSecurityRsn,
773 false));
774 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
775 flimflam::kSecurityWep,
776 true));
777 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
778 flimflam::kSecurityPsk,
779 false));
780}
781
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800782TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
Paul Stewart3c504012013-01-17 17:49:58 -0800783 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityPsk);
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800784 NiceMock<MockStore> mock_store;
785 const string storage_id = service->GetStorageIdentifier();
786 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
787 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800788 set<string> groups;
789 groups.insert(storage_id);
790 EXPECT_CALL(mock_store, GetGroupsWithProperties(
791 ContainsWiFiProperties(
Paul Stewart3c504012013-01-17 17:49:58 -0800792 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityPsk)))
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800793 .WillRepeatedly(Return(groups));
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800794 EXPECT_CALL(mock_store, GetBool(_, _, _))
795 .WillRepeatedly(Return(false));
796 const string passphrase = "passphrase";
797 EXPECT_CALL(mock_store,
798 GetCryptedString(StrEq(storage_id),
799 WiFiService::kStoragePassphrase, _))
800 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
801 EXPECT_CALL(mock_store,
802 GetCryptedString(StrEq(storage_id),
803 StrNe(WiFiService::kStoragePassphrase), _))
804 .WillRepeatedly(Return(false));
805 EXPECT_TRUE(service->need_passphrase_);
806 EXPECT_TRUE(service->Load(&mock_store));
807 EXPECT_EQ(passphrase, service->passphrase_);
808 EXPECT_TRUE(service->connectable());
809 EXPECT_FALSE(service->need_passphrase_);
810 service->Unload();
811 EXPECT_EQ(string(""), service->passphrase_);
812 EXPECT_FALSE(service->connectable());
813 EXPECT_TRUE(service->need_passphrase_);
814}
815
Christopher Wiley27b47232012-11-02 13:13:00 -0700816TEST_F(WiFiServiceTest, ConfigureMakesConnectable) {
817 string guid("legit_guid");
818 KeyValueStore args;
819 args.SetString(flimflam::kEapIdentityProperty, "legit_identity");
820 args.SetString(flimflam::kEapPasswordProperty, "legit_password");
821 args.SetString(flimflam::kEAPEAPProperty, "PEAP");
822 args.SetString(flimflam::kGuidProperty, guid);
823 Error error;
Christopher Wiley27b47232012-11-02 13:13:00 -0700824
Paul Stewart3c504012013-01-17 17:49:58 -0800825 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
Christopher Wiley27b47232012-11-02 13:13:00 -0700826 // Hack the GUID in so that we don't have to mess about with WiFi to regsiter
827 // our service. This way, Manager will handle the lookup itself.
828 service->set_guid(guid);
829 manager()->RegisterService(service);
830 EXPECT_FALSE(service->connectable());
831 EXPECT_EQ(service.get(), manager()->GetService(args, &error).get());
832 EXPECT_TRUE(error.IsSuccess());
833 EXPECT_TRUE(service->connectable());
834}
835
Paul Stewart3c504012013-01-17 17:49:58 -0800836TEST_F(WiFiServiceTest, ConfigurePassphrase) {
837 EXPECT_EQ(Error::kNotSupported,
838 TestConfigurePassphrase(flimflam::kSecurityNone, ""));
839 EXPECT_EQ(Error::kNotSupported,
840 TestConfigurePassphrase(flimflam::kSecurityNone, "foo"));
841 EXPECT_EQ(Error::kSuccess,
842 TestConfigurePassphrase(flimflam::kSecurityWep, NULL));
843 EXPECT_EQ(Error::kInvalidPassphrase,
844 TestConfigurePassphrase(flimflam::kSecurityWep, ""));
845 EXPECT_EQ(Error::kInvalidPassphrase,
846 TestConfigurePassphrase(flimflam::kSecurityWep, "abcd"));
847 EXPECT_EQ(Error::kSuccess,
848 TestConfigurePassphrase(flimflam::kSecurityWep, "abcde"));
849 EXPECT_EQ(Error::kSuccess,
850 TestConfigurePassphrase(flimflam::kSecurityWep, "abcdefghijklm"));
851 EXPECT_EQ(Error::kSuccess,
852 TestConfigurePassphrase(flimflam::kSecurityWep, "0:abcdefghijklm"));
853 EXPECT_EQ(Error::kSuccess,
854 TestConfigurePassphrase(flimflam::kSecurityWep, "0102030405"));
855 EXPECT_EQ(Error::kInvalidPassphrase,
856 TestConfigurePassphrase(flimflam::kSecurityWep, "0x0102030405"));
857 EXPECT_EQ(Error::kInvalidPassphrase,
858 TestConfigurePassphrase(flimflam::kSecurityWep, "O102030405"));
859 EXPECT_EQ(Error::kInvalidPassphrase,
860 TestConfigurePassphrase(flimflam::kSecurityWep, "1:O102030405"));
861 EXPECT_EQ(Error::kInvalidPassphrase,
862 TestConfigurePassphrase(flimflam::kSecurityWep, "1:0xO102030405"));
863 EXPECT_EQ(Error::kInvalidPassphrase,
864 TestConfigurePassphrase(flimflam::kSecurityWep, "0xO102030405"));
865 EXPECT_EQ(Error::kSuccess,
866 TestConfigurePassphrase(flimflam::kSecurityWep,
867 "0102030405060708090a0b0c0d"));
868 EXPECT_EQ(Error::kSuccess,
869 TestConfigurePassphrase(flimflam::kSecurityWep,
870 "0102030405060708090A0B0C0D"));
871 EXPECT_EQ(Error::kSuccess,
872 TestConfigurePassphrase(flimflam::kSecurityWep,
873 "0:0102030405060708090a0b0c0d"));
874 EXPECT_EQ(Error::kSuccess,
875 TestConfigurePassphrase(flimflam::kSecurityWep,
876 "0:0x0102030405060708090a0b0c0d"));
877 EXPECT_EQ(Error::kSuccess,
878 TestConfigurePassphrase(flimflam::kSecurityWpa, NULL));
879 EXPECT_EQ(Error::kSuccess,
880 TestConfigurePassphrase(flimflam::kSecurityWpa, "secure password"));
881 EXPECT_EQ(Error::kInvalidPassphrase,
882 TestConfigurePassphrase(flimflam::kSecurityWpa, ""));
883 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
884 flimflam::kSecurityWpa,
885 string(IEEE_80211::kWPAAsciiMinLen, 'Z').c_str()));
886 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
887 flimflam::kSecurityWpa,
888 string(IEEE_80211::kWPAAsciiMaxLen, 'Z').c_str()));
889 // subtle: invalid length for hex key, but valid as ascii passphrase
890 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
891 flimflam::kSecurityWpa,
892 string(IEEE_80211::kWPAHexLen-1, '1').c_str()));
893 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
894 flimflam::kSecurityWpa,
895 string(IEEE_80211::kWPAHexLen, '1').c_str()));
896 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
897 flimflam::kSecurityWpa,
898 string(IEEE_80211::kWPAAsciiMinLen-1, 'Z').c_str()));
899 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
900 flimflam::kSecurityWpa,
901 string(IEEE_80211::kWPAAsciiMaxLen+1, 'Z').c_str()));
902 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
903 flimflam::kSecurityWpa,
904 string(IEEE_80211::kWPAHexLen+1, '1').c_str()));
905}
906
907TEST_F(WiFiServiceTest, ConfigureRedundantProperties) {
908 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
909 KeyValueStore args;
910 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
911 args.SetString(flimflam::kSSIDProperty, simple_ssid_string());
912 args.SetString(flimflam::kSecurityProperty, flimflam::kSecurityNone);
913 const string kGUID = "aguid";
914 args.SetString(flimflam::kGuidProperty, kGUID);
915
916 EXPECT_EQ("", service->guid());
917 Error error;
918 service->Configure(args, &error);
919 EXPECT_TRUE(error.IsSuccess());
920 EXPECT_EQ(kGUID, service->guid());
921}
922
923TEST_F(WiFiServiceTest, DisconnectWithWiFi) {
924 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityWep);
925 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
926 Error error;
927 service->Disconnect(&error);
928}
929
930TEST_F(WiFiServiceTest, DisconnectWithoutWiFi) {
931 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
932 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
933 Error error;
934 service->Disconnect(&error);
935 EXPECT_EQ(Error::kOperationFailed, error.type());
936}
937
938TEST_F(WiFiServiceTest, DisconnectWithoutWiFiWhileAssociating) {
939 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
940 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
941 service->SetState(Service::kStateAssociating);
942 ScopedMockLog log;
943 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
944 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
945 HasSubstr("WiFi endpoints do not (yet) exist.")));
946 Error error;
947 service->Disconnect(&error);
948 EXPECT_EQ(Error::kOperationFailed, error.type());
949}
950
Paul Stewart835934a2012-12-06 19:27:09 -0800951TEST_F(WiFiServiceTest, UnloadAndClearCacheWEP) {
Paul Stewart3c504012013-01-17 17:49:58 -0800952 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityWep);
Paul Stewart835934a2012-12-06 19:27:09 -0800953 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
954 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -0800955 service->Unload();
956}
957
958TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
Paul Stewart3c504012013-01-17 17:49:58 -0800959 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
Paul Stewart835934a2012-12-06 19:27:09 -0800960 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
961 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -0800962 service->Unload();
963}
964
Paul Stewart0756db92012-01-27 08:34:47 -0800965TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewart3c504012013-01-17 17:49:58 -0800966 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewarta41e38d2011-11-11 07:47:29 -0800967 const string storage_id = service->GetStorageIdentifier();
968 string address;
969 string mode;
970 string security;
971 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
972 &security));
Paul Stewart3c504012013-01-17 17:49:58 -0800973 EXPECT_EQ(StringToLowerASCII(GetAnyDeviceAddress()), address);
Paul Stewarta41e38d2011-11-11 07:47:29 -0800974 EXPECT_EQ(flimflam::kModeManaged, mode);
975 EXPECT_EQ(flimflam::kSecurityNone, security);
976}
977
Paul Stewart0756db92012-01-27 08:34:47 -0800978TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
979 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
980 // which needs to be dealt with specially in the parser.
Paul Stewart3c504012013-01-17 17:49:58 -0800981 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
Paul Stewart0756db92012-01-27 08:34:47 -0800982 const string storage_id = service->GetStorageIdentifier();
983 string address;
984 string mode;
985 string security;
986 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
987 &security));
Paul Stewart3c504012013-01-17 17:49:58 -0800988 EXPECT_EQ(StringToLowerASCII(GetAnyDeviceAddress()), address);
Paul Stewart0756db92012-01-27 08:34:47 -0800989 EXPECT_EQ(flimflam::kModeManaged, mode);
990 EXPECT_EQ(flimflam::kSecurity8021x, security);
991}
992
Paul Stewart85aea152013-01-22 09:31:56 -0800993TEST_F(WiFiServiceFixupStorageTest, FixedEntries) {
994 const string kNonWiFiId = "vpn_foo";
995 const string kUnparsableWiFiId = "wifi_foo";
996
997 AddGroup(kNonWiFiId);
998 AddGroup(kUnparsableWiFiId);
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800999 AddServiceEntry(true, true, true, true);
1000 AddServiceEntry(false, false, false, false);
1001 AddServiceEntry(true, true, true, true);
1002 AddServiceEntry(false, false, false, false);
Paul Stewart85aea152013-01-22 09:31:56 -08001003 EXPECT_TRUE(FixupServiceEntries());
1004}
1005
1006TEST_F(WiFiServiceFixupStorageTest, NoFixedEntries) {
1007 const string kNonWiFiId = "vpn_foo";
1008 const string kUnparsableWiFiId = "wifi_foo";
1009
1010 AddGroup(kNonWiFiId);
1011 AddGroup(kUnparsableWiFiId);
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001012 AddServiceEntry(true, true, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001013 EXPECT_FALSE(FixupServiceEntries());
1014}
1015
1016TEST_F(WiFiServiceFixupStorageTest, MissingTypeProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001017 AddServiceEntry(false, true, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001018 EXPECT_TRUE(FixupServiceEntries());
1019}
1020
1021TEST_F(WiFiServiceFixupStorageTest, MissingModeProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001022 AddServiceEntry(true, false, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001023 EXPECT_TRUE(FixupServiceEntries());
1024}
1025
1026TEST_F(WiFiServiceFixupStorageTest, MissingSecurityProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001027 AddServiceEntry(true, true, false, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001028 EXPECT_TRUE(FixupServiceEntries());
1029}
1030
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001031TEST_F(WiFiServiceFixupStorageTest, MissingSecurityClassProperty) {
1032 AddServiceEntry(true, true, true, false);
1033 EXPECT_TRUE(FixupServiceEntries());
1034}
Paul Stewart85aea152013-01-22 09:31:56 -08001035
mukesh agrawal29c13a12011-11-24 00:09:19 +00001036TEST_F(WiFiServiceTest, Connectable) {
1037 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001038 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001039
1040 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -08001041 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001042
1043 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001044 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001045
1046 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001047 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001048
1049 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001050 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001051
1052 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -08001053 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
1054 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
1055 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001056
1057 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001058 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
1059
1060 Service::EapCredentials eap;
1061 // Empty EAP credentials should not make a 802.1x network connectable.
1062 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1063
1064 eap.identity = "something";
1065 // If client certificate is being used, a private key must exist.
1066 eap.client_cert = "some client cert";
1067 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1068 eap.private_key = "some private key";
1069 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1070
1071 // Identity is always required.
1072 eap.identity.clear();
1073 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1074
1075 eap.identity = "something";
1076 // For non EAP-TLS types, a password is required.
1077 eap.eap = "Non-TLS";
1078 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1079 eap.password = "some password";
1080 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -08001081 // Dynamic WEP + 802.1X should be connectable under the same conditions.
1082 eap.key_management = "IEEE8021X";
1083 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001084}
1085
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001086TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001087 const char *reason;
Paul Stewart3c504012013-01-17 17:49:58 -08001088 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001089 EXPECT_CALL(*wifi(), IsIdle())
1090 .WillRepeatedly(Return(true));
1091 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001092 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1093 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001094
mukesh agrawalbf14e942012-03-02 14:36:34 -08001095 reason = "";
mukesh agrawal43970a22013-02-15 16:00:07 -08001096 WiFiEndpointRefPtr endpoint =
1097 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001098 service->AddEndpoint(endpoint);
1099 EXPECT_CALL(*wifi(), IsIdle())
1100 .WillRepeatedly(Return(true));
1101 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001102 EXPECT_TRUE(service->IsAutoConnectable(&reason));
1103 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001104
1105 // WiFi only supports connecting to one Service at a time. So, to
1106 // avoid disrupting connectivity, we only allow auto-connection to
1107 // a WiFiService when the corresponding WiFi is idle.
1108 EXPECT_CALL(*wifi(), IsIdle())
1109 .WillRepeatedly(Return(false));
1110 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001111 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1112 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001113}
1114
1115TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001116 const char *reason;
Paul Stewart3c504012013-01-17 17:49:58 -08001117 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001118 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001119 EXPECT_CALL(*wifi(), ConnectTo(_, _))
1120 .Times(0);
1121 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001122 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001123
mukesh agrawal43970a22013-02-15 16:00:07 -08001124 WiFiEndpointRefPtr endpoint =
1125 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001126 service->AddEndpoint(endpoint);
1127 EXPECT_CALL(*wifi(), IsIdle())
1128 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -08001129 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001130 EXPECT_CALL(*wifi(), ConnectTo(_, _));
1131 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001132 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -08001133
1134 Error error;
Christopher Wileyabd3b502012-09-26 13:08:52 -07001135 service->UserInitiatedDisconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001136 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -08001137 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001138}
1139
Gaurav Shah10109f22011-11-11 20:16:22 -08001140TEST_F(WiFiServiceTest, Populate8021x) {
Paul Stewart3c504012013-01-17 17:49:58 -08001141 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Gaurav Shah10109f22011-11-11 20:16:22 -08001142 Service::EapCredentials eap;
1143 eap.identity = "testidentity";
Paul Stewart20550982012-04-16 12:16:11 -07001144 eap.pin = "xxxx";
Gaurav Shah10109f22011-11-11 20:16:22 -08001145 service->set_eap(eap);
1146 map<string, ::DBus::Variant> params;
1147 service->Populate8021xProperties(&params);
1148 // Test that only non-empty 802.1x properties are populated.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001149 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapIdentity));
1150 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
1151 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
1152
Paul Stewart20550982012-04-16 12:16:11 -07001153 // Test that CA path is set by default.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001154 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
1155
Paul Stewart20550982012-04-16 12:16:11 -07001156 // Test that hardware-backed security arguments are not set.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001157 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
1158 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
1159 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
Paul Stewart20550982012-04-16 12:16:11 -07001160}
1161
1162TEST_F(WiFiServiceTest, Populate8021xNoSystemCAs) {
Paul Stewart3c504012013-01-17 17:49:58 -08001163 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewart20550982012-04-16 12:16:11 -07001164 Service::EapCredentials eap;
1165 eap.identity = "testidentity";
1166 eap.use_system_cas = false;
1167 service->set_eap(eap);
1168 map<string, ::DBus::Variant> params;
1169 service->Populate8021xProperties(&params);
1170 // Test that CA path is not set if use_system_cas is explicitly false.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001171 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
Paul Stewart20550982012-04-16 12:16:11 -07001172}
1173
1174TEST_F(WiFiServiceTest, Populate8021xUsingHardwareAuth) {
Paul Stewart3c504012013-01-17 17:49:58 -08001175 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewart20550982012-04-16 12:16:11 -07001176 Service::EapCredentials eap;
1177 eap.identity = "testidentity";
1178 eap.key_id = "key_id";
1179 eap.pin = "xxxx";
1180 service->set_eap(eap);
1181 map<string, ::DBus::Variant> params;
1182 service->Populate8021xProperties(&params);
1183 // Test that EAP engine parameters set if key_id is set.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001184 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
1185 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
1186 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
1187 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
1188}
1189
1190TEST_F(WiFiServiceTest, Populate8021xNSS) {
1191 vector<uint8_t> ssid(1, 'a');
Paul Stewart3c504012013-01-17 17:49:58 -08001192 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewartecf4cd12012-04-17 11:08:39 -07001193 Service::EapCredentials eap;
1194 eap.ca_cert_nss = "nss_nickname";
1195 service->set_eap(eap);
1196 MockNSS nss;
1197 service->nss_ = &nss;
1198
1199 const string kNSSCertfile("/tmp/nss-cert");
1200 FilePath nss_cert(kNSSCertfile);
1201 vector<char> ssid_in_chars(ssid.begin(), ssid.end());
1202 EXPECT_CALL(nss, GetDERCertfile(eap.ca_cert_nss, ssid_in_chars))
1203 .WillOnce(Return(nss_cert));
1204
1205 map<string, ::DBus::Variant> params;
1206 service->Populate8021xProperties(&params);
1207 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
1208 if (ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert)) {
1209 EXPECT_EQ(kNSSCertfile, params[wpa_supplicant::kNetworkPropertyEapCaCert]
1210 .reader().get_string());
1211 }
Gaurav Shah10109f22011-11-11 20:16:22 -08001212}
1213
Paul Stewart5baebb72013-03-14 11:43:29 -07001214TEST_F(WiFiServiceTest, Populate8021xPEM) {
1215 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
1216 Service::EapCredentials eap;
1217 eap.ca_cert_pem = "-pem-certificate-here-";
1218 service->set_eap(eap);
1219 MockCertificateFile *certificate_file = new MockCertificateFile();
1220 service->certificate_file_.reset(certificate_file); // Passes ownership.
1221
1222 const string kPEMCertfile("/tmp/pem-cert");
1223 FilePath pem_cert(kPEMCertfile);
1224 EXPECT_CALL(*certificate_file, CreateDERFromString(eap.ca_cert_pem))
1225 .WillOnce(Return(pem_cert));
1226
1227 map<string, ::DBus::Variant> params;
1228 service->Populate8021xProperties(&params);
1229 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
1230 if (ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert)) {
1231 EXPECT_EQ(kPEMCertfile, params[wpa_supplicant::kNetworkPropertyEapCaCert]
1232 .reader().get_string());
1233 }
1234}
1235
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001236TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
Paul Stewart3c504012013-01-17 17:49:58 -08001237 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWep);
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001238
1239 EXPECT_EQ("", wifi_service->passphrase_);
1240
1241 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001242 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001243 wifi_service->mutable_store(),
1244 flimflam::kPassphraseProperty,
1245 DBusAdaptor::StringToVariant("0:abcde"),
1246 &error));
1247 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
1248
1249 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
1250 flimflam::kPassphraseProperty,
1251 &error));
1252 EXPECT_EQ("", wifi_service->passphrase_);
1253}
1254
mukesh agrawale1d90e92012-02-15 17:36:08 -08001255TEST_F(WiFiServiceTest, SignalToStrength) {
1256 // Verify that our mapping is sane, in the sense that it preserves ordering.
1257 // We break the test into two domains, because we assume that positive
1258 // values aren't actually in dBm.
1259 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
1260 int16 current_mapped = WiFiService::SignalToStrength(i);
1261 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1262 EXPECT_LE(current_mapped, next_mapped)
1263 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001264 EXPECT_GE(current_mapped, Service::kStrengthMin);
1265 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001266 }
1267 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
1268 int16 current_mapped = WiFiService::SignalToStrength(i);
1269 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1270 EXPECT_LE(current_mapped, next_mapped)
1271 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001272 EXPECT_GE(current_mapped, Service::kStrengthMin);
1273 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001274 }
1275}
1276
1277TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
1278 // If the chosen signal values don't map to distinct strength
1279 // values, then we can't expect our other tests to pass. So verify
1280 // their distinctness.
1281 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
1282 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
1283 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
1284}
1285
1286TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
1287 // Initial endpoint updates values.
1288 EXPECT_CALL(adaptor, EmitUint16Changed(
1289 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001290 EXPECT_CALL(adaptor, EmitStringChanged(
1291 flimflam::kWifiBSsid, kOkEndpointBssId));
1292 EXPECT_CALL(adaptor, EmitUint8Changed(
mukesh agrawale1d90e92012-02-15 17:36:08 -08001293 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1294 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001295 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001296 Mock::VerifyAndClearExpectations(&adaptor);
1297
1298 // Endpoint with stronger signal updates values.
1299 EXPECT_CALL(adaptor, EmitUint16Changed(
1300 flimflam::kWifiFrequency, kGoodEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001301 EXPECT_CALL(adaptor, EmitStringChanged(
1302 flimflam::kWifiBSsid, kGoodEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001303 EXPECT_CALL(adaptor, EmitUint8Changed(
1304 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
1305 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001306 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001307 Mock::VerifyAndClearExpectations(&adaptor);
1308
1309 // Endpoint with lower signal does not change values.
1310 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001311 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001312 EXPECT_CALL(adaptor,
1313 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1314 service->AddEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001315 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001316 Mock::VerifyAndClearExpectations(&adaptor);
1317
1318 // Removing non-optimal endpoint does not change values.
1319 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001320 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001321 EXPECT_CALL(adaptor,
1322 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1323 service->RemoveEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001324 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001325 Mock::VerifyAndClearExpectations(&adaptor);
1326
1327 // Removing optimal endpoint updates values.
1328 EXPECT_CALL(adaptor, EmitUint16Changed(
1329 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001330 EXPECT_CALL(adaptor, EmitStringChanged(
1331 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001332 EXPECT_CALL(adaptor, EmitUint8Changed(
1333 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1334 service->RemoveEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001335 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001336 Mock::VerifyAndClearExpectations(&adaptor);
1337
1338 // Removing last endpoint updates values (and doesn't crash).
1339 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001340 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001341 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1342 service->RemoveEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001343 EXPECT_EQ(0, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001344 Mock::VerifyAndClearExpectations(&adaptor);
1345}
1346
1347TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1348 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001349 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001350 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1351 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1352 service->AddEndpoint(bad_endpoint);
1353 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001354 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001355 Mock::VerifyAndClearExpectations(&adaptor);
1356
1357 // Setting current endpoint forces adoption of its values, even if it
1358 // doesn't have the highest signal.
1359 EXPECT_CALL(adaptor, EmitUint16Changed(
1360 flimflam::kWifiFrequency, kBadEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001361 EXPECT_CALL(adaptor, EmitStringChanged(
1362 flimflam::kWifiBSsid, kBadEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001363 EXPECT_CALL(adaptor, EmitUint8Changed(
1364 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
1365 service->NotifyCurrentEndpoint(bad_endpoint);
1366 Mock::VerifyAndClearExpectations(&adaptor);
1367
1368 // Adding a better endpoint doesn't matter, when current endpoint is set.
1369 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001370 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001371 EXPECT_CALL(adaptor,
1372 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1373 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001374 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001375 Mock::VerifyAndClearExpectations(&adaptor);
1376
1377 // Removing a better endpoint doesn't matter, when current endpoint is set.
1378 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001379 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001380 EXPECT_CALL(adaptor,
1381 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1382 service->RemoveEndpoint(good_endpoint);
1383 Mock::VerifyAndClearExpectations(&adaptor);
1384
1385 // Removing the current endpoint is safe and sane.
1386 EXPECT_CALL(adaptor, EmitUint16Changed(
1387 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001388 EXPECT_CALL(adaptor, EmitStringChanged(
1389 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001390 EXPECT_CALL(adaptor, EmitUint8Changed(
1391 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1392 service->RemoveEndpoint(bad_endpoint);
1393 Mock::VerifyAndClearExpectations(&adaptor);
1394
1395 // Clearing the current endpoint (without removing it) is also safe and sane.
1396 service->NotifyCurrentEndpoint(ok_endpoint);
1397 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001398 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001399 EXPECT_CALL(adaptor,
1400 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1401 service->NotifyCurrentEndpoint(NULL);
1402 Mock::VerifyAndClearExpectations(&adaptor);
1403}
1404
1405TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1406 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001407 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001408 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1409 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1410 service->AddEndpoint(ok_endpoint);
1411 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001412 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001413 Mock::VerifyAndClearExpectations(&adaptor);
1414
1415 // Updating sub-optimal Endpoint doesn't update Service.
1416 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001417 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001418 EXPECT_CALL(adaptor,
1419 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1420 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
Paul Stewart3c504012013-01-17 17:49:58 -08001421 service->NotifyEndpointUpdated(ok_endpoint);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001422 Mock::VerifyAndClearExpectations(&adaptor);
1423
1424 // Updating optimal Endpoint updates appropriate Service property.
1425 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001426 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001427 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1428 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
Paul Stewart3c504012013-01-17 17:49:58 -08001429 service->NotifyEndpointUpdated(good_endpoint);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001430 Mock::VerifyAndClearExpectations(&adaptor);
1431
1432 // Change in optimal Endpoint updates Service properties.
1433 EXPECT_CALL(adaptor, EmitUint16Changed(
1434 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001435 EXPECT_CALL(adaptor, EmitStringChanged(
1436 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001437 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1438 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
Paul Stewart3c504012013-01-17 17:49:58 -08001439 service->NotifyEndpointUpdated(ok_endpoint);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001440 Mock::VerifyAndClearExpectations(&adaptor);
1441}
1442
Paul Stewarta5e7d5f2013-01-09 18:06:15 -08001443TEST_F(WiFiServiceUpdateFromEndpointsTest, Ieee80211w) {
1444 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1445 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1446 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1447 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1448 service->AddEndpoint(ok_endpoint);
1449 EXPECT_FALSE(service->ieee80211w_required());
1450 good_endpoint->ieee80211w_required_ = true;
1451 service->AddEndpoint(good_endpoint);
1452 EXPECT_TRUE(service->ieee80211w_required());
1453 service->RemoveEndpoint(good_endpoint);
1454 EXPECT_TRUE(service->ieee80211w_required());
1455}
1456
Paul Stewart8653f462013-02-06 12:21:05 -08001457TEST_F(WiFiServiceUpdateFromEndpointsTest, WarningOnDisconnect) {
1458 service->AddEndpoint(ok_endpoint);
1459 service->SetState(Service::kStateAssociating);
1460 ScopedMockLog log;
1461 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1462 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
1463 EndsWith("disconnect due to no remaining endpoints.")));
1464 service->RemoveEndpoint(ok_endpoint);
1465}
1466
Paul Stewart6df20bd2013-03-13 19:31:25 -07001467TEST_F(WiFiServiceTest, SecurityFromCurrentEndpoint) {
1468 WiFiServiceRefPtr service(MakeSimpleService(flimflam::kSecurityPsk));
1469 EXPECT_EQ(flimflam::kSecurityPsk, service->GetSecurity(NULL));
1470 WiFiEndpoint *endpoint = MakeOpenEndpoint(
1471 simple_ssid_string(), "00:00:00:00:00:00", 0, 0);
1472 service->AddEndpoint(endpoint);
1473 EXPECT_EQ(flimflam::kSecurityPsk, service->GetSecurity(NULL));
1474 service->NotifyCurrentEndpoint(endpoint);
1475 EXPECT_EQ(flimflam::kSecurityNone, service->GetSecurity(NULL));
1476 service->NotifyCurrentEndpoint(NULL);
1477 EXPECT_EQ(flimflam::kSecurityPsk, service->GetSecurity(NULL));
1478}
1479
mukesh agrawal43970a22013-02-15 16:00:07 -08001480TEST_F(WiFiServiceTest, UpdateSecurity) {
1481 // Cleartext and pre-shared-key crypto.
1482 {
1483 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
1484 EXPECT_EQ(Service::kCryptoNone, service->crypto_algorithm());
1485 EXPECT_FALSE(service->key_rotation());
1486 EXPECT_FALSE(service->endpoint_auth());
1487 }
1488 {
1489 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
1490 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1491 EXPECT_FALSE(service->key_rotation());
1492 EXPECT_FALSE(service->endpoint_auth());
1493 }
1494 {
1495 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityPsk);
1496 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1497 EXPECT_TRUE(service->key_rotation());
1498 EXPECT_FALSE(service->endpoint_auth());
1499 }
1500 {
1501 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWpa);
1502 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1503 EXPECT_TRUE(service->key_rotation());
1504 EXPECT_FALSE(service->endpoint_auth());
1505 }
1506 {
1507 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityRsn);
1508 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
1509 EXPECT_TRUE(service->key_rotation());
1510 EXPECT_FALSE(service->endpoint_auth());
1511 }
1512
1513 // Crypto with 802.1X key management.
1514 {
1515 // WEP
1516 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
1517 service->SetEAPKeyManagement("IEEE8021X");
1518 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1519 EXPECT_TRUE(service->key_rotation());
1520 EXPECT_TRUE(service->endpoint_auth());
1521 }
1522 {
1523 // WPA
1524 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
1525 WiFiEndpointRefPtr endpoint =
1526 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false);
1527 service->AddEndpoint(endpoint);
1528 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1529 EXPECT_TRUE(service->key_rotation());
1530 EXPECT_TRUE(service->endpoint_auth());
1531 }
1532 {
1533 // RSN
1534 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
1535 WiFiEndpointRefPtr endpoint =
1536 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true);
1537 service->AddEndpoint(endpoint);
1538 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
1539 EXPECT_TRUE(service->key_rotation());
1540 EXPECT_TRUE(service->endpoint_auth());
1541 }
1542 {
1543 // AP supports both WPA and RSN.
1544 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
1545 WiFiEndpointRefPtr endpoint =
1546 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true);
1547 service->AddEndpoint(endpoint);
1548 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
1549 EXPECT_TRUE(service->key_rotation());
1550 EXPECT_TRUE(service->endpoint_auth());
1551 }
1552}
1553
1554TEST_F(WiFiServiceTest, ComputeCipher8021x) {
1555 // No endpoints.
1556 {
1557 const set<WiFiEndpointConstRefPtr> endpoints;
1558 EXPECT_EQ(Service::kCryptoNone,
1559 WiFiService::ComputeCipher8021x(endpoints));
1560 }
1561
1562 // Single endpoint, various configs.
1563 {
1564 set<WiFiEndpointConstRefPtr> endpoints;
1565 endpoints.insert(
1566 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
1567 EXPECT_EQ(Service::kCryptoNone,
1568 WiFiService::ComputeCipher8021x(endpoints));
1569 }
1570 {
1571 set<WiFiEndpointConstRefPtr> endpoints;
1572 endpoints.insert(
1573 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
1574 EXPECT_EQ(Service::kCryptoRc4,
1575 WiFiService::ComputeCipher8021x(endpoints));
1576 }
1577 {
1578 set<WiFiEndpointConstRefPtr> endpoints;
1579 endpoints.insert(
1580 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
1581 EXPECT_EQ(Service::kCryptoAes,
1582 WiFiService::ComputeCipher8021x(endpoints));
1583 }
1584 {
1585 set<WiFiEndpointConstRefPtr> endpoints;
1586 endpoints.insert(
1587 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
1588 EXPECT_EQ(Service::kCryptoAes,
1589 WiFiService::ComputeCipher8021x(endpoints));
1590 }
1591
1592 // Multiple endpoints.
1593 {
1594 set<WiFiEndpointConstRefPtr> endpoints;
1595 endpoints.insert(
1596 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
1597 endpoints.insert(
1598 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, false));
1599 EXPECT_EQ(Service::kCryptoNone,
1600 WiFiService::ComputeCipher8021x(endpoints));
1601 }
1602 {
1603 set<WiFiEndpointConstRefPtr> endpoints;
1604 endpoints.insert(
1605 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
1606 endpoints.insert(
1607 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
1608 EXPECT_EQ(Service::kCryptoNone,
1609 WiFiService::ComputeCipher8021x(endpoints));
1610 }
1611 {
1612 set<WiFiEndpointConstRefPtr> endpoints;
1613 endpoints.insert(
1614 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
1615 endpoints.insert(
1616 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
1617 EXPECT_EQ(Service::kCryptoRc4,
1618 WiFiService::ComputeCipher8021x(endpoints));
1619 }
1620 {
1621 set<WiFiEndpointConstRefPtr> endpoints;
1622 endpoints.insert(
1623 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
1624 endpoints.insert(
1625 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
1626 EXPECT_EQ(Service::kCryptoRc4,
1627 WiFiService::ComputeCipher8021x(endpoints));
1628 }
1629 {
1630 set<WiFiEndpointConstRefPtr> endpoints;
1631 endpoints.insert(
1632 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
1633 endpoints.insert(
1634 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
1635 EXPECT_EQ(Service::kCryptoAes,
1636 WiFiService::ComputeCipher8021x(endpoints));
1637 }
1638 {
1639 set<WiFiEndpointConstRefPtr> endpoints;
1640 endpoints.insert(
1641 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
1642 endpoints.insert(
1643 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, true));
1644 EXPECT_EQ(Service::kCryptoAes,
1645 WiFiService::ComputeCipher8021x(endpoints));
1646 }
1647}
1648
Albert Chaulk0e1cdea2013-02-27 15:32:55 -08001649TEST_F(WiFiServiceTest, Unload) {
1650 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityNone);
1651 EXPECT_CALL(*wifi(), DestroyIPConfigLease(service->GetStorageIdentifier())).
1652 Times(1);
1653 service->Unload();
1654}
1655
1656
Chris Masone34af2182011-08-22 11:59:36 -07001657} // namespace shill