| Index: chrome/browser/extensions/api/networking_private/networking_private_service_client.cc
|
| diff --git a/chrome/browser/extensions/api/networking_private/networking_private_service_client.cc b/chrome/browser/extensions/api/networking_private/networking_private_service_client.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6e109e218564253bae39f7dd73541caf51be76b0
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/api/networking_private/networking_private_service_client.cc
|
| @@ -0,0 +1,464 @@
|
| +// Copyright 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h"
|
| +
|
| +#include "base/base64.h"
|
| +#include "base/bind.h"
|
| +#include "base/sequenced_task_runner.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "base/threading/worker_pool.h"
|
| +#include "chrome/browser/browser_process.h"
|
| +#include "chrome/browser/extensions/api/networking_private/networking_private_crypto.h"
|
| +#include "chrome/common/extensions/api/networking_private.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/utility_process_host.h"
|
| +
|
| +using content::BrowserThread;
|
| +using extensions::api::networking_private::VerificationProperties;
|
| +
|
| +namespace extensions {
|
| +
|
| +namespace {
|
| +
|
| +const char kNetworkingPrivateServiceClient[] = "NetworkingPrivateServiceClient";
|
| +const char kNetworkingPrivateSequenceTokenName[] = "NetworkingPrivate";
|
| +
|
| +// Implementation of Verify* methods using NetworkingPrivateCrypto.
|
| +// TODO(mef): Move this into NetworkingPrivateCrypto class.
|
| +class CryptoVerifyImpl : public NetworkingPrivateServiceClient::CryptoVerify {
|
| + bool VerifyDestination(const VerificationProperties& properties) {
|
| + std::vector<std::string> data_parts;
|
| + data_parts.push_back(properties.device_ssid);
|
| + data_parts.push_back(properties.device_serial);
|
| + data_parts.push_back(properties.device_bssid);
|
| + data_parts.push_back(properties.public_key);
|
| + data_parts.push_back(properties.nonce);
|
| + std::string unsigned_data = JoinString(data_parts, ",");
|
| + std::string signed_data;
|
| + if (!base::Base64Decode(properties.signed_data, &signed_data))
|
| + return false;
|
| + NetworkingPrivateCrypto crypto;
|
| + return crypto.VerifyCredentials(properties.certificate,
|
| + signed_data,
|
| + unsigned_data,
|
| + properties.device_bssid);
|
| + }
|
| +
|
| + virtual void VerifyDestination(scoped_ptr<base::ListValue> args,
|
| + bool* verified,
|
| + std::string* error) OVERRIDE {
|
| + using extensions::api::networking_private::VerifyDestination::Params;
|
| + scoped_ptr<Params> params = Params::Create(*args);
|
| + *verified = VerifyDestination(params->properties);
|
| + }
|
| +
|
| + virtual void VerifyAndEncryptData(scoped_ptr<base::ListValue> args,
|
| + std::string* base64_encoded_ciphertext,
|
| + std::string* error) OVERRIDE {
|
| + using extensions::api::networking_private::VerifyAndEncryptData::Params;
|
| + scoped_ptr<Params> params = Params::Create(*args);
|
| +
|
| + if (!VerifyDestination(params->properties)) {
|
| + *error = "VerifyError";
|
| + return;
|
| + }
|
| +
|
| + std::string public_key;
|
| + if (!base::Base64Decode(params->properties.public_key, &public_key)) {
|
| + *error = "DecodeError";
|
| + return;
|
| + }
|
| +
|
| + NetworkingPrivateCrypto crypto;
|
| + std::string ciphertext;
|
| + if (!crypto.EncryptByteString(public_key, params->data, &ciphertext)) {
|
| + *error = "EncryptError";
|
| + return;
|
| + }
|
| +
|
| + if (!base::Base64Encode(ciphertext, base64_encoded_ciphertext)) {
|
| + *error = "EncodeError";
|
| + return;
|
| + }
|
| + }
|
| +};
|
| +
|
| +// Deletes WiFiService and CryptoVerify objects on worker thread.
|
| +void ShutdownServicesOnWorkerThread(
|
| + scoped_ptr<wifi::WiFiService> wifi_service,
|
| + scoped_ptr<NetworkingPrivateServiceClient::CryptoVerify> crypto_verify) {
|
| + DCHECK(wifi_service.get());
|
| + DCHECK(crypto_verify.get());
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +NetworkingPrivateServiceClient::NetworkingPrivateServiceClient(
|
| + wifi::WiFiService* wifi_service,
|
| + CryptoVerify* crypto_verify)
|
| + : crypto_verify_(crypto_verify),
|
| + wifi_service_(wifi_service),
|
| + weak_factory_(this) {
|
| + sequence_token_ = BrowserThread::GetBlockingPool()->
|
| + GetNamedSequenceToken(kNetworkingPrivateSequenceTokenName);
|
| + task_runner_ = BrowserThread::GetBlockingPool()->
|
| + GetSequencedTaskRunnerWithShutdownBehavior(
|
| + sequence_token_,
|
| + base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
|
| + task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &WiFiService::SetEventObservers,
|
| + base::Unretained(wifi_service_.get()),
|
| + base::MessageLoopProxy::current(),
|
| + base::Bind(
|
| + &NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread,
|
| + weak_factory_.GetWeakPtr()),
|
| + base::Bind(
|
| + &NetworkingPrivateServiceClient::
|
| + OnNetworkListChangedEventOnUIThread,
|
| + weak_factory_.GetWeakPtr())));
|
| +}
|
| +
|
| +NetworkingPrivateServiceClient::~NetworkingPrivateServiceClient() {}
|
| +
|
| +NetworkingPrivateServiceClient::CryptoVerify*
|
| + NetworkingPrivateServiceClient::CryptoVerify::Create() {
|
| + return new CryptoVerifyImpl();
|
| +}
|
| +
|
| +NetworkingPrivateServiceClient::ServiceCallbacks::ServiceCallbacks() {}
|
| +
|
| +NetworkingPrivateServiceClient::ServiceCallbacks::~ServiceCallbacks() {}
|
| +
|
| +void NetworkingPrivateServiceClient::Shutdown() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + // Clear callbacks map to release callbacks from UI thread.
|
| + callbacks_map_.Clear();
|
| +
|
| + task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&ShutdownServicesOnWorkerThread,
|
| + base::Passed(&wifi_service_),
|
| + base::Passed(&crypto_verify_)));
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::AddObserver(Observer* observer) {
|
| + network_events_observers_.AddObserver(observer);
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::RemoveObserver(Observer* observer) {
|
| + network_events_observers_.RemoveObserver(observer);
|
| +}
|
| +
|
| +NetworkingPrivateServiceClient::ServiceCallbacks*
|
| +NetworkingPrivateServiceClient::AddServiceCallbacks() {
|
| + ServiceCallbacks* service_callbacks = new ServiceCallbacks();
|
| + service_callbacks->id = callbacks_map_.Add(service_callbacks);
|
| + return service_callbacks;
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::RemoveServiceCallbacks(
|
| + ServiceCallbacksID callback_id) {
|
| + callbacks_map_.Remove(callback_id);
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::GetProperties(
|
| + const std::string& network_guid,
|
| + const DictionaryResultCallback& callback,
|
| + const ErrorCallback& error_callback) {
|
| + ServiceCallbacks* service_callbacks = AddServiceCallbacks();
|
| + service_callbacks->error_callback = error_callback;
|
| + service_callbacks->get_properties_callback = callback;
|
| +
|
| + DictionaryValue* properties = new DictionaryValue();
|
| + std::string* error = new std::string;
|
| +
|
| + task_runner_->PostTaskAndReply(
|
| + FROM_HERE,
|
| + base::Bind(&WiFiService::GetProperties,
|
| + base::Unretained(wifi_service_.get()),
|
| + network_guid,
|
| + properties,
|
| + error),
|
| + base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties,
|
| + weak_factory_.GetWeakPtr(),
|
| + service_callbacks->id,
|
| + network_guid,
|
| + base::Owned(properties),
|
| + base::Owned(error)));
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::GetVisibleNetworks(
|
| + const ListResultCallback& callback) {
|
| + ServiceCallbacks* service_callbacks = AddServiceCallbacks();
|
| + service_callbacks->get_visible_networks_callback = callback;
|
| +
|
| + ListValue* networks = new ListValue();
|
| +
|
| + task_runner_->PostTaskAndReply(
|
| + FROM_HERE,
|
| + base::Bind(&WiFiService::GetVisibleNetworks,
|
| + base::Unretained(wifi_service_.get()),
|
| + networks),
|
| + base::Bind(&NetworkingPrivateServiceClient::AfterGetVisibleNetworks,
|
| + weak_factory_.GetWeakPtr(),
|
| + service_callbacks->id,
|
| + base::Owned(networks)));
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::RequestNetworkScan() {
|
| + task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&WiFiService::RequestNetworkScan,
|
| + base::Unretained(wifi_service_.get())));
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::SetProperties(
|
| + const std::string& network_guid,
|
| + const base::DictionaryValue& properties,
|
| + const base::Closure& callback,
|
| + const ErrorCallback& error_callback) {
|
| + ServiceCallbacks* service_callbacks = AddServiceCallbacks();
|
| + service_callbacks->error_callback = error_callback;
|
| + service_callbacks->set_properties_callback = callback;
|
| +
|
| + scoped_ptr<base::DictionaryValue> properties_ptr(properties.DeepCopy());
|
| + std::string* error = new std::string;
|
| +
|
| + task_runner_->PostTaskAndReply(
|
| + FROM_HERE,
|
| + base::Bind(&WiFiService::SetProperties,
|
| + base::Unretained(wifi_service_.get()),
|
| + network_guid,
|
| + base::Passed(&properties_ptr),
|
| + error),
|
| + base::Bind(&NetworkingPrivateServiceClient::AfterSetProperties,
|
| + weak_factory_.GetWeakPtr(),
|
| + service_callbacks->id,
|
| + base::Owned(error)));
|
| +}
|
| +
|
| +
|
| +void NetworkingPrivateServiceClient::StartConnect(
|
| + const std::string& network_guid,
|
| + const base::Closure& callback,
|
| + const ErrorCallback& error_callback) {
|
| + ServiceCallbacks* service_callbacks = AddServiceCallbacks();
|
| + service_callbacks->error_callback = error_callback;
|
| + service_callbacks->start_connect_callback = callback;
|
| +
|
| + std::string* error = new std::string;
|
| +
|
| + task_runner_->PostTaskAndReply(
|
| + FROM_HERE,
|
| + base::Bind(&WiFiService::StartConnect,
|
| + base::Unretained(wifi_service_.get()),
|
| + network_guid,
|
| + error),
|
| + base::Bind(&NetworkingPrivateServiceClient::AfterStartConnect,
|
| + weak_factory_.GetWeakPtr(),
|
| + service_callbacks->id,
|
| + base::Owned(error)));
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::StartDisconnect(
|
| + const std::string& network_guid,
|
| + const base::Closure& callback,
|
| + const ErrorCallback& error_callback) {
|
| + ServiceCallbacks* service_callbacks = AddServiceCallbacks();
|
| + service_callbacks->error_callback = error_callback;
|
| + service_callbacks->start_disconnect_callback = callback;
|
| +
|
| + std::string* error = new std::string;
|
| +
|
| + task_runner_->PostTaskAndReply(
|
| + FROM_HERE,
|
| + base::Bind(&WiFiService::StartDisconnect,
|
| + base::Unretained(wifi_service_.get()),
|
| + network_guid,
|
| + error),
|
| + base::Bind(&NetworkingPrivateServiceClient::AfterStartDisconnect,
|
| + weak_factory_.GetWeakPtr(),
|
| + service_callbacks->id,
|
| + base::Owned(error)));
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::VerifyDestination(
|
| + scoped_ptr<base::ListValue> args,
|
| + const BoolResultCallback& callback,
|
| + const CryptoErrorCallback& error_callback) {
|
| + ServiceCallbacks* service_callbacks = AddServiceCallbacks();
|
| + service_callbacks->crypto_error_callback = error_callback;
|
| + service_callbacks->verify_destination_callback = callback;
|
| +
|
| + bool* result = new bool;
|
| + std::string* error = new std::string;
|
| +
|
| + task_runner_->PostTaskAndReply(
|
| + FROM_HERE,
|
| + base::Bind(&CryptoVerify::VerifyDestination,
|
| + base::Unretained(crypto_verify_.get()),
|
| + base::Passed(&args),
|
| + result,
|
| + error),
|
| + base::Bind(&NetworkingPrivateServiceClient::AfterVerifyDestination,
|
| + weak_factory_.GetWeakPtr(),
|
| + service_callbacks->id,
|
| + base::Owned(result),
|
| + base::Owned(error)));
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::VerifyAndEncryptData(
|
| + scoped_ptr<base::ListValue> args,
|
| + const StringResultCallback& callback,
|
| + const CryptoErrorCallback& error_callback) {
|
| + ServiceCallbacks* service_callbacks = AddServiceCallbacks();
|
| + service_callbacks->crypto_error_callback = error_callback;
|
| + service_callbacks->verify_and_encrypt_data_callback = callback;
|
| +
|
| + std::string* result = new std::string;
|
| + std::string* error = new std::string;
|
| +
|
| + task_runner_->PostTaskAndReply(
|
| + FROM_HERE,
|
| + base::Bind(&CryptoVerify::VerifyAndEncryptData,
|
| + base::Unretained(crypto_verify_.get()),
|
| + base::Passed(&args),
|
| + result,
|
| + error),
|
| + base::Bind(&NetworkingPrivateServiceClient::AfterVerifyAndEncryptData,
|
| + weak_factory_.GetWeakPtr(),
|
| + service_callbacks->id,
|
| + base::Owned(result),
|
| + base::Owned(error)));
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::AfterGetProperties(
|
| + ServiceCallbacksID callback_id,
|
| + const std::string& network_guid,
|
| + const DictionaryValue* properties,
|
| + const std::string* error) {
|
| + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
|
| + DCHECK(service_callbacks);
|
| + if (!error->empty()) {
|
| + DCHECK(!service_callbacks->error_callback.is_null());
|
| + service_callbacks->error_callback.Run(*error,
|
| + scoped_ptr<base::DictionaryValue>());
|
| + } else {
|
| + DCHECK(!service_callbacks->get_properties_callback.is_null());
|
| + service_callbacks->get_properties_callback.Run(network_guid, *properties);
|
| + }
|
| + RemoveServiceCallbacks(callback_id);
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::AfterGetVisibleNetworks(
|
| + ServiceCallbacksID callback_id,
|
| + const ListValue* networks) {
|
| + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
|
| + DCHECK(service_callbacks);
|
| + DCHECK(!service_callbacks->get_visible_networks_callback.is_null());
|
| + service_callbacks->get_visible_networks_callback.Run(*networks);
|
| + RemoveServiceCallbacks(callback_id);
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::AfterSetProperties(
|
| + ServiceCallbacksID callback_id,
|
| + const std::string* error) {
|
| + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
|
| + DCHECK(service_callbacks);
|
| + if (!error->empty()) {
|
| + DCHECK(!service_callbacks->error_callback.is_null());
|
| + service_callbacks->error_callback.Run(*error,
|
| + scoped_ptr<base::DictionaryValue>());
|
| + } else {
|
| + DCHECK(!service_callbacks->set_properties_callback.is_null());
|
| + service_callbacks->set_properties_callback.Run();
|
| + }
|
| + RemoveServiceCallbacks(callback_id);
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::AfterStartConnect(
|
| + ServiceCallbacksID callback_id,
|
| + const std::string* error) {
|
| + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
|
| + DCHECK(service_callbacks);
|
| + if (!error->empty()) {
|
| + DCHECK(!service_callbacks->error_callback.is_null());
|
| + service_callbacks->error_callback.Run(*error,
|
| + scoped_ptr<base::DictionaryValue>());
|
| + } else {
|
| + DCHECK(!service_callbacks->start_connect_callback.is_null());
|
| + service_callbacks->start_connect_callback.Run();
|
| + }
|
| + RemoveServiceCallbacks(callback_id);
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::AfterStartDisconnect(
|
| + ServiceCallbacksID callback_id,
|
| + const std::string* error) {
|
| + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
|
| + DCHECK(service_callbacks);
|
| + if (!error->empty()) {
|
| + DCHECK(!service_callbacks->error_callback.is_null());
|
| + service_callbacks->error_callback.Run(*error,
|
| + scoped_ptr<base::DictionaryValue>());
|
| + } else {
|
| + DCHECK(!service_callbacks->start_disconnect_callback.is_null());
|
| + service_callbacks->start_disconnect_callback.Run();
|
| + }
|
| + RemoveServiceCallbacks(callback_id);
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::AfterVerifyDestination(
|
| + ServiceCallbacksID callback_id,
|
| + const bool* result,
|
| + const std::string* error) {
|
| + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
|
| + DCHECK(service_callbacks);
|
| + if (!error->empty()) {
|
| + DCHECK(!service_callbacks->crypto_error_callback.is_null());
|
| + service_callbacks->crypto_error_callback.Run(*error, *error);
|
| + } else {
|
| + DCHECK(!service_callbacks->verify_destination_callback.is_null());
|
| + service_callbacks->verify_destination_callback.Run(*result);
|
| + }
|
| + RemoveServiceCallbacks(callback_id);
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::AfterVerifyAndEncryptData(
|
| + ServiceCallbacksID callback_id,
|
| + const std::string* result,
|
| + const std::string* error) {
|
| + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
|
| + DCHECK(service_callbacks);
|
| + if (!error->empty()) {
|
| + DCHECK(!service_callbacks->crypto_error_callback.is_null());
|
| + service_callbacks->crypto_error_callback.Run(*error, *error);
|
| + } else {
|
| + DCHECK(!service_callbacks->verify_and_encrypt_data_callback.is_null());
|
| + service_callbacks->verify_and_encrypt_data_callback.Run(*result);
|
| + }
|
| + RemoveServiceCallbacks(callback_id);
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread(
|
| + const std::vector<std::string>& network_guids) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + FOR_EACH_OBSERVER(Observer,
|
| + network_events_observers_,
|
| + OnNetworksChangedEvent(network_guids));
|
| +}
|
| +
|
| +void NetworkingPrivateServiceClient::OnNetworkListChangedEventOnUIThread(
|
| + const std::vector<std::string>& network_guids) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + FOR_EACH_OBSERVER(Observer,
|
| + network_events_observers_,
|
| + OnNetworkListChangedEvent(network_guids));
|
| +}
|
| +
|
| +} // namespace extensions
|
|
|