1a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// found in the LICENSE file. 4a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 5a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/network/network_connection_handler.h" 6a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 7a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/bind.h" 8a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/json/json_reader.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/location.h" 1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/cert_loader.h" 13a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 14a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/dbus/shill_manager_client.h" 15a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/dbus/shill_service_client.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/network/certificate_pattern.h" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chromeos/network/client_cert_resolver.h" 18c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "chromeos/network/client_cert_util.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chromeos/network/managed_network_configuration_handler.h" 20a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/network/network_configuration_handler.h" 21a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/network/network_event_log.h" 22a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/network/network_handler_callbacks.h" 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/network/network_profile_handler.h" 24a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/network/network_state.h" 25a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chromeos/network/network_state_handler.h" 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chromeos/network/shill_property_util.h" 27a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "dbus/object_path.h" 28a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/cert/x509_certificate.h" 29a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 30a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace chromeos { 32a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace { 34a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void InvokeErrorCallback(const std::string& service_path, 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const network_handler::ErrorCallback& error_callback, 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& error_name) { 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NET_LOG_ERROR("Connect Error: " + error_name, service_path); 391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) network_handler::RunErrorCallback( 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_callback, service_path, error_name, ""); 41a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool IsAuthenticationError(const std::string& error) { 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return (error == shill::kErrorBadWEPKey || 4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) error == shill::kErrorPppAuthFailed || 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) error == shill::kErrorEapLocalTlsFailed || 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) error == shill::kErrorEapRemoteTlsFailed || 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) error == shill::kErrorEapAuthenticationFailed); 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool VPNRequiresCredentials(const std::string& service_path, 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& provider_type, 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::DictionaryValue& provider_properties) { 5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (provider_type == shill::kProviderOpenVpn) { 55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::string username; 56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch provider_properties.GetStringWithoutPathExpansion( 5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kOpenVPNUserProperty, &username); 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (username.empty()) { 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NET_LOG_EVENT("OpenVPN: No username", service_path); 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool passphrase_required = false; 63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch provider_properties.GetBooleanWithoutPathExpansion( 6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kPassphraseRequiredProperty, &passphrase_required); 65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (passphrase_required) { 66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch NET_LOG_EVENT("OpenVPN: Passphrase Required", service_path); 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NET_LOG_EVENT("OpenVPN Is Configured", service_path); 70a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } else { 71a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) bool passphrase_required = false; 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch provider_properties.GetBooleanWithoutPathExpansion( 7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kL2tpIpsecPskRequiredProperty, &passphrase_required); 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (passphrase_required) { 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NET_LOG_EVENT("VPN: PSK Required", service_path); 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider_properties.GetBooleanWithoutPathExpansion( 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shill::kPassphraseRequiredProperty, &passphrase_required); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (passphrase_required) { 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NET_LOG_EVENT("VPN: Passphrase Required", service_path); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NET_LOG_EVENT("VPN Is Configured", service_path); 85a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::string GetDefaultUserProfilePath(const NetworkState* network) { 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!NetworkHandler::IsInitialized() || 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (LoginState::IsInitialized() && 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) !LoginState::Get()->UserHasNetworkProfile()) || 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (network && network->type() == shill::kTypeWifi && 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) network->security() == shill::kSecurityNone)) { 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NetworkProfileHandler::GetSharedProfilePath(); 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const NetworkProfile* profile = 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NetworkHandler::Get()->network_profile_handler()->GetDefaultUserProfile(); 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return profile ? profile->path 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : NetworkProfileHandler::GetSharedProfilePath(); 101a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 102a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} // namespace 104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char NetworkConnectionHandler::kErrorNotFound[] = "not-found"; 106a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char NetworkConnectionHandler::kErrorConnected[] = "connected"; 107a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char NetworkConnectionHandler::kErrorConnecting[] = "connecting"; 108a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char NetworkConnectionHandler::kErrorNotConnected[] = "not-connected"; 109a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char NetworkConnectionHandler::kErrorPassphraseRequired[] = 110a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) "passphrase-required"; 111a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char NetworkConnectionHandler::kErrorActivationRequired[] = 112a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) "activation-required"; 113a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char NetworkConnectionHandler::kErrorCertificateRequired[] = 114a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) "certificate-required"; 115a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char NetworkConnectionHandler::kErrorConfigurationRequired[] = 116a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) "configuration-required"; 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char NetworkConnectionHandler::kErrorAuthenticationRequired[] = 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "authentication-required"; 119a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char NetworkConnectionHandler::kErrorShillError[] = "shill-error"; 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst char NetworkConnectionHandler::kErrorConfigureFailed[] = 121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "configure-failed"; 122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst char NetworkConnectionHandler::kErrorConnectCanceled[] = 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "connect-canceled"; 12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const char NetworkConnectionHandler::kErrorCertLoadTimeout[] = 12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "cert-load-timeout"; 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct NetworkConnectionHandler::ConnectRequest { 1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ConnectRequest(const std::string& service_path, 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& profile_path, 1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::Closure& success, 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const network_handler::ErrorCallback& error) 1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : service_path(service_path), 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile_path(profile_path), 1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) connect_state(CONNECT_REQUESTED), 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) success_callback(success), 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_callback(error) { 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) enum ConnectState { 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CONNECT_REQUESTED = 0, 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CONNECT_STARTED = 1, 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CONNECT_CONNECTING = 2 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string service_path; 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string profile_path; 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ConnectState connect_state; 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Closure success_callback; 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_handler::ErrorCallback error_callback; 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 149a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NetworkConnectionHandler::NetworkConnectionHandler() 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : cert_loader_(NULL), 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) network_state_handler_(NULL), 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configuration_handler_(NULL), 1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) logged_in_(false), 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) certificates_loaded_(false), 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) applied_autoconnect_policy_(false), 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) requested_connect_to_best_network_(false) { 158a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 159a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NetworkConnectionHandler::~NetworkConnectionHandler() { 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (network_state_handler_) 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) network_state_handler_->RemoveObserver(this, FROM_HERE); 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (cert_loader_) 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cert_loader_->RemoveObserver(this); 1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (LoginState::IsInitialized()) 1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) LoginState::Get()->RemoveObserver(this); 167a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 168a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void NetworkConnectionHandler::Init( 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NetworkStateHandler* network_state_handler, 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NetworkConfigurationHandler* network_configuration_handler, 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ManagedNetworkConfigurationHandler* managed_network_configuration_handler) { 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (LoginState::IsInitialized()) 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) LoginState::Get()->AddObserver(this); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (CertLoader::IsInitialized()) { 177558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch cert_loader_ = CertLoader::Get(); 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cert_loader_->AddObserver(this); 17923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (cert_loader_->certificates_loaded()) { 18023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NET_LOG_EVENT("Certificates Loaded", ""); 18123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) certificates_loaded_ = true; 18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else { 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(tbarzic): Require a mock or stub cert_loader in tests. 18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NET_LOG_EVENT("Certificate Loader not initialized", ""); 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) certificates_loaded_ = true; 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (network_state_handler) { 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_state_handler_ = network_state_handler; 1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) network_state_handler_->AddObserver(this, FROM_HERE); 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configuration_handler_ = network_configuration_handler; 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (managed_network_configuration_handler) { 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) managed_configuration_handler_ = managed_network_configuration_handler; 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) managed_configuration_handler_->AddObserver(this); 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // After this point, the NetworkConnectionHandler is fully initialized (all 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // handler references set, observers registered, ...). 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (LoginState::IsInitialized()) 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LoggedInStateChanged(); 205a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 206a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void NetworkConnectionHandler::LoggedInStateChanged() { 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LoginState* login_state = LoginState::Get(); 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (logged_in_ || !login_state->IsUserLoggedIn()) 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NET_LOG_EVENT("Logged In", ""); 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) logged_in_ = true; 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) logged_in_time_ = base::TimeTicks::Now(); 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DisconnectIfPolicyRequires(); 2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void NetworkConnectionHandler::OnCertificatesLoaded( 2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const net::CertificateList& cert_list, 2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool initial_load) { 2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) certificates_loaded_ = true; 2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NET_LOG_EVENT("Certificates Loaded", ""); 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (queued_connect_) { 22523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ConnectToQueuedNetwork(); 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else if (initial_load) { 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Connecting to the "best" available network requires certificates to be 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // loaded. Try to connect now. 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ConnectToBestNetworkAfterLogin(); 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void NetworkConnectionHandler::PolicyChanged(const std::string& userhash) { 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ignore user policies. 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!userhash.empty()) 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DisconnectIfPolicyRequires(); 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void NetworkConnectionHandler::ConnectToNetwork( 241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const std::string& service_path, 242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::Closure& success_callback, 24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const network_handler::ErrorCallback& error_callback, 244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool check_error_state) { 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NET_LOG_USER("ConnectToNetwork", service_path); 2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Clear any existing queued connect request. 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) queued_connect_.reset(); 248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (HasConnectingNetwork(service_path)) { 249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NET_LOG_USER("Connect Request While Pending", service_path); 250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) InvokeErrorCallback(service_path, error_callback, kErrorConnecting); 251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Check cached network state for connected, connecting, or unactivated 255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // networks. These states will not be affected by a recent configuration. 256c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // Note: NetworkState may not exist for a network that was recently 257c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // configured, in which case these checks do not apply anyway. 258a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const NetworkState* network = 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) network_state_handler_->GetNetworkState(service_path); 260a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 261c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (network) { 262c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // For existing networks, perform some immediate consistency checks. 263c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (network->IsConnectedState()) { 264c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch InvokeErrorCallback(service_path, error_callback, kErrorConnected); 265ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 266ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 267c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (network->IsConnectingState()) { 268c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch InvokeErrorCallback(service_path, error_callback, kErrorConnecting); 269ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 270ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 271c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 272c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (check_error_state) { 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& error = network->last_error(); 27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (error == shill::kErrorBadPassphrase) { 27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) InvokeErrorCallback(service_path, error_callback, error); 276c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; 277c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 278c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (IsAuthenticationError(error)) { 279c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch InvokeErrorCallback( 280c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch service_path, error_callback, kErrorAuthenticationRequired); 281c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; 282c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 283c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 284ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If the network does not have a profile path, specify the correct default 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // profile here and set it once connected. Otherwise leave it empty to 2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // indicate that it does not need to be set. 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string profile_path; 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!network || network->profile_path().empty()) 291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) profile_path = GetDefaultUserProfilePath(network); 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 293a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // All synchronous checks passed, add |service_path| to connecting list. 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_requests_.insert(std::make_pair( 2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) service_path, 2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ConnectRequest(service_path, profile_path, 2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) success_callback, error_callback))); 298a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Connect immediately to 'connectable' networks. 300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // TODO(stevenjb): Shill needs to properly set Connectable for VPN. 30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (network && network->connectable() && network->type() != shill::kTypeVPN) { 302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CallShillConnect(service_path); 303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Request additional properties to check. VerifyConfiguredAndConnect will 307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // use only these properties, not cached properties, to ensure that they 308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // are up to date after any recent configuration. 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configuration_handler_->GetProperties( 310c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch service_path, 311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&NetworkConnectionHandler::VerifyConfiguredAndConnect, 312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AsWeakPtr(), check_error_state), 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&NetworkConnectionHandler::HandleConfigurationFailure, 314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AsWeakPtr(), service_path)); 315a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 316a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 317a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void NetworkConnectionHandler::DisconnectNetwork( 318a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const std::string& service_path, 319a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::Closure& success_callback, 320a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const network_handler::ErrorCallback& error_callback) { 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NET_LOG_USER("DisconnectNetwork", service_path); 322a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const NetworkState* network = 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) network_state_handler_->GetNetworkState(service_path); 324a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!network) { 325a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) InvokeErrorCallback(service_path, error_callback, kErrorNotFound); 326a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return; 327a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 328a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!network->IsConnectedState()) { 329a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) InvokeErrorCallback(service_path, error_callback, kErrorNotConnected); 330a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return; 331a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 332a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) CallShillDisconnect(service_path, success_callback, error_callback); 333a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 334a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool NetworkConnectionHandler::HasConnectingNetwork( 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& service_path) { 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return pending_requests_.count(service_path) != 0; 338a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 339a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool NetworkConnectionHandler::HasPendingConnectRequest() { 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return pending_requests_.size() > 0; 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkConnectionHandler::NetworkListChanged() { 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CheckAllPendingRequests(); 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkConnectionHandler::NetworkPropertiesUpdated( 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const NetworkState* network) { 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (HasConnectingNetwork(network->path())) 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CheckPendingRequest(network->path()); 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)NetworkConnectionHandler::ConnectRequest* 355c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben MurdochNetworkConnectionHandler::GetPendingRequest(const std::string& service_path) { 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::map<std::string, ConnectRequest>::iterator iter = 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_requests_.find(service_path); 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return iter != pending_requests_.end() ? &(iter->second) : NULL; 359a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 360a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// ConnectToNetwork implementation 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 363a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void NetworkConnectionHandler::VerifyConfiguredAndConnect( 364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool check_error_state, 365a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const std::string& service_path, 366558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const base::DictionaryValue& service_properties) { 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NET_LOG_EVENT("VerifyConfiguredAndConnect", service_path); 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If 'passphrase_required' is still true, then the 'Passphrase' property 370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // has not been set to a minimum length value. 371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool passphrase_required = false; 372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) service_properties.GetBooleanWithoutPathExpansion( 37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kPassphraseRequiredProperty, &passphrase_required); 374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (passphrase_required) { 375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ErrorCallbackForPendingRequest(service_path, kErrorPassphraseRequired); 376a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return; 377a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 378a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 379c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch std::string type, security; 38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) service_properties.GetStringWithoutPathExpansion(shill::kTypeProperty, &type); 381ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch service_properties.GetStringWithoutPathExpansion( 38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kSecurityProperty, &security); 383c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch bool connectable = false; 384c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch service_properties.GetBooleanWithoutPathExpansion( 38568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kConnectableProperty, &connectable); 386c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 387c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // In case NetworkState was not available in ConnectToNetwork (e.g. it had 388c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // been recently configured), we need to check Connectable again. 38968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (connectable && type != shill::kTypeVPN) { 390c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // TODO(stevenjb): Shill needs to properly set Connectable for VPN. 391c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch CallShillConnect(service_path); 392c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; 393c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 394ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 395ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Get VPN provider type and host (required for configuration) and ensure 396ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // that required VPN non-cert properties are set. 3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::DictionaryValue* provider_properties = NULL; 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string vpn_provider_type, vpn_provider_host, vpn_client_cert_id; 39968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (type == shill::kTypeVPN) { 400ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // VPN Provider values are read from the "Provider" dictionary, not the 401ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // "Provider.Type", etc keys (which are used only to set the values). 402ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (service_properties.GetDictionaryWithoutPathExpansion( 40368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kProviderProperty, &provider_properties)) { 404ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch provider_properties->GetStringWithoutPathExpansion( 40568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kTypeProperty, &vpn_provider_type); 406ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch provider_properties->GetStringWithoutPathExpansion( 40768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kHostProperty, &vpn_provider_host); 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider_properties->GetStringWithoutPathExpansion( 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shill::kL2tpIpsecClientCertIdProperty, &vpn_client_cert_id); 410ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 411ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (vpn_provider_type.empty() || vpn_provider_host.empty()) { 41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); 413ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 414ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 415a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 416a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string guid; 418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service_properties.GetStringWithoutPathExpansion(shill::kGuidProperty, &guid); 419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string profile; 420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service_properties.GetStringWithoutPathExpansion(shill::kProfileProperty, 421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &profile); 422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::DictionaryValue* user_policy = 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch managed_configuration_handler_->FindPolicyByGuidAndProfile(guid, profile); 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_cert::ClientCertConfig cert_config_from_policy; 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (user_policy) 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_cert::OncToClientCertConfig(*user_policy, &cert_config_from_policy); 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 429c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch client_cert::ConfigType client_cert_type = client_cert::CONFIG_TYPE_NONE; 43068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (type == shill::kTypeVPN) { 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (vpn_provider_type == shill::kProviderOpenVpn) { 432c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch client_cert_type = client_cert::CONFIG_TYPE_OPENVPN; 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // L2TP/IPSec only requires a certificate if one is specified in ONC 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // or one was configured by the UI. Otherwise it is L2TP/IPSec with 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // PSK and doesn't require a certificate. 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(benchan): Modify shill to specify the authentication type via 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the kL2tpIpsecAuthenticationType property, so that Chrome doesn't need 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to deduce the authentication type based on the 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // kL2tpIpsecClientCertIdProperty here (and also in VPNConfigView). 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!vpn_client_cert_id.empty() || 443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cert_config_from_policy.client_cert_type != 444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch onc::client_cert::kClientCertTypeNone) { 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_cert_type = client_cert::CONFIG_TYPE_IPSEC; 446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 44868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else if (type == shill::kTypeWifi && security == shill::kSecurity8021x) { 449c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch client_cert_type = client_cert::CONFIG_TYPE_EAP; 450ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 452ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::DictionaryValue config_properties; 453c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (client_cert_type != client_cert::CONFIG_TYPE_NONE) { 45423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Note: if we get here then a certificate *may* be required, so we want 45523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // to ensure that certificates have loaded successfully before attempting 45623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // to connect. 45723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 45823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // User must be logged in to connect to a network requiring a certificate. 45923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!logged_in_ || !cert_loader_) { 46023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NET_LOG_ERROR("User not logged in", ""); 46123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired); 46223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 46323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 46423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // If certificates have not been loaded yet, queue the connect request. 46523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!certificates_loaded_) { 46623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NET_LOG_EVENT("Certificates not loaded", ""); 46723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QueueConnectRequest(service_path); 46823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 46923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 47023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Check certificate properties from policy. 472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (cert_config_from_policy.client_cert_type == 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch onc::client_cert::kPattern) { 4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ClientCertResolver::ResolveCertificatePatternSync( 4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_cert_type, 4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cert_config_from_policy.pattern, 4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &config_properties)) { 478c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired); 479c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; 4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (check_error_state && 48258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !client_cert::IsCertificateConfigured(client_cert_type, 48358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) service_properties)) { 48458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Network may not be configured. 48558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); 48658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 487ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 488ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 489ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 4904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (type == shill::kTypeVPN) { 4914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // VPN may require a username, and/or passphrase to be set. (Check after 4924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // ensuring that any required certificates are configured). 4934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(provider_properties); 4944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (VPNRequiresCredentials( 4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) service_path, vpn_provider_type, *provider_properties)) { 4964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NET_LOG_USER("VPN Requires Credentials", service_path); 4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); 4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 4994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If it's L2TP/IPsec PSK, there is no properties to configure, so proceed 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to connect. 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (client_cert_type == client_cert::CONFIG_TYPE_NONE) { 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CallShillConnect(service_path); 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 509ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!config_properties.empty()) { 510ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch NET_LOG_EVENT("Configuring Network", service_path); 511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configuration_handler_->SetProperties( 512d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) service_path, 513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) config_properties, 514d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&NetworkConnectionHandler::CallShillConnect, 515d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AsWeakPtr(), 516d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) service_path), 517d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&NetworkConnectionHandler::HandleConfigurationFailure, 518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AsWeakPtr(), 519d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) service_path)); 520d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 521a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 522a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 523ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Otherwise, we probably still need to configure the network since 524ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 'Connectable' is false. If |check_error_state| is true, signal an 525ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // error, otherwise attempt to connect to possibly gain additional error 526ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // state from Shill (or in case 'Connectable' is improperly unset). 527ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (check_error_state) 528ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); 529ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch else 530ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CallShillConnect(service_path); 531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 53323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void NetworkConnectionHandler::QueueConnectRequest( 53423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const std::string& service_path) { 53523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ConnectRequest* request = GetPendingRequest(service_path); 53623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!request) { 53723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NET_LOG_ERROR("No pending request to queue", service_path); 53823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 53923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 54023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 54123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int kMaxCertLoadTimeSeconds = 15; 54223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::TimeDelta dtime = base::TimeTicks::Now() - logged_in_time_; 54323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (dtime > base::TimeDelta::FromSeconds(kMaxCertLoadTimeSeconds)) { 54423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NET_LOG_ERROR("Certificate load timeout", service_path); 54523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) InvokeErrorCallback(service_path, 54623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) request->error_callback, 54723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kErrorCertLoadTimeout); 54823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 54923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 55023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 55123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NET_LOG_EVENT("Connect Request Queued", service_path); 55223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) queued_connect_.reset(new ConnectRequest( 55323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) service_path, request->profile_path, 55423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) request->success_callback, request->error_callback)); 55523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pending_requests_.erase(service_path); 55623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 55723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Post a delayed task to check to see if certificates have loaded. If they 55823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // haven't, and queued_connect_ has not been cleared (e.g. by a successful 55923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // connect request), cancel the request and notify the user. 56023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::MessageLoopProxy::current()->PostDelayedTask( 56123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FROM_HERE, 56223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&NetworkConnectionHandler::CheckCertificatesLoaded, 56323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) AsWeakPtr()), 56423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::TimeDelta::FromSeconds(kMaxCertLoadTimeSeconds) - dtime); 56523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 56623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 56723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void NetworkConnectionHandler::CheckCertificatesLoaded() { 56823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (certificates_loaded_) 56923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 57023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // If queued_connect_ has been cleared (e.g. another connect request occurred 57123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // and wasn't queued), do nothing here. 57223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!queued_connect_) 57323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 57423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Otherwise, notify the user. 57523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NET_LOG_ERROR("Certificate load timeout", queued_connect_->service_path); 57623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) InvokeErrorCallback(queued_connect_->service_path, 57723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) queued_connect_->error_callback, 57823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kErrorCertLoadTimeout); 57923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) queued_connect_.reset(); 58023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 58123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 58223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void NetworkConnectionHandler::ConnectToQueuedNetwork() { 58323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(queued_connect_); 58423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 58523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Make a copy of |queued_connect_| parameters, because |queued_connect_| 58623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // will get reset at the beginning of |ConnectToNetwork|. 58723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string service_path = queued_connect_->service_path; 58823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Closure success_callback = queued_connect_->success_callback; 58923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) network_handler::ErrorCallback error_callback = 59023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) queued_connect_->error_callback; 59123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 59223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NET_LOG_EVENT("Connecting to Queued Network", service_path); 59323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ConnectToNetwork(service_path, success_callback, error_callback, 59423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) false /* check_error_state */); 59523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 59623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkConnectionHandler::CallShillConnect( 598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& service_path) { 5997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NET_LOG_EVENT("Sending Connect Request to Shill", service_path); 600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) network_state_handler_->ClearLastErrorForNetwork(service_path); 601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DBusThreadManager::Get()->GetShillServiceClient()->Connect( 602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dbus::ObjectPath(service_path), 603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&NetworkConnectionHandler::HandleShillConnectSuccess, 604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AsWeakPtr(), service_path), 605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&NetworkConnectionHandler::HandleShillConnectFailure, 606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AsWeakPtr(), service_path)); 607a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 608a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 609a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void NetworkConnectionHandler::HandleConfigurationFailure( 610a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const std::string& service_path, 611a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const std::string& error_name, 612a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) scoped_ptr<base::DictionaryValue> error_data) { 613c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch ConnectRequest* request = GetPendingRequest(service_path); 614c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!request) { 615c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch NET_LOG_ERROR("HandleConfigurationFailure called with no pending request.", 616c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch service_path); 617c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; 618c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_handler::ErrorCallback error_callback = request->error_callback; 620a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) pending_requests_.erase(service_path); 621a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!error_callback.is_null()) 622ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch error_callback.Run(kErrorConfigureFailed, error_data.Pass()); 623a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 624a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkConnectionHandler::HandleShillConnectSuccess( 626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& service_path) { 627c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch ConnectRequest* request = GetPendingRequest(service_path); 628c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!request) { 629c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch NET_LOG_ERROR("HandleShillConnectSuccess called with no pending request.", 630c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch service_path); 631c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; 632c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->connect_state = ConnectRequest::CONNECT_STARTED; 6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NET_LOG_EVENT("Connect Request Acknowledged", service_path); 635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Do not call success_callback here, wait for one of the following 636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // conditions: 63723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // * State transitions to a non connecting state indicating success or failure 638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // * Network is no longer in the visible list, indicating failure 639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CheckPendingRequest(service_path); 640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkConnectionHandler::HandleShillConnectFailure( 643a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const std::string& service_path, 6447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& dbus_error_name, 6457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& dbus_error_message) { 646c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch ConnectRequest* request = GetPendingRequest(service_path); 647c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!request) { 648c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch NET_LOG_ERROR("HandleShillConnectFailure called with no pending request.", 649c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch service_path); 650c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; 651c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_handler::ErrorCallback error_callback = request->error_callback; 653a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) pending_requests_.erase(service_path); 654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_handler::ShillErrorCallbackFunction( 65568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) shill::kErrorConnectFailed, service_path, error_callback, 6567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dbus_error_name, dbus_error_message); 657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkConnectionHandler::CheckPendingRequest( 660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string service_path) { 661c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch ConnectRequest* request = GetPendingRequest(service_path); 662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(request); 663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (request->connect_state == ConnectRequest::CONNECT_REQUESTED) 664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; // Request has not started, ignore update 665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const NetworkState* network = 666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_state_handler_->GetNetworkState(service_path); 667c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!network) 668c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; // NetworkState may not be be updated yet. 669c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (network->IsConnectingState()) { 671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->connect_state = ConnectRequest::CONNECT_CONNECTING; 672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (network->IsConnectedState()) { 675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NET_LOG_EVENT("Connect Request Succeeded", service_path); 6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!request->profile_path.empty()) { 6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If a profile path was specified, set it on a successful connection. 678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) configuration_handler_->SetNetworkProfile( 679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) service_path, 680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request->profile_path, 6814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&base::DoNothing), 6824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chromeos::network_handler::ErrorCallback()); 6834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!request->success_callback.is_null()) 685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->success_callback.Run(); 686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_requests_.erase(service_path); 687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 68968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (network->connection_state() == shill::kStateIdle && 690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->connect_state != ConnectRequest::CONNECT_CONNECTING) { 691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Connection hasn't started yet, keep waiting. 692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Network is neither connecting or connected; an error occurred. 6964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string error_name; // 'Canceled' or 'Failed' 69768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (network->connection_state() == shill::kStateIdle && 698ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_requests_.size() > 1) { 699ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Another connect request canceled this one. 700ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch error_name = kErrorConnectCanceled; 701ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 70268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) error_name = shill::kErrorConnectFailed; 7034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (network->connection_state() != shill::kStateFailure) { 7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NET_LOG_ERROR("Unexpected State: " + network->connection_state(), 7054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) service_path); 706ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_handler::ErrorCallback error_callback = request->error_callback; 710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_requests_.erase(service_path); 711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error_callback.is_null()) { 712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NET_LOG_ERROR("Connect Error, no callback: " + error_name, service_path); 713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InvokeErrorCallback(service_path, error_callback, error_name); 716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkConnectionHandler::CheckAllPendingRequests() { 719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (std::map<std::string, ConnectRequest>::iterator iter = 720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_requests_.begin(); iter != pending_requests_.end(); ++iter) { 721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CheckPendingRequest(iter->first); 722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void NetworkConnectionHandler::ErrorCallbackForPendingRequest( 7267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& service_path, 7277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& error_name) { 728c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch ConnectRequest* request = GetPendingRequest(service_path); 729c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!request) { 730c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch NET_LOG_ERROR("ErrorCallbackForPendingRequest with no pending request.", 731c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch service_path); 732c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return; 733c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch } 7347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Remove the entry before invoking the callback in case it triggers a retry. 7357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) network_handler::ErrorCallback error_callback = request->error_callback; 7367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) pending_requests_.erase(service_path); 7377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) InvokeErrorCallback(service_path, error_callback, error_name); 7387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 7397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Disconnect 741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 742868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkConnectionHandler::CallShillDisconnect( 743868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& service_path, 744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::Closure& success_callback, 745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const network_handler::ErrorCallback& error_callback) { 746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NET_LOG_USER("Disconnect Request", service_path); 747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DBusThreadManager::Get()->GetShillServiceClient()->Disconnect( 748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dbus::ObjectPath(service_path), 749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&NetworkConnectionHandler::HandleShillDisconnectSuccess, 750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AsWeakPtr(), service_path, success_callback), 7517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&network_handler::ShillErrorCallbackFunction, 752ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch kErrorShillError, service_path, error_callback)); 753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkConnectionHandler::HandleShillDisconnectSuccess( 756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& service_path, 757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::Closure& success_callback) { 758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NET_LOG_EVENT("Disconnect Request Sent", service_path); 7597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!success_callback.is_null()) 7607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch success_callback.Run(); 761a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 762a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void NetworkConnectionHandler::ConnectToBestNetworkAfterLogin() { 764cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (requested_connect_to_best_network_ || !applied_autoconnect_policy_ || 765cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !certificates_loaded_) { 766cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 767cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 768cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 769cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) requested_connect_to_best_network_ = true; 770cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) network_state_handler_->ConnectToBestWifiNetwork(); 771cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 773cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void NetworkConnectionHandler::DisconnectIfPolicyRequires() { 774cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (applied_autoconnect_policy_ || !LoginState::Get()->IsUserLoggedIn()) 775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 776cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 777cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::DictionaryValue* global_network_config = 778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) managed_configuration_handler_->GetGlobalConfigFromPolicy(std::string()); 779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!global_network_config) 780cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 781cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 782cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) applied_autoconnect_policy_ = true; 783cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool only_policy_autoconnect = false; 785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) global_network_config->GetBooleanWithoutPathExpansion( 786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect, 787cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &only_policy_autoconnect); 788cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 789cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!only_policy_autoconnect) 790cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 791cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 792cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NET_LOG_DEBUG("DisconnectIfPolicyRequires", 793cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "Disconnecting unmanaged and shared networks if any exist."); 794cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 795cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the list of unmanaged & shared networks that are connected or 796cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // connecting. 797cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NetworkStateHandler::NetworkStateList networks; 798f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) network_state_handler_->GetVisibleNetworkListByType( 799f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NetworkTypePattern::Wireless(), &networks); 800cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (NetworkStateHandler::NetworkStateList::const_iterator it = 801cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) networks.begin(); 802cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != networks.end(); 803cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 804cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const NetworkState* network = *it; 805cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!(network->IsConnectingState() || network->IsConnectedState())) 806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; // Connected and connecting networks are listed first. 807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 808cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (network->IsPrivate()) 809cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) continue; 810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const bool network_is_policy_managed = 812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !network->profile_path().empty() && !network->guid().empty() && 813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) managed_configuration_handler_->FindPolicyByGuidAndProfile( 814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) network->guid(), network->profile_path()); 815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (network_is_policy_managed) 816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) continue; 817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NET_LOG_EVENT("Disconnect Forced by Policy", network->path()); 819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CallShillDisconnect( 820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) network->path(), base::Closure(), network_handler::ErrorCallback()); 821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ConnectToBestNetworkAfterLogin(); 824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 825cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 826a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} // namespace chromeos 827