diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 02:05:06 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 02:05:06 +0000 |
commit | 76451fe7fbce667742dff671cad06cbd039f8296 (patch) | |
tree | 0b2196989e5bb6643a026eb71964cbfaa2b66feb /remoting/host | |
parent | e8478ae4ef8bd1dbb83cd46e8af060d5331ba2df (diff) | |
download | chromium_src-76451fe7fbce667742dff671cad06cbd039f8296.zip chromium_src-76451fe7fbce667742dff671cad06cbd039f8296.tar.gz chromium_src-76451fe7fbce667742dff671cad06cbd039f8296.tar.bz2 |
Basic user access check for chromoting host.
BUG=53984
TEST=unittests
Review URL: http://codereview.chromium.org/3303001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58301 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host')
-rw-r--r-- | remoting/host/access_verifier.cc | 39 | ||||
-rw-r--r-- | remoting/host/access_verifier.h | 36 | ||||
-rw-r--r-- | remoting/host/access_verifier_unittest.cc | 60 | ||||
-rw-r--r-- | remoting/host/chromoting_host.cc | 9 | ||||
-rw-r--r-- | remoting/host/chromoting_host.h | 3 | ||||
-rw-r--r-- | remoting/host/heartbeat_sender.h | 2 | ||||
-rw-r--r-- | remoting/host/heartbeat_sender_unittest.cc | 16 | ||||
-rw-r--r-- | remoting/host/host_config.h | 2 | ||||
-rw-r--r-- | remoting/host/in_memory_host_config.cc | 36 | ||||
-rw-r--r-- | remoting/host/in_memory_host_config.h | 42 |
10 files changed, 232 insertions, 13 deletions
diff --git a/remoting/host/access_verifier.cc b/remoting/host/access_verifier.cc new file mode 100644 index 0000000..1c31577 --- /dev/null +++ b/remoting/host/access_verifier.cc @@ -0,0 +1,39 @@ +// Copyright (c) 2010 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 "base/logging.h" +#include "base/string_util.h" +#include "remoting/host/host_config.h" + +namespace remoting { + +AccessVerifier::AccessVerifier() + : initialized_(false) { +} + +bool AccessVerifier::Init(HostConfig* config) { + std::string host_jid; + + if (!config->GetString(kXmppLoginConfigPath, &host_jid) || + host_jid.empty()) { + LOG(ERROR) << "XMPP credentials are not defined in the config."; + return false; + } + + host_jid_prefix_ = host_jid + '/'; + initialized_ = true; + + return true; +} + +bool AccessVerifier::VerifyPermissions(const std::string& client_jid) { + CHECK(initialized_); + // Check that the client has the same bare jid as the host, i.e. + // client's full jid starts with host's bare jid. + return StartsWithASCII(client_jid, host_jid_prefix_, true); +} + +} // namespace remoting diff --git a/remoting/host/access_verifier.h b/remoting/host/access_verifier.h new file mode 100644 index 0000000..41244ef --- /dev/null +++ b/remoting/host/access_verifier.h @@ -0,0 +1,36 @@ +// Copyright (c) 2010 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_ACCESS_VERIFIER_H_ +#define REMOTING_HOST_ACCESS_VERIFIER_H_ + +#include <string> + +#include "base/basictypes.h" + +namespace remoting { + +class HostConfig; + +// AccessVerifier is used by to verify that the client has access to the host. +// Currently it just checks that host and client have the same bare JID. +// +// TODO(sergeyu): AccessVerifier should query directory to verify user +// permissions. +class AccessVerifier { + public: + AccessVerifier(); + bool Init(HostConfig* config); + bool VerifyPermissions(const std::string& client_jid); + + private: + std::string host_jid_prefix_; + bool initialized_; + + DISALLOW_COPY_AND_ASSIGN(AccessVerifier); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_ACCESS_VERIFIER_H_ diff --git a/remoting/host/access_verifier_unittest.cc b/remoting/host/access_verifier_unittest.cc new file mode 100644 index 0000000..7d151f5 --- /dev/null +++ b/remoting/host/access_verifier_unittest.cc @@ -0,0 +1,60 @@ +// Copyright (c) 2010 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 "base/ref_counted.h" +#include "base/task.h" +#include "remoting/host/access_verifier.h" +#include "remoting/host/in_memory_host_config.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace remoting { + +namespace { +const char kTestJid[] = "host@domain.com"; +} // namespace + +class AccessVerifierTest : public testing::Test { + protected: + class TestConfigUpdater : + public base::RefCountedThreadSafe<TestConfigUpdater> { + public: + void DoUpdate(scoped_refptr<InMemoryHostConfig> target) { + target->SetString(kXmppLoginConfigPath, kTestJid); + } + }; + + virtual void SetUp() { + config_ = new InMemoryHostConfig(); + } + + void InitConfig() { + scoped_refptr<TestConfigUpdater> config_updater(new TestConfigUpdater()); + config_->Update( + NewRunnableMethod(config_updater.get(), &TestConfigUpdater::DoUpdate, + config_)); + } + + scoped_refptr<InMemoryHostConfig> config_; +}; + +TEST_F(AccessVerifierTest, InvalidConfig) { + AccessVerifier target; + EXPECT_FALSE(target.Init(config_)); +} + +TEST_F(AccessVerifierTest, VerifyPermissions) { + AccessVerifier target; + InitConfig(); + ASSERT_TRUE(target.Init(config_)); + EXPECT_TRUE(target.VerifyPermissions("host@domain.com/123123")); + EXPECT_FALSE(target.VerifyPermissions("host@domain.com")); + EXPECT_FALSE(target.VerifyPermissions("otherhost@domain.com/123123")); + EXPECT_FALSE(target.VerifyPermissions("host@otherdomain.com/123123")); + EXPECT_FALSE(target.VerifyPermissions("")); + EXPECT_FALSE(target.VerifyPermissions("host@domain.co/saf")); + EXPECT_FALSE(target.VerifyPermissions("host@domain.com.other/blah")); +} + +} // namespace remoting diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 1bc7b98..18f6399 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -168,6 +168,10 @@ bool ChromotingHost::OnAcceptConnection( if (client_.get()) return false; + // Check that the user has access to the host. + if (!access_verifier_.VerifyPermissions(jid)) + return false; + LOG(INFO) << "Client connected: " << jid << std::endl; // If we accept the connected then create a client object and set the @@ -212,10 +216,13 @@ void ChromotingHost::DoStart(Task* shutdown_task) { std::string xmpp_auth_token; if (!config_->GetString(kXmppLoginConfigPath, &xmpp_login) || !config_->GetString(kXmppAuthTokenConfigPath, &xmpp_auth_token)) { - LOG(ERROR) << "XMMP credentials are not defined in config."; + LOG(ERROR) << "XMPP credentials are not defined in the config."; return; } + if (!access_verifier_.Init(config_)) + return; + // Connect to the talk network with a JingleClient. jingle_client_ = new JingleClient(context_->jingle_thread()); jingle_client_->Init(xmpp_login, xmpp_auth_token, diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index c45fe08..cffa4fc 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -9,6 +9,7 @@ #include "base/thread.h" #include "remoting/base/encoder.h" +#include "remoting/host/access_verifier.h" #include "remoting/host/capturer.h" #include "remoting/host/client_connection.h" #include "remoting/host/event_executor.h" @@ -133,6 +134,8 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // Objects that takes care of sending heartbeats to the chromoting bot. scoped_refptr<HeartbeatSender> heartbeat_sender_; + AccessVerifier access_verifier_; + // A ClientConnection manages the connectino to a remote client. // TODO(hclam): Expand this to a list of clients. scoped_refptr<ClientConnection> client_; diff --git a/remoting/host/heartbeat_sender.h b/remoting/host/heartbeat_sender.h index 07e2568e..e2befa9 100644 --- a/remoting/host/heartbeat_sender.h +++ b/remoting/host/heartbeat_sender.h @@ -84,6 +84,8 @@ class HeartbeatSender : public base::RefCountedThreadSafe<HeartbeatSender> { scoped_ptr<IqRequest> request_; std::string host_id_; HostKeyPair key_pair_; + + DISALLOW_COPY_AND_ASSIGN(HeartbeatSender); }; } // namespace remoting diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index f5877e1..6615871 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc @@ -5,13 +5,12 @@ #include "base/message_loop.h" #include "base/message_loop_proxy.h" #include "base/ref_counted.h" -#include "base/scoped_temp_dir.h" #include "base/string_number_conversions.h" #include "media/base/data_buffer.h" #include "remoting/base/constants.h" #include "remoting/host/heartbeat_sender.h" #include "remoting/host/host_key_pair.h" -#include "remoting/host/json_host_config.h" +#include "remoting/host/in_memory_host_config.h" #include "remoting/host/test_key_pair.h" #include "remoting/jingle_glue/iq_request.h" #include "remoting/jingle_glue/jingle_client.h" @@ -56,25 +55,19 @@ class HeartbeatSenderTest : public testing::Test { class TestConfigUpdater : public base::RefCountedThreadSafe<TestConfigUpdater> { public: - void DoUpdate(scoped_refptr<JsonHostConfig> target) { + void DoUpdate(scoped_refptr<InMemoryHostConfig> target) { target->SetString(kHostIdConfigPath, kHostId); target->SetString(kPrivateKeyConfigPath, kTestHostKeyPair); } }; virtual void SetUp() { - ASSERT_TRUE(test_dir_.CreateUniqueTempDir()); - FilePath config_path = test_dir_.path().AppendASCII("test_config.json"); - config_ = new JsonHostConfig( - config_path, base::MessageLoopProxy::CreateForCurrentThread()); + config_ = new InMemoryHostConfig(); scoped_refptr<TestConfigUpdater> config_updater(new TestConfigUpdater()); config_->Update( NewRunnableMethod(config_updater.get(), &TestConfigUpdater::DoUpdate, config_)); - // Run the message loop to save new config. - message_loop_.RunAllPending(); - jingle_thread_.message_loop_ = &message_loop_; jingle_client_ = new MockJingleClient(&jingle_thread_); @@ -84,8 +77,7 @@ class HeartbeatSenderTest : public testing::Test { JingleThread jingle_thread_; scoped_refptr<MockJingleClient> jingle_client_; MessageLoop message_loop_; - ScopedTempDir test_dir_; - scoped_refptr<JsonHostConfig> config_; + scoped_refptr<InMemoryHostConfig> config_; }; TEST_F(HeartbeatSenderTest, DoSendStanza) { diff --git a/remoting/host/host_config.h b/remoting/host/host_config.h index f0912bc..7223767 100644 --- a/remoting/host/host_config.h +++ b/remoting/host/host_config.h @@ -39,6 +39,8 @@ class HostConfig : public base::RefCountedThreadSafe<HostConfig> { }; // MutableHostConfig extends HostConfig for mutability. +// +// TODO(sergeyu): Simplify this interface. class MutableHostConfig : public HostConfig { public: MutableHostConfig() { }; diff --git a/remoting/host/in_memory_host_config.cc b/remoting/host/in_memory_host_config.cc new file mode 100644 index 0000000..2450638 --- /dev/null +++ b/remoting/host/in_memory_host_config.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2010 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/in_memory_host_config.h" + +#include "base/task.h" +#include "base/values.h" + +namespace remoting { + +InMemoryHostConfig::InMemoryHostConfig() + : values_(new DictionaryValue()) { +} + +bool InMemoryHostConfig::GetString(const std::string& path, + std::string* out_value) { + AutoLock auto_lock(lock_); + return values_->GetString(path, out_value); +} + +void InMemoryHostConfig::Update(Task* task) { + { + AutoLock auto_lock(lock_); + task->Run(); + } + delete task; +} + +void InMemoryHostConfig::SetString(const std::string& path, + const std::string& in_value) { + lock_.AssertAcquired(); + values_->SetString(path, in_value); +} + +} // namespace remoting diff --git a/remoting/host/in_memory_host_config.h b/remoting/host/in_memory_host_config.h new file mode 100644 index 0000000..6a44e39 --- /dev/null +++ b/remoting/host/in_memory_host_config.h @@ -0,0 +1,42 @@ +// Copyright (c) 2010 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_IN_MEMORY_HOST_CONFIG_H_ +#define REMOTING_HOST_IN_MEMORY_HOST_CONFIG_H_ + +#include <string> + +#include "base/file_path.h" +#include "base/lock.h" +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "remoting/host/host_config.h" + +class DictionaryValue; +class Task; + +namespace remoting { + +// In-memory host config. Used by unittests. +class InMemoryHostConfig : public MutableHostConfig { + public: + InMemoryHostConfig(); + + // MutableHostConfig interface. + virtual bool GetString(const std::string& path, std::string* out_value); + + virtual void Update(Task* task); + + virtual void SetString(const std::string& path, const std::string& in_value); + + private: + Lock lock_; + scoped_ptr<DictionaryValue> values_; + + DISALLOW_COPY_AND_ASSIGN(InMemoryHostConfig); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_IN_MEMORY_HOST_CONFIG_H_ |