1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chromeos/network/network_connection_handler_impl.h"
6 
7 #include <map>
8 #include <memory>
9 #include <set>
10 
11 #include "base/bind.h"
12 #include "base/files/file_util.h"
13 #include "base/json/json_reader.h"
14 #include "base/macros.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/test/task_environment.h"
18 #include "chromeos/network/managed_network_configuration_handler_impl.h"
19 #include "chromeos/network/network_cert_loader.h"
20 #include "chromeos/network/network_configuration_handler.h"
21 #include "chromeos/network/network_connection_observer.h"
22 #include "chromeos/network/network_handler.h"
23 #include "chromeos/network/network_profile_handler.h"
24 #include "chromeos/network/network_state_handler.h"
25 #include "chromeos/network/network_state_test_helper.h"
26 #include "chromeos/network/onc/onc_utils.h"
27 #include "chromeos/network/prohibited_technologies_handler.h"
28 #include "components/onc/onc_constants.h"
29 #include "crypto/scoped_nss_types.h"
30 #include "crypto/scoped_test_nss_db.h"
31 #include "net/base/net_errors.h"
32 #include "net/cert/nss_cert_database_chromeos.h"
33 #include "net/cert/x509_certificate.h"
34 #include "net/test/cert_test_util.h"
35 #include "net/test/test_data_directory.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "third_party/cros_system_api/dbus/service_constants.h"
38 #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
39 
40 namespace chromeos {
41 
42 namespace {
43 
44 const char kSuccessResult[] = "success";
45 
46 const char kTetherGuid[] = "tether-guid";
47 
48 class TestNetworkConnectionObserver : public NetworkConnectionObserver {
49  public:
50   TestNetworkConnectionObserver() = default;
51   ~TestNetworkConnectionObserver() override = default;
52 
53   // NetworkConnectionObserver
ConnectToNetworkRequested(const std::string & service_path)54   void ConnectToNetworkRequested(const std::string& service_path) override {
55     requests_.insert(service_path);
56   }
57 
ConnectSucceeded(const std::string & service_path)58   void ConnectSucceeded(const std::string& service_path) override {
59     results_[service_path] = kSuccessResult;
60   }
61 
ConnectFailed(const std::string & service_path,const std::string & error_name)62   void ConnectFailed(const std::string& service_path,
63                      const std::string& error_name) override {
64     results_[service_path] = error_name;
65   }
66 
DisconnectRequested(const std::string & service_path)67   void DisconnectRequested(const std::string& service_path) override {
68     requests_.insert(service_path);
69   }
70 
GetRequested(const std::string & service_path)71   bool GetRequested(const std::string& service_path) {
72     return requests_.count(service_path) != 0;
73   }
74 
GetResult(const std::string & service_path)75   std::string GetResult(const std::string& service_path) {
76     auto iter = results_.find(service_path);
77     if (iter == results_.end())
78       return "";
79     return iter->second;
80   }
81 
82  private:
83   std::set<std::string> requests_;
84   std::map<std::string, std::string> results_;
85 
86   DISALLOW_COPY_AND_ASSIGN(TestNetworkConnectionObserver);
87 };
88 
89 class FakeTetherDelegate : public NetworkConnectionHandler::TetherDelegate {
90  public:
FakeTetherDelegate()91   FakeTetherDelegate()
92       : last_delegate_function_type_(DelegateFunctionType::NONE) {}
93   ~FakeTetherDelegate() override = default;
94 
95   enum class DelegateFunctionType { NONE, CONNECT, DISCONNECT };
96 
last_delegate_function_type()97   DelegateFunctionType last_delegate_function_type() {
98     return last_delegate_function_type_;
99   }
100 
ConnectToNetwork(const std::string & service_path,base::OnceClosure success_callback,StringErrorCallback error_callback)101   void ConnectToNetwork(const std::string& service_path,
102                         base::OnceClosure success_callback,
103                         StringErrorCallback error_callback) override {
104     last_delegate_function_type_ = DelegateFunctionType::CONNECT;
105     last_service_path_ = service_path;
106     last_success_callback_ = std::move(success_callback);
107     last_error_callback_ = std::move(error_callback);
108   }
109 
DisconnectFromNetwork(const std::string & service_path,base::OnceClosure success_callback,StringErrorCallback error_callback)110   void DisconnectFromNetwork(const std::string& service_path,
111                              base::OnceClosure success_callback,
112                              StringErrorCallback error_callback) override {
113     last_delegate_function_type_ = DelegateFunctionType::DISCONNECT;
114     last_service_path_ = service_path;
115     last_success_callback_ = std::move(success_callback);
116     last_error_callback_ = std::move(error_callback);
117   }
118 
last_service_path()119   std::string& last_service_path() { return last_service_path_; }
120 
last_success_callback()121   base::OnceClosure& last_success_callback() { return last_success_callback_; }
122 
last_error_callback()123   StringErrorCallback& last_error_callback() { return last_error_callback_; }
124 
125  private:
126   std::string last_service_path_;
127   base::OnceClosure last_success_callback_;
128   StringErrorCallback last_error_callback_;
129   DelegateFunctionType last_delegate_function_type_;
130 };
131 
132 }  // namespace
133 
134 class NetworkConnectionHandlerImplTest : public testing::Test {
135  public:
NetworkConnectionHandlerImplTest()136   NetworkConnectionHandlerImplTest()
137       : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}
138 
139   ~NetworkConnectionHandlerImplTest() override = default;
140 
SetUp()141   void SetUp() override {
142     ASSERT_TRUE(test_nssdb_.is_open());
143 
144     // Use the same DB for public and private slot.
145     test_nsscertdb_.reset(new net::NSSCertDatabaseChromeOS(
146         crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot())),
147         crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot()))));
148 
149     NetworkCertLoader::Initialize();
150     NetworkCertLoader::ForceHardwareBackedForTesting();
151 
152     LoginState::Initialize();
153 
154     network_config_handler_.reset(
155         NetworkConfigurationHandler::InitializeForTest(
156             helper_.network_state_handler(),
157             nullptr /* network_device_handler */));
158 
159     network_profile_handler_.reset(new NetworkProfileHandler());
160     network_profile_handler_->Init();
161 
162     managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl());
163     managed_config_handler_->Init(
164         helper_.network_state_handler(), network_profile_handler_.get(),
165         network_config_handler_.get(), nullptr /* network_device_handler */,
166         nullptr /* prohibited_tecnologies_handler */);
167 
168     network_connection_handler_.reset(new NetworkConnectionHandlerImpl());
169     network_connection_handler_->Init(helper_.network_state_handler(),
170                                       network_config_handler_.get(),
171                                       managed_config_handler_.get());
172     network_connection_observer_.reset(new TestNetworkConnectionObserver);
173     network_connection_handler_->AddObserver(
174         network_connection_observer_.get());
175 
176     task_environment_.RunUntilIdle();
177 
178     fake_tether_delegate_.reset(new FakeTetherDelegate());
179   }
180 
TearDown()181   void TearDown() override {
182     managed_config_handler_.reset();
183     network_profile_handler_.reset();
184     network_connection_handler_->RemoveObserver(
185         network_connection_observer_.get());
186     network_connection_observer_.reset();
187     network_connection_handler_.reset();
188     network_config_handler_.reset();
189 
190     LoginState::Shutdown();
191 
192     NetworkCertLoader::Shutdown();
193   }
194 
195  protected:
ServicePathFromGuid(const std::string & guid)196   std::string ServicePathFromGuid(const std::string& guid) {
197     std::string service_path =
198         helper_.service_test()->FindServiceMatchingGUID(guid);
199     EXPECT_FALSE(service_path.empty());
200     return service_path;
201   }
202 
Connect(const std::string & service_path)203   void Connect(const std::string& service_path) {
204     network_connection_handler_->ConnectToNetwork(
205         service_path,
206         base::BindOnce(&NetworkConnectionHandlerImplTest::SuccessCallback,
207                        base::Unretained(this)),
208         base::BindOnce(&NetworkConnectionHandlerImplTest::ErrorCallback,
209                        base::Unretained(this)),
210         true /* check_error_state */, ConnectCallbackMode::ON_COMPLETED);
211     task_environment_.RunUntilIdle();
212   }
213 
Disconnect(const std::string & service_path)214   void Disconnect(const std::string& service_path) {
215     network_connection_handler_->DisconnectNetwork(
216         service_path,
217         base::BindOnce(&NetworkConnectionHandlerImplTest::SuccessCallback,
218                        base::Unretained(this)),
219         base::BindOnce(&NetworkConnectionHandlerImplTest::ErrorCallback,
220                        base::Unretained(this)));
221     task_environment_.RunUntilIdle();
222   }
223 
SuccessCallback()224   void SuccessCallback() { result_ = kSuccessResult; }
225 
ErrorCallback(const std::string & error_name,std::unique_ptr<base::DictionaryValue> error_data)226   void ErrorCallback(const std::string& error_name,
227                      std::unique_ptr<base::DictionaryValue> error_data) {
228     result_ = error_name;
229   }
230 
GetResultAndReset()231   std::string GetResultAndReset() {
232     std::string result;
233     result.swap(result_);
234     return result;
235   }
236 
StartNetworkCertLoader()237   void StartNetworkCertLoader() {
238     NetworkCertLoader::Get()->SetUserNSSDB(test_nsscertdb_.get());
239     task_environment_.RunUntilIdle();
240   }
241 
LoginToRegularUser()242   void LoginToRegularUser() {
243     LoginState::Get()->SetLoggedInState(LoginState::LOGGED_IN_ACTIVE,
244                                         LoginState::LOGGED_IN_USER_REGULAR);
245     task_environment_.RunUntilIdle();
246   }
247 
ImportTestClientCert()248   scoped_refptr<net::X509Certificate> ImportTestClientCert() {
249     net::ScopedCERTCertificateList ca_cert_list =
250         net::CreateCERTCertificateListFromFile(
251             net::GetTestCertsDirectory(), "client_1_ca.pem",
252             net::X509Certificate::FORMAT_AUTO);
253     if (ca_cert_list.empty()) {
254       LOG(ERROR) << "No CA cert loaded.";
255       return nullptr;
256     }
257     net::NSSCertDatabase::ImportCertFailureList failures;
258     EXPECT_TRUE(test_nsscertdb_->ImportCACerts(
259         ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures));
260     if (!failures.empty()) {
261       LOG(ERROR) << net::ErrorToString(failures[0].net_error);
262       return nullptr;
263     }
264 
265     // Import a client cert signed by that CA.
266     scoped_refptr<net::X509Certificate> client_cert(
267         net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(),
268                                             "client_1.pem", "client_1.pk8",
269                                             test_nssdb_.slot()));
270     return client_cert;
271   }
272 
SetupPolicy(const std::string & network_configs_json,const base::DictionaryValue & global_config,bool user_policy)273   void SetupPolicy(const std::string& network_configs_json,
274                    const base::DictionaryValue& global_config,
275                    bool user_policy) {
276     base::JSONReader::ValueWithError parsed_json =
277         base::JSONReader::ReadAndReturnValueWithError(
278             network_configs_json, base::JSON_ALLOW_TRAILING_COMMAS);
279     ASSERT_TRUE(parsed_json.value) << parsed_json.error_message;
280 
281     base::ListValue* network_configs = nullptr;
282     ASSERT_TRUE(parsed_json.value->GetAsList(&network_configs));
283 
284     if (user_policy) {
285       managed_config_handler_->SetPolicy(::onc::ONC_SOURCE_USER_POLICY,
286                                          helper_.UserHash(), *network_configs,
287                                          global_config);
288     } else {
289       managed_config_handler_->SetPolicy(::onc::ONC_SOURCE_DEVICE_POLICY,
290                                          std::string(),  // no username hash
291                                          *network_configs, global_config);
292     }
293     task_environment_.RunUntilIdle();
294   }
295 
ConfigureService(const std::string & shill_json_string)296   std::string ConfigureService(const std::string& shill_json_string) {
297     return helper_.ConfigureService(shill_json_string);
298   }
299 
GetServiceStringProperty(const std::string & service_path,const std::string & key)300   std::string GetServiceStringProperty(const std::string& service_path,
301                                        const std::string& key) {
302     return helper_.GetServiceStringProperty(service_path, key);
303   }
304 
network_state_handler()305   NetworkStateHandler* network_state_handler() {
306     return helper_.network_state_handler();
307   }
network_connection_observer()308   TestNetworkConnectionObserver* network_connection_observer() {
309     return network_connection_observer_.get();
310   }
network_connection_handler()311   NetworkConnectionHandler* network_connection_handler() {
312     return network_connection_handler_.get();
313   }
fake_tether_delegate()314   FakeTetherDelegate* fake_tether_delegate() {
315     return fake_tether_delegate_.get();
316   }
317 
318  private:
319   base::test::TaskEnvironment task_environment_;
320   NetworkStateTestHelper helper_{false /* use_default_devices_and_services */};
321   std::unique_ptr<NetworkConfigurationHandler> network_config_handler_;
322   std::unique_ptr<NetworkConnectionHandler> network_connection_handler_;
323   std::unique_ptr<TestNetworkConnectionObserver> network_connection_observer_;
324   std::unique_ptr<ManagedNetworkConfigurationHandlerImpl>
325       managed_config_handler_;
326   std::unique_ptr<NetworkProfileHandler> network_profile_handler_;
327   crypto::ScopedTestNSSDB test_nssdb_;
328   std::unique_ptr<net::NSSCertDatabaseChromeOS> test_nsscertdb_;
329   std::string result_;
330   std::unique_ptr<FakeTetherDelegate> fake_tether_delegate_;
331 
332   DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerImplTest);
333 };
334 
335 namespace {
336 
337 const char* kNoNetwork = "no-network";
338 
339 const char* kConfigWifi0Connectable =
340     "{ \"GUID\": \"wifi0\", \"Type\": \"wifi\", \"State\": \"idle\", "
341     "  \"Connectable\": true }";
342 const char* kConfigWifi1Connected =
343     "{ \"GUID\": \"wifi1\", \"Type\": \"wifi\", \"State\": \"online\" }";
344 const char* kConfigWifi2Connecting =
345     "{ \"GUID\": \"wifi2\", \"Type\": \"wifi\", \"State\": \"association\" }";
346 const char* kConfigWifi3RequiresPassphrase =
347     "{ \"GUID\": \"wifi3\", \"Type\": \"wifi\", "
348     "  \"PassphraseRequired\": true }";
349 
350 const char* kPolicyWifi0 =
351     "[{ \"GUID\": \"wifi0\",  \"IPAddressConfigType\": \"DHCP\", "
352     "   \"Type\": \"WiFi\", \"Name\": \"My WiFi Network\","
353     "   \"WiFi\": { \"SSID\": \"wifi0\"}}]";
354 
355 }  // namespace
356 
TEST_F(NetworkConnectionHandlerImplTest,NetworkConnectionHandlerConnectSuccess)357 TEST_F(NetworkConnectionHandlerImplTest,
358        NetworkConnectionHandlerConnectSuccess) {
359   std::string wifi0_service_path = ConfigureService(kConfigWifi0Connectable);
360   ASSERT_FALSE(wifi0_service_path.empty());
361   Connect(wifi0_service_path);
362   EXPECT_EQ(kSuccessResult, GetResultAndReset());
363   EXPECT_EQ(
364       shill::kStateOnline,
365       GetServiceStringProperty(wifi0_service_path, shill::kStateProperty));
366   // Observer expectations
367   EXPECT_TRUE(network_connection_observer()->GetRequested(wifi0_service_path));
368   EXPECT_EQ(kSuccessResult,
369             network_connection_observer()->GetResult(wifi0_service_path));
370 }
371 
TEST_F(NetworkConnectionHandlerImplTest,NetworkConnectionHandlerConnectBlockedByManagedOnly)372 TEST_F(NetworkConnectionHandlerImplTest,
373        NetworkConnectionHandlerConnectBlockedByManagedOnly) {
374   std::string wifi0_service_path = ConfigureService(kConfigWifi0Connectable);
375   ASSERT_FALSE(wifi0_service_path.empty());
376   base::DictionaryValue global_config;
377   global_config.SetKey(
378       ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect,
379       base::Value(true));
380   SetupPolicy("[]", global_config, false /* load as device policy */);
381   SetupPolicy("[]", base::DictionaryValue(), true /* load as user policy */);
382   LoginToRegularUser();
383   Connect(wifi0_service_path);
384   EXPECT_EQ(NetworkConnectionHandler::kErrorBlockedByPolicy,
385             GetResultAndReset());
386 
387   SetupPolicy(kPolicyWifi0, global_config, false /* load as device policy */);
388   Connect(wifi0_service_path);
389   EXPECT_EQ(kSuccessResult, GetResultAndReset());
390 }
391 
TEST_F(NetworkConnectionHandlerImplTest,NetworkConnectionHandlerConnectBlockedBySSID)392 TEST_F(NetworkConnectionHandlerImplTest,
393        NetworkConnectionHandlerConnectBlockedBySSID) {
394   std::string wifi0_service_path = ConfigureService(kConfigWifi0Connectable);
395   ASSERT_FALSE(wifi0_service_path.empty());
396 
397   // Set a device policy which blocks wifi0.
398   base::Value::ListStorage blocked;
399   blocked.push_back(base::Value("7769666930"));  // hex(wifi0) = 7769666930
400   base::DictionaryValue global_config;
401   global_config.SetKey(::onc::global_network_config::kBlockedHexSSIDs,
402                        base::Value(blocked));
403   SetupPolicy("[]", global_config, false /* load as device policy */);
404   SetupPolicy("[]", base::DictionaryValue(), true /* load as user policy */);
405 
406   LoginToRegularUser();
407 
408   Connect(wifi0_service_path);
409   EXPECT_EQ(NetworkConnectionHandler::kErrorBlockedByPolicy,
410             GetResultAndReset());
411 
412   // Set a user policy, which configures wifi0 (==allowed).
413   SetupPolicy(kPolicyWifi0, base::DictionaryValue(),
414               true /* load as user policy */);
415   Connect(wifi0_service_path);
416   EXPECT_EQ(kSuccessResult, GetResultAndReset());
417 }
418 
419 // Handles basic failure cases.
TEST_F(NetworkConnectionHandlerImplTest,NetworkConnectionHandlerConnectFailure)420 TEST_F(NetworkConnectionHandlerImplTest,
421        NetworkConnectionHandlerConnectFailure) {
422   Connect(kNoNetwork);
423   EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
424             GetResultAndReset());
425   EXPECT_TRUE(network_connection_observer()->GetRequested(kNoNetwork));
426   EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
427             network_connection_observer()->GetResult(kNoNetwork));
428 
429   std::string wifi1_service_path = ConfigureService(kConfigWifi1Connected);
430   ASSERT_FALSE(wifi1_service_path.empty());
431   Connect(wifi1_service_path);
432   EXPECT_EQ(NetworkConnectionHandler::kErrorConnected, GetResultAndReset());
433   EXPECT_TRUE(network_connection_observer()->GetRequested(wifi1_service_path));
434   EXPECT_EQ(NetworkConnectionHandler::kErrorConnected,
435             network_connection_observer()->GetResult(wifi1_service_path));
436 
437   std::string wifi2_service_path = ConfigureService(kConfigWifi2Connecting);
438   ASSERT_FALSE(wifi2_service_path.empty());
439   Connect(wifi2_service_path);
440   EXPECT_EQ(NetworkConnectionHandler::kErrorConnecting, GetResultAndReset());
441   EXPECT_TRUE(network_connection_observer()->GetRequested(wifi2_service_path));
442   EXPECT_EQ(NetworkConnectionHandler::kErrorConnecting,
443             network_connection_observer()->GetResult(wifi2_service_path));
444 
445   std::string wifi3_service_path =
446       ConfigureService(kConfigWifi3RequiresPassphrase);
447   Connect(wifi3_service_path);
448   EXPECT_EQ(NetworkConnectionHandler::kErrorPassphraseRequired,
449             GetResultAndReset());
450   EXPECT_TRUE(network_connection_observer()->GetRequested(wifi3_service_path));
451   EXPECT_EQ(NetworkConnectionHandler::kErrorPassphraseRequired,
452             network_connection_observer()->GetResult(wifi3_service_path));
453 }
454 
455 namespace {
456 
457 const char* kPolicyWithCertPatternTemplate =
458     "[ { \"GUID\": \"wifi4\","
459     "    \"Name\": \"wifi4\","
460     "    \"Type\": \"WiFi\","
461     "    \"WiFi\": {"
462     "      \"Security\": \"WPA-EAP\","
463     "      \"SSID\": \"wifi_ssid\","
464     "      \"EAP\": {"
465     "        \"Outer\": \"EAP-TLS\","
466     "        \"ClientCertType\": \"Pattern\","
467     "        \"ClientCertPattern\": {"
468     "          \"Subject\": {"
469     "            \"CommonName\" : \"%s\""
470     "          }"
471     "        }"
472     "      }"
473     "    }"
474     "} ]";
475 
476 }  // namespace
477 
478 // Handle certificates.
TEST_F(NetworkConnectionHandlerImplTest,ConnectCertificateMissing)479 TEST_F(NetworkConnectionHandlerImplTest, ConnectCertificateMissing) {
480   StartNetworkCertLoader();
481   SetupPolicy(base::StringPrintf(kPolicyWithCertPatternTemplate, "unknown"),
482               base::DictionaryValue(),  // no global config
483               true);                    // load as user policy
484 
485   Connect(ServicePathFromGuid("wifi4"));
486   EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired,
487             GetResultAndReset());
488 }
489 
TEST_F(NetworkConnectionHandlerImplTest,ConnectWithCertificateSuccess)490 TEST_F(NetworkConnectionHandlerImplTest, ConnectWithCertificateSuccess) {
491   StartNetworkCertLoader();
492   scoped_refptr<net::X509Certificate> cert = ImportTestClientCert();
493   ASSERT_TRUE(cert.get());
494 
495   SetupPolicy(base::StringPrintf(kPolicyWithCertPatternTemplate,
496                                  cert->subject().common_name.c_str()),
497               base::DictionaryValue(),  // no global config
498               true);                    // load as user policy
499 
500   Connect(ServicePathFromGuid("wifi4"));
501   EXPECT_EQ(kSuccessResult, GetResultAndReset());
502 }
503 
504 // Disabled, see http://crbug.com/396729.
TEST_F(NetworkConnectionHandlerImplTest,DISABLED_ConnectWithCertificateRequestedBeforeCertsAreLoaded)505 TEST_F(NetworkConnectionHandlerImplTest,
506        DISABLED_ConnectWithCertificateRequestedBeforeCertsAreLoaded) {
507   scoped_refptr<net::X509Certificate> cert = ImportTestClientCert();
508   ASSERT_TRUE(cert.get());
509 
510   SetupPolicy(base::StringPrintf(kPolicyWithCertPatternTemplate,
511                                  cert->subject().common_name.c_str()),
512               base::DictionaryValue(),  // no global config
513               true);                    // load as user policy
514 
515   Connect(ServicePathFromGuid("wifi4"));
516 
517   // Connect request came before the cert loader loaded certificates, so the
518   // connect request should have been throttled until the certificates are
519   // loaded.
520   EXPECT_EQ("", GetResultAndReset());
521 
522   StartNetworkCertLoader();
523 
524   // |StartNetworkCertLoader| should have triggered certificate loading.
525   // When the certificates got loaded, the connection request should have
526   // proceeded and eventually succeeded.
527   EXPECT_EQ(kSuccessResult, GetResultAndReset());
528 }
529 
TEST_F(NetworkConnectionHandlerImplTest,NetworkConnectionHandlerDisconnectSuccess)530 TEST_F(NetworkConnectionHandlerImplTest,
531        NetworkConnectionHandlerDisconnectSuccess) {
532   std::string wifi1_service_path = ConfigureService(kConfigWifi1Connected);
533   ASSERT_FALSE(wifi1_service_path.empty());
534   Disconnect(wifi1_service_path);
535   EXPECT_TRUE(network_connection_observer()->GetRequested(wifi1_service_path));
536   EXPECT_EQ(kSuccessResult, GetResultAndReset());
537 }
538 
TEST_F(NetworkConnectionHandlerImplTest,NetworkConnectionHandlerDisconnectFailure)539 TEST_F(NetworkConnectionHandlerImplTest,
540        NetworkConnectionHandlerDisconnectFailure) {
541   Connect(kNoNetwork);
542   EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
543             GetResultAndReset());
544 
545   std::string wifi0_service_path = ConfigureService(kConfigWifi0Connectable);
546   ASSERT_FALSE(wifi0_service_path.empty());
547   Disconnect(wifi0_service_path);
548   EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
549 }
550 
TEST_F(NetworkConnectionHandlerImplTest,ConnectToTetherNetwork_Success)551 TEST_F(NetworkConnectionHandlerImplTest, ConnectToTetherNetwork_Success) {
552   network_state_handler()->SetTetherTechnologyState(
553       NetworkStateHandler::TECHNOLOGY_ENABLED);
554   network_state_handler()->AddTetherNetworkState(
555       kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */,
556       100 /* signal_strength */, true /* has_connected_to_host */);
557   network_connection_handler()->SetTetherDelegate(fake_tether_delegate());
558 
559   // For tether networks, guid == service_path.
560   Connect(kTetherGuid /* service_path */);
561 
562   EXPECT_EQ(FakeTetherDelegate::DelegateFunctionType::CONNECT,
563             fake_tether_delegate()->last_delegate_function_type());
564   EXPECT_EQ(kTetherGuid, fake_tether_delegate()->last_service_path());
565   std::move(fake_tether_delegate()->last_success_callback()).Run();
566   EXPECT_EQ(kSuccessResult, GetResultAndReset());
567   EXPECT_TRUE(network_connection_observer()->GetRequested(kTetherGuid));
568   EXPECT_EQ(kSuccessResult,
569             network_connection_observer()->GetResult(kTetherGuid));
570 }
571 
TEST_F(NetworkConnectionHandlerImplTest,ConnectToTetherNetwork_Failure)572 TEST_F(NetworkConnectionHandlerImplTest, ConnectToTetherNetwork_Failure) {
573   network_state_handler()->SetTetherTechnologyState(
574       NetworkStateHandler::TECHNOLOGY_ENABLED);
575   network_state_handler()->AddTetherNetworkState(
576       kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */,
577       100 /* signal_strength */, true /* has_connected_to_host */);
578   network_connection_handler()->SetTetherDelegate(fake_tether_delegate());
579 
580   // For tether networks, guid == service_path.
581   Connect(kTetherGuid /* service_path */);
582 
583   EXPECT_EQ(FakeTetherDelegate::DelegateFunctionType::CONNECT,
584             fake_tether_delegate()->last_delegate_function_type());
585   EXPECT_EQ(kTetherGuid, fake_tether_delegate()->last_service_path());
586   std::move(fake_tether_delegate()->last_error_callback())
587       .Run(NetworkConnectionHandler::kErrorConnectFailed);
588   EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset());
589   EXPECT_TRUE(network_connection_observer()->GetRequested(kTetherGuid));
590   EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed,
591             network_connection_observer()->GetResult(kTetherGuid));
592 }
593 
TEST_F(NetworkConnectionHandlerImplTest,ConnectToVpnNetworkWhenProhibited_Failure)594 TEST_F(NetworkConnectionHandlerImplTest,
595        ConnectToVpnNetworkWhenProhibited_Failure) {
596   // This test tests a code that accesses NetworkHandler::Get() directly (when
597   // checking if VPN is disabled by policy when attempting to connect to a VPN
598   // network), so NetworkStateTestHelper can not be used here. That's because
599   // NetworkStateTestHelper initializes a NetworkStateHandler for testing, but
600   // NetworkHandler::Initialize() constructs its own NetworkStateHandler
601   // instance and NetworkHandler::Get() uses it.
602   NetworkHandler::Initialize();
603   NetworkHandler::Get()
604       ->prohibited_technologies_handler()
605       ->AddGloballyProhibitedTechnology(shill::kTypeVPN);
606 
607   const std::string kVpnGuid = "vpn_guid";
608   const std::string kShillJsonStringTemplate =
609       R"({"GUID": "$1", "Type": "vpn", "State": "idle",
610             "Provider": {"Type": "l2tpipsec", "Host": "host"}})";
611 
612   const std::string shill_json_string =
613       base::ReplaceStringPlaceholders(kShillJsonStringTemplate, {kVpnGuid},
614                                       /*offsets=*/nullptr);
615   const std::string vpn_service_path = ConfigureService(shill_json_string);
616   ASSERT_FALSE(vpn_service_path.empty());
617 
618   Connect(/*service_path=*/vpn_service_path);
619   EXPECT_EQ(NetworkConnectionHandler::kErrorBlockedByPolicy,
620             GetResultAndReset());
621 }
622 
TEST_F(NetworkConnectionHandlerImplTest,ConnectToTetherNetwork_NoTetherDelegate)623 TEST_F(NetworkConnectionHandlerImplTest,
624        ConnectToTetherNetwork_NoTetherDelegate) {
625   network_state_handler()->SetTetherTechnologyState(
626       NetworkStateHandler::TECHNOLOGY_ENABLED);
627   network_state_handler()->AddTetherNetworkState(
628       kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */,
629       100 /* signal_strength */, true /* has_connected_to_host */);
630 
631   // Do not set a tether delegate.
632 
633   // For tether networks, guid == service_path.
634   Connect(kTetherGuid /* service_path */);
635 
636   EXPECT_EQ(FakeTetherDelegate::DelegateFunctionType::NONE,
637             fake_tether_delegate()->last_delegate_function_type());
638   EXPECT_EQ(NetworkConnectionHandler::kErrorTetherAttemptWithNoDelegate,
639             GetResultAndReset());
640   EXPECT_TRUE(network_connection_observer()->GetRequested(kTetherGuid));
641   EXPECT_EQ(NetworkConnectionHandler::kErrorTetherAttemptWithNoDelegate,
642             network_connection_observer()->GetResult(kTetherGuid));
643 }
644 
TEST_F(NetworkConnectionHandlerImplTest,DisconnectFromTetherNetwork_Success)645 TEST_F(NetworkConnectionHandlerImplTest, DisconnectFromTetherNetwork_Success) {
646   network_state_handler()->SetTetherTechnologyState(
647       NetworkStateHandler::TECHNOLOGY_ENABLED);
648   network_state_handler()->AddTetherNetworkState(
649       kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */,
650       100 /* signal_strength */, true /* has_connected_to_host */);
651   network_state_handler()->SetTetherNetworkStateConnecting(kTetherGuid);
652   network_connection_handler()->SetTetherDelegate(fake_tether_delegate());
653 
654   // For tether networks, guid == service_path.
655   Disconnect(kTetherGuid /* service_path */);
656 
657   EXPECT_EQ(FakeTetherDelegate::DelegateFunctionType::DISCONNECT,
658             fake_tether_delegate()->last_delegate_function_type());
659   EXPECT_EQ(kTetherGuid, fake_tether_delegate()->last_service_path());
660   std::move(fake_tether_delegate()->last_success_callback()).Run();
661   EXPECT_EQ(kSuccessResult, GetResultAndReset());
662   EXPECT_TRUE(network_connection_observer()->GetRequested(kTetherGuid));
663   EXPECT_EQ(kSuccessResult,
664             network_connection_observer()->GetResult(kTetherGuid));
665 }
666 
TEST_F(NetworkConnectionHandlerImplTest,DisconnectFromTetherNetwork_Failure)667 TEST_F(NetworkConnectionHandlerImplTest, DisconnectFromTetherNetwork_Failure) {
668   network_state_handler()->SetTetherTechnologyState(
669       NetworkStateHandler::TECHNOLOGY_ENABLED);
670   network_state_handler()->AddTetherNetworkState(
671       kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */,
672       100 /* signal_strength */, true /* has_connected_to_host */);
673   network_state_handler()->SetTetherNetworkStateConnecting(kTetherGuid);
674   network_connection_handler()->SetTetherDelegate(fake_tether_delegate());
675 
676   // For tether networks, guid == service_path.
677   Disconnect(kTetherGuid /* service_path */);
678 
679   EXPECT_EQ(FakeTetherDelegate::DelegateFunctionType::DISCONNECT,
680             fake_tether_delegate()->last_delegate_function_type());
681   EXPECT_EQ(kTetherGuid, fake_tether_delegate()->last_service_path());
682   std::move(fake_tether_delegate()->last_error_callback())
683       .Run(NetworkConnectionHandler::kErrorConnectFailed);
684   EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset());
685   EXPECT_TRUE(network_connection_observer()->GetRequested(kTetherGuid));
686   EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed,
687             network_connection_observer()->GetResult(kTetherGuid));
688 }
689 
TEST_F(NetworkConnectionHandlerImplTest,DisconnectFromTetherNetwork_NoTetherDelegate)690 TEST_F(NetworkConnectionHandlerImplTest,
691        DisconnectFromTetherNetwork_NoTetherDelegate) {
692   network_state_handler()->SetTetherTechnologyState(
693       NetworkStateHandler::TECHNOLOGY_ENABLED);
694   network_state_handler()->AddTetherNetworkState(
695       kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */,
696       100 /* signal_strength */, true /* has_connected_to_host */);
697   network_state_handler()->SetTetherNetworkStateConnecting(kTetherGuid);
698 
699   // Do not set a tether delegate.
700 
701   // For tether networks, guid == service_path.
702   Disconnect(kTetherGuid /* service_path */);
703 
704   EXPECT_EQ(FakeTetherDelegate::DelegateFunctionType::NONE,
705             fake_tether_delegate()->last_delegate_function_type());
706   EXPECT_EQ(NetworkConnectionHandler::kErrorTetherAttemptWithNoDelegate,
707             GetResultAndReset());
708   EXPECT_TRUE(network_connection_observer()->GetRequested(kTetherGuid));
709   EXPECT_EQ(NetworkConnectionHandler::kErrorTetherAttemptWithNoDelegate,
710             network_connection_observer()->GetResult(kTetherGuid));
711 }
712 
713 }  // namespace chromeos
714