diff options
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/host/access_verifier.h | 35 | ||||
-rw-r--r-- | remoting/host/chromoting_host.cc | 23 | ||||
-rw-r--r-- | remoting/host/chromoting_host.h | 14 | ||||
-rw-r--r-- | remoting/host/chromoting_host_unittest.cc | 5 | ||||
-rw-r--r-- | remoting/host/host_mock_objects.cc | 4 | ||||
-rw-r--r-- | remoting/host/host_mock_objects.h | 13 | ||||
-rw-r--r-- | remoting/host/self_access_verifier.cc (renamed from remoting/host/access_verifier.cc) | 14 | ||||
-rw-r--r-- | remoting/host/self_access_verifier.h | 52 | ||||
-rw-r--r-- | remoting/host/self_access_verifier_unittest.cc (renamed from remoting/host/access_verifier_unittest.cc) | 12 | ||||
-rw-r--r-- | remoting/host/simple_host_process.cc | 26 | ||||
-rw-r--r-- | remoting/host/support_access_verifier.cc | 66 | ||||
-rw-r--r-- | remoting/host/support_access_verifier.h | 40 | ||||
-rw-r--r-- | remoting/protocol/auth_token_utils.cc | 55 | ||||
-rw-r--r-- | remoting/protocol/auth_token_utils.h | 25 | ||||
-rw-r--r-- | remoting/protocol/connection_to_host.cc | 29 | ||||
-rw-r--r-- | remoting/protocol/connection_to_host.h | 5 | ||||
-rw-r--r-- | remoting/protocol/jingle_session_manager.cc | 82 | ||||
-rw-r--r-- | remoting/remoting.gyp | 9 |
18 files changed, 399 insertions, 110 deletions
diff --git a/remoting/host/access_verifier.h b/remoting/host/access_verifier.h index 85c314c..00a8d66 100644 --- a/remoting/host/access_verifier.h +++ b/remoting/host/access_verifier.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -11,35 +11,16 @@ namespace remoting { -namespace protocol { -class ClientAuthToken; -} // namespace protocol - -class HostConfig; - -// AccessVerifier is used by to verify that the client has access to the host. -// Currently it -// -// 1) Checks that host and client have the same bare JID. -// 2) Verifies that the access token can be decoded. -// -// TODO(sergeyu): Remove the bare-JID check, and instead ask the directory to -// perform user authorization. +// AccessVerifier is used by ChromotingHost to verify that access to +// the host. There are two implementations: SelfAccessVerifier is used +// in the Me2Me scenario, SupportAccessVerifier is used for Me2Mom. class AccessVerifier { public: - AccessVerifier(); - bool Init(HostConfig* config); - bool VerifyPermissions(const std::string& client_jid, - const std::string& encoded_client_token); - - private: - bool DecodeClientAuthToken(const std::string& encoded_client_token, - protocol::ClientAuthToken* client_token); - - std::string host_jid_prefix_; - bool initialized_; + AccessVerifier() { } + virtual ~AccessVerifier() { } - DISALLOW_COPY_AND_ASSIGN(AccessVerifier); + virtual bool VerifyPermissions(const std::string& client_jid, + const std::string& encoded_client_token) = 0; }; } // namespace remoting diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index ceca4f6..270c845 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -33,28 +33,33 @@ namespace remoting { // static ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, - MutableHostConfig* config) { + MutableHostConfig* config, + AccessVerifier* access_verifier) { Capturer* capturer = Capturer::Create(); EventExecutor* event_executor = EventExecutor::Create(context->ui_message_loop(), capturer); Curtain* curtain = Curtain::Create(); return Create(context, config, - new DesktopEnvironment(capturer, event_executor, curtain)); + new DesktopEnvironment(capturer, event_executor, curtain), + access_verifier); } // static ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, MutableHostConfig* config, - DesktopEnvironment* environment) { - return new ChromotingHost(context, config, environment); + DesktopEnvironment* environment, + AccessVerifier* access_verifier) { + return new ChromotingHost(context, config, environment, access_verifier); } ChromotingHost::ChromotingHost(ChromotingHostContext* context, MutableHostConfig* config, - DesktopEnvironment* environment) + DesktopEnvironment* environment, + AccessVerifier* access_verifier) : context_(context), config_(config), desktop_environment_(environment), + access_verifier_(access_verifier), state_(kInitial), protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), is_curtained_(false) { @@ -74,6 +79,7 @@ void ChromotingHost::Start(Task* shutdown_task) { DCHECK(!jingle_client_); DCHECK(shutdown_task); + DCHECK(access_verifier_.get()); // Make sure this object is not started. { @@ -94,9 +100,6 @@ void ChromotingHost::Start(Task* shutdown_task) { return; } - if (!access_verifier_.Init(config_)) - return; - // Connect to the talk network with a JingleClient. signal_strategy_.reset( new XmppSignalStrategy(context_->jingle_thread(), xmpp_login, @@ -265,8 +268,8 @@ void ChromotingHost::OnNewClientSession( } // Check that the client has access to the host. - if (!access_verifier_.VerifyPermissions(session->jid(), - session->initiator_token())) { + if (!access_verifier_->VerifyPermissions(session->jid(), + session->initiator_token())) { *response = protocol::SessionManager::DECLINE; return; } diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index 4666bcb..99f1fd7 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -70,10 +70,12 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // Factory methods that must be used to create ChromotingHost instances. // Default capturer and input stub are used if it is not specified. static ChromotingHost* Create(ChromotingHostContext* context, - MutableHostConfig* config); + MutableHostConfig* config, + AccessVerifier* access_verifier); static ChromotingHost* Create(ChromotingHostContext* context, MutableHostConfig* config, - DesktopEnvironment* environment); + DesktopEnvironment* environment, + AccessVerifier* access_verifier); // Asynchronously start the host process. // @@ -126,8 +128,10 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, typedef std::vector<scoped_refptr<HostStatusObserver> > StatusObserverList; typedef std::vector<scoped_refptr<ClientSession> > ClientList; - ChromotingHost(ChromotingHostContext* context, MutableHostConfig* config, - DesktopEnvironment* environment); + ChromotingHost(ChromotingHostContext* context, + MutableHostConfig* config, + DesktopEnvironment* environment, + AccessVerifier* access_verifier); virtual ~ChromotingHost(); enum State { @@ -168,7 +172,7 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, StatusObserverList status_observers_; - AccessVerifier access_verifier_; + scoped_ptr<AccessVerifier> access_verifier_; // The connections to remote clients. ClientList clients_; diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index ea8dbb4..450267a 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc @@ -89,7 +89,10 @@ class ChromotingHostTest : public testing::Test { curtain_ = new MockCurtain(); DesktopEnvironment* desktop = new DesktopEnvironment(capturer, event_executor_, curtain_); - host_ = ChromotingHost::Create(&context_, config_, desktop); + MockAccessVerifier* access_verifier = new MockAccessVerifier(); + + host_ = ChromotingHost::Create(&context_, config_, + desktop, access_verifier); credentials_.set_type(protocol::PASSWORD); credentials_.set_username("user"); credentials_.set_credential("password"); diff --git a/remoting/host/host_mock_objects.cc b/remoting/host/host_mock_objects.cc index f47a284..41acc0d 100644 --- a/remoting/host/host_mock_objects.cc +++ b/remoting/host/host_mock_objects.cc @@ -35,4 +35,8 @@ MockUserAuthenticator::MockUserAuthenticator() {} MockUserAuthenticator::~MockUserAuthenticator() {} +MockAccessVerifier::MockAccessVerifier() {} + +MockAccessVerifier::~MockAccessVerifier() {} + } // namespace remoting diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index 58d6381..25ac953 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -5,6 +5,7 @@ #ifndef REMOTING_HOST_HOST_MOCK_OBJECTS_H_ #define REMOTING_HOST_HOST_MOCK_OBJECTS_H_ +#include "remoting/host/access_verifier.h" #include "remoting/host/capturer.h" #include "remoting/host/curtain.h" #include "remoting/host/chromoting_host_context.h" @@ -97,6 +98,18 @@ class MockUserAuthenticator : public UserAuthenticator { DISALLOW_COPY_AND_ASSIGN(MockUserAuthenticator); }; +class MockAccessVerifier : public AccessVerifier { + public: + MockAccessVerifier(); + virtual ~MockAccessVerifier(); + + MOCK_METHOD2(VerifyPermissions, bool(const std::string& client_jid, + const std::string& token)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockAccessVerifier); +}; + } // namespace remoting #endif // REMOTING_HOST_HOST_MOCK_OBJECTS_H_ diff --git a/remoting/host/access_verifier.cc b/remoting/host/self_access_verifier.cc index 9e37da3..a4564ea 100644 --- a/remoting/host/access_verifier.cc +++ b/remoting/host/self_access_verifier.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/host/access_verifier.h" +#include "remoting/host/self_access_verifier.h" #include "base/logging.h" #include "base/string_util.h" @@ -11,11 +11,13 @@ namespace remoting { -AccessVerifier::AccessVerifier() +SelfAccessVerifier::SelfAccessVerifier() : initialized_(false) { } -bool AccessVerifier::Init(HostConfig* config) { +SelfAccessVerifier::~SelfAccessVerifier() { } + +bool SelfAccessVerifier::Init(HostConfig* config) { std::string host_jid; if (!config->GetString(kXmppLoginConfigPath, &host_jid) || @@ -30,7 +32,7 @@ bool AccessVerifier::Init(HostConfig* config) { return true; } -bool AccessVerifier::VerifyPermissions( +bool SelfAccessVerifier::VerifyPermissions( const std::string& client_jid, const std::string& encoded_access_token) { CHECK(initialized_); @@ -60,7 +62,7 @@ bool AccessVerifier::VerifyPermissions( return true; } -bool AccessVerifier::DecodeClientAuthToken( +bool SelfAccessVerifier::DecodeClientAuthToken( const std::string& encoded_client_token, protocol::ClientAuthToken* client_token) { // TODO(ajwong): Implement this. diff --git a/remoting/host/self_access_verifier.h b/remoting/host/self_access_verifier.h new file mode 100644 index 0000000..29b07ed --- /dev/null +++ b/remoting/host/self_access_verifier.h @@ -0,0 +1,52 @@ +// Copyright (c) 2011 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_HOST_SELF_ACCESS_VERIFIER_H_ +#define REMOTING_HOST_SELF_ACCESS_VERIFIER_H_ + +#include "remoting/host/access_verifier.h" + +#include "base/compiler_specific.h" + +namespace remoting { + +class HostConfig; + +namespace protocol { +class ClientAuthToken; +} // namespace protocol + +// SelfAccessVerifier is used by to verify that the client has access +// to the host in the Me2Me scenario. Currently it +// +// 1) Checks that host and client have the same bare JID. +// 2) Verifies that the access token can be decoded. +// +// TODO(sergeyu): Remove the bare-JID check, and instead ask the directory to +// perform user authorization. +class SelfAccessVerifier : public AccessVerifier { + public: + SelfAccessVerifier(); + virtual ~SelfAccessVerifier(); + + bool Init(HostConfig* config); + + // AccessVerifier interface. + virtual bool VerifyPermissions( + const std::string& client_jid, + const std::string& encoded_client_token) OVERRIDE; + + private: + bool DecodeClientAuthToken(const std::string& encoded_client_token, + protocol::ClientAuthToken* client_token); + + std::string host_jid_prefix_; + bool initialized_; + + DISALLOW_COPY_AND_ASSIGN(SelfAccessVerifier); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_SELF_ACCESS_VERIFIER_H_ diff --git a/remoting/host/access_verifier_unittest.cc b/remoting/host/self_access_verifier_unittest.cc index 1e1bebe..f0fd179 100644 --- a/remoting/host/access_verifier_unittest.cc +++ b/remoting/host/self_access_verifier_unittest.cc @@ -4,8 +4,8 @@ #include "base/memory/ref_counted.h" #include "base/task.h" -#include "remoting/host/access_verifier.h" #include "remoting/host/in_memory_host_config.h" +#include "remoting/host/self_access_verifier.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -15,7 +15,7 @@ namespace { const char kTestJid[] = "host@domain.com"; } // namespace -class AccessVerifierTest : public testing::Test { +class SelfAccessVerifierTest : public testing::Test { protected: virtual void SetUp() { config_ = new InMemoryHostConfig(); @@ -28,13 +28,13 @@ class AccessVerifierTest : public testing::Test { scoped_refptr<InMemoryHostConfig> config_; }; -TEST_F(AccessVerifierTest, InvalidConfig) { - AccessVerifier target; +TEST_F(SelfAccessVerifierTest, InvalidConfig) { + SelfAccessVerifier target; EXPECT_FALSE(target.Init(config_)); } -TEST_F(AccessVerifierTest, VerifyPermissions) { - AccessVerifier target; +TEST_F(SelfAccessVerifierTest, VerifyPermissions) { + SelfAccessVerifier target; InitConfig(); ASSERT_TRUE(target.Init(config_)); EXPECT_TRUE(target.VerifyPermissions("host@domain.com/123123", "")); diff --git a/remoting/host/simple_host_process.cc b/remoting/host/simple_host_process.cc index ffd53ce..d423c06 100644 --- a/remoting/host/simple_host_process.cc +++ b/remoting/host/simple_host_process.cc @@ -40,6 +40,8 @@ #include "remoting/host/heartbeat_sender.h" #include "remoting/host/json_host_config.h" #include "remoting/host/register_support_host_request.h" +#include "remoting/host/self_access_verifier.h" +#include "remoting/host/support_access_verifier.h" #include "remoting/proto/video.pb.h" #if defined(TOOLKIT_USES_GTK) @@ -105,6 +107,24 @@ class SimpleHost { return 1; } + // Initialize AccessVerifier. + scoped_ptr<remoting::AccessVerifier> access_verifier; + if (me2mom_) { + scoped_ptr<remoting::SupportAccessVerifier> support_access_verifier( + new remoting::SupportAccessVerifier()); + if (!support_access_verifier->Init()) + return 1; + std::cout << "Access Code: " + << support_access_verifier->access_code() << std::endl; + access_verifier.reset(support_access_verifier.release()); + } else { + scoped_ptr<remoting::SelfAccessVerifier> self_access_verifier( + new remoting::SelfAccessVerifier()); + if (!self_access_verifier->Init(config)) + return 1; + access_verifier.reset(self_access_verifier.release()); + } + // Construct a chromoting host. scoped_refptr<ChromotingHost> host; if (fake_) { @@ -115,9 +135,11 @@ class SimpleHost { remoting::Curtain* curtain = remoting::Curtain::Create(); host = ChromotingHost::Create( &context, config, - new DesktopEnvironment(capturer, event_executor, curtain)); + new DesktopEnvironment(capturer, event_executor, curtain), + access_verifier.release()); } else { - host = ChromotingHost::Create(&context, config); + host = ChromotingHost::Create(&context, config, + access_verifier.release()); } if (protocol_config_.get()) { diff --git a/remoting/host/support_access_verifier.cc b/remoting/host/support_access_verifier.cc new file mode 100644 index 0000000..e3bc8ae --- /dev/null +++ b/remoting/host/support_access_verifier.cc @@ -0,0 +1,66 @@ +// Copyright (c) 2011 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/host/support_access_verifier.h" + +#include <stdlib.h> + +#include "base/logging.h" +#include "base/rand_util.h" +#include "base/string_util.h" +#include "remoting/host/host_config.h" +#include "remoting/protocol/auth_token_utils.h" + +namespace remoting { + +namespace { +// 5 characters long from 34-letter alphabet gives 4.5M possible +// access codes with uniform distribution, which should be enough +// for short-term passwords. +const int kAccessCodeLength = 5; + +// The following set includes 10 digits and Latin alphabet except I +// and O. I and O are not used to avoid confusion with 1 and 0. +const char kAccessCodeAlphabet[] = "ABCDEFGHJKLMNPQRSTUVWXYZ0123456789"; + +// Generates cryptographically strong random number in the range [0, max). +int CryptoRandomInt(int max) { + uint32 random_int32; + base::RandBytes(&random_int32, sizeof(random_int32)); + return random_int32 % max; +} + +std::string GenerateRandomAccessCode() { + std::vector<char> result; + int alphabet_size = strlen(kAccessCodeAlphabet); + result.resize(kAccessCodeLength); + for (int i = 0; i < kAccessCodeLength; ++i) { + result[i] = kAccessCodeAlphabet[CryptoRandomInt(alphabet_size)]; + } + return std::string(result.begin(), result.end()); +} + +} // namespace + +SupportAccessVerifier::SupportAccessVerifier() + : initialized_(false) { +} + +SupportAccessVerifier::~SupportAccessVerifier() { } + +bool SupportAccessVerifier::Init() { + access_code_ = GenerateRandomAccessCode(); + initialized_ = true; + return true; +} + +bool SupportAccessVerifier::VerifyPermissions( + const std::string& client_jid, + const std::string& encoded_access_token) { + CHECK(initialized_); + return protocol::VerifySupportAuthToken( + client_jid, access_code_, encoded_access_token); +} + +} // namespace remoting diff --git a/remoting/host/support_access_verifier.h b/remoting/host/support_access_verifier.h new file mode 100644 index 0000000..74dda27 --- /dev/null +++ b/remoting/host/support_access_verifier.h @@ -0,0 +1,40 @@ +// Copyright (c) 2011 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_HOST_SUPPORT_ACCESS_VERIFIER_H_ +#define REMOTING_HOST_SUPPORT_ACCESS_VERIFIER_H_ + +#include "remoting/host/access_verifier.h" + +#include "base/compiler_specific.h" + +namespace remoting { + +class HostConfig; + +// SupportAccessVerifier is used in Me2Mom scenario to verify that the +// client has access code for the host. +class SupportAccessVerifier : public AccessVerifier { + public: + SupportAccessVerifier(); + virtual ~SupportAccessVerifier(); + + bool Init(); + const std::string& access_code() const { return access_code_; } + + // AccessVerifier interface. + virtual bool VerifyPermissions( + const std::string& client_jid, + const std::string& encoded_client_token) OVERRIDE; + + private: + bool initialized_; + std::string access_code_; + + DISALLOW_COPY_AND_ASSIGN(SupportAccessVerifier); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_SUPPORT_ACCESS_VERIFIER_H_ diff --git a/remoting/protocol/auth_token_utils.cc b/remoting/protocol/auth_token_utils.cc new file mode 100644 index 0000000..29728f3 --- /dev/null +++ b/remoting/protocol/auth_token_utils.cc @@ -0,0 +1,55 @@ +// Copyright (c) 2011 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/protocol/auth_token_utils.h" + +#include "base/base64.h" +#include "base/logging.h" +#include "base/string_util.h" +#include "crypto/sha2.h" + +namespace remoting { +namespace protocol { + +namespace { + +// Normalizes access code. Must be applied on the access code entered +// by the user before generating auth token. It (1)converts the string +// to upper case, (2) replaces O with 0 and (3) replaces I with 1. +std::string NormalizeAccessCode(const std::string& access_code) { + std::string normalized = access_code; + StringToUpperASCII(&normalized); + for (std::string::iterator i = normalized.begin(); + i != normalized.end(); ++i) { + if (*i == 'O') { + *i = '0'; + } else if (*i == 'I') { + *i = '1'; + } + } + return normalized; +} + +} // namespace + +std::string GenerateSupportAuthToken(const std::string& jid, + const std::string& access_code) { + std::string sha256 = crypto::SHA256HashString(jid + " " + access_code); + std::string sha256_base64; + if (!base::Base64Encode(sha256, &sha256_base64)) { + LOG(FATAL) << "Failed to encode auth token"; + } + return sha256_base64; +} + +bool VerifySupportAuthToken(const std::string& jid, + const std::string& access_code, + const std::string& auth_token) { + std::string expected_token = + GenerateSupportAuthToken(jid, NormalizeAccessCode(access_code)); + return expected_token == auth_token; +} + +} // namespace protocol +} // namespace remoting diff --git a/remoting/protocol/auth_token_utils.h b/remoting/protocol/auth_token_utils.h new file mode 100644 index 0000000..9be1170 --- /dev/null +++ b/remoting/protocol/auth_token_utils.h @@ -0,0 +1,25 @@ +// Copyright (c) 2011 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_PROTOCOL_AUTH_TOKEN_UTILS_H_ +#define REMOTING_PROTOCOL_AUTH_TOKEN_UTILS_H_ + +#include <string> + +namespace remoting { +namespace protocol { + +// Generates auth token for the specified |jid| and |access_code|. +std::string GenerateSupportAuthToken(const std::string& jid, + const std::string& access_code); + +// Verifies validity of an |access_token|. +bool VerifySupportAuthToken(const std::string& jid, + const std::string& access_code, + const std::string& auth_token); + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_AUTH_TOKEN_UTILS_H_ diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc index 2d46cd9..f4a82f3 100644 --- a/remoting/protocol/connection_to_host.cc +++ b/remoting/protocol/connection_to_host.cc @@ -9,7 +9,7 @@ #include "remoting/base/constants.h" #include "remoting/jingle_glue/http_port_allocator.h" #include "remoting/jingle_glue/jingle_thread.h" -#include "remoting/proto/auth.pb.h" +#include "remoting/protocol/auth_token_utils.h" #include "remoting/protocol/client_message_dispatcher.h" #include "remoting/protocol/client_stub.h" #include "remoting/protocol/host_control_sender.h" @@ -56,15 +56,14 @@ MessageLoop* ConnectionToHost::message_loop() { void ConnectionToHost::Connect(const std::string& username, const std::string& auth_token, const std::string& host_jid, - const std::string& nonce, + const std::string& access_code, HostEventCallback* event_callback, ClientStub* client_stub, VideoStub* video_stub) { event_callback_ = event_callback; client_stub_ = client_stub; video_stub_ = video_stub; - - NOTIMPLEMENTED() << "Nonce ignored."; + access_code_ = access_code; // Initialize |jingle_client_|. signal_strategy_.reset( @@ -84,15 +83,14 @@ void ConnectionToHost::Connect(const std::string& username, void ConnectionToHost::ConnectSandboxed(scoped_refptr<XmppProxy> xmpp_proxy, const std::string& your_jid, const std::string& host_jid, - const std::string& nonce, + const std::string& access_code, HostEventCallback* event_callback, ClientStub* client_stub, VideoStub* video_stub) { event_callback_ = event_callback; client_stub_ = client_stub; video_stub_ = video_stub; - - NOTIMPLEMENTED() << "Nonce ignored."; + access_code_ = access_code; // Initialize |jingle_client_|. JavascriptSignalStrategy* strategy = new JavascriptSignalStrategy(your_jid); @@ -127,31 +125,24 @@ void ConnectionToHost::Disconnect() { void ConnectionToHost::InitSession() { DCHECK_EQ(message_loop(), MessageLoop::current()); + std::string jid = jingle_client_->GetFullJid(); + // Initialize chromotocol |session_manager_|. JingleSessionManager* session_manager = new JingleSessionManager(thread_); // TODO(ajwong): Make this a command switch when we're more stable. session_manager->set_allow_local_ips(true); session_manager->Init( - jingle_client_->GetFullJid(), - jingle_client_->session_manager(), + jid, jingle_client_->session_manager(), NewCallback(this, &ConnectionToHost::OnNewSession), NULL, NULL); session_manager_ = session_manager; CandidateSessionConfig* candidate_config = CandidateSessionConfig::CreateDefault(); - // TODO(sergeyu): Set resolution in the |candidate_config| to the desired - // resolution. - - ClientAuthToken auth_token_proto; - auth_token_proto.set_host_full_jid(host_jid_); - auth_token_proto.set_client_full_jid(jingle_client_->GetFullJid()); - // TODO(ajwong): Use real token. - auth_token_proto.set_client_oauth_token(""); - // TODO(ajwong): We should encrypt this based on the host's public key. - std::string client_token = auth_token_proto.SerializeAsString(); + std::string client_token = + protocol::GenerateSupportAuthToken(jid, access_code_); // Initialize |session_|. session_ = session_manager_->Connect( diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h index 5aeb070..ac88645 100644 --- a/remoting/protocol/connection_to_host.h +++ b/remoting/protocol/connection_to_host.h @@ -74,14 +74,14 @@ class ConnectionToHost : public JingleClient::Callback { virtual void Connect(const std::string& username, const std::string& auth_token, const std::string& host_jid, - const std::string& nonce, + const std::string& access_code, HostEventCallback* event_callback, ClientStub* client_stub, VideoStub* video_stub); virtual void ConnectSandboxed(scoped_refptr<XmppProxy> xmpp_proxy, const std::string& your_jid, const std::string& host_jid, - const std::string& nonce, + const std::string& access_code, HostEventCallback* event_callback, ClientStub* client_stub, VideoStub* video_stub); @@ -145,6 +145,7 @@ class ConnectionToHost : public JingleClient::Callback { HostEventCallback* event_callback_; std::string host_jid_; + std::string access_code_; scoped_ptr<ClientMessageDispatcher> dispatcher_; diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc index 9a1827b..f0a0a04 100644 --- a/remoting/protocol/jingle_session_manager.cc +++ b/remoting/protocol/jingle_session_manager.cc @@ -37,6 +37,7 @@ const char kVideoTag[] = "video"; const char kResolutionTag[] = "initial-resolution"; const char kAuthenticationTag[] = "authentication"; const char kCertificateTag[] = "certificate"; +const char kAuthTokenTag[] = "auth-token"; const char kTransportAttr[] = "transport"; const char kVersionAttr[] = "version"; @@ -329,6 +330,7 @@ void JingleSessionManager::AcceptConnection( const ContentDescription* content_description = static_cast<const ContentDescription*>(content->description); jingle_session->set_candidate_config(content_description->config()->Clone()); + jingle_session->set_initiator_token(content_description->auth_token()); // Always reject connection if there is no callback. IncomingSessionResponse response = protocol::SessionManager::DECLINE; @@ -429,30 +431,36 @@ bool JingleSessionManager::ParseContent( *config->mutable_initial_resolution() = resolution; - std::string auth_token; - // TODO(ajwong): Parse this out. - - // Parse the certificate. + // Parse authentication information. scoped_refptr<net::X509Certificate> certificate; + std::string auth_token; child = element->FirstNamed(QName(kChromotingXmlNamespace, kAuthenticationTag)); if (child) { - child = child->FirstNamed(QName(kChromotingXmlNamespace, - kCertificateTag)); - } - if (child) { - std::string base64_cert = child->BodyText(); - std::string der_cert; - if (!base::Base64Decode(base64_cert, &der_cert)) { - LOG(ERROR) << "Failed to decode certificate received from the peer."; - return false; + // Parse the certificate. + const XmlElement* cert_tag = + child->FirstNamed(QName(kChromotingXmlNamespace, kCertificateTag)); + if (cert_tag) { + std::string base64_cert = cert_tag->BodyText(); + std::string der_cert; + if (!base::Base64Decode(base64_cert, &der_cert)) { + LOG(ERROR) << "Failed to decode certificate received from the peer."; + return false; + } + + certificate = net::X509Certificate::CreateFromBytes(der_cert.data(), + der_cert.length()); + if (!certificate) { + LOG(ERROR) << "Failed to create platform-specific certificate handle"; + return false; + } } - certificate = net::X509Certificate::CreateFromBytes(der_cert.data(), - der_cert.length()); - if (!certificate) { - LOG(ERROR) << "Failed to create platform-specific certificate handle"; - return false; + // Parse auth-token. + const XmlElement* auth_token_tag = + child->FirstNamed(QName(kChromotingXmlNamespace, kAuthTokenTag)); + if (auth_token_tag) { + auth_token = auth_token_tag->BodyText(); } } @@ -473,7 +481,8 @@ bool JingleSessionManager::ParseContent( // <initial-resolution width="800" height="600" /> // <authentication> // <certificate>[BASE64 Encoded Certificate]</certificate> -// </authentication>" /> +// <auth-token>...</auth-token> // Me2Mom only. +// </authentication> // </description> // bool JingleSessionManager::WriteContent( @@ -515,22 +524,35 @@ bool JingleSessionManager::WriteContent( config->initial_resolution().height)); root->AddElement(resolution_tag); - if (desc->certificate()) { + if (desc->certificate() || !desc->auth_token().empty()) { XmlElement* authentication_tag = new XmlElement( QName(kChromotingXmlNamespace, kAuthenticationTag)); - XmlElement* certificate_tag = new XmlElement( - QName(kChromotingXmlNamespace, kCertificateTag)); - std::string der_cert; - bool ret = desc->certificate()->GetDEREncoded(&der_cert); - DCHECK(ret) << "Cannot obtain DER encoded certificate"; + if (desc->certificate()) { + XmlElement* certificate_tag = new XmlElement( + QName(kChromotingXmlNamespace, kCertificateTag)); - std::string base64_cert; - ret = base::Base64Encode(der_cert, &base64_cert); - DCHECK(ret) << "Cannot perform base64 encode on certificate"; + std::string der_cert; + if (!desc->certificate()->GetDEREncoded(&der_cert)) { + LOG(DFATAL) << "Cannot obtain DER encoded certificate"; + } + + std::string base64_cert; + if (!base::Base64Encode(der_cert, &base64_cert)) { + LOG(DFATAL) << "Cannot perform base64 encode on certificate"; + } + + certificate_tag->SetBodyText(base64_cert); + authentication_tag->AddElement(certificate_tag); + } + + if (!desc->auth_token().empty()) { + XmlElement* auth_token_tag = new XmlElement( + QName(kChromotingXmlNamespace, kAuthTokenTag)); + auth_token_tag->SetBodyText(desc->auth_token()); + authentication_tag->AddElement(auth_token_tag); + } - certificate_tag->SetBodyText(base64_cert); - authentication_tag->AddElement(certificate_tag); root->AddElement(authentication_tag); } diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 980a260..d486f08 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -241,7 +241,6 @@ '../crypto/crypto.gyp:crypto', ], 'sources': [ - 'host/access_verifier.cc', 'host/access_verifier.h', 'host/capturer.h', 'host/capturer_helper.cc', @@ -282,8 +281,12 @@ 'host/json_host_config.h', 'host/register_support_host_request.cc', 'host/register_support_host_request.h', + 'host/self_access_verifier.cc', + 'host/self_access_verifier.h', 'host/screen_recorder.cc', 'host/screen_recorder.h', + 'host/support_access_verifier.cc', + 'host/support_access_verifier.h', 'host/user_authenticator.h', 'host/user_authenticator_linux.cc', 'host/user_authenticator_mac.cc', @@ -427,6 +430,8 @@ 'chromoting_jingle_glue', ], 'sources': [ + 'protocol/auth_token_utils.cc', + 'protocol/auth_token_utils.h', 'protocol/buffered_socket_writer.cc', 'protocol/buffered_socket_writer.h', 'protocol/client_control_sender.cc', @@ -575,7 +580,6 @@ 'base/base_mock_objects.cc', 'base/base_mock_objects.h', # BUG57351 'client/chromoting_view_unittest.cc', - 'host/access_verifier_unittest.cc', 'host/capturer_linux_unittest.cc', 'host/capturer_mac_unittest.cc', 'host/capturer_win_unittest.cc', @@ -590,6 +594,7 @@ 'host/host_mock_objects.h', 'host/json_host_config_unittest.cc', 'host/register_support_host_request_unittest.cc', + 'host/self_access_verifier_unittest.cc', 'host/screen_recorder_unittest.cc', 'host/test_key_pair.h', 'jingle_glue/iq_request_unittest.cc', |