diff options
author | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-27 05:36:36 +0000 |
---|---|---|
committer | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-27 05:36:36 +0000 |
commit | 7e494c6d13267fe91a649c81ca858a58c449d6c4 (patch) | |
tree | 25f545d92c1638b7c6a29bb7a38a706a90fae3e9 | |
parent | 278a4e8244ff8105dd2fdd4f8c593b4bd6a34cee (diff) | |
download | chromium_src-7e494c6d13267fe91a649c81ca858a58c449d6c4.zip chromium_src-7e494c6d13267fe91a649c81ca858a58c449d6c4.tar.gz chromium_src-7e494c6d13267fe91a649c81ca858a58c449d6c4.tar.bz2 |
Revert 94247 - Add an authentication step to stream channel setup in JingleStreamConnector.
Fix JingleStreamConnector and JingleDatagramConnector tear-down semantics in case of failure.
BUG=88130,90624
TEST=
Review URL: http://codereview.chromium.org/7501007
TBR=wez@chromium.org
Review URL: http://codereview.chromium.org/7497026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94249 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | remoting/host/chromoting_host.cc | 3 | ||||
-rw-r--r-- | remoting/host/chromoting_host.h | 5 | ||||
-rw-r--r-- | remoting/host/plugin/host_script_object.cc | 3 | ||||
-rw-r--r-- | remoting/protocol/connection_to_host.cc | 3 | ||||
-rw-r--r-- | remoting/protocol/fake_session.cc | 10 | ||||
-rw-r--r-- | remoting/protocol/fake_session.h | 5 | ||||
-rw-r--r-- | remoting/protocol/jingle_datagram_connector.cc | 3 | ||||
-rw-r--r-- | remoting/protocol/jingle_session.cc | 12 | ||||
-rw-r--r-- | remoting/protocol/jingle_session.h | 9 | ||||
-rw-r--r-- | remoting/protocol/jingle_session_unittest.cc | 119 | ||||
-rw-r--r-- | remoting/protocol/jingle_stream_connector.cc | 193 | ||||
-rw-r--r-- | remoting/protocol/jingle_stream_connector.h | 29 | ||||
-rw-r--r-- | remoting/protocol/protocol_mock_objects.h | 2 | ||||
-rw-r--r-- | remoting/protocol/session.h | 4 |
14 files changed, 62 insertions, 338 deletions
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 10956e0..ddd4f99 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -298,9 +298,6 @@ void ChromotingHost::OnNewClientSession( session->set_receiver_token( GenerateHostAuthToken(session->initiator_token())); - // Provide the Access Code as shared secret for SSL channel authentication. - session->set_shared_secret(access_code_); - *response = protocol::SessionManager::ACCEPT; logger_->Log(logging::LOG_INFO, "Client connected: %s", diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index 234700d..f280914 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -133,9 +133,6 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, void set_it2me(bool is_it2me) { is_it2me_ = is_it2me; } - void set_access_code(const std::string& access_code) { - access_code_ = access_code; - } // Notify all active client sessions that local input has been detected, and // that remote input should be ignored for a short time. @@ -227,8 +224,6 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // are pre-authenticated, and hence the local login challenge can be bypassed. bool is_it2me_; - std::string access_code_; - // Stores list of tasks that should be executed when we finish // shutdown. Used only while |state_| is set to kStopping. std::vector<Task*> shutdown_tasks_; diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc index 460655a..cfb3b9c 100644 --- a/remoting/host/plugin/host_script_object.cc +++ b/remoting/host/plugin/host_script_object.cc @@ -458,9 +458,6 @@ void HostNPScriptObject::OnReceivedSupportID( access_code_ = support_id + access_verifier->host_secret(); access_code_lifetime_ = lifetime; - // Tell the ChromotingHost the access code, to use as shared-secret. - host_->set_access_code(access_code_); - // Let the caller know that life is good. OnStateChanged(kReceivedAccessCode); } diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc index 3841fc7..b82143b 100644 --- a/remoting/protocol/connection_to_host.cc +++ b/remoting/protocol/connection_to_host.cc @@ -127,9 +127,6 @@ void ConnectionToHost::InitSession() { session_.reset(session_manager_->Connect( host_jid_, host_public_key_, client_token, candidate_config, NewCallback(this, &ConnectionToHost::OnSessionStateChange))); - - // Set the shared-secret for securing SSL channels. - session_->set_shared_secret(access_code_); } const SessionConfig* ConnectionToHost::config() { diff --git a/remoting/protocol/fake_session.cc b/remoting/protocol/fake_session.cc index b23dbb1..2403a20 100644 --- a/remoting/protocol/fake_session.cc +++ b/remoting/protocol/fake_session.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -205,14 +205,6 @@ void FakeSession::set_receiver_token(const std::string& receiver_token) { receiver_token_ = receiver_token; } -void FakeSession::set_shared_secret(const std::string& shared_secret) { - shared_secret_ = shared_secret; -} - -const std::string& FakeSession::shared_secret() { - return shared_secret_; -} - void FakeSession::Close() { closed_ = true; } diff --git a/remoting/protocol/fake_session.h b/remoting/protocol/fake_session.h index 912cfb0..d892ede 100644 --- a/remoting/protocol/fake_session.h +++ b/remoting/protocol/fake_session.h @@ -128,9 +128,6 @@ class FakeSession : public Session { virtual const std::string& receiver_token(); virtual void set_receiver_token(const std::string& receiver_token); - virtual void set_shared_secret(const std::string& secret); - virtual const std::string& shared_secret(); - virtual void Close(); public: @@ -147,8 +144,6 @@ class FakeSession : public Session { std::string initiator_token_; std::string receiver_token_; - std::string shared_secret_; - std::string jid_; bool closed_; }; diff --git a/remoting/protocol/jingle_datagram_connector.cc b/remoting/protocol/jingle_datagram_connector.cc index 5a789d1..0a45425 100644 --- a/remoting/protocol/jingle_datagram_connector.cc +++ b/remoting/protocol/jingle_datagram_connector.cc @@ -35,9 +35,8 @@ void JingleDatagramConnector::Connect( // TODO(sergeyu): Implement encryption for datagram channels. - session_->OnChannelConnectorFinished(name_, this); callback_.Run(name_, socket); - delete this; + session_->OnChannelConnectorFinished(name_, this); } } // namespace protocol diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc index 8485336..3e08dca 100644 --- a/remoting/protocol/jingle_session.cc +++ b/remoting/protocol/jingle_session.cc @@ -303,17 +303,6 @@ void JingleSession::set_receiver_token(const std::string& receiver_token) { receiver_token_ = receiver_token; } -void JingleSession::set_shared_secret(const std::string& secret) { - DCHECK(CalledOnValidThread()); - shared_secret_ = secret; -} - -const std::string& JingleSession::shared_secret() { - DCHECK(CalledOnValidThread()); - return shared_secret_; -} - - void JingleSession::Close() { DCHECK(CalledOnValidThread()); @@ -503,6 +492,7 @@ void JingleSession::OnChannelConnectorFinished( DCHECK(CalledOnValidThread()); DCHECK_EQ(channel_connectors_[name], connector); channel_connectors_[name] = NULL; + delete connector; } void JingleSession::CreateChannels() { diff --git a/remoting/protocol/jingle_session.h b/remoting/protocol/jingle_session.h index e91a45c..cc40660 100644 --- a/remoting/protocol/jingle_session.h +++ b/remoting/protocol/jingle_session.h @@ -49,8 +49,6 @@ class JingleSession : public protocol::Session, virtual void set_initiator_token(const std::string& initiator_token) OVERRIDE; virtual const std::string& receiver_token() OVERRIDE; virtual void set_receiver_token(const std::string& receiver_token) OVERRIDE; - virtual void set_shared_secret(const std::string& secret) OVERRIDE; - virtual const std::string& shared_secret() OVERRIDE; virtual void Close() OVERRIDE; private: @@ -115,8 +113,7 @@ class JingleSession : public protocol::Session, JingleChannelConnector* connector); // Called by JingleChannelConnector when it has finished connecting - // the channel, to remove itself from the table of pending connectors. The - // connector assumes responsibility for destroying itself after this call. + // the channel and needs to be destroyed. void OnChannelConnectorFinished(const std::string& name, JingleChannelConnector* connector); @@ -155,10 +152,6 @@ class JingleSession : public protocol::Session, // session-initiate message (encrypted with the host's key). std::string master_key_; - // Shared secret to use in channel authentication. This is currently only - // used in IT2Me. - std::string shared_secret_; - State state_; scoped_ptr<StateChangeCallback> state_change_callback_; diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc index 2054cb5..d0f753e 100644 --- a/remoting/protocol/jingle_session_unittest.cc +++ b/remoting/protocol/jingle_session_unittest.cc @@ -22,10 +22,8 @@ #include "third_party/libjingle/source/talk/p2p/client/basicportallocator.h" using testing::_; -using testing::AnyNumber; using testing::DeleteArg; using testing::DoAll; -using testing::InSequence; using testing::Invoke; using testing::InvokeWithoutArgs; using testing::Return; @@ -65,9 +63,6 @@ const char kTestHostPublicKey[] = "A78Oi+IbcJf/jJUZO119VNnRKGiPsf5GZIoHyXX8O5OUQk5soKdQPeK1FwWkeZu6fuXl" "QoU12I6podD6xMFa/PA/xefMwcpmuWTRhcso9bp10zVFGQIDAQAB"; -const char kTestSharedSecret[] = "1234-1234-5678"; -const char kTestSharedSecretBad[] = "0000-0000-0001"; - void QuitCurrentThread() { MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); } @@ -121,7 +116,6 @@ class JingleSessionTest : public testing::Test { &MockSessionCallback::OnStateChange)); session->set_config(SessionConfig::CreateDefault()); - session->set_shared_secret(kTestSharedSecret); } protected: @@ -133,6 +127,11 @@ class JingleSessionTest : public testing::Test { CloseSessionManager(); } + void CreateServerPair() { + // Sessions must be initialized on the jingle thread. + DoCreateServerPair(); + } + void CloseSessions() { if (host_session_.get()) { host_session_->Close(); @@ -144,7 +143,7 @@ class JingleSessionTest : public testing::Test { } } - void CreateServerPair() { + void DoCreateServerPair() { FilePath certs_dir; PathService::Get(base::DIR_SOURCE_ROOT, &certs_dir); certs_dir = certs_dir.AppendASCII("net"); @@ -202,7 +201,7 @@ class JingleSessionTest : public testing::Test { client_signal_strategy_.reset(); } - bool InitiateConnection(const char* shared_secret) { + bool InitiateConnection() { int not_connected_peers = 2; EXPECT_CALL(host_server_callback_, OnIncomingSession(_, _)) @@ -211,49 +210,31 @@ class JingleSessionTest : public testing::Test { this, &JingleSessionTest::SetHostSession)), SetArgumentPointee<1>(protocol::SessionManager::ACCEPT))); - { - InSequence dummy; - - EXPECT_CALL(host_connection_callback_, - OnStateChange(Session::CONNECTING)) - .Times(1); - if (shared_secret == kTestSharedSecret) { - EXPECT_CALL(host_connection_callback_, - OnStateChange(Session::CONNECTED)) - .Times(1) - .WillOnce(QuitThreadOnCounter(¬_connected_peers)); - // Expect that the connection will be closed eventually. - EXPECT_CALL(host_connection_callback_, - OnStateChange(Session::CLOSED)) - .Times(1); - } else { - // Might pass through the CONNECTED state. - EXPECT_CALL(host_connection_callback_, - OnStateChange(Session::CONNECTED)) - .Times(AnyNumber()); - // Expect that the connection will be closed eventually. - EXPECT_CALL(host_connection_callback_, - OnStateChange(Session::FAILED)) - .Times(1) - .WillOnce(InvokeWithoutArgs(&QuitCurrentThread)); - } - } + base::WaitableEvent host_connected_event(true, false); + EXPECT_CALL(host_connection_callback_, + OnStateChange(Session::CONNECTING)) + .Times(1); + EXPECT_CALL(host_connection_callback_, + OnStateChange(Session::CONNECTED)) + .Times(1) + .WillOnce(QuitThreadOnCounter(¬_connected_peers)); + // Expect that the connection will be closed eventually. + EXPECT_CALL(host_connection_callback_, + OnStateChange(Session::CLOSED)) + .Times(1); - { - InSequence dummy; - - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::CONNECTING)) - .Times(1); - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::CONNECTED)) - .Times(1) - .WillOnce(QuitThreadOnCounter(¬_connected_peers)); - // Expect that the connection will be closed eventually. - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::CLOSED)) - .Times(1); - } + base::WaitableEvent client_connected_event(true, false); + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::CONNECTING)) + .Times(1); + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::CONNECTED)) + .Times(1) + .WillOnce(QuitThreadOnCounter(¬_connected_peers)); + // Expect that the connection will be closed eventually. + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::CLOSED)) + .Times(1); client_session_.reset(client_server_->Connect( kHostJid, kTestHostPublicKey, kTestToken, @@ -261,8 +242,6 @@ class JingleSessionTest : public testing::Test { NewCallback(&client_connection_callback_, &MockSessionCallback::OnStateChange))); - client_session_->set_shared_secret(shared_secret); - return RunMessageLoopWithTimeout(TestTimeouts::action_max_timeout_ms()); } @@ -638,17 +617,13 @@ TEST_F(JingleSessionTest, RejectConnection) { EXPECT_CALL(host_server_callback_, 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::CLOSED)) - .Times(1) - .WillOnce(InvokeWithoutArgs(&QuitCurrentThread)); - } + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::CONNECTING)) + .Times(1); + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::CLOSED)) + .Times(1) + .WillOnce(InvokeWithoutArgs(&QuitCurrentThread)); client_session_.reset(client_server_->Connect( kHostJid, kTestHostPublicKey, kTestToken, @@ -662,19 +637,13 @@ TEST_F(JingleSessionTest, RejectConnection) { // Verify that we can connect two endpoints. TEST_F(JingleSessionTest, Connect) { CreateServerPair(); - ASSERT_TRUE(InitiateConnection(kTestSharedSecret)); -} - -// Verify that we can't connect two endpoints with mismatched secrets. -TEST_F(JingleSessionTest, ConnectBadChannelAuth) { - CreateServerPair(); - ASSERT_TRUE(InitiateConnection(kTestSharedSecretBad)); + ASSERT_TRUE(InitiateConnection()); } // Verify that data can be transmitted over the event channel. TEST_F(JingleSessionTest, TestControlChannel) { CreateServerPair(); - ASSERT_TRUE(InitiateConnection(kTestSharedSecret)); + ASSERT_TRUE(InitiateConnection()); scoped_refptr<TCPChannelTester> tester( new TCPChannelTester(host_session_.get(), client_session_.get(), kMessageSize, kMessages)); @@ -689,7 +658,7 @@ TEST_F(JingleSessionTest, TestControlChannel) { // Verify that data can be transmitted over the video channel. TEST_F(JingleSessionTest, TestVideoChannel) { CreateServerPair(); - ASSERT_TRUE(InitiateConnection(kTestSharedSecret)); + ASSERT_TRUE(InitiateConnection()); scoped_refptr<TCPChannelTester> tester( new TCPChannelTester(host_session_.get(), client_session_.get(), kMessageSize, kMessageSize)); @@ -704,7 +673,7 @@ TEST_F(JingleSessionTest, TestVideoChannel) { // Verify that data can be transmitted over the event channel. TEST_F(JingleSessionTest, TestEventChannel) { CreateServerPair(); - ASSERT_TRUE(InitiateConnection(kTestSharedSecret)); + ASSERT_TRUE(InitiateConnection()); scoped_refptr<TCPChannelTester> tester( new TCPChannelTester(host_session_.get(), client_session_.get(), kMessageSize, kMessageSize)); @@ -719,7 +688,7 @@ TEST_F(JingleSessionTest, TestEventChannel) { // Verify that data can be transmitted over the video RTP channel. TEST_F(JingleSessionTest, TestVideoRtpChannel) { CreateServerPair(); - ASSERT_TRUE(InitiateConnection(kTestSharedSecret)); + ASSERT_TRUE(InitiateConnection()); scoped_refptr<UDPChannelTester> tester( new UDPChannelTester(host_session_.get(), client_session_.get())); tester->Start(ChannelTesterBase::VIDEO_RTP); @@ -734,7 +703,7 @@ TEST_F(JingleSessionTest, TestVideoRtpChannel) { // using sockets from JingleSession. TEST_F(JingleSessionTest, DISABLED_TestSpeed) { CreateServerPair(); - ASSERT_TRUE(InitiateConnection(kTestSharedSecret)); + ASSERT_TRUE(InitiateConnection()); scoped_refptr<ChannelSpeedTester> tester; tester = new ChannelSpeedTester(host_session_.get(), diff --git a/remoting/protocol/jingle_stream_connector.cc b/remoting/protocol/jingle_stream_connector.cc index 66ea3d0..650c119 100644 --- a/remoting/protocol/jingle_stream_connector.cc +++ b/remoting/protocol/jingle_stream_connector.cc @@ -4,7 +4,6 @@ #include "remoting/protocol/jingle_stream_connector.h" -#include "crypto/hmac.h" #include "jingle/glue/channel_socket_adapter.h" #include "jingle/glue/pseudotcp_adapter.h" #include "net/base/cert_status_flags.h" @@ -22,12 +21,6 @@ namespace protocol { namespace { -// Size of the SHA-256 authentication digest. -const int kAuthDigestLength = 32; - -// Labels for use when exporting the SSL master keys. -const char kClientSslExporterLabel[] = "EXPORTER-remoting-channel-auth-client"; - // Value is choosen to balance the extra latency against the reduced // load due to ACK traffic. const int kTcpAckDelayMilliseconds = 10; @@ -37,9 +30,6 @@ net::SSLClientSocket* CreateSSLClientSocket( net::StreamSocket* socket, const std::string& der_cert, net::CertVerifier* cert_verifier) { net::SSLConfig ssl_config; - // If False Start is enabled then the Connect callback will fire before - // the cipher has been set up, and ExportKeyingMaterial will fail. - ssl_config.false_start_enabled = false; // Certificate provided by the host doesn't need authority. net::SSLConfig::CertAndStatus cert_and_status; @@ -69,16 +59,10 @@ JingleStreamConnector::JingleStreamConnector( initiator_(false), local_private_key_(NULL), raw_channel_(NULL), - ssl_client_socket_(NULL), - ssl_server_socket_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(tcp_connect_callback_( this, &JingleStreamConnector::OnTCPConnect)), ALLOW_THIS_IN_INITIALIZER_LIST(ssl_connect_callback_( - this, &JingleStreamConnector::OnSSLConnect)), - ALLOW_THIS_IN_INITIALIZER_LIST(auth_write_callback_( - this, &JingleStreamConnector::OnAuthBytesWritten)), - ALLOW_THIS_IN_INITIALIZER_LIST(auth_read_callback_( - this, &JingleStreamConnector::OnAuthBytesRead)) { + this, &JingleStreamConnector::OnSSLConnect)) { } JingleStreamConnector::~JingleStreamConnector() { @@ -131,11 +115,11 @@ bool JingleStreamConnector::EstablishSSLConnection() { cert_verifier_.reset(new net::CertVerifier()); // Create client SSL socket. - ssl_client_socket_ = CreateSSLClientSocket( + net::SSLClientSocket* ssl_client_socket = CreateSSLClientSocket( socket_.release(), remote_cert_, cert_verifier_.get()); - socket_.reset(ssl_client_socket_); + socket_.reset(ssl_client_socket); - result = ssl_client_socket_->Connect(&ssl_connect_callback_); + result = ssl_client_socket->Connect(&ssl_connect_callback_); } else { scoped_refptr<net::X509Certificate> cert = net::X509Certificate::CreateFromBytes( @@ -147,13 +131,13 @@ bool JingleStreamConnector::EstablishSSLConnection() { // Create server SSL socket. net::SSLConfig ssl_config; - ssl_config.false_start_enabled = false; - ssl_server_socket_ = net::CreateSSLServerSocket( - socket_.release(), cert, local_private_key_, ssl_config); - socket_.reset(ssl_server_socket_); + net::SSLServerSocket* ssl_server_socket = + net::CreateSSLServerSocket(socket_.release(), cert, + local_private_key_, ssl_config); + socket_.reset(ssl_server_socket); - result = ssl_server_socket_->Handshake(&ssl_connect_callback_); + result = ssl_server_socket->Handshake(&ssl_connect_callback_); } if (result == net::ERR_IO_PENDING) { @@ -191,171 +175,18 @@ void JingleStreamConnector::OnSSLConnect(int result) { } DCHECK(socket_->IsConnected()); - AuthenticateChannel(); -} - -void JingleStreamConnector::AuthenticateChannel() { - DCHECK(CalledOnValidThread()); - if (initiator_) { - // Allocate a buffer to write the authentication digest. - scoped_refptr<net::IOBuffer> write_buf = - new net::IOBuffer(kAuthDigestLength); - auth_write_buf_ = new net::DrainableIOBuffer(write_buf, - kAuthDigestLength); - - // Generate the auth digest to send. - if (!GetAuthBytes(kClientSslExporterLabel, auth_write_buf_->data())) { - NotifyError(); - return; - } - - DoAuthWrite(); - } else { - // Read an authentication digest. - auth_read_buf_ = new net::GrowableIOBuffer(); - auth_read_buf_->SetCapacity(kAuthDigestLength); - DoAuthRead(); - } -} - -void JingleStreamConnector::DoAuthWrite() { - while (true) { - int result = socket_->Write(auth_write_buf_, - auth_write_buf_->BytesRemaining(), - &auth_write_callback_); - if (result == net::ERR_IO_PENDING) - break; - if (!HandleAuthBytesWritten(result)) - break; - } -} - -void JingleStreamConnector::DoAuthRead() { - while (true) { - int result = socket_->Read(auth_read_buf_, - auth_read_buf_->RemainingCapacity(), - &auth_read_callback_); - if (result == net::ERR_IO_PENDING) - break; - if (!HandleAuthBytesRead(result)) - break; - } -} - -void JingleStreamConnector::OnAuthBytesWritten(int result) { - if (HandleAuthBytesWritten(result)) - DoAuthWrite(); -} - -void JingleStreamConnector::OnAuthBytesRead(int result) { - if (HandleAuthBytesRead(result)) - DoAuthRead(); -} - -bool JingleStreamConnector::HandleAuthBytesWritten(int result) { - DCHECK(CalledOnValidThread()); - - if (result <= 0) { - LOG(ERROR) << "Error writing authentication: " << result; - NotifyError(); - return false; - } - - auth_write_buf_->DidConsume(result); - if (auth_write_buf_->BytesRemaining() > 0) - return true; - NotifyDone(socket_.release()); - return false; -} - -bool JingleStreamConnector::HandleAuthBytesRead(int read_result) { - DCHECK(CalledOnValidThread()); - - if (read_result <= 0) { - LOG(ERROR) << "Error reading authentication: " << read_result; - NotifyError(); - return false; - } - - auth_read_buf_->set_offset(auth_read_buf_->offset() + read_result); - if (auth_read_buf_->RemainingCapacity() > 0) - return true; - - if (!VerifyAuthBytes( - kClientSslExporterLabel, - auth_read_buf_->StartOfBuffer())) { - NotifyError(); - return false; - } - - NotifyDone(socket_.release()); - return false; -} - -bool JingleStreamConnector::VerifyAuthBytes(const char* label, - const char* auth_bytes) { - char expected[kAuthDigestLength]; - if (!GetAuthBytes(label, expected)) - return false; - // Compare the received and expected digests in fixed time, to limit the - // scope for timing attacks. - uint8 result = 0; - for (unsigned i = 0; i < sizeof(expected); i++) { - result |= auth_bytes[i] ^ expected[i]; - } - if (result != 0) { - LOG(ERROR) << "Mismatched authentication"; - return false; - } - return true; -} - -bool JingleStreamConnector::GetAuthBytes(const char* label, - char* out_bytes) { - // Fetch keying material from the socket. - unsigned char key_material[kAuthDigestLength]; - int result; - if (initiator_) { - result = ssl_client_socket_->ExportKeyingMaterial( - kClientSslExporterLabel, "", key_material, sizeof(key_material)); - } else { - result = ssl_server_socket_->ExportKeyingMaterial( - kClientSslExporterLabel, "", key_material, sizeof(key_material)); - } - if (result != net::OK) { - LOG(ERROR) << "Error fetching keying material: " << result; - return false; - } - - // Generate auth digest based on the keying material and shared secret. - crypto::HMAC response(crypto::HMAC::SHA256); - if (!response.Init(session_->shared_secret())) { - NOTREACHED() << "HMAC::Init failed"; - return false; - } - base::StringPiece message(reinterpret_cast<const char*>(key_material), - sizeof(key_material)); - if (!response.Sign( - message, - reinterpret_cast<unsigned char*>(out_bytes), - kAuthDigestLength)) { - NOTREACHED() << "HMAC::Sign failed"; - return false; - } - - return true; } void JingleStreamConnector::NotifyDone(net::StreamSocket* socket) { - session_->OnChannelConnectorFinished(name_, this); callback_.Run(name_, socket); - delete this; + session_->OnChannelConnectorFinished(name_, this); } void JingleStreamConnector::NotifyError() { socket_.reset(); - NotifyDone(NULL); + callback_.Run(name_, NULL); + session_->OnChannelConnectorFinished(name_, this); } } // namespace protocol diff --git a/remoting/protocol/jingle_stream_connector.h b/remoting/protocol/jingle_stream_connector.h index df003e3..9abfc63 100644 --- a/remoting/protocol/jingle_stream_connector.h +++ b/remoting/protocol/jingle_stream_connector.h @@ -22,8 +22,6 @@ class TransportChannelSocketAdapter; namespace net { class CertVerifier; class StreamSocket; -class SSLClientSocket; -class SSLServerSocket; } // namespace net namespace remoting { @@ -31,12 +29,6 @@ namespace protocol { class JingleSession; -// JingleStreamConnector creates the named datagram channel in the supplied -// JingleSession, and uses PseudoTcp to turn it into a stream channel. Within -// the stream channel SSL is used to secure the protocol stream. Finally, the -// initiator authenticates the channel to the recipient by sending a digest -// based on a secret shared by the two parties, and keying material derived -// from the SSL session's master secret and nonces. class JingleStreamConnector : public JingleChannelConnector { public: JingleStreamConnector(JingleSession* session, @@ -60,21 +52,13 @@ class JingleStreamConnector : public JingleChannelConnector { bool EstablishSSLConnection(); void OnSSLConnect(int result); - void AuthenticateChannel(); - void DoAuthWrite(); - void DoAuthRead(); - void OnAuthBytesWritten(int result); - void OnAuthBytesRead(int result); - bool HandleAuthBytesWritten(int result); - bool HandleAuthBytesRead(int result); - bool VerifyAuthBytes(const char* label, const char* auth_bytes); - bool GetAuthBytes(const char* label, char* out_bytes); - void NotifyDone(net::StreamSocket* socket); void NotifyError(); JingleSession* session_; + std::string name_; + Session::StreamChannelCallback callback_; bool initiator_; @@ -82,24 +66,15 @@ class JingleStreamConnector : public JingleChannelConnector { std::string remote_cert_; crypto::RSAPrivateKey* local_private_key_; - scoped_refptr<net::DrainableIOBuffer> auth_write_buf_; - scoped_refptr<net::GrowableIOBuffer> auth_read_buf_; - cricket::TransportChannel* raw_channel_; scoped_ptr<net::StreamSocket> socket_; - // TODO(wez): Ugly up-casts needed so we can fetch SSL keying material. - net::SSLClientSocket* ssl_client_socket_; - net::SSLServerSocket* ssl_server_socket_; - // Used to verify the certificate received in SSLClientSocket. scoped_ptr<net::CertVerifier> cert_verifier_; // Callback called by the TCP and SSL layers. net::CompletionCallbackImpl<JingleStreamConnector> tcp_connect_callback_; net::CompletionCallbackImpl<JingleStreamConnector> ssl_connect_callback_; - net::CompletionCallbackImpl<JingleStreamConnector> auth_write_callback_; - net::CompletionCallbackImpl<JingleStreamConnector> auth_read_callback_; DISALLOW_COPY_AND_ASSIGN(JingleStreamConnector); }; diff --git a/remoting/protocol/protocol_mock_objects.h b/remoting/protocol/protocol_mock_objects.h index 716a3b4..199dd2d 100644 --- a/remoting/protocol/protocol_mock_objects.h +++ b/remoting/protocol/protocol_mock_objects.h @@ -128,8 +128,6 @@ class MockSession : public Session { MOCK_METHOD1(set_initiator_token, void(const std::string& initiator_token)); MOCK_METHOD0(receiver_token, const std::string&()); MOCK_METHOD1(set_receiver_token, void(const std::string& receiver_token)); - MOCK_METHOD1(set_shared_secret, void(const std::string& secret)); - MOCK_METHOD0(shared_secret, const std::string&()); MOCK_METHOD0(Close, void()); private: diff --git a/remoting/protocol/session.h b/remoting/protocol/session.h index fc40a6d..059a21f 100644 --- a/remoting/protocol/session.h +++ b/remoting/protocol/session.h @@ -92,10 +92,6 @@ class Session : public base::NonThreadSafe { virtual const std::string& receiver_token() = 0; virtual void set_receiver_token(const std::string& receiver_token) = 0; - // A shared secret to use to mutually-authenticate the SSL channels. - virtual void set_shared_secret(const std::string& secret) = 0; - virtual const std::string& shared_secret() = 0; - // Closes connection. Callbacks are guaranteed not to be called // after this method returns. Must be called before the object is // destroyed, unless the state is set to FAILED or CLOSED. |