summaryrefslogtreecommitdiffstats
path: root/blimp/net
diff options
context:
space:
mode:
authorhaibinlu <haibinlu@chromium.org>2015-12-08 17:43:21 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-09 01:45:07 +0000
commit9fa0095471e61a1de43d902974567355585157fe (patch)
tree45a69a6a7f1842bd70c562de941c242e8c9fb96a /blimp/net
parente313b496592d4ae6fd9d76f4b684265f03e350d2 (diff)
downloadchromium_src-9fa0095471e61a1de43d902974567355585157fe.zip
chromium_src-9fa0095471e61a1de43d902974567355585157fe.tar.gz
chromium_src-9fa0095471e61a1de43d902974567355585157fe.tar.bz2
[Blimp Net] Add EngineAuthHandler.
It is a ConnectionHandler which expects each new connection to supply a StartConnection message with a valid client authentication token, verifies it, and if successful then hands the connection off to the main ConnectionHandler. BUG=567817 Review URL: https://codereview.chromium.org/1492643003 Cr-Commit-Position: refs/heads/master@{#363880}
Diffstat (limited to 'blimp/net')
-rw-r--r--blimp/net/BUILD.gn3
-rw-r--r--blimp/net/blimp_connection.cc2
-rw-r--r--blimp/net/blimp_connection.h9
-rw-r--r--blimp/net/engine_authentication_handler.cc126
-rw-r--r--blimp/net/engine_authentication_handler.h40
-rw-r--r--blimp/net/engine_authentication_handler_unittest.cc123
-rw-r--r--blimp/net/test_common.cc4
-rw-r--r--blimp/net/test_common.h15
8 files changed, 319 insertions, 3 deletions
diff --git a/blimp/net/BUILD.gn b/blimp/net/BUILD.gn
index bd73b7a..c58fa77 100644
--- a/blimp/net/BUILD.gn
+++ b/blimp/net/BUILD.gn
@@ -27,6 +27,8 @@ component("blimp_net") {
"common.h",
"connection_error_observer.h",
"connection_handler.h",
+ "engine_authentication_handler.cc",
+ "engine_authentication_handler.h",
"engine_connection_manager.cc",
"engine_connection_manager.h",
"input_message_generator.cc",
@@ -84,6 +86,7 @@ source_set("unit_tests") {
"blimp_message_output_buffer_unittest.cc",
"blimp_message_pump_unittest.cc",
"client_connection_manager_unittest.cc",
+ "engine_authentication_handler_unittest.cc",
"engine_connection_manager_unittest.cc",
"input_message_unittest.cc",
"stream_packet_reader_unittest.cc",
diff --git a/blimp/net/blimp_connection.cc b/blimp/net/blimp_connection.cc
index c5b0700..db2f63d 100644
--- a/blimp/net/blimp_connection.cc
+++ b/blimp/net/blimp_connection.cc
@@ -96,6 +96,8 @@ BlimpConnection::BlimpConnection(scoped_ptr<PacketReader> reader,
DCHECK(writer_);
}
+BlimpConnection::BlimpConnection() {}
+
BlimpConnection::~BlimpConnection() {}
void BlimpConnection::SetConnectionErrorObserver(
diff --git a/blimp/net/blimp_connection.h b/blimp/net/blimp_connection.h
index 9f48f50..f95a91c 100644
--- a/blimp/net/blimp_connection.h
+++ b/blimp/net/blimp_connection.h
@@ -27,15 +27,18 @@ class BLIMP_NET_EXPORT BlimpConnection {
virtual ~BlimpConnection();
// Lets |observer| know when the network connection encounters an error.
- void SetConnectionErrorObserver(ConnectionErrorObserver* observer);
+ virtual void SetConnectionErrorObserver(ConnectionErrorObserver* observer);
// Sets the processor which will take incoming messages for this connection.
// Can be set multiple times, but previously set processors are discarded.
// Caller retains the ownership of |processor|.
- void SetIncomingMessageProcessor(BlimpMessageProcessor* processor);
+ virtual void SetIncomingMessageProcessor(BlimpMessageProcessor* processor);
// Gets a processor for BrowserSession->BlimpConnection message routing.
- BlimpMessageProcessor* GetOutgoingMessageProcessor() const;
+ virtual BlimpMessageProcessor* GetOutgoingMessageProcessor() const;
+
+ protected:
+ BlimpConnection();
private:
scoped_ptr<PacketReader> reader_;
diff --git a/blimp/net/engine_authentication_handler.cc b/blimp/net/engine_authentication_handler.cc
new file mode 100644
index 0000000..e49f5ea
--- /dev/null
+++ b/blimp/net/engine_authentication_handler.cc
@@ -0,0 +1,126 @@
+// Copyright 2015 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 "blimp/net/engine_authentication_handler.h"
+
+#include "base/callback_helpers.h"
+#include "base/logging.h"
+#include "base/timer/timer.h"
+#include "blimp/common/proto/blimp_message.pb.h"
+#include "blimp/net/blimp_connection.h"
+#include "blimp/net/blimp_message_processor.h"
+#include "blimp/net/blimp_transport.h"
+#include "blimp/net/connection_error_observer.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_errors.h"
+
+namespace blimp {
+
+namespace {
+// Expect Client to send the StartConnection within ten seconds of becoming
+// connected.
+const int kAuthTimeoutDurationInSeconds = 10;
+
+// Authenticates one connection. It deletes itself when
+// * the connection is authenticated and passed to |connection_handler|.
+// * the connection gets into an error state.
+// * the auth message does not arrive within a reasonable time.
+class Authenticator : public ConnectionErrorObserver,
+ public BlimpMessageProcessor {
+ public:
+ explicit Authenticator(scoped_ptr<BlimpConnection> connection,
+ base::WeakPtr<ConnectionHandler> connection_handler);
+ ~Authenticator() override;
+
+ private:
+ // Processes authentication result and deletes |this|.
+ void OnConnectionAuthenticated(bool authenticated);
+
+ // Handles timeout waiting for auth message, and deletes |this|.
+ void OnAuthenticationTimeout();
+
+ // ConnectionErrorObserver implementation.
+ void OnConnectionError(int error) override;
+
+ // BlimpMessageProcessor implementation.
+ void ProcessMessage(scoped_ptr<BlimpMessage> message,
+ const net::CompletionCallback& callback) override;
+
+ // The connection to be authenticated.
+ scoped_ptr<BlimpConnection> connection_;
+
+ // Handler to pass successfully authenticated connections to.
+ base::WeakPtr<ConnectionHandler> connection_handler_;
+
+ // A timer to fail authentication on timeout.
+ base::OneShotTimer timeout_timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(Authenticator);
+};
+
+Authenticator::Authenticator(
+ scoped_ptr<BlimpConnection> connection,
+ base::WeakPtr<ConnectionHandler> connection_handler)
+ : connection_(std::move(connection)),
+ connection_handler_(connection_handler) {
+ connection_->SetConnectionErrorObserver(this);
+ connection_->SetIncomingMessageProcessor(this);
+ timeout_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromSeconds(kAuthTimeoutDurationInSeconds),
+ this, &Authenticator::OnAuthenticationTimeout);
+}
+
+Authenticator::~Authenticator() {}
+
+void Authenticator::OnConnectionAuthenticated(bool authenticated) {
+ connection_->SetIncomingMessageProcessor(nullptr);
+ connection_->SetConnectionErrorObserver(nullptr);
+
+ if (authenticated && connection_handler_) {
+ connection_handler_->HandleConnection(std::move(connection_));
+ }
+
+ delete this;
+}
+
+void Authenticator::OnAuthenticationTimeout() {
+ DVLOG(1) << "Connection authentication timeout";
+ OnConnectionAuthenticated(false);
+}
+
+void Authenticator::OnConnectionError(int error) {
+ DVLOG(1) << "Connection error before authenticated "
+ << net::ErrorToString(error);
+ OnConnectionAuthenticated(false);
+}
+
+void Authenticator::ProcessMessage(scoped_ptr<BlimpMessage> message,
+ const net::CompletionCallback& callback) {
+ if (message->type() == BlimpMessage::PROTOCOL_CONTROL) {
+ // TODO(haibinlu): check client token.
+ OnConnectionAuthenticated(true);
+ } else {
+ DVLOG(1) << "The first message is not START_CONNECTION";
+ OnConnectionAuthenticated(false);
+ }
+
+ callback.Run(net::OK);
+}
+
+} // namespace
+
+EngineAuthenticationHandler::EngineAuthenticationHandler(
+ ConnectionHandler* connection_handler)
+ : connection_handler_weak_factory_(connection_handler) {}
+
+EngineAuthenticationHandler::~EngineAuthenticationHandler() {}
+
+void EngineAuthenticationHandler::HandleConnection(
+ scoped_ptr<BlimpConnection> connection) {
+ // Authenticator manages its own lifetime.
+ new Authenticator(std::move(connection),
+ connection_handler_weak_factory_.GetWeakPtr());
+}
+
+} // namespace blimp
diff --git a/blimp/net/engine_authentication_handler.h b/blimp/net/engine_authentication_handler.h
new file mode 100644
index 0000000..686a096
--- /dev/null
+++ b/blimp/net/engine_authentication_handler.h
@@ -0,0 +1,40 @@
+// Copyright 2015 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 BLIMP_NET_ENGINE_AUTHENTICATION_HANDLER_H_
+#define BLIMP_NET_ENGINE_AUTHENTICATION_HANDLER_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "blimp/net/blimp_net_export.h"
+#include "blimp/net/connection_handler.h"
+
+namespace blimp {
+
+class BlimpConnection;
+class BlimpMessage;
+
+// Authenticates connections and passes successfully authenticated connections
+// to |connection_handler|.
+class BLIMP_NET_EXPORT EngineAuthenticationHandler : public ConnectionHandler {
+ public:
+ explicit EngineAuthenticationHandler(ConnectionHandler* connection_handler);
+
+ ~EngineAuthenticationHandler() override;
+
+ // ConnectionHandler implementation.
+ void HandleConnection(scoped_ptr<BlimpConnection> connection) override;
+
+ private:
+ // Used to abandon pending authenticated connections if |this| is deleted.
+ base::WeakPtrFactory<ConnectionHandler> connection_handler_weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(EngineAuthenticationHandler);
+};
+
+} // namespace blimp
+
+#endif // BLIMP_NET_ENGINE_AUTHENTICATION_HANDLER_H_
diff --git a/blimp/net/engine_authentication_handler_unittest.cc b/blimp/net/engine_authentication_handler_unittest.cc
new file mode 100644
index 0000000..9a3f4ca
--- /dev/null
+++ b/blimp/net/engine_authentication_handler_unittest.cc
@@ -0,0 +1,123 @@
+// Copyright 2015 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 <stddef.h>
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/test/test_mock_time_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "blimp/common/create_blimp_message.h"
+#include "blimp/common/proto/blimp_message.pb.h"
+#include "blimp/net/blimp_connection.h"
+#include "blimp/net/blimp_transport.h"
+#include "blimp/net/common.h"
+#include "blimp/net/connection_error_observer.h"
+#include "blimp/net/engine_authentication_handler.h"
+#include "blimp/net/test_common.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Eq;
+using testing::SaveArg;
+
+namespace blimp {
+
+class EngineAuthenticationHandlerTest : public testing::Test {
+ public:
+ EngineAuthenticationHandlerTest()
+ : runner_(new base::TestMockTimeTaskRunner),
+ runner_handle_(runner_),
+ auth_handler_(new EngineAuthenticationHandler(&connection_handler_)),
+ connection_(new testing::StrictMock<MockBlimpConnection>()) {}
+
+ ~EngineAuthenticationHandlerTest() override {}
+
+ protected:
+ void ExpectOnConnection() {
+ EXPECT_CALL(*connection_, SetConnectionErrorObserver(_))
+ .Times(2)
+ .WillRepeatedly(SaveArg<0>(&error_observer_));
+ EXPECT_CALL(*connection_, SetIncomingMessageProcessor(_))
+ .Times(2)
+ .WillRepeatedly(SaveArg<0>(&incoming_message_processor_));
+ }
+
+ scoped_refptr<base::TestMockTimeTaskRunner> runner_;
+ base::ThreadTaskRunnerHandle runner_handle_;
+ testing::StrictMock<MockConnectionHandler> connection_handler_;
+ scoped_ptr<EngineAuthenticationHandler> auth_handler_;
+ scoped_ptr<testing::StrictMock<MockBlimpConnection>> connection_;
+ ConnectionErrorObserver* error_observer_ = nullptr;
+ BlimpMessageProcessor* incoming_message_processor_ = nullptr;
+};
+
+TEST_F(EngineAuthenticationHandlerTest, AuthenticationSucceeds) {
+ ExpectOnConnection();
+ EXPECT_CALL(connection_handler_, HandleConnectionPtr(Eq(connection_.get())));
+ auth_handler_->HandleConnection(std::move(connection_));
+ EXPECT_NE(nullptr, error_observer_);
+ EXPECT_NE(nullptr, incoming_message_processor_);
+
+ scoped_ptr<BlimpMessage> blimp_message = CreateStartConnectionMessage("", 0);
+ net::TestCompletionCallback process_message_cb;
+ incoming_message_processor_->ProcessMessage(std::move(blimp_message),
+ process_message_cb.callback());
+ EXPECT_EQ(net::OK, process_message_cb.WaitForResult());
+ EXPECT_EQ(nullptr, error_observer_);
+ EXPECT_EQ(nullptr, incoming_message_processor_);
+}
+
+TEST_F(EngineAuthenticationHandlerTest, WrongMessageReceived) {
+ ExpectOnConnection();
+ auth_handler_->HandleConnection(std::move(connection_));
+
+ InputMessage* input_message;
+ scoped_ptr<BlimpMessage> blimp_message = CreateBlimpMessage(&input_message);
+ net::TestCompletionCallback process_message_cb;
+ incoming_message_processor_->ProcessMessage(std::move(blimp_message),
+ process_message_cb.callback());
+ EXPECT_EQ(net::OK, process_message_cb.WaitForResult());
+ EXPECT_EQ(nullptr, error_observer_);
+ EXPECT_EQ(nullptr, incoming_message_processor_);
+}
+
+TEST_F(EngineAuthenticationHandlerTest, ConnectionError) {
+ ExpectOnConnection();
+ auth_handler_->HandleConnection(std::move(connection_));
+ EXPECT_NE(nullptr, error_observer_);
+ EXPECT_NE(nullptr, incoming_message_processor_);
+ error_observer_->OnConnectionError(net::ERR_FAILED);
+ EXPECT_EQ(nullptr, error_observer_);
+ EXPECT_EQ(nullptr, incoming_message_processor_);
+}
+
+TEST_F(EngineAuthenticationHandlerTest, Timeout) {
+ ExpectOnConnection();
+ auth_handler_->HandleConnection(std::move(connection_));
+ EXPECT_NE(nullptr, error_observer_);
+ EXPECT_NE(nullptr, incoming_message_processor_);
+
+ runner_->FastForwardBy(base::TimeDelta::FromSeconds(11));
+ EXPECT_EQ(nullptr, error_observer_);
+ EXPECT_EQ(nullptr, incoming_message_processor_);
+}
+
+TEST_F(EngineAuthenticationHandlerTest, AuthHandlerDeletedFirst) {
+ ExpectOnConnection();
+ auth_handler_->HandleConnection(std::move(connection_));
+ auth_handler_.reset();
+
+ scoped_ptr<BlimpMessage> blimp_message = CreateStartConnectionMessage("", 0);
+ net::TestCompletionCallback process_message_cb;
+ incoming_message_processor_->ProcessMessage(std::move(blimp_message),
+ process_message_cb.callback());
+ EXPECT_EQ(net::OK, process_message_cb.WaitForResult());
+}
+
+} // namespace blimp
diff --git a/blimp/net/test_common.cc b/blimp/net/test_common.cc
index 06eddac..888841ae 100644
--- a/blimp/net/test_common.cc
+++ b/blimp/net/test_common.cc
@@ -47,6 +47,10 @@ MockPacketWriter::MockPacketWriter() {}
MockPacketWriter::~MockPacketWriter() {}
+MockBlimpConnection::MockBlimpConnection() {}
+
+MockBlimpConnection::~MockBlimpConnection() {}
+
MockConnectionErrorObserver::MockConnectionErrorObserver() {}
MockConnectionErrorObserver::~MockConnectionErrorObserver() {}
diff --git a/blimp/net/test_common.h b/blimp/net/test_common.h
index 58ee2f6..b42c3d8 100644
--- a/blimp/net/test_common.h
+++ b/blimp/net/test_common.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "blimp/common/proto/blimp_message.pb.h"
+#include "blimp/net/blimp_connection.h"
#include "blimp/net/blimp_message_processor.h"
#include "blimp/net/blimp_transport.h"
#include "blimp/net/connection_error_observer.h"
@@ -165,6 +166,20 @@ class MockPacketWriter : public PacketWriter {
const net::CompletionCallback&));
};
+class MockBlimpConnection : public BlimpConnection {
+ public:
+ MockBlimpConnection();
+ ~MockBlimpConnection() override;
+
+ MOCK_METHOD1(SetConnectionErrorObserver,
+ void(ConnectionErrorObserver* observer));
+
+ MOCK_METHOD1(SetIncomingMessageProcessor,
+ void(BlimpMessageProcessor* processor));
+
+ MOCK_CONST_METHOD0(GetOutgoingMessageProcessor, BlimpMessageProcessor*());
+};
+
class MockConnectionErrorObserver : public ConnectionErrorObserver {
public:
MockConnectionErrorObserver();