Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 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/auto_connect_handler.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/bind_helpers.h" | |
| 11 #include "base/values.h" | |
| 12 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 13 #include "chromeos/dbus/shill_service_client.h" | |
| 14 #include "chromeos/network/managed_network_configuration_handler.h" | |
| 15 #include "chromeos/network/network_event_log.h" | |
| 16 #include "chromeos/network/network_state.h" | |
| 17 #include "dbus/object_path.h" | |
| 18 | |
| 19 namespace chromeos { | |
| 20 | |
| 21 AutoConnectHandler::AutoConnectHandler() | |
| 22 : client_cert_resolver_(nullptr), | |
| 23 request_best_connection_pending_(false), | |
| 24 device_policy_applied_(false), | |
| 25 user_policy_applied_(false), | |
| 26 client_certs_resolved_(false), | |
| 27 applied_autoconnect_policy_(false) { | |
| 28 } | |
| 29 | |
| 30 AutoConnectHandler::~AutoConnectHandler() { | |
| 31 if (client_cert_resolver_) | |
| 32 client_cert_resolver_->RemoveObserver(this); | |
| 33 if (LoginState::IsInitialized()) | |
| 34 LoginState::Get()->RemoveObserver(this); | |
| 35 if (managed_configuration_handler_) | |
| 36 managed_configuration_handler_->RemoveObserver(this); | |
| 37 } | |
| 38 | |
| 39 void AutoConnectHandler::Init( | |
| 40 ClientCertResolver* client_cert_resolver, | |
| 41 NetworkConnectionHandler* network_connection_handler, | |
| 42 NetworkStateHandler* network_state_handler, | |
| 43 ManagedNetworkConfigurationHandler* managed_network_configuration_handler) { | |
| 44 if (LoginState::IsInitialized()) | |
| 45 LoginState::Get()->AddObserver(this); | |
| 46 | |
| 47 client_cert_resolver_ = client_cert_resolver; | |
| 48 if (client_cert_resolver_) | |
| 49 client_cert_resolver_->AddObserver(this); | |
| 50 | |
| 51 network_connection_handler_ = network_connection_handler; | |
| 52 if (network_connection_handler_) | |
| 53 network_connection_handler_->AddObserver(this); | |
| 54 | |
| 55 network_state_handler_ = network_state_handler; | |
| 56 | |
| 57 if (managed_network_configuration_handler) { | |
| 58 managed_configuration_handler_ = managed_network_configuration_handler; | |
| 59 managed_configuration_handler_->AddObserver(this); | |
| 60 } | |
| 61 | |
| 62 if (LoginState::IsInitialized()) | |
| 63 LoggedInStateChanged(); | |
| 64 } | |
| 65 | |
| 66 void AutoConnectHandler::LoggedInStateChanged() { | |
| 67 if (!LoginState::Get()->IsUserLoggedIn()) | |
| 68 return; | |
| 69 | |
| 70 // Disconnect before connecting, to ensure that we do not disconnect a network | |
| 71 // that we just connected. | |
| 72 DisconnectIfPolicyRequires(); | |
| 73 NET_LOG_DEBUG("RequestBestConnection", "User logged in"); | |
| 74 RequestBestConnection(); | |
| 75 } | |
| 76 | |
| 77 void AutoConnectHandler::ConnectToNetworkRequested() { | |
| 78 // Stop any pending request to connect to the best newtork. | |
| 79 request_best_connection_pending_ = false; | |
| 80 } | |
| 81 | |
| 82 void AutoConnectHandler::PoliciesChanged(const std::string& userhash) { | |
| 83 // Ignore user policies. | |
| 84 if (!userhash.empty()) | |
| 85 return; | |
| 86 DisconnectIfPolicyRequires(); | |
| 87 } | |
| 88 | |
| 89 void AutoConnectHandler::PoliciesApplied(const std::string& userhash) { | |
| 90 if (userhash.empty()) | |
| 91 device_policy_applied_ = true; | |
| 92 else | |
| 93 user_policy_applied_ = true; | |
| 94 | |
| 95 // Request to connect to the best network only if there is at least one | |
| 96 // managed network. Otherwise only process existing requests. | |
| 97 const ManagedNetworkConfigurationHandler::GuidToPolicyMap* managed_networks = | |
| 98 managed_configuration_handler_->GetNetworkConfigsFromPolicy(userhash); | |
| 99 DCHECK(managed_networks); | |
| 100 if (managed_networks->empty()) { | |
| 101 CheckBestConnection(); | |
| 102 } else { | |
| 103 NET_LOG_DEBUG("RequestBestConnection", "Policy applied"); | |
| 104 RequestBestConnection(); | |
| 105 } | |
|
stevenjb
2014/11/07 17:19:06
nit: invert this logic to be consistent with the l
pneubeck (no reviews)
2014/11/08 16:49:55
Done.
| |
| 106 } | |
| 107 | |
| 108 void AutoConnectHandler::ResolveRequestCompleted( | |
| 109 bool network_properties_changed) { | |
| 110 client_certs_resolved_ = true; | |
| 111 | |
| 112 // Only request to connect to the best network if network properties were | |
| 113 // actually changed. Otherwise only process existing requests. | |
| 114 if (network_properties_changed) { | |
| 115 NET_LOG_DEBUG("RequestBestConnection", | |
| 116 "Client certificate patterns resolved"); | |
| 117 RequestBestConnection(); | |
| 118 } else { | |
| 119 CheckBestConnection(); | |
| 120 } | |
| 121 } | |
| 122 | |
| 123 void AutoConnectHandler::RequestBestConnection() { | |
| 124 request_best_connection_pending_ = true; | |
| 125 CheckBestConnection(); | |
| 126 } | |
| 127 | |
| 128 void AutoConnectHandler::CheckBestConnection() { | |
| 129 // Return immediately if there is currently no request pending to change to | |
| 130 // the best network. | |
| 131 if (!request_best_connection_pending_) | |
| 132 return; | |
| 133 | |
| 134 bool policy_application_running = | |
| 135 managed_configuration_handler_->IsAnyPolicyApplicationRunning(); | |
| 136 bool client_cert_resolve_task_running = | |
| 137 client_cert_resolver_->IsAnyResolveTaskRunning(); | |
| 138 VLOG(2) << "device policy applied: " << device_policy_applied_ | |
| 139 << "\nuser policy applied: " << user_policy_applied_ | |
| 140 << "\npolicy application running: " << policy_application_running | |
| 141 << "\nclient cert patterns resolved: " << client_certs_resolved_ | |
| 142 << "\nclient cert resolve task running: " | |
| 143 << client_cert_resolve_task_running; | |
| 144 if (!device_policy_applied_ || policy_application_running || | |
| 145 client_cert_resolve_task_running) { | |
| 146 return; | |
| 147 } | |
| 148 | |
| 149 if (LoginState::Get()->IsUserLoggedIn()) { | |
| 150 // Before changing connection after login, we wait at least for: | |
| 151 // - user policy applied at least once | |
| 152 // - client certificate patterns resolved | |
| 153 if (!user_policy_applied_ || !client_certs_resolved_) | |
| 154 return; | |
| 155 } | |
| 156 | |
| 157 request_best_connection_pending_ = false; | |
| 158 NET_LOG_EVENT("ConnectToBestWifiNetwork", ""); | |
| 159 network_state_handler_->ConnectToBestWifiNetwork(); | |
|
stevenjb
2014/11/07 17:19:06
Should we remove this from NSH/SPH and make the Sh
pneubeck (no reviews)
2014/11/08 16:49:55
can't move it without further changes. NSH is at f
| |
| 160 } | |
| 161 | |
| 162 void AutoConnectHandler::DisconnectIfPolicyRequires() { | |
| 163 if (applied_autoconnect_policy_ || !LoginState::Get()->IsUserLoggedIn()) | |
| 164 return; | |
| 165 | |
| 166 const base::DictionaryValue* global_network_config = | |
| 167 managed_configuration_handler_->GetGlobalConfigFromPolicy(std::string()); | |
|
stevenjb
2014/11/07 17:19:06
nit: comment what std::string() represents
pneubeck (no reviews)
2014/11/08 16:49:55
Done.
| |
| 168 | |
| 169 if (!global_network_config) | |
| 170 return; // Device policy is not set, yet. | |
| 171 | |
| 172 applied_autoconnect_policy_ = true; | |
| 173 | |
| 174 bool only_policy_autoconnect = false; | |
| 175 global_network_config->GetBooleanWithoutPathExpansion( | |
| 176 ::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect, | |
| 177 &only_policy_autoconnect); | |
| 178 | |
| 179 if (only_policy_autoconnect) | |
| 180 DisconnectFromUnmanagedSharedWiFiNetworks(); | |
| 181 } | |
| 182 | |
| 183 void AutoConnectHandler::DisconnectFromUnmanagedSharedWiFiNetworks() { | |
| 184 NET_LOG_DEBUG("DisconnectFromUnmanagedSharedWiFiNetworks", ""); | |
| 185 | |
| 186 NetworkStateHandler::NetworkStateList networks; | |
| 187 network_state_handler_->GetVisibleNetworkListByType( | |
| 188 NetworkTypePattern::Wireless(), &networks); | |
| 189 for (const NetworkState* network : networks) { | |
| 190 if (!(network->IsConnectingState() || network->IsConnectedState())) | |
| 191 break; // Connected and connecting networks are listed first. | |
| 192 | |
| 193 if (network->IsPrivate()) | |
| 194 continue; | |
| 195 | |
| 196 const bool network_is_policy_managed = | |
| 197 !network->profile_path().empty() && !network->guid().empty() && | |
| 198 managed_configuration_handler_->FindPolicyByGuidAndProfile( | |
| 199 network->guid(), network->profile_path()); | |
| 200 if (network_is_policy_managed) | |
| 201 continue; | |
| 202 | |
| 203 NET_LOG_EVENT("Disconnect Forced by Policy", network->path()); | |
| 204 DBusThreadManager::Get()->GetShillServiceClient()->Disconnect( | |
| 205 dbus::ObjectPath(network->path()), base::Bind(&base::DoNothing), | |
| 206 base::Bind(&network_handler::ShillErrorCallbackFunction, | |
| 207 "AutoConnectHandler.Disconnect failed", network->path(), | |
| 208 network_handler::ErrorCallback())); | |
| 209 } | |
| 210 } | |
| 211 | |
| 212 } // namespace chromeos | |
| OLD | NEW |