diff options
-rw-r--r-- | remoting/client/chromoting_client.cc | 1 | ||||
-rw-r--r-- | remoting/client/client_config.h | 1 | ||||
-rw-r--r-- | remoting/client/client_user_interface.h | 6 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.cc | 50 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.h | 15 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_token_fetcher.cc | 40 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_token_fetcher.h | 44 | ||||
-rw-r--r-- | remoting/protocol/negotiating_authenticator_unittest.cc | 3 | ||||
-rw-r--r-- | remoting/protocol/negotiating_client_authenticator.cc | 19 | ||||
-rw-r--r-- | remoting/protocol/negotiating_client_authenticator.h | 10 | ||||
-rw-r--r-- | remoting/protocol/third_party_authenticator_unittest.cc | 4 | ||||
-rw-r--r-- | remoting/protocol/third_party_client_authenticator.cc | 4 | ||||
-rw-r--r-- | remoting/protocol/third_party_client_authenticator.h | 7 | ||||
-rw-r--r-- | remoting/remoting.gyp | 2 |
14 files changed, 189 insertions, 17 deletions
diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc index f9febdc..cf13d13 100644 --- a/remoting/client/chromoting_client.cc +++ b/remoting/client/chromoting_client.cc @@ -55,6 +55,7 @@ void ChromotingClient::Start( scoped_ptr<protocol::Authenticator> authenticator( new protocol::NegotiatingClientAuthenticator( config_.authentication_tag, config_.fetch_secret_callback, + user_interface_->GetTokenFetcher(config_.host_public_key), config_.authentication_methods)); // Create a WeakPtr to ourself for to use for all posted tasks. diff --git a/remoting/client/client_config.h b/remoting/client/client_config.h index a7e87e9..9b954d1 100644 --- a/remoting/client/client_config.h +++ b/remoting/client/client_config.h @@ -24,6 +24,7 @@ struct ClientConfig { std::string host_public_key; protocol::FetchSecretCallback fetch_secret_callback; + std::vector<protocol::AuthenticationMethod> authentication_methods; std::string authentication_tag; }; diff --git a/remoting/client/client_user_interface.h b/remoting/client/client_user_interface.h index 4b32a70..646c7c8 100644 --- a/remoting/client/client_user_interface.h +++ b/remoting/client/client_user_interface.h @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "remoting/protocol/connection_to_host.h" +#include "remoting/protocol/third_party_client_authenticator.h" namespace remoting { @@ -34,6 +35,11 @@ class ClientUserInterface { // Get the view's CursorShapeStub implementation. virtual protocol::CursorShapeStub* GetCursorShapeStub() = 0; + + // Get the view's TokenFetcher implementation. + // The TokenFetcher implementation may require interactive authentication. + virtual scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher> + GetTokenFetcher(const std::string& host_public_key) = 0; }; } // namespace remoting diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc index 1514466..fef612e 100644 --- a/remoting/client/plugin/chromoting_instance.cc +++ b/remoting/client/plugin/chromoting_instance.cc @@ -19,6 +19,7 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" #include "base/values.h" +#include "googleurl/src/gurl.h" #include "jingle/glue/thread_wrapper.h" #include "media/base/media.h" #include "net/socket/ssl_server_socket.h" @@ -35,6 +36,7 @@ #include "remoting/client/plugin/pepper_audio_player.h" #include "remoting/client/plugin/pepper_input_handler.h" #include "remoting/client/plugin/pepper_port_allocator.h" +#include "remoting/client/plugin/pepper_token_fetcher.h" #include "remoting/client/plugin/pepper_view.h" #include "remoting/client/plugin/pepper_xmpp_proxy.h" #include "remoting/client/rectangle_update_decoder.h" @@ -135,7 +137,7 @@ logging::LogMessageHandlerFunction g_logging_old_handler = NULL; const char ChromotingInstance::kApiFeatures[] = "highQualityScaling injectKeyEvent sendClipboardItem remapKey trapKey " "notifyClientDimensions notifyClientResolution pauseVideo pauseAudio " - "asyncPin"; + "asyncPin thirdPartyAuth"; bool ChromotingInstance::ParseAuthMethods(const std::string& auth_methods_str, ClientConfig* config) { @@ -395,6 +397,15 @@ void ChromotingInstance::HandleMessage(const pp::Var& message) { return; } OnPinFetched(pin); + } else if (method == "onThirdPartyTokenFetched") { + std::string token; + std::string shared_secret; + if (!data->GetString("token", &token) || + !data->GetString("sharedSecret", &shared_secret)) { + LOG(ERROR) << "Invalid onThirdPartyTokenFetched data."; + return; + } + OnThirdPartyTokenFetched(token, shared_secret); } } @@ -440,6 +451,23 @@ void ChromotingInstance::OnConnectionState( PostChromotingMessage("onConnectionStatus", data.Pass()); } +void ChromotingInstance::FetchThirdPartyToken( + const GURL& token_url, + const std::string& host_public_key, + const std::string& scope, + base::WeakPtr<PepperTokenFetcher> pepper_token_fetcher) { + // 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(!pepper_token_fetcher_); + pepper_token_fetcher_ = pepper_token_fetcher; + scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); + data->SetString("tokenUrl", token_url.spec()); + data->SetString("hostPublicKey", host_public_key); + data->SetString("scope", scope); + PostChromotingMessage("fetchThirdPartyToken", data.Pass()); +} + void ChromotingInstance::OnConnectionReady(bool ready) { scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); data->SetBoolean("ready", ready); @@ -475,6 +503,12 @@ protocol::CursorShapeStub* ChromotingInstance::GetCursorShapeStub() { return this; } +scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher> +ChromotingInstance::GetTokenFetcher(const std::string& host_public_key) { + return scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>( + new PepperTokenFetcher(this->AsWeakPtr(), host_public_key)); +} + void ChromotingInstance::InjectClipboardEvent( const protocol::ClipboardEvent& event) { scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); @@ -688,13 +722,23 @@ void ChromotingInstance::PauseAudio(bool pause) { audio_control.set_enable(!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."; + LOG(WARNING) << "Ignored OnPinFetched received without a pending fetch."; + } +} + +void ChromotingInstance::OnThirdPartyTokenFetched( + const std::string& token, + const std::string& shared_secret) { + if (pepper_token_fetcher_) { + pepper_token_fetcher_->OnTokenFetched(token, shared_secret); + pepper_token_fetcher_.reset(); + } else { + LOG(WARNING) << "Ignored OnThirdPartyTokenFetched without a pending fetch."; } } diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h index a57275a..c6c8f578f 100644 --- a/remoting/client/plugin/chromoting_instance.h +++ b/remoting/client/plugin/chromoting_instance.h @@ -40,6 +40,7 @@ #include "remoting/protocol/input_event_tracker.h" #include "remoting/protocol/mouse_input_filter.h" #include "remoting/protocol/negotiating_client_authenticator.h" +#include "remoting/protocol/third_party_client_authenticator.h" namespace base { class DictionaryValue; @@ -57,6 +58,7 @@ class ChromotingStats; class ClientContext; class FrameConsumerProxy; class PepperAudioPlayer; +class PepperTokenFetcher; class PepperView; class PepperXmppProxy; class RectangleUpdateDecoder; @@ -108,6 +110,8 @@ class ChromotingInstance : virtual void OnConnectionReady(bool ready) OVERRIDE; virtual protocol::ClipboardStub* GetClipboardStub() OVERRIDE; virtual protocol::CursorShapeStub* GetCursorShapeStub() OVERRIDE; + virtual scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher> + GetTokenFetcher(const std::string& host_public_key) OVERRIDE; // protocol::ClipboardStub interface. virtual void InjectClipboardEvent( @@ -147,6 +151,13 @@ class ChromotingInstance : static bool LogToUI(int severity, const char* file, int line, size_t message_start, const std::string& str); + // Requests the webapp to fetch a third-party token. + void FetchThirdPartyToken( + const GURL& token_url, + const std::string& host_public_key, + const std::string& scope, + const base::WeakPtr<PepperTokenFetcher> pepper_token_fetcher); + private: FRIEND_TEST_ALL_PREFIXES(ChromotingInstanceTest, TestCaseSetup); @@ -170,6 +181,8 @@ class ChromotingInstance : void PauseVideo(bool pause); void PauseAudio(bool pause); void OnPinFetched(const std::string& pin); + void OnThirdPartyTokenFetched(const std::string& token, + const std::string& shared_secret); // Helper method to post messages to the webapp. void PostChromotingMessage(const std::string& method, @@ -227,6 +240,8 @@ class ChromotingInstance : bool use_async_pin_dialog_; protocol::SecretFetchedCallback secret_fetched_callback_; + base::WeakPtr<PepperTokenFetcher> pepper_token_fetcher_; + base::WeakPtrFactory<ChromotingInstance> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ChromotingInstance); diff --git a/remoting/client/plugin/pepper_token_fetcher.cc b/remoting/client/plugin/pepper_token_fetcher.cc new file mode 100644 index 0000000..1127230 --- /dev/null +++ b/remoting/client/plugin/pepper_token_fetcher.cc @@ -0,0 +1,40 @@ +// 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 "remoting/client/plugin/pepper_token_fetcher.h" + +#include "remoting/client/plugin/chromoting_instance.h" + +namespace remoting { + +PepperTokenFetcher::PepperTokenFetcher(base::WeakPtr<ChromotingInstance> plugin, + const std::string& host_public_key) + : plugin_(plugin), + host_public_key_(host_public_key), + ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { +} + +PepperTokenFetcher::~PepperTokenFetcher() { +} + +void PepperTokenFetcher::FetchThirdPartyToken( + const GURL& token_url, + const std::string& scope, + const TokenFetchedCallback& token_fetched_callback) { + if (plugin_) { + token_fetched_callback_ = token_fetched_callback; + plugin_->FetchThirdPartyToken(token_url, host_public_key_, scope, + weak_factory_.GetWeakPtr()); + } +} + +void PepperTokenFetcher::OnTokenFetched( + const std::string& token, const std::string& shared_secret) { + if (!token_fetched_callback_.is_null()) { + token_fetched_callback_.Run(token, shared_secret); + token_fetched_callback_.Reset(); + } +} + +} // namespace remoting diff --git a/remoting/client/plugin/pepper_token_fetcher.h b/remoting/client/plugin/pepper_token_fetcher.h new file mode 100644 index 0000000..b914f51 --- /dev/null +++ b/remoting/client/plugin/pepper_token_fetcher.h @@ -0,0 +1,44 @@ +// 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. + +#ifndef REMOTING_CLIENT_PLUGIN_PEPPER_TOKEN_FETCHER_H_ +#define REMOTING_CLIENT_PLUGIN_PEPPER_TOKEN_FETCHER_H_ + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "remoting/protocol/third_party_client_authenticator.h" + +namespace remoting { + +class ChromotingInstance; + +class PepperTokenFetcher + : public protocol::ThirdPartyClientAuthenticator::TokenFetcher { + public: + PepperTokenFetcher(base::WeakPtr<ChromotingInstance> plugin, + const std::string& host_public_key); + virtual ~PepperTokenFetcher(); + + // protocol::TokenClientAuthenticator::TokenFetcher interface. + virtual void FetchThirdPartyToken( + const GURL& token_url, + const std::string& scope, + const TokenFetchedCallback& token_fetched_callback) OVERRIDE; + + // Called by ChromotingInstance when the webapp finishes fetching the token. + void OnTokenFetched(const std::string& token, + const std::string& shared_secret); + + private: + base::WeakPtr<ChromotingInstance> plugin_; + std::string host_public_key_; + TokenFetchedCallback token_fetched_callback_; + base::WeakPtrFactory<PepperTokenFetcher> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PepperTokenFetcher); +}; + +} // namespace remoting + +#endif // REMOTING_CLIENT_PLUGIN_PEPPER_TOKEN_FETCHER_H_ diff --git a/remoting/protocol/negotiating_authenticator_unittest.cc b/remoting/protocol/negotiating_authenticator_unittest.cc index e33b7d6..92047d6 100644 --- a/remoting/protocol/negotiating_authenticator_unittest.cc +++ b/remoting/protocol/negotiating_authenticator_unittest.cc @@ -61,7 +61,8 @@ class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { } client_.reset(new NegotiatingClientAuthenticator( kTestHostId, base::Bind(&NegotiatingAuthenticatorTest::FetchSecret, - client_secret), methods)); + client_secret), + scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher>(), methods)); } static void FetchSecret( diff --git a/remoting/protocol/negotiating_client_authenticator.cc b/remoting/protocol/negotiating_client_authenticator.cc index c7ab0f5..6210cef 100644 --- a/remoting/protocol/negotiating_client_authenticator.cc +++ b/remoting/protocol/negotiating_client_authenticator.cc @@ -21,10 +21,12 @@ namespace protocol { NegotiatingClientAuthenticator::NegotiatingClientAuthenticator( const std::string& authentication_tag, const FetchSecretCallback& fetch_secret_callback, + scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher, const std::vector<AuthenticationMethod>& methods) : NegotiatingAuthenticatorBase(MESSAGE_READY), authentication_tag_(authentication_tag), fetch_secret_callback_(fetch_secret_callback), + token_fetcher_(token_fetcher.Pass()), method_set_by_host_(false), weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { DCHECK(!methods.empty()); @@ -97,9 +99,20 @@ scoped_ptr<buzz::XmlElement> NegotiatingClientAuthenticator::GetNextMessage() { void NegotiatingClientAuthenticator::CreateAuthenticator( Authenticator::State preferred_initial_state, const base::Closure& resume_callback) { - fetch_secret_callback_.Run(base::Bind( - &NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret, - weak_factory_.GetWeakPtr(), preferred_initial_state, resume_callback)); + DCHECK(current_method_.is_valid()); + if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) { + // |ThirdPartyClientAuthenticator| takes ownership of |token_fetcher_|. + // The authentication method negotiation logic should guarantee that only + // one |ThirdPartyClientAuthenticator| will need to be created per session. + DCHECK(token_fetcher_); + current_authenticator_.reset(new ThirdPartyClientAuthenticator( + token_fetcher_.Pass())); + resume_callback.Run(); + } else { + fetch_secret_callback_.Run(base::Bind( + &NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret, + weak_factory_.GetWeakPtr(), preferred_initial_state, resume_callback)); + } } void NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret( diff --git a/remoting/protocol/negotiating_client_authenticator.h b/remoting/protocol/negotiating_client_authenticator.h index 0927bd7..d2047fe 100644 --- a/remoting/protocol/negotiating_client_authenticator.h +++ b/remoting/protocol/negotiating_client_authenticator.h @@ -14,6 +14,7 @@ #include "remoting/protocol/authentication_method.h" #include "remoting/protocol/authenticator.h" #include "remoting/protocol/negotiating_authenticator_base.h" +#include "remoting/protocol/third_party_client_authenticator.h" namespace remoting { namespace protocol { @@ -29,6 +30,7 @@ class NegotiatingClientAuthenticator : public NegotiatingAuthenticatorBase { NegotiatingClientAuthenticator( const std::string& authentication_tag, const FetchSecretCallback& fetch_secret_callback, + scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher_, const std::vector<AuthenticationMethod>& methods); virtual ~NegotiatingClientAuthenticator(); @@ -53,8 +55,16 @@ class NegotiatingClientAuthenticator : public NegotiatingAuthenticatorBase { const base::Closure& resume_callback, const std::string& shared_secret); + // Used for both authenticators. std::string authentication_tag_; + + // Used for shared secret authenticators. FetchSecretCallback fetch_secret_callback_; + + // Used for third party authenticators. + scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher_; + + // Internal NegotiatingClientAuthenticator data. bool method_set_by_host_; base::WeakPtrFactory<NegotiatingClientAuthenticator> weak_factory_; diff --git a/remoting/protocol/third_party_authenticator_unittest.cc b/remoting/protocol/third_party_authenticator_unittest.cc index fc95f82..b787a62 100644 --- a/remoting/protocol/third_party_authenticator_unittest.cc +++ b/remoting/protocol/third_party_authenticator_unittest.cc @@ -41,7 +41,6 @@ class ThirdPartyAuthenticatorTest : public AuthenticatorTestBase { public: virtual void FetchThirdPartyToken( const GURL& token_url, - const std::string& host_public_key, const std::string& scope, const TokenFetchedCallback& token_fetched_callback) OVERRIDE { ASSERT_EQ(token_url.spec(), kTokenUrl); @@ -113,8 +112,7 @@ class ThirdPartyAuthenticatorTest : public AuthenticatorTestBase { scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher(new FakeTokenFetcher()); token_fetcher_ = static_cast<FakeTokenFetcher*>(token_fetcher.get()); - client_.reset(new ThirdPartyClientAuthenticator( - host_public_key_, token_fetcher.Pass())); + client_.reset(new ThirdPartyClientAuthenticator(token_fetcher.Pass())); } FakeTokenFetcher* token_fetcher_; diff --git a/remoting/protocol/third_party_client_authenticator.cc b/remoting/protocol/third_party_client_authenticator.cc index 70a5c28..27d792b 100644 --- a/remoting/protocol/third_party_client_authenticator.cc +++ b/remoting/protocol/third_party_client_authenticator.cc @@ -19,10 +19,8 @@ namespace remoting { namespace protocol { ThirdPartyClientAuthenticator::ThirdPartyClientAuthenticator( - const std::string& host_public_key, scoped_ptr<TokenFetcher> token_fetcher) : ThirdPartyAuthenticatorBase(WAITING_MESSAGE), - host_public_key_(host_public_key), token_fetcher_(token_fetcher.Pass()) { } @@ -48,7 +46,7 @@ void ThirdPartyClientAuthenticator::ProcessTokenMessage( // |token_fetcher_| is owned, so Unretained() is safe here. token_fetcher_->FetchThirdPartyToken( - GURL(token_url), host_public_key_, token_scope, base::Bind( + GURL(token_url), token_scope, base::Bind( &ThirdPartyClientAuthenticator::OnThirdPartyTokenFetched, base::Unretained(this), resume_callback)); } diff --git a/remoting/protocol/third_party_client_authenticator.h b/remoting/protocol/third_party_client_authenticator.h index 0827c17..696d8a67 100644 --- a/remoting/protocol/third_party_client_authenticator.h +++ b/remoting/protocol/third_party_client_authenticator.h @@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" +#include "googleurl/src/gurl.h" #include "remoting/protocol/third_party_authenticator_base.h" class GURL; @@ -49,15 +50,14 @@ class ThirdPartyClientAuthenticator : public ThirdPartyAuthenticatorBase { // The request is canceled if the TokenFetcher is destroyed. virtual void FetchThirdPartyToken( const GURL& token_url, - const std::string& host_public_key, const std::string& scope, const TokenFetchedCallback& token_fetched_callback) = 0; }; // Creates a third-party client authenticator for the host with the given // |host_public_key|. |token_fetcher| is used to get the authentication token. - ThirdPartyClientAuthenticator(const std::string& host_public_key, - scoped_ptr<TokenFetcher> token_fetcher); + explicit ThirdPartyClientAuthenticator( + scoped_ptr<TokenFetcher> token_fetcher); virtual ~ThirdPartyClientAuthenticator(); protected: @@ -72,7 +72,6 @@ class ThirdPartyClientAuthenticator : public ThirdPartyAuthenticatorBase { const std::string& third_party_token, const std::string& shared_secret); - std::string host_public_key_; std::string token_; scoped_ptr<TokenFetcher> token_fetcher_; diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index ce276ca..596a737 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -1910,6 +1910,8 @@ 'client/plugin/pepper_plugin_thread_delegate.h', 'client/plugin/pepper_port_allocator.cc', 'client/plugin/pepper_port_allocator.h', + 'client/plugin/pepper_token_fetcher.cc', + 'client/plugin/pepper_token_fetcher.h', 'client/plugin/pepper_view.cc', 'client/plugin/pepper_view.h', 'client/plugin/pepper_util.cc', |