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 "chrome/browser/extensions/api/networking_private/networking_private_chromeos.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/callback.h" 10 #include "chrome/browser/chromeos/profiles/profile_helper.h" 11 #include "chrome/browser/extensions/api/networking_private/networking_private_api.h" 12 #include "chrome/common/extensions/api/networking_private.h" 13 #include "chrome/common/extensions/api/networking_private.h" 14 #include "chromeos/dbus/dbus_thread_manager.h" 15 #include "chromeos/dbus/shill_manager_client.h" 16 #include "chromeos/login/login_state.h" 17 #include "chromeos/network/managed_network_configuration_handler.h" 18 #include "chromeos/network/network_connection_handler.h" 19 #include "chromeos/network/network_device_handler.h" 20 #include "chromeos/network/network_event_log.h" 21 #include "chromeos/network/network_state.h" 22 #include "chromeos/network/network_state_handler.h" 23 #include "chromeos/network/network_util.h" 24 #include "chromeos/network/onc/onc_signature.h" 25 #include "chromeos/network/onc/onc_translator.h" 26 #include "chromeos/network/onc/onc_utils.h" 27 #include "chromeos/network/portal_detector/network_portal_detector.h" 28 #include "components/onc/onc_constants.h" 29 #include "content/public/browser/browser_context.h" 30 31 using chromeos::NetworkHandler; 32 using chromeos::NetworkTypePattern; 33 using chromeos::ShillManagerClient; 34 using extensions::NetworkingPrivateDelegate; 35 36 namespace { 37 38 chromeos::ShillManagerClient* GetShillManagerClient() { 39 return chromeos::DBusThreadManager::Get()->GetShillManagerClient(); 40 } 41 42 chromeos::NetworkStateHandler* GetStateHandler() { 43 return NetworkHandler::Get()->network_state_handler(); 44 } 45 46 chromeos::ManagedNetworkConfigurationHandler* GetManagedConfigurationHandler() { 47 return NetworkHandler::Get()->managed_network_configuration_handler(); 48 } 49 50 ShillManagerClient::VerificationProperties ConvertVerificationProperties( 51 const extensions::api::networking_private::VerificationProperties& input) { 52 ShillManagerClient::VerificationProperties output; 53 output.certificate = input.certificate; 54 output.public_key = input.public_key; 55 output.nonce = input.nonce; 56 output.signed_data = input.signed_data; 57 output.device_serial = input.device_serial; 58 output.device_ssid = input.device_ssid; 59 output.device_bssid = input.device_bssid; 60 return output; 61 } 62 63 bool GetServicePathFromGuid(const std::string& guid, 64 std::string* service_path, 65 std::string* error) { 66 const chromeos::NetworkState* network = 67 GetStateHandler()->GetNetworkStateFromGuid(guid); 68 if (!network) { 69 *error = extensions::networking_private::kErrorInvalidNetworkGuid; 70 return false; 71 } 72 *service_path = network->path(); 73 return true; 74 } 75 76 bool GetUserIdHash(content::BrowserContext* browser_context, 77 std::string* user_hash, 78 std::string* error) { 79 std::string profile_user_hash = 80 chromeos::ProfileHelper::GetUserIdHashFromProfile( 81 static_cast<Profile*>(browser_context)); 82 83 // Currently Chrome OS only configures networks for the primary user. 84 // Configuration attempts from other browser contexts should fail. 85 // TODO(stevenjb): use an ExtensionsBrowserClient method to access 86 // ProfileHelper when moving this to src/extensions. 87 if (profile_user_hash != chromeos::LoginState::Get()->primary_user_hash()) { 88 // Disallow class requiring a user id hash from a non-primary user context 89 // to avoid complexities with the policy code. 90 LOG(ERROR) << "networkingPrivate API call from non primary user: " 91 << profile_user_hash; 92 *error = "Error.NonPrimaryUser"; 93 return false; 94 } 95 *user_hash = profile_user_hash; 96 return true; 97 } 98 99 void NetworkHandlerDictionaryCallback( 100 const NetworkingPrivateDelegate::DictionaryCallback& callback, 101 const std::string& service_path, 102 const base::DictionaryValue& dictionary) { 103 scoped_ptr<base::DictionaryValue> dictionary_copy(dictionary.DeepCopy()); 104 callback.Run(dictionary_copy.Pass()); 105 } 106 107 void NetworkHandlerFailureCallback( 108 const NetworkingPrivateDelegate::FailureCallback& callback, 109 const std::string& error_name, 110 scoped_ptr<base::DictionaryValue> error_data) { 111 callback.Run(error_name); 112 } 113 114 void ShillFailureCallback( 115 const NetworkingPrivateDelegate::FailureCallback& callback, 116 const std::string& error_name, 117 const std::string& error_message) { 118 callback.Run(error_name); 119 } 120 121 } // namespace 122 123 //////////////////////////////////////////////////////////////////////////////// 124 125 namespace extensions { 126 127 NetworkingPrivateChromeOS::NetworkingPrivateChromeOS( 128 content::BrowserContext* browser_context) 129 : browser_context_(browser_context) { 130 } 131 132 NetworkingPrivateChromeOS::~NetworkingPrivateChromeOS() {} 133 134 void NetworkingPrivateChromeOS::GetProperties( 135 const std::string& guid, 136 const DictionaryCallback& success_callback, 137 const FailureCallback& failure_callback) { 138 std::string service_path, error; 139 if (!GetServicePathFromGuid(guid, &service_path, &error)) { 140 failure_callback.Run(error); 141 return; 142 } 143 144 GetManagedConfigurationHandler()->GetProperties( 145 service_path, 146 base::Bind(&NetworkHandlerDictionaryCallback, success_callback), 147 base::Bind(&NetworkHandlerFailureCallback, failure_callback)); 148 } 149 150 void NetworkingPrivateChromeOS::GetManagedProperties( 151 const std::string& guid, 152 const DictionaryCallback& success_callback, 153 const FailureCallback& failure_callback) { 154 std::string service_path, error; 155 if (!GetServicePathFromGuid(guid, &service_path, &error)) { 156 failure_callback.Run(error); 157 return; 158 } 159 160 std::string user_id_hash; 161 if (!GetUserIdHash(browser_context_, &user_id_hash, &error)) { 162 failure_callback.Run(error); 163 return; 164 } 165 166 GetManagedConfigurationHandler()->GetManagedProperties( 167 user_id_hash, 168 service_path, 169 base::Bind(&NetworkHandlerDictionaryCallback, success_callback), 170 base::Bind(&NetworkHandlerFailureCallback, failure_callback)); 171 } 172 173 void NetworkingPrivateChromeOS::GetState( 174 const std::string& guid, 175 const DictionaryCallback& success_callback, 176 const FailureCallback& failure_callback) { 177 std::string service_path, error; 178 if (!GetServicePathFromGuid(guid, &service_path, &error)) { 179 failure_callback.Run(error); 180 return; 181 } 182 183 const chromeos::NetworkState* network_state = 184 GetStateHandler()->GetNetworkStateFromServicePath( 185 service_path, false /* configured_only */); 186 if (!network_state) { 187 failure_callback.Run(networking_private::kErrorNetworkUnavailable); 188 return; 189 } 190 191 scoped_ptr<base::DictionaryValue> network_properties = 192 chromeos::network_util::TranslateNetworkStateToONC(network_state); 193 194 success_callback.Run(network_properties.Pass()); 195 } 196 197 void NetworkingPrivateChromeOS::SetProperties( 198 const std::string& guid, 199 scoped_ptr<base::DictionaryValue> properties, 200 const VoidCallback& success_callback, 201 const FailureCallback& failure_callback) { 202 std::string service_path, error; 203 if (!GetServicePathFromGuid(guid, &service_path, &error)) { 204 failure_callback.Run(error); 205 return; 206 } 207 208 GetManagedConfigurationHandler()->SetProperties( 209 service_path, 210 *properties, 211 success_callback, 212 base::Bind(&NetworkHandlerFailureCallback, failure_callback)); 213 } 214 215 void NetworkingPrivateChromeOS::CreateNetwork( 216 bool shared, 217 scoped_ptr<base::DictionaryValue> properties, 218 const StringCallback& success_callback, 219 const FailureCallback& failure_callback) { 220 std::string user_id_hash, error; 221 // Do not allow configuring a non-shared network from a non-primary user. 222 if (!shared && !GetUserIdHash(browser_context_, &user_id_hash, &error)) { 223 failure_callback.Run(error); 224 return; 225 } 226 227 GetManagedConfigurationHandler()->CreateConfiguration( 228 user_id_hash, 229 *properties, 230 success_callback, 231 base::Bind(&NetworkHandlerFailureCallback, failure_callback)); 232 } 233 234 void NetworkingPrivateChromeOS::GetNetworks( 235 const std::string& network_type, 236 bool configured_only, 237 bool visible_only, 238 int limit, 239 const NetworkListCallback& success_callback, 240 const FailureCallback& failure_callback) { 241 NetworkTypePattern pattern = 242 chromeos::onc::NetworkTypePatternFromOncType(network_type); 243 scoped_ptr<base::ListValue> network_properties_list = 244 chromeos::network_util::TranslateNetworkListToONC( 245 pattern, configured_only, visible_only, limit, false /* debugging */); 246 success_callback.Run(network_properties_list.Pass()); 247 } 248 249 void NetworkingPrivateChromeOS::StartConnect( 250 const std::string& guid, 251 const VoidCallback& success_callback, 252 const FailureCallback& failure_callback) { 253 std::string service_path, error; 254 if (!GetServicePathFromGuid(guid, &service_path, &error)) { 255 failure_callback.Run(error); 256 return; 257 } 258 259 const bool check_error_state = false; 260 NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork( 261 service_path, 262 success_callback, 263 base::Bind(&NetworkHandlerFailureCallback, failure_callback), 264 check_error_state); 265 } 266 267 void NetworkingPrivateChromeOS::StartDisconnect( 268 const std::string& guid, 269 const VoidCallback& success_callback, 270 const FailureCallback& failure_callback) { 271 std::string service_path, error; 272 if (!GetServicePathFromGuid(guid, &service_path, &error)) { 273 failure_callback.Run(error); 274 return; 275 } 276 277 NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork( 278 service_path, 279 success_callback, 280 base::Bind(&NetworkHandlerFailureCallback, failure_callback)); 281 } 282 283 void NetworkingPrivateChromeOS::VerifyDestination( 284 const VerificationProperties& verification_properties, 285 const BoolCallback& success_callback, 286 const FailureCallback& failure_callback) { 287 ShillManagerClient::VerificationProperties verification_property_struct = 288 ConvertVerificationProperties(verification_properties); 289 290 GetShillManagerClient()->VerifyDestination( 291 verification_property_struct, 292 success_callback, 293 base::Bind(&ShillFailureCallback, failure_callback)); 294 } 295 296 void NetworkingPrivateChromeOS::VerifyAndEncryptCredentials( 297 const std::string& guid, 298 const VerificationProperties& verification_properties, 299 const StringCallback& success_callback, 300 const FailureCallback& failure_callback) { 301 std::string service_path, error; 302 if (!GetServicePathFromGuid(guid, &service_path, &error)) { 303 failure_callback.Run(error); 304 return; 305 } 306 307 ShillManagerClient::VerificationProperties verification_property_struct = 308 ConvertVerificationProperties(verification_properties); 309 310 GetShillManagerClient()->VerifyAndEncryptCredentials( 311 verification_property_struct, 312 service_path, 313 success_callback, 314 base::Bind(&ShillFailureCallback, failure_callback)); 315 } 316 317 void NetworkingPrivateChromeOS::VerifyAndEncryptData( 318 const VerificationProperties& verification_properties, 319 const std::string& data, 320 const StringCallback& success_callback, 321 const FailureCallback& failure_callback) { 322 ShillManagerClient::VerificationProperties verification_property_struct = 323 ConvertVerificationProperties(verification_properties); 324 325 GetShillManagerClient()->VerifyAndEncryptData( 326 verification_property_struct, 327 data, 328 success_callback, 329 base::Bind(&ShillFailureCallback, failure_callback)); 330 } 331 332 void NetworkingPrivateChromeOS::SetWifiTDLSEnabledState( 333 const std::string& ip_or_mac_address, 334 bool enabled, 335 const StringCallback& success_callback, 336 const FailureCallback& failure_callback) { 337 NetworkHandler::Get()->network_device_handler()->SetWifiTDLSEnabled( 338 ip_or_mac_address, 339 enabled, 340 success_callback, 341 base::Bind(&NetworkHandlerFailureCallback, failure_callback)); 342 } 343 344 void NetworkingPrivateChromeOS::GetWifiTDLSStatus( 345 const std::string& ip_or_mac_address, 346 const StringCallback& success_callback, 347 const FailureCallback& failure_callback) { 348 NetworkHandler::Get()->network_device_handler()->GetWifiTDLSStatus( 349 ip_or_mac_address, 350 success_callback, 351 base::Bind(&NetworkHandlerFailureCallback, failure_callback)); 352 } 353 354 void NetworkingPrivateChromeOS::GetCaptivePortalStatus( 355 const std::string& guid, 356 const StringCallback& success_callback, 357 const FailureCallback& failure_callback) { 358 chromeos::NetworkPortalDetector* detector = 359 chromeos::NetworkPortalDetector::Get(); 360 if (!detector) { 361 failure_callback.Run(networking_private::kErrorNotReady); 362 return; 363 } 364 365 chromeos::NetworkPortalDetector::CaptivePortalState state = 366 detector->GetCaptivePortalState(guid); 367 success_callback.Run( 368 chromeos::NetworkPortalDetector::CaptivePortalStatusString(state.status)); 369 } 370 371 scoped_ptr<base::ListValue> 372 NetworkingPrivateChromeOS::GetEnabledNetworkTypes() { 373 chromeos::NetworkStateHandler* state_handler = GetStateHandler(); 374 375 scoped_ptr<base::ListValue> network_list(new base::ListValue); 376 377 if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Ethernet())) 378 network_list->AppendString(::onc::network_type::kEthernet); 379 if (state_handler->IsTechnologyEnabled(NetworkTypePattern::WiFi())) 380 network_list->AppendString(::onc::network_type::kWiFi); 381 if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Wimax())) 382 network_list->AppendString(::onc::network_type::kWimax); 383 if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Cellular())) 384 network_list->AppendString(::onc::network_type::kCellular); 385 386 return network_list.Pass(); 387 } 388 389 bool NetworkingPrivateChromeOS::EnableNetworkType(const std::string& type) { 390 NetworkTypePattern pattern = 391 chromeos::onc::NetworkTypePatternFromOncType(type); 392 393 GetStateHandler()->SetTechnologyEnabled( 394 pattern, true, chromeos::network_handler::ErrorCallback()); 395 396 return true; 397 } 398 399 bool NetworkingPrivateChromeOS::DisableNetworkType(const std::string& type) { 400 NetworkTypePattern pattern = 401 chromeos::onc::NetworkTypePatternFromOncType(type); 402 403 GetStateHandler()->SetTechnologyEnabled( 404 pattern, false, chromeos::network_handler::ErrorCallback()); 405 406 return true; 407 } 408 409 bool NetworkingPrivateChromeOS::RequestScan() { 410 GetStateHandler()->RequestScan(); 411 return true; 412 } 413 414 } // namespace extensions 415