Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1510)

Unified Diff: chrome/browser/extensions/api/networking_private/networking_private_process_client.cc

Issue 22295002: Base infrastructure for Networking Private API on Windows and Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use crypto_verify_mock for browser_test. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/networking_private/networking_private_process_client.cc
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_process_client.cc b/chrome/browser/extensions/api/networking_private/networking_private_process_client.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6afe60de14657fe2a102c76b064b9511f4cd9250
--- /dev/null
+++ b/chrome/browser/extensions/api/networking_private/networking_private_process_client.cc
@@ -0,0 +1,458 @@
+// 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_process_client.h"
+
+#include "base/base64.h"
+#include "base/bind.h"
+#include "base/strings/string_number_conversions.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 "chrome/common/networking_private_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/utility_process_host.h"
+
+using content::BrowserThread;
+using content::UtilityProcessHost;
+using extensions::api::networking_private::VerificationProperties;
+
+namespace extensions {
+
+namespace {
+// Implementation of Verify* methods using NetworkingPrivateCrypto.
+// TODO(mef): Move this into NetworkingPrivateCrypto class.
+class CryptoVerifyImpl : public NetworkingPrivateProcessClient::CryptoVerify {
+ virtual bool VerifyDestination(
+ const VerificationProperties& properties) OVERRIDE {
+ 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 bool VerifyAndEncryptData(const VerificationProperties& properties,
+ const std::string& plaintext,
+ std::string* base64_ciphertext) OVERRIDE {
+ if (!VerifyDestination(properties))
+ return false;
+
+ std::string public_key;
+ if (!base::Base64Decode(properties.public_key, &public_key))
+ return false;
+
+ NetworkingPrivateCrypto crypto;
+ std::string ciphertext;
+ if (!crypto.EncryptByteString(public_key, plaintext, &ciphertext))
+ return false;
+
+ return base::Base64Encode(ciphertext, base64_ciphertext);
+ }
+};
+
+const char kNetworkingPrivateProcessClient[] = "NetworkingPrivateProcessClient";
+
+} // namespace
+
+scoped_refptr<NetworkingPrivateProcessClient>
+NetworkingPrivateProcessClient::GetForProfile(Profile* profile) {
+ profile = profile->GetOriginalProfile();
+ if (!profile->GetUserData(kNetworkingPrivateProcessClient)) {
+ NetworkingPrivateProcessClient* client =
+ new NetworkingPrivateProcessClient(profile);
+ profile->SetUserData(
+ kNetworkingPrivateProcessClient,
+ new base::UserDataAdapter<NetworkingPrivateProcessClient>(client));
+ client->Start();
+ }
+
+ return scoped_refptr<NetworkingPrivateProcessClient>(
+ base::UserDataAdapter<NetworkingPrivateProcessClient>::Get(
+ profile, kNetworkingPrivateProcessClient));
+}
+
+NetworkingPrivateProcessClient::NetworkingPrivateProcessClient(Profile* profile)
+ : profile_(profile),
+ crypto_verify_(new CryptoVerifyImpl()) {}
+
+NetworkingPrivateProcessClient::~NetworkingPrivateProcessClient() {
+ // TODO(mef): |message_callbacks_| should be cleared on UI thread prior to
+ // destruction, for example from NetworkingPrivateEventRouterImpl::Shutdown().
+}
+
+NetworkingPrivateProcessClient::MessageCallbacks::MessageCallbacks() {}
+
+NetworkingPrivateProcessClient::MessageCallbacks::~MessageCallbacks() {}
+
+void NetworkingPrivateProcessClient::Start() {
+ BrowserThread::ID thread_id;
+ CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_id));
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&NetworkingPrivateProcessClient::StartProcessOnIOThread,
+ this,
+ thread_id));
+}
+
+void NetworkingPrivateProcessClient::StartProcessOnIOThread(
+ BrowserThread::ID thread_id) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ utility_process_host_ = UtilityProcessHost::Create(
+ this, BrowserThread::GetMessageLoopProxyForThread(thread_id).get())
+ ->AsWeakPtr();
+ utility_process_host_->DisableSandbox();
+ utility_process_host_->StartBatchMode();
+}
+
+void NetworkingPrivateProcessClient::AddObserver(Observer* observer) {
+ network_events_observers_.AddObserver(observer);
+}
+
+void NetworkingPrivateProcessClient::RemoveObserver(Observer* observer) {
+ network_events_observers_.RemoveObserver(observer);
+ // Shutdown will occur when all remaining calls are completed.
+ ShutdownIfDone();
+}
+
+void NetworkingPrivateProcessClient::ShutdownIfDone() {
+ if (!network_events_observers_.might_have_observers() &&
+ callbacks_map_.IsEmpty()) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&NetworkingPrivateProcessClient::ShutdownProcessOnIOThread,
+ this));
+ // Remove current process client from profile, so new API calls would launch
+ // new process.
+ profile_->RemoveUserData(kNetworkingPrivateProcessClient);
+ }
+}
+
+void NetworkingPrivateProcessClient::ShutdownProcessOnIOThread() {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ // The utility_process_host_ will take care of deleting itself.
+ if (utility_process_host_.get()) {
+ utility_process_host_->EndBatchMode();
+ utility_process_host_.reset();
+ }
+}
+
+void NetworkingPrivateProcessClient::Send(IPC::Message* message) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(
+ &NetworkingPrivateProcessClient::SendOnIOThread, this, message));
+}
+
+void NetworkingPrivateProcessClient::SendOnIOThread(IPC::Message* message) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (utility_process_host_.get())
+ utility_process_host_->Send(message);
+}
+
+void NetworkingPrivateProcessClient::OnProcessCrashed(int exit_code) {
+ std::string error_code("UtilityProcessCrashed");
+ // Report error for all pending callbacks
+ for (IDMap<MessageCallbacks, IDMapOwnPointer>::iterator iter(&callbacks_map_);
+ !iter.IsAtEnd();
+ iter.Advance()) {
+ if (!iter.GetCurrentValue()->error_callback.is_null()) {
+ scoped_ptr<DictionaryValue> error_data_ptr(new DictionaryValue());
+ iter.GetCurrentValue()->error_callback.Run(error_code,
+ error_data_ptr.Pass());
+ }
+ }
+ callbacks_map_.Clear();
+ if (network_events_observers_.might_have_observers()) {
+ // Restart the utility process.
+ Start();
+ } else {
+ ShutdownIfDone();
+ }
+}
+
+bool NetworkingPrivateProcessClient::OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(NetworkingPrivateProcessClient, message)
+ // Responses from NetworkingPrivateHandler.
+ IPC_MESSAGE_HANDLER(NetworkingPrivateMsg_API_Error, OnApiError)
+ IPC_MESSAGE_HANDLER(NetworkingPrivateMsg_GetProperties_Succeeded,
+ OnGetPropertiesSucceeded)
+ IPC_MESSAGE_HANDLER(NetworkingPrivateMsg_StartConnect_Succeeded,
+ OnStartConnectSucceeded)
+ IPC_MESSAGE_HANDLER(NetworkingPrivateMsg_StartDisconnect_Succeeded,
+ OnStartDisconnectSucceeded)
+ IPC_MESSAGE_HANDLER(NetworkingPrivateMsg_SetProperties_Succeeded,
+ OnSetPropertiesSucceeded)
+ IPC_MESSAGE_HANDLER(NetworkingPrivateMsg_GetVisibleNetworksSucceeded,
+ OnGetVisibleNetworksSucceeded)
+ IPC_MESSAGE_HANDLER(NetworkingPrivateMsg_NetworksChanged_Event,
+ OnNetworksChangedEvent)
+ IPC_MESSAGE_HANDLER(NetworkingPrivateMsg_NetworkListChanged_Event,
+ OnNetworkListChangedEvent)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void NetworkingPrivateProcessClient::GetProperties(
+ const std::string& service_path,
+ const DictionaryResultCallback& callback,
+ const ErrorCallback& error_callback) {
+ MessageCallbacks* message_callbacks = AddMessageCallbacks();
+ message_callbacks->error_callback = error_callback;
+ message_callbacks->get_properties_callback = callback;
+
+ Send(new NetworkingPrivateMsg_GetProperties(message_callbacks->id,
+ service_path));
+}
+
+void NetworkingPrivateProcessClient::GetVisibleNetworks(
+ const ListResultCallback& callback) {
+ MessageCallbacks* message_callbacks = AddMessageCallbacks();
+ message_callbacks->get_visible_networks_callback = callback;
+
+ Send(new NetworkingPrivateMsg_GetVisibleNetworks(message_callbacks->id));
+}
+
+// Requests network scan. Broadcasts NetworkListChangedEvent upon completion.
+void NetworkingPrivateProcessClient::RequestNetworkScan() {
+ Send(new NetworkingPrivateMsg_RequestNetworkScan());
+}
+
+void NetworkingPrivateProcessClient::SetProperties(
+ const std::string& service_path,
+ const base::DictionaryValue& properties,
+ const VoidResultCallback& callback,
+ const ErrorCallback& error_callback) {
+ MessageCallbacks* message_callbacks = AddMessageCallbacks();
+ message_callbacks->error_callback = error_callback;
+ message_callbacks->set_properties_callback = callback;
+
+ scoped_ptr<DictionaryValue> properties_ptr(properties.DeepCopy());
+ Send(new NetworkingPrivateMsg_SetProperties(
+ message_callbacks->id, service_path, *properties_ptr));
+}
+
+void NetworkingPrivateProcessClient::StartConnect(
+ const std::string& service_path,
+ const VoidResultCallback& callback,
+ const ErrorCallback& error_callback) {
+ MessageCallbacks* message_callbacks = AddMessageCallbacks();
+ message_callbacks->error_callback = error_callback;
+ message_callbacks->start_connect_callback = callback;
+
+ Send(new NetworkingPrivateMsg_StartConnect(message_callbacks->id,
+ service_path));
+}
+
+void NetworkingPrivateProcessClient::StartDisconnect(
+ const std::string& service_path,
+ const VoidResultCallback& callback,
+ const ErrorCallback& error_callback) {
+ MessageCallbacks* message_callbacks = AddMessageCallbacks();
+ message_callbacks->error_callback = error_callback;
+ message_callbacks->start_disconnect_callback = callback;
+
+ Send(new NetworkingPrivateMsg_StartDisconnect(message_callbacks->id,
+ service_path));
+}
+
+void NetworkingPrivateProcessClient::VerifyDestination(
+ scoped_ptr<base::ListValue> args,
+ const BoolResultCallback& callback,
+ const CryptoErrorCallback& error_callback) {
+ base::WorkerPool::PostTask(
+ FROM_HERE,
+ base::Bind(
+ &NetworkingPrivateProcessClient::VerifyDestinationOnWorkerThread,
+ this,
+ Passed(&args),
+ callback,
+ error_callback),
+ false);
+}
+
+void NetworkingPrivateProcessClient::VerifyDestinationOnWorkerThread(
+ scoped_ptr<base::ListValue> args,
+ const BoolResultCallback& callback,
+ const CryptoErrorCallback& error_callback) {
+ using extensions::api::networking_private::VerifyDestination::Params;
+ scoped_ptr<Params> params = Params::Create(*args);
+ bool result = crypto_verify_->VerifyDestination(params->properties);
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(callback, result));
+}
+
+void NetworkingPrivateProcessClient::VerifyAndEncryptData(
+ scoped_ptr<base::ListValue> args,
+ const StringResultCallback& callback,
+ const CryptoErrorCallback& error_callback) {
+ base::WorkerPool::PostTask(
+ FROM_HERE,
+ base::Bind(
+ &NetworkingPrivateProcessClient::VerifyAndEncryptDataOnWorkerThread,
+ this,
+ Passed(&args),
+ callback,
+ error_callback),
+ false);
+}
+
+
+void NetworkingPrivateProcessClient::VerifyAndEncryptDataOnWorkerThread(
+ scoped_ptr<base::ListValue> args,
+ const StringResultCallback& callback,
+ const CryptoErrorCallback& error_callback) {
+ using extensions::api::networking_private::VerifyAndEncryptData::Params;
+ scoped_ptr<Params> params = Params::Create(*args);
+ std::string encoded_data;
+ bool verified = crypto_verify_->VerifyAndEncryptData(
+ params->properties, params->data, &encoded_data);
+ if (verified) {
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(callback, encoded_data));
+ } else {
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(error_callback, "VerifyError", "Error"));
+ }
+}
+
+NetworkingPrivateProcessClient::MessageCallbacks*
+NetworkingPrivateProcessClient::AddMessageCallbacks() {
+ MessageCallbacks* message_callbacks = new MessageCallbacks();
+ message_callbacks->id = callbacks_map_.Add(message_callbacks);
+ return message_callbacks;
+}
+
+void NetworkingPrivateProcessClient::RemoveMessageCallbacks(
+ MessageCallbacksID message_id) {
+ callbacks_map_.Remove(message_id);
+ ShutdownIfDone();
+}
+
+void NetworkingPrivateProcessClient::SetUpForTest(
+ const base::DictionaryValue& parameters,
+ CryptoVerify* crypto_verify_mock) {
+ DCHECK(crypto_verify_mock);
+ crypto_verify_.reset(crypto_verify_mock);
+ // Prevent shutdown between calls.
+ AddMessageCallbacks();
+ // Pass mock parameters to utility process itself.
+ scoped_ptr<DictionaryValue> parameters_ptr(parameters.DeepCopy());
+ Send(new NetworkingPrivateMsg_SetUpForTest(*parameters_ptr));
+}
+
+void NetworkingPrivateProcessClient::TearDownForTest() {
+ // Remove extra callback added in SetUpForTest to prevent shutdown between
+ // calls.
+ callbacks_map_.Clear();
+ ShutdownIfDone();
+}
+
+// Message handlers
+void NetworkingPrivateProcessClient::OnApiError(
+ MessageCallbacksID message_id,
+ const std::string& error_code,
+ const base::DictionaryValue& error_data) {
+ MessageCallbacks* message_callbacks = callbacks_map_.Lookup(message_id);
+ if (message_callbacks != NULL) {
+ scoped_ptr<DictionaryValue> error_data_ptr(error_data.DeepCopy());
+ if (!message_callbacks->error_callback.is_null())
+ message_callbacks->error_callback.Run(error_code, error_data_ptr.Pass());
+ RemoveMessageCallbacks(message_id);
+ }
+}
+
+void NetworkingPrivateProcessClient::OnGetPropertiesSucceeded(
+ MessageCallbacksID message_id,
+ const std::string& network_guid,
+ const base::DictionaryValue& properties) {
+ MessageCallbacks* message_callbacks = callbacks_map_.Lookup(message_id);
+ if (message_callbacks != NULL) {
+ if (!message_callbacks->get_properties_callback.is_null())
+ message_callbacks->get_properties_callback.Run(network_guid, properties);
+ RemoveMessageCallbacks(message_id);
+ }
+}
+
+void NetworkingPrivateProcessClient::OnGetVisibleNetworksSucceeded(
+ MessageCallbacksID message_id,
+ const base::ListValue& network_list) {
+ MessageCallbacks* message_callbacks = callbacks_map_.Lookup(message_id);
+ if (message_callbacks != NULL) {
+ if (!message_callbacks->get_visible_networks_callback.is_null())
+ message_callbacks->get_visible_networks_callback.Run(network_list);
+ RemoveMessageCallbacks(message_id);
+ }
+}
+
+void NetworkingPrivateProcessClient::OnNetworksChangedEvent(
+ const std::vector<std::string>& network_guids) {
+ FOR_EACH_OBSERVER(Observer,
+ network_events_observers_,
+ OnNetworksChangedEvent(network_guids));
+}
+
+void NetworkingPrivateProcessClient::OnNetworkListChangedEvent(
+ const std::vector<std::string>& network_guids) {
+ FOR_EACH_OBSERVER(Observer,
+ network_events_observers_,
+ OnNetworkListChangedEvent(network_guids));
+}
+
+void NetworkingPrivateProcessClient::OnSetPropertiesSucceeded(
+ MessageCallbacksID message_id,
+ const std::string& network_guid) {
+ MessageCallbacks* message_callbacks = callbacks_map_.Lookup(message_id);
+ if (message_callbacks != NULL) {
+ if (!message_callbacks->set_properties_callback.is_null())
+ message_callbacks->set_properties_callback.Run();
+ RemoveMessageCallbacks(message_id);
+ }
+}
+
+void NetworkingPrivateProcessClient::OnStartConnectSucceeded(
+ MessageCallbacksID message_id,
+ const std::string& network_guid) {
+ MessageCallbacks* message_callbacks = callbacks_map_.Lookup(message_id);
+ if (message_callbacks != NULL) {
+ if (!message_callbacks->start_connect_callback.is_null())
+ message_callbacks->start_connect_callback.Run();
+ RemoveMessageCallbacks(message_id);
+ }
+}
+
+void NetworkingPrivateProcessClient::OnStartDisconnectSucceeded(
+ MessageCallbacksID message_id,
+ const std::string& network_guid) {
+ MessageCallbacks* message_callbacks = callbacks_map_.Lookup(message_id);
+ if (message_callbacks != NULL) {
+ if (!message_callbacks->start_disconnect_callback.is_null())
+ message_callbacks->start_disconnect_callback.Run();
+ RemoveMessageCallbacks(message_id);
+ }
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698