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..e06f673f4415f15ede7a944a0e54dae00730fe1d |
--- /dev/null |
+++ b/chrome/browser/extensions/api/networking_private/networking_private_service_client.cc |
@@ -0,0 +1,465 @@ |
+// 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/browser/profiles/profile.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 ShutdownWiFiServiceOnWorkerThread( |
cbentzel
2013/11/16 02:28:05
Nit: ShutdownOnWorkerThread since both WiFiService
mef
2013/11/17 20:05:19
Done.
|
+ wifi::WiFiService* wifi_service, |
+ NetworkingPrivateServiceClient::CryptoVerify* crypto_verify) { |
+ DCHECK(wifi_service); |
+ DCHECK(crypto_verify); |
+ delete wifi_service; |
+ delete crypto_verify; |
+} |
+} // namespace |
+ |
+NetworkingPrivateServiceClient::NetworkingPrivateServiceClient( |
+ Profile* profile, |
+ wifi::WiFiService* wifi_service, |
+ CryptoVerify* crypto_verify) |
+ : profile_(profile), |
+ 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); |
+ wifi_service_->SetEventObservers( |
cbentzel
2013/11/16 02:28:05
this should preferably be done on worker thread
mef
2013/11/17 20:05:19
Done.
|
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), |
+ 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(&ShutdownWiFiServiceOnWorkerThread, |
+ base::Unretained(wifi_service_), |
+ base::Unretained(crypto_verify_))); |
+ wifi_service_ = NULL; |
+ crypto_verify_ = NULL; |
+} |
+ |
+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_), |
+ 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_), |
+ 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_))); |
+} |
+ |
+void NetworkingPrivateServiceClient::SetProperties( |
+ const std::string& network_guid, |
+ const base::DictionaryValue& properties, |
+ const VoidResultCallback& 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_), |
+ network_guid, |
+ 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 VoidResultCallback& 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_), |
+ 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 VoidResultCallback& 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_), |
+ 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_), |
+ 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_), |
+ 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 |