diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-14 00:13:39 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-14 00:13:39 +0000 |
commit | 1bc9c7c298b6e67052da148fd4469338c8cb7520 (patch) | |
tree | 6d1918e618d93310029bdd110559a07c0f3e0ca0 /remoting/protocol | |
parent | 4294c531d9eb41613d64c260b8a23d4958009fea (diff) | |
download | chromium_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.cc | 24 | ||||
-rw-r--r-- | remoting/protocol/jingle_messages.h | 5 | ||||
-rw-r--r-- | remoting/protocol/jingle_messages_unittest.cc | 29 | ||||
-rw-r--r-- | remoting/protocol/jingle_session_unittest.cc | 40 | ||||
-rw-r--r-- | remoting/protocol/pepper_session.cc | 95 | ||||
-rw-r--r-- | remoting/protocol/pepper_session.h | 5 | ||||
-rw-r--r-- | remoting/protocol/pepper_session_manager.cc | 5 | ||||
-rw-r--r-- | remoting/protocol/pepper_session_unittest.cc | 272 | ||||
-rw-r--r-- | remoting/protocol/ppapi_module_stub.cc | 14 |
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 |