summaryrefslogtreecommitdiffstats
path: root/remoting/host
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-02 02:05:06 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-02 02:05:06 +0000
commit76451fe7fbce667742dff671cad06cbd039f8296 (patch)
tree0b2196989e5bb6643a026eb71964cbfaa2b66feb /remoting/host
parente8478ae4ef8bd1dbb83cd46e8af060d5331ba2df (diff)
downloadchromium_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.cc39
-rw-r--r--remoting/host/access_verifier.h36
-rw-r--r--remoting/host/access_verifier_unittest.cc60
-rw-r--r--remoting/host/chromoting_host.cc9
-rw-r--r--remoting/host/chromoting_host.h3
-rw-r--r--remoting/host/heartbeat_sender.h2
-rw-r--r--remoting/host/heartbeat_sender_unittest.cc16
-rw-r--r--remoting/host/host_config.h2
-rw-r--r--remoting/host/in_memory_host_config.cc36
-rw-r--r--remoting/host/in_memory_host_config.h42
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_