summaryrefslogtreecommitdiffstats
path: root/remoting/client
diff options
context:
space:
mode:
authorrmsousa@chromium.org <rmsousa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-23 18:39:13 +0000
committerrmsousa@chromium.org <rmsousa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-23 18:39:13 +0000
commit21257525cd0e90c87d1f94e8c18c3204229d9651 (patch)
tree0a00ca66eb7943607c100f4eb838d3ce19f5feda /remoting/client
parent2d401ff88410a222791306b4410d1d3ee60f6f20 (diff)
downloadchromium_src-21257525cd0e90c87d1f94e8c18c3204229d9651.zip
chromium_src-21257525cd0e90c87d1f94e8c18c3204229d9651.tar.gz
chromium_src-21257525cd0e90c87d1f94e8c18c3204229d9651.tar.bz2
Protocol / client plugin changes to support interactively asking for a PIN.
This has a few special cases, to be able to deal with all sorts of combinations of Me2Me/It2Me/old-plugin/old-webapp/old-host. The idea is: A webapp that supports asking for PINs asynchronously will explicitly notify the plugin of that. Older webapps (or It2Me) will send the passphrase directly on connect. The negotiating authenticator, instead of immediately trying to send the first SPAKE message, first sends a message with the supported methods to the host, and only when the host replies with the specific method it tries to create the authenticator. If there is a PinFetcher interface, it tries to use a PinClientAuthenticator (a thin layer on top of V2Authenticator that takes care of asynchronously asking for PIN), otherwise it uses V2Authenticator directly with the pre-provided pass phrase. This also adds support for authenticators that can't be created in a particular state (e.g. ones for which the first message must go in one particular direction). The NegotiatingAuthenticator takes care of sending blank messages/ignoring those messages as appropriate. BUG=115899 Review URL: https://chromiumcodereview.appspot.com/12518027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190056 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/client')
-rw-r--r--remoting/client/chromoting_client.cc4
-rw-r--r--remoting/client/client_config.h3
-rw-r--r--remoting/client/plugin/chromoting_instance.cc54
-rw-r--r--remoting/client/plugin/chromoting_instance.h45
4 files changed, 86 insertions, 20 deletions
diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc
index c0edb1b..c83002f 100644
--- a/remoting/client/chromoting_client.cc
+++ b/remoting/client/chromoting_client.cc
@@ -54,8 +54,8 @@ void ChromotingClient::Start(
scoped_ptr<protocol::Authenticator> authenticator(
protocol::NegotiatingAuthenticator::CreateForClient(
- config_.authentication_tag,
- config_.shared_secret, config_.authentication_methods));
+ config_.authentication_tag, config_.fetch_secret_callback,
+ config_.authentication_methods));
// Create a WeakPtr to ourself for to use for all posted tasks.
weak_ptr_ = weak_factory_.GetWeakPtr();
diff --git a/remoting/client/client_config.h b/remoting/client/client_config.h
index bf8474b..8cc67b3 100644
--- a/remoting/client/client_config.h
+++ b/remoting/client/client_config.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "remoting/protocol/authentication_method.h"
+#include "remoting/protocol/negotiating_authenticator.h"
namespace remoting {
@@ -22,7 +23,7 @@ struct ClientConfig {
std::string host_jid;
std::string host_public_key;
- std::string shared_secret;
+ protocol::FetchSecretCallback fetch_secret_callback;
std::vector<protocol::AuthenticationMethod> authentication_methods;
std::string authentication_tag;
};
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index 9247610..1514466 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -134,7 +134,8 @@ logging::LogMessageHandlerFunction g_logging_old_handler = NULL;
// String sent in the "hello" message to the plugin to describe features.
const char ChromotingInstance::kApiFeatures[] =
"highQualityScaling injectKeyEvent sendClipboardItem remapKey trapKey "
- "notifyClientDimensions notifyClientResolution pauseVideo pauseAudio";
+ "notifyClientDimensions notifyClientResolution pauseVideo pauseAudio "
+ "asyncPin";
bool ChromotingInstance::ParseAuthMethods(const std::string& auth_methods_str,
ClientConfig* config) {
@@ -171,6 +172,7 @@ ChromotingInstance::ChromotingInstance(PP_Instance pp_instance)
key_mapper_(&input_tracker_),
#endif
input_handler_(&key_mapper_),
+ use_async_pin_dialog_(false),
weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL);
RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
@@ -270,14 +272,25 @@ void ChromotingInstance::HandleMessage(const pp::Var& message) {
if (!data->GetString("hostJid", &config.host_jid) ||
!data->GetString("hostPublicKey", &config.host_public_key) ||
!data->GetString("localJid", &config.local_jid) ||
- !data->GetString("sharedSecret", &config.shared_secret) ||
!data->GetString("authenticationMethods", &auth_methods) ||
!ParseAuthMethods(auth_methods, &config) ||
!data->GetString("authenticationTag", &config.authentication_tag)) {
LOG(ERROR) << "Invalid connect() data.";
return;
}
-
+ if (use_async_pin_dialog_) {
+ config.fetch_secret_callback =
+ base::Bind(&ChromotingInstance::FetchSecretFromDialog,
+ this->AsWeakPtr());
+ } else {
+ std::string shared_secret;
+ if (!data->GetString("sharedSecret", &shared_secret)) {
+ LOG(ERROR) << "sharedSecret not specified in connect().";
+ return;
+ }
+ config.fetch_secret_callback =
+ base::Bind(&ChromotingInstance::FetchSecretFromString, shared_secret);
+ }
Connect(config);
} else if (method == "disconnect") {
Disconnect();
@@ -373,6 +386,15 @@ void ChromotingInstance::HandleMessage(const pp::Var& message) {
return;
}
PauseAudio(pause);
+ } else if (method == "useAsyncPinDialog") {
+ use_async_pin_dialog_ = true;
+ } else if (method == "onPinFetched") {
+ std::string pin;
+ if (!data->GetString("pin", &pin)) {
+ LOG(ERROR) << "Invalid onPinFetched.";
+ return;
+ }
+ OnPinFetched(pin);
}
}
@@ -424,6 +446,23 @@ void ChromotingInstance::OnConnectionReady(bool ready) {
PostChromotingMessage("onConnectionReady", data.Pass());
}
+void ChromotingInstance::FetchSecretFromDialog(
+ const protocol::SecretFetchedCallback& secret_fetched_callback) {
+ // Once the Session object calls this function, it won't continue the
+ // authentication until the callback is called (or connection is canceled).
+ // So, it's impossible to reach this with a callback already registered.
+ DCHECK(secret_fetched_callback_.is_null());
+ secret_fetched_callback_ = secret_fetched_callback;
+ scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue());
+ PostChromotingMessage("fetchPin", data.Pass());
+}
+
+void ChromotingInstance::FetchSecretFromString(
+ const std::string& shared_secret,
+ const protocol::SecretFetchedCallback& secret_fetched_callback) {
+ secret_fetched_callback.Run(shared_secret);
+}
+
protocol::ClipboardStub* ChromotingInstance::GetClipboardStub() {
// TODO(sergeyu): Move clipboard handling to a separate class.
// crbug.com/138108
@@ -650,6 +689,15 @@ void ChromotingInstance::PauseAudio(bool pause) {
host_connection_->host_stub()->ControlAudio(audio_control);
}
+void ChromotingInstance::OnPinFetched(const std::string& pin) {
+ if (!secret_fetched_callback_.is_null()) {
+ secret_fetched_callback_.Run(pin);
+ secret_fetched_callback_.Reset();
+ } else {
+ VLOG(1) << "Ignored OnPinFetched received without a pending fetch.";
+ }
+}
+
ChromotingStats* ChromotingInstance::GetStats() {
if (!client_.get())
return NULL;
diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h
index 9765f96..e814eaf 100644
--- a/remoting/client/plugin/chromoting_instance.h
+++ b/remoting/client/plugin/chromoting_instance.h
@@ -39,6 +39,7 @@
#include "remoting/protocol/cursor_shape_stub.h"
#include "remoting/protocol/input_event_tracker.h"
#include "remoting/protocol/mouse_input_filter.h"
+#include "remoting/protocol/negotiating_authenticator.h"
namespace base {
class DictionaryValue;
@@ -120,20 +121,6 @@ class ChromotingInstance :
void SetDesktopSize(const SkISize& size, const SkIPoint& dpi);
void OnFirstFrameReceived();
- // Message handlers for messages that come from JavaScript. Called
- // from HandleMessage().
- void Connect(const ClientConfig& config);
- void Disconnect();
- void OnIncomingIq(const std::string& iq);
- void ReleaseAllKeys();
- void InjectKeyEvent(const protocol::KeyEvent& event);
- void RemapKey(uint32 in_usb_keycode, uint32 out_usb_keycode);
- void TrapKey(uint32 usb_keycode, bool trap);
- void SendClipboardItem(const std::string& mime_type, const std::string& item);
- void NotifyClientResolution(int width, int height, int x_dpi, int y_dpi);
- void PauseVideo(bool pause);
- void PauseAudio(bool pause);
-
// Return statistics record by ChromotingClient.
// If no connection is currently active then NULL will be returned.
ChromotingStats* GetStats();
@@ -163,6 +150,27 @@ class ChromotingInstance :
private:
FRIEND_TEST_ALL_PREFIXES(ChromotingInstanceTest, TestCaseSetup);
+ // Used as the |FetchSecretCallback| for IT2Me (or Me2Me from old webapps).
+ // Immediately calls |secret_fetched_callback| with |shared_secret|.
+ static void FetchSecretFromString(
+ const std::string& shared_secret,
+ const protocol::SecretFetchedCallback& secret_fetched_callback);
+
+ // Message handlers for messages that come from JavaScript. Called
+ // from HandleMessage().
+ void Connect(const ClientConfig& config);
+ void Disconnect();
+ void OnIncomingIq(const std::string& iq);
+ void ReleaseAllKeys();
+ void InjectKeyEvent(const protocol::KeyEvent& event);
+ void RemapKey(uint32 in_usb_keycode, uint32 out_usb_keycode);
+ void TrapKey(uint32 usb_keycode, bool trap);
+ void SendClipboardItem(const std::string& mime_type, const std::string& item);
+ void NotifyClientResolution(int width, int height, int x_dpi, int y_dpi);
+ void PauseVideo(bool pause);
+ void PauseAudio(bool pause);
+ void OnPinFetched(const std::string& pin);
+
// Helper method to post messages to the webapp.
void PostChromotingMessage(const std::string& method,
scoped_ptr<base::DictionaryValue> data);
@@ -183,6 +191,11 @@ class ChromotingInstance :
// Returns true if there is a ConnectionToHost and it is connected.
bool IsConnected();
+ // Used as the |FetchSecretCallback| for Me2Me connections.
+ // Uses the PIN request dialog in the webapp to obtain the shared secret.
+ void FetchSecretFromDialog(
+ const protocol::SecretFetchedCallback& secret_fetched_callback);
+
bool initialized_;
PepperPluginThreadDelegate plugin_thread_delegate_;
@@ -210,6 +223,10 @@ class ChromotingInstance :
// connection.
scoped_refptr<PepperXmppProxy> xmpp_proxy_;
+ // PIN Fetcher.
+ bool use_async_pin_dialog_;
+ protocol::SecretFetchedCallback secret_fetched_callback_;
+
base::WeakPtrFactory<ChromotingInstance> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ChromotingInstance);