summaryrefslogtreecommitdiffstats
path: root/remoting/protocol
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-14 00:13:39 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-14 00:13:39 +0000
commit1bc9c7c298b6e67052da148fd4469338c8cb7520 (patch)
tree6d1918e618d93310029bdd110559a07c0f3e0ca0 /remoting/protocol
parent4294c531d9eb41613d64c260b8a23d4958009fea (diff)
downloadchromium_src-1bc9c7c298b6e67052da148fd4469338c8cb7520.zip
chromium_src-1bc9c7c298b6e67052da148fd4469338c8cb7520.tar.gz
chromium_src-1bc9c7c298b6e67052da148fd4469338c8cb7520.tar.bz2
Implement multi-step auth support in PepperSession.
Also added unittests for PepperSession. BUG=105214 Review URL: http://codereview.chromium.org/8827001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114318 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/protocol')
-rw-r--r--remoting/protocol/jingle_messages.cc24
-rw-r--r--remoting/protocol/jingle_messages.h5
-rw-r--r--remoting/protocol/jingle_messages_unittest.cc29
-rw-r--r--remoting/protocol/jingle_session_unittest.cc40
-rw-r--r--remoting/protocol/pepper_session.cc95
-rw-r--r--remoting/protocol/pepper_session.h5
-rw-r--r--remoting/protocol/pepper_session_manager.cc5
-rw-r--r--remoting/protocol/pepper_session_unittest.cc272
-rw-r--r--remoting/protocol/ppapi_module_stub.cc14
9 files changed, 449 insertions, 40 deletions
diff --git a/remoting/protocol/jingle_messages.cc b/remoting/protocol/jingle_messages.cc
index 6c66641..6d0abd7 100644
--- a/remoting/protocol/jingle_messages.cc
+++ b/remoting/protocol/jingle_messages.cc
@@ -59,6 +59,7 @@ static const NameMapElement<JingleMessage::ActionType> kActionTypes[] = {
{ JingleMessage::SESSION_INITIATE, "session-initiate" },
{ JingleMessage::SESSION_ACCEPT, "session-accept" },
{ JingleMessage::SESSION_TERMINATE, "session-terminate" },
+ { JingleMessage::SESSION_INFO, "session-info" },
{ JingleMessage::TRANSPORT_INFO, "transport-info" },
};
@@ -185,6 +186,19 @@ bool JingleMessage::ParseXml(const buzz::XmlElement* stanza,
return false;
}
+ if (action == SESSION_INFO) {
+ // session-info messages may contain arbitrary information not
+ // defined by the Jingle protocol. We don't need to parse it.
+ const XmlElement* child = jingle_tag->FirstElement();
+ if (child) {
+ // session-info is allowed to be empty.
+ info.reset(new XmlElement(*child));
+ } else {
+ info.reset(NULL);
+ }
+ return true;
+ }
+
const XmlElement* reason_tag =
jingle_tag->FirstNamed(QName(kJingleNamespace, "reason"));
if (reason_tag && reason_tag->FirstElement()) {
@@ -267,6 +281,12 @@ buzz::XmlElement* JingleMessage::ToXml() {
LOG(FATAL) << "Invalid action value " << action;
jingle_tag->AddAttr(QName(kEmptyNamespace, "action"), action_attr);
+ if (action == SESSION_INFO) {
+ if (info.get())
+ jingle_tag->AddElement(new XmlElement(*info.get()));
+ return root.release();
+ }
+
if (action == SESSION_INITIATE)
jingle_tag->AddAttr(QName(kEmptyNamespace, "initiator"), from);
@@ -371,6 +391,10 @@ buzz::XmlElement* JingleMessageReply::ToXml(
type = "modify";
name = QName(kJabberNamespace, "unexpected-request");
break;
+ case UNSUPPORTED_INFO:
+ type = "modify";
+ name = QName(kJabberNamespace, "feature-not-implemented");
+ break;
default:
NOTREACHED();
}
diff --git a/remoting/protocol/jingle_messages.h b/remoting/protocol/jingle_messages.h
index 069d48f9..bcacbf0 100644
--- a/remoting/protocol/jingle_messages.h
+++ b/remoting/protocol/jingle_messages.h
@@ -30,6 +30,7 @@ struct JingleMessage {
SESSION_INITIATE,
SESSION_ACCEPT,
SESSION_TERMINATE,
+ SESSION_INFO,
TRANSPORT_INFO,
};
@@ -66,6 +67,9 @@ struct JingleMessage {
scoped_ptr<ContentDescription> description;
std::list<cricket::Candidate> candidates;
+ // Content of session-info messages.
+ scoped_ptr<buzz::XmlElement> info;
+
// Value from the <reason> tag if it is present in the
// message. Useful mainly for session-terminate messages, but Jingle
// spec allows it in any message.
@@ -83,6 +87,7 @@ struct JingleMessageReply {
NOT_IMPLEMENTED,
INVALID_SID,
UNEXPECTED_REQUEST,
+ UNSUPPORTED_INFO,
};
JingleMessageReply();
diff --git a/remoting/protocol/jingle_messages_unittest.cc b/remoting/protocol/jingle_messages_unittest.cc
index 98810b9..4d2501d 100644
--- a/remoting/protocol/jingle_messages_unittest.cc
+++ b/remoting/protocol/jingle_messages_unittest.cc
@@ -220,6 +220,35 @@ TEST(JingleMessageTest, SessionTerminate) {
<< error;
}
+TEST(JingleMessageTest, SessionInfo) {
+ const char* kTestSessionTerminateMessage =
+ "<cli:iq from='user@gmail.com/chromoting016DBB07' "
+ "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
+ "xmlns:cli='jabber:client'><jingle action='session-info' "
+ "sid='2227053353' xmlns='urn:xmpp:jingle:1'><test-info>TestMessage"
+ "</test-info></jingle></cli:iq>";
+
+ scoped_ptr<XmlElement> source_message(
+ XmlElement::ForStr(kTestSessionTerminateMessage));
+ ASSERT_TRUE(source_message.get());
+
+ EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
+
+ JingleMessage message;
+ std::string error;
+ EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
+
+ EXPECT_EQ(message.action, JingleMessage::SESSION_INFO);
+ ASSERT_TRUE(message.info.get() != NULL);
+ EXPECT_TRUE(message.info->Name() ==
+ buzz::QName("urn:xmpp:jingle:1", "test-info"));
+
+ scoped_ptr<XmlElement> formatted_message(message.ToXml());
+ ASSERT_TRUE(formatted_message.get());
+ EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
+ << error;
+}
+
TEST(JingleMessageReplyTest, ToXml) {
const char* kTestIncomingMessage =
"<cli:iq from='user@gmail.com/chromoting016DBB07' id='4' "
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc
index 6c1fdfb..e2bf2d1 100644
--- a/remoting/protocol/jingle_session_unittest.cc
+++ b/remoting/protocol/jingle_session_unittest.cc
@@ -93,7 +93,7 @@ class JingleSessionTest : public testing::Test {
: message_loop_(talk_base::Thread::Current()) {
}
- // Helper method to copy to set value of client_connection_.
+ // Helper method that handles OnIncomingSession().
void SetHostSession(Session* session) {
DCHECK(session);
host_session_.reset(session);
@@ -120,7 +120,7 @@ class JingleSessionTest : public testing::Test {
client_session_.reset();
}
- void CreateServerPair(int auth_round_trips,
+ void CreateSessionManagers(int auth_round_trips,
FakeAuthenticator::Action auth_action) {
host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid));
client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid));
@@ -286,13 +286,13 @@ class JingleSessionTest : public testing::Test {
// Verify that we can create and destory server objects without a connection.
TEST_F(JingleSessionTest, CreateAndDestoy) {
- CreateServerPair(1, FakeAuthenticator::ACCEPT);
+ CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
}
// Verify that incoming session can be rejected, and that the status
-// of the connection is set to CLOSED in this case.
+// of the connection is set to FAILED in this case.
TEST_F(JingleSessionTest, RejectConnection) {
- CreateServerPair(1, FakeAuthenticator::ACCEPT);
+ CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
// Reject incoming session.
EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
@@ -320,32 +320,32 @@ TEST_F(JingleSessionTest, RejectConnection) {
message_loop_.RunAllPending();
}
-// Verify that we can connect two endpoints.
+// Verify that we can connect two endpoints with single-step authentication.
TEST_F(JingleSessionTest, Connect) {
- CreateServerPair(1, FakeAuthenticator::ACCEPT);
+ CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
InitiateConnection(1, FakeAuthenticator::ACCEPT, false);
}
// Verify that we can connect two endpoints with multi-step authentication.
-TEST_F(JingleSessionTest, ConnectMultistep) {
- CreateServerPair(3, FakeAuthenticator::ACCEPT);
+TEST_F(JingleSessionTest, ConnectWithMultistep) {
+ CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
InitiateConnection(3, FakeAuthenticator::ACCEPT, false);
}
-// Verify that connection is terminated when auth fails.
-TEST_F(JingleSessionTest, ConnectBadAuth) {
- CreateServerPair(1, FakeAuthenticator::REJECT);
+// Verify that connection is terminated when single-step auth fails.
+TEST_F(JingleSessionTest, ConnectWithBadAuth) {
+ CreateSessionManagers(1, FakeAuthenticator::REJECT);
InitiateConnection(1, FakeAuthenticator::ACCEPT, true);
}
-// Verify that connection is terminted when multi-step auth fails.
-TEST_F(JingleSessionTest, ConnectBadMultistepAuth) {
- CreateServerPair(3, FakeAuthenticator::REJECT);
+// Verify that connection is terminated when multi-step auth fails.
+TEST_F(JingleSessionTest, ConnectWithBadMultistepAuth) {
+ CreateSessionManagers(3, FakeAuthenticator::REJECT);
InitiateConnection(3, FakeAuthenticator::ACCEPT, true);
}
-TEST_F(JingleSessionTest, ConnectBadChannelAuth) {
- CreateServerPair(1, FakeAuthenticator::REJECT_CHANNEL);
+TEST_F(JingleSessionTest, ConnectWithBadChannelAuth) {
+ CreateSessionManagers(1, FakeAuthenticator::REJECT_CHANNEL);
ASSERT_NO_FATAL_FAILURE(
InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
@@ -373,7 +373,7 @@ TEST_F(JingleSessionTest, ConnectBadChannelAuth) {
// Verify that data can be transmitted over the event channel.
TEST_F(JingleSessionTest, TestTcpChannel) {
- CreateServerPair(1, FakeAuthenticator::ACCEPT);
+ CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
ASSERT_NO_FATAL_FAILURE(
InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
@@ -388,7 +388,7 @@ TEST_F(JingleSessionTest, TestTcpChannel) {
// Verify that we can connect channels with multistep auth.
TEST_F(JingleSessionTest, TestMultistepAuthTcpChannel) {
- CreateServerPair(3, FakeAuthenticator::ACCEPT);
+ CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
ASSERT_NO_FATAL_FAILURE(
InitiateConnection(3, FakeAuthenticator::ACCEPT, false));
@@ -403,7 +403,7 @@ TEST_F(JingleSessionTest, TestMultistepAuthTcpChannel) {
// Verify that data can be transmitted over the video RTP channel.
TEST_F(JingleSessionTest, TestUdpChannel) {
- CreateServerPair(1, FakeAuthenticator::ACCEPT);
+ CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
ASSERT_NO_FATAL_FAILURE(
InitiateConnection(1, FakeAuthenticator::ACCEPT, false));
diff --git a/remoting/protocol/pepper_session.cc b/remoting/protocol/pepper_session.cc
index e22287d..8eabb09 100644
--- a/remoting/protocol/pepper_session.cc
+++ b/remoting/protocol/pepper_session.cc
@@ -190,6 +190,10 @@ void PepperSession::OnIncomingMessage(const JingleMessage& message,
OnAccept(message, reply);
break;
+ case JingleMessage::SESSION_INFO:
+ OnSessionInfo(message, reply);
+ break;
+
case JingleMessage::TRANSPORT_INFO:
ProcessTransportInfo(message);
break;
@@ -221,27 +225,43 @@ void PepperSession::OnAccept(const JingleMessage& message,
DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE);
authenticator_->ProcessMessage(auth_message);
- // Support for more than two auth message is not implemented yet.
- DCHECK(authenticator_->state() != Authenticator::WAITING_MESSAGE &&
- authenticator_->state() != Authenticator::MESSAGE_READY);
-
- if (authenticator_->state() == Authenticator::REJECTED) {
- OnError(AUTHENTICATION_FAILED);
- return;
- }
if (!InitializeConfigFromDescription(message.description.get())) {
OnError(INCOMPATIBLE_PROTOCOL);
return;
}
+ // In case there is transport information in the accept message.
+ ProcessTransportInfo(message);
+
SetState(CONNECTED);
- if (authenticator_->state() == Authenticator::ACCEPTED)
+ // Process authentication.
+ if (authenticator_->state() == Authenticator::ACCEPTED) {
SetState(AUTHENTICATED);
+ } else {
+ ProcessAuthenticationStep();
+ }
+}
- // In case there is transport information in the accept message.
- ProcessTransportInfo(message);
+void PepperSession::OnSessionInfo(const JingleMessage& message,
+ JingleMessageReply* reply) {
+ if (message.info.get() &&
+ Authenticator::IsAuthenticatorMessage(message.info.get())) {
+ if (state_ != CONNECTED ||
+ authenticator_->state() != Authenticator::WAITING_MESSAGE) {
+ LOG(WARNING) << "Received unexpected authenticator message "
+ << message.info->Str();
+ *reply = JingleMessageReply(JingleMessageReply::UNEXPECTED_REQUEST);
+ OnError(INCOMPATIBLE_PROTOCOL);
+ return;
+ }
+
+ authenticator_->ProcessMessage(message.info.get());
+ ProcessAuthenticationStep();
+ } else {
+ *reply = JingleMessageReply(JingleMessageReply::UNSUPPORTED_INFO);
+ }
}
void PepperSession::ProcessTransportInfo(const JingleMessage& message) {
@@ -277,16 +297,21 @@ void PepperSession::OnTerminate(const JingleMessage& message,
return;
}
- if (state_ == CONNECTED || state_ == AUTHENTICATED) {
- if (message.reason == JingleMessage::GENERAL_ERROR) {
- OnError(CHANNEL_CONNECTION_ERROR);
- } else {
- CloseInternal(false);
- }
- return;
+ if (state_ != CONNECTED && state_ != AUTHENTICATED) {
+ LOG(WARNING) << "Received unexpected session-terminate message.";
}
- LOG(WARNING) << "Received unexpected session-terminate message.";
+ if (message.reason == JingleMessage::SUCCESS) {
+ CloseInternal(false);
+ } else if (message.reason == JingleMessage::DECLINE) {
+ OnError(AUTHENTICATION_FAILED);
+ } else if (message.reason == JingleMessage::GENERAL_ERROR) {
+ OnError(CHANNEL_CONNECTION_ERROR);
+ } else if (message.reason == JingleMessage::INCOMPATIBLE_PARAMETERS) {
+ OnError(INCOMPATIBLE_PROTOCOL);
+ } else {
+ OnError(UNKNOWN_ERROR);
+ }
}
bool PepperSession::InitializeConfigFromDescription(
@@ -305,6 +330,38 @@ bool PepperSession::InitializeConfigFromDescription(
return true;
}
+void PepperSession::ProcessAuthenticationStep() {
+ DCHECK_EQ(state_, CONNECTED);
+
+ if (authenticator_->state() == Authenticator::MESSAGE_READY) {
+ JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_);
+ message.info.reset(authenticator_->GetNextMessage());
+ DCHECK(message.info.get());
+
+ session_info_request_.reset(session_manager_->iq_sender()->SendIq(
+ message.ToXml(), base::Bind(
+ &PepperSession::OnSessionInfoResponse,
+ base::Unretained(this))));
+ }
+ DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY);
+
+ if (authenticator_->state() == Authenticator::ACCEPTED) {
+ SetState(AUTHENTICATED);
+ } else if (authenticator_->state() == Authenticator::REJECTED) {
+ OnError(AUTHENTICATION_FAILED);
+ }
+}
+
+void PepperSession::OnSessionInfoResponse(const buzz::XmlElement* response) {
+ const std::string& type = response->Attr(buzz::QName("", "type"));
+ if (type != "result") {
+ LOG(ERROR) << "Received error in response to session-info message: \""
+ << response->Str()
+ << "\". Terminating the session.";
+ OnError(AUTHENTICATION_FAILED);
+ }
+}
+
void PepperSession::AddLocalCandidate(const cricket::Candidate& candidate) {
pending_candidates_.push_back(candidate);
diff --git a/remoting/protocol/pepper_session.h b/remoting/protocol/pepper_session.h
index e13b875..83a0ad9 100644
--- a/remoting/protocol/pepper_session.h
+++ b/remoting/protocol/pepper_session.h
@@ -83,12 +83,16 @@ class PepperSession : public Session {
// Message handlers for incoming messages.
void OnAccept(const JingleMessage& message, JingleMessageReply* reply);
+ void OnSessionInfo(const JingleMessage& message, JingleMessageReply* reply);
void OnTerminate(const JingleMessage& message, JingleMessageReply* reply);
void ProcessTransportInfo(const JingleMessage& message);
// Called from OnAccept() to initialize session config.
bool InitializeConfigFromDescription(const ContentDescription* description);
+ void ProcessAuthenticationStep();
+ void OnSessionInfoResponse(const buzz::XmlElement* response);
+
// Called by PepperChannel.
void AddLocalCandidate(const cricket::Candidate& candidate);
void OnDeleteChannel(PepperChannel* channel);
@@ -116,6 +120,7 @@ class PepperSession : public Session {
scoped_ptr<Authenticator> authenticator_;
scoped_ptr<IqRequest> initiate_request_;
+ scoped_ptr<IqRequest> session_info_request_;
scoped_ptr<IqRequest> transport_info_request_;
ChannelsMap channels_;
diff --git a/remoting/protocol/pepper_session_manager.cc b/remoting/protocol/pepper_session_manager.cc
index 2e558a7..9317fbb 100644
--- a/remoting/protocol/pepper_session_manager.cc
+++ b/remoting/protocol/pepper_session_manager.cc
@@ -92,7 +92,10 @@ void PepperSessionManager::Close() {
listener_ = NULL;
jingle_info_request_.reset();
- signal_strategy_->RemoveListener(this);
+ if (signal_strategy_) {
+ signal_strategy_->RemoveListener(this);
+ signal_strategy_ = NULL;
+ }
}
void PepperSessionManager::set_authenticator_factory(
diff --git a/remoting/protocol/pepper_session_unittest.cc b/remoting/protocol/pepper_session_unittest.cc
new file mode 100644
index 0000000..a6cc271
--- /dev/null
+++ b/remoting/protocol/pepper_session_unittest.cc
@@ -0,0 +1,272 @@
+// 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/pepper_session.h"
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/time.h"
+#include "base/test/test_timeouts.h"
+#include "remoting/base/constants.h"
+#include "remoting/protocol/authenticator.h"
+#include "remoting/protocol/channel_authenticator.h"
+#include "remoting/protocol/connection_tester.h"
+#include "remoting/protocol/fake_authenticator.h"
+#include "remoting/protocol/jingle_session.h"
+#include "remoting/protocol/jingle_session_manager.h"
+#include "remoting/protocol/pepper_session_manager.h"
+#include "remoting/jingle_glue/jingle_thread.h"
+#include "remoting/jingle_glue/fake_signal_strategy.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::AtMost;
+using testing::DeleteArg;
+using testing::DoAll;
+using testing::InSequence;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::Return;
+using testing::SaveArg;
+using testing::SetArgumentPointee;
+using testing::WithArg;
+
+namespace remoting {
+namespace protocol {
+
+namespace {
+
+const char kHostJid[] = "host1@gmail.com/123";
+const char kClientJid[] = "host2@gmail.com/321";
+
+class MockSessionManagerListener : public SessionManager::Listener {
+ public:
+ MOCK_METHOD0(OnSessionManagerInitialized, void());
+ MOCK_METHOD2(OnIncomingSession,
+ void(Session*,
+ SessionManager::IncomingSessionResponse*));
+};
+
+class MockSessionCallback {
+ public:
+ MOCK_METHOD1(OnStateChange, void(Session::State));
+};
+
+} // namespace
+
+class PepperSessionTest : public testing::Test {
+ public:
+ PepperSessionTest()
+ : message_loop_(talk_base::Thread::Current()) {
+ }
+
+ // Helper method that handles OnIncomingSession().
+ void SetHostSession(Session* session) {
+ DCHECK(session);
+ host_session_.reset(session);
+ host_session_->SetStateChangeCallback(
+ base::Bind(&MockSessionCallback::OnStateChange,
+ base::Unretained(&host_connection_callback_)));
+
+ session->set_config(SessionConfig::GetDefault());
+ }
+
+ protected:
+ virtual void SetUp() {
+ }
+
+ virtual void TearDown() {
+ CloseSessions();
+ CloseSessionManager();
+ }
+
+ void CloseSessions() {
+ host_session_.reset();
+ client_session_.reset();
+ }
+
+ void CreateSessionManagers(int auth_round_trips,
+ FakeAuthenticator::Action auth_action) {
+ host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid));
+ client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid));
+ FakeSignalStrategy::Connect(host_signal_strategy_.get(),
+ client_signal_strategy_.get());
+
+ EXPECT_CALL(host_server_listener_, OnSessionManagerInitialized())
+ .Times(1);
+ host_server_.reset(new JingleSessionManager(
+ base::MessageLoopProxy::current()));
+ host_server_->Init(
+ kHostJid, host_signal_strategy_.get(), &host_server_listener_, false);
+
+ host_server_->set_authenticator_factory(
+ new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true));
+
+ EXPECT_CALL(client_server_listener_, OnSessionManagerInitialized())
+ .Times(1);
+ client_server_.reset(new PepperSessionManager(NULL));
+ client_server_->Init(
+ kClientJid, client_signal_strategy_.get(),
+ &client_server_listener_, false);
+ }
+
+ void CloseSessionManager() {
+ if (host_server_.get()) {
+ host_server_->Close();
+ host_server_.reset();
+ }
+ if (client_server_.get()) {
+ client_server_->Close();
+ client_server_.reset();
+ }
+ host_signal_strategy_.reset();
+ client_signal_strategy_.reset();
+ }
+
+ void InitiateConnection(int auth_round_trips,
+ FakeAuthenticator::Action auth_action,
+ bool expect_fail) {
+ EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
+ .WillOnce(DoAll(
+ WithArg<0>(Invoke(this, &PepperSessionTest::SetHostSession)),
+ SetArgumentPointee<1>(protocol::SessionManager::ACCEPT)));
+
+ {
+ InSequence dummy;
+
+ EXPECT_CALL(host_connection_callback_,
+ OnStateChange(Session::CONNECTED))
+ .Times(AtMost(1));
+ if (expect_fail) {
+ EXPECT_CALL(host_connection_callback_,
+ OnStateChange(Session::FAILED))
+ .Times(1);
+ } else {
+ EXPECT_CALL(host_connection_callback_,
+ OnStateChange(Session::AUTHENTICATED))
+ .Times(1);
+ // Expect that the connection will be closed eventually.
+ EXPECT_CALL(host_connection_callback_,
+ OnStateChange(Session::CLOSED))
+ .Times(AtMost(1));
+ }
+ }
+
+ {
+ InSequence dummy;
+
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(Session::CONNECTING))
+ .Times(1);
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(Session::CONNECTED))
+ .Times(AtMost(1));
+ if (expect_fail) {
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(Session::FAILED))
+ .Times(1);
+ } else {
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(Session::AUTHENTICATED))
+ .Times(1);
+ // Expect that the connection will be closed eventually.
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(Session::CLOSED))
+ .Times(AtMost(1));
+ }
+ }
+
+ Authenticator* authenticator = new FakeAuthenticator(
+ FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true);
+
+ client_session_.reset(client_server_->Connect(
+ kHostJid, authenticator,
+ CandidateSessionConfig::CreateDefault(),
+ base::Bind(&MockSessionCallback::OnStateChange,
+ base::Unretained(&client_connection_callback_))));
+
+ message_loop_.RunAllPending();
+ }
+
+ JingleThreadMessageLoop message_loop_;
+
+ scoped_ptr<FakeSignalStrategy> host_signal_strategy_;
+ scoped_ptr<FakeSignalStrategy> client_signal_strategy_;
+
+ scoped_ptr<JingleSessionManager> host_server_;
+ MockSessionManagerListener host_server_listener_;
+ scoped_ptr<PepperSessionManager> client_server_;
+ MockSessionManagerListener client_server_listener_;
+
+ scoped_ptr<Session> host_session_;
+ MockSessionCallback host_connection_callback_;
+ scoped_ptr<Session> client_session_;
+ MockSessionCallback client_connection_callback_;
+};
+
+
+// Verify that we can create and destroy session managers without a
+// connection.
+TEST_F(PepperSessionTest, CreateAndDestoy) {
+ CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
+}
+
+// Verify that an incoming session can be rejected, and that the
+// status of the connection is set to FAILED in this case.
+TEST_F(PepperSessionTest, RejectConnection) {
+ CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
+
+ // Reject incoming session.
+ EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
+ .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE));
+
+ {
+ InSequence dummy;
+
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(Session::CONNECTING))
+ .Times(1);
+ EXPECT_CALL(client_connection_callback_,
+ OnStateChange(Session::FAILED))
+ .Times(1);
+ }
+
+ Authenticator* authenticator = new FakeAuthenticator(
+ FakeAuthenticator::CLIENT, 1, FakeAuthenticator::ACCEPT, true);
+ client_session_.reset(client_server_->Connect(
+ kHostJid, authenticator,
+ CandidateSessionConfig::CreateDefault(),
+ base::Bind(&MockSessionCallback::OnStateChange,
+ base::Unretained(&client_connection_callback_))));
+
+ message_loop_.RunAllPending();
+}
+
+// Verify that we can connect two endpoints with single-step authentication.
+TEST_F(PepperSessionTest, Connect) {
+ CreateSessionManagers(1, FakeAuthenticator::ACCEPT);
+ InitiateConnection(1, FakeAuthenticator::ACCEPT, false);
+}
+
+// Verify that we can connect two endpoints with multi-step authentication.
+TEST_F(PepperSessionTest, ConnectWithMultistep) {
+ CreateSessionManagers(3, FakeAuthenticator::ACCEPT);
+ InitiateConnection(3, FakeAuthenticator::ACCEPT, false);
+}
+
+// Verify that connection is terminated when single-step auth fails.
+TEST_F(PepperSessionTest, ConnectWithBadAuth) {
+ CreateSessionManagers(1, FakeAuthenticator::REJECT);
+ InitiateConnection(1, FakeAuthenticator::ACCEPT, true);
+}
+
+// Verify that connection is terminated when multi-step auth fails.
+TEST_F(PepperSessionTest, ConnectWithBadMultistepAuth) {
+ CreateSessionManagers(3, FakeAuthenticator::REJECT);
+ InitiateConnection(3, FakeAuthenticator::ACCEPT, true);
+}
+
+} // namespace protocol
+} // namespace remoting
diff --git a/remoting/protocol/ppapi_module_stub.cc b/remoting/protocol/ppapi_module_stub.cc
new file mode 100644
index 0000000..829aaaa
--- /dev/null
+++ b/remoting/protocol/ppapi_module_stub.cc
@@ -0,0 +1,14 @@
+// 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 "ppapi/cpp/module.h"
+
+namespace pp {
+
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+ return NULL;
+}
+
+} // namespace pp