| Index: remoting/protocol/jingle_session.cc
|
| diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc
|
| index 8b258f3626bb1ec2e1c7a9808663e9cf8ac67895..071cb90231ff18f1544810e80222c56d5014093b 100644
|
| --- a/remoting/protocol/jingle_session.cc
|
| +++ b/remoting/protocol/jingle_session.cc
|
| @@ -4,22 +4,22 @@
|
|
|
| #include "remoting/protocol/jingle_session.h"
|
|
|
| +#include "base/base64.h"
|
| #include "base/bind.h"
|
| #include "base/location.h"
|
| #include "base/message_loop_proxy.h"
|
| #include "base/rand_util.h"
|
| #include "base/stl_util.h"
|
| #include "crypto/hmac.h"
|
| -#include "crypto/rsa_private_key.h"
|
| #include "net/base/net_errors.h"
|
| #include "net/socket/stream_socket.h"
|
| #include "remoting/base/constants.h"
|
| #include "remoting/protocol/auth_util.h"
|
| +#include "remoting/protocol/authenticator.h"
|
| +#include "remoting/protocol/channel_authenticator.h"
|
| #include "remoting/protocol/jingle_datagram_connector.h"
|
| #include "remoting/protocol/jingle_session_manager.h"
|
| #include "remoting/protocol/jingle_stream_connector.h"
|
| -#include "remoting/protocol/v1_client_channel_authenticator.h"
|
| -#include "remoting/protocol/v1_host_channel_authenticator.h"
|
| #include "third_party/libjingle/source/talk/base/thread.h"
|
| #include "third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.h"
|
| #include "third_party/libjingle/source/talk/p2p/base/session.h"
|
| @@ -30,41 +30,21 @@ using cricket::BaseSession;
|
| namespace remoting {
|
| namespace protocol {
|
|
|
| -// static
|
| -JingleSession* JingleSession::CreateClientSession(
|
| - JingleSessionManager* manager, const std::string& host_public_key) {
|
| - return new JingleSession(manager, "", NULL, host_public_key);
|
| -}
|
| -
|
| -// static
|
| -JingleSession* JingleSession::CreateServerSession(
|
| - JingleSessionManager* manager,
|
| - const std::string& certificate,
|
| - crypto::RSAPrivateKey* key) {
|
| - return new JingleSession(manager, certificate, key, "");
|
| -}
|
| -
|
| JingleSession::JingleSession(
|
| JingleSessionManager* jingle_session_manager,
|
| - const std::string& local_cert,
|
| - crypto::RSAPrivateKey* local_private_key,
|
| - const std::string& peer_public_key)
|
| + cricket::Session* cricket_session,
|
| + Authenticator* authenticator)
|
| : jingle_session_manager_(jingle_session_manager),
|
| - local_cert_(local_cert),
|
| + authenticator_(authenticator),
|
| state_(INITIALIZING),
|
| error_(OK),
|
| closing_(false),
|
| - cricket_session_(NULL),
|
| + cricket_session_(cricket_session),
|
| config_set_(false),
|
| ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
|
| - // TODO(hclam): Need a better way to clone a key.
|
| - if (local_private_key) {
|
| - std::vector<uint8> key_bytes;
|
| - CHECK(local_private_key->ExportPrivateKey(&key_bytes));
|
| - local_private_key_.reset(
|
| - crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
|
| - CHECK(local_private_key_.get());
|
| - }
|
| + jid_ = cricket_session_->remote_name();
|
| + cricket_session_->SignalState.connect(this, &JingleSession::OnSessionState);
|
| + cricket_session_->SignalError.connect(this, &JingleSession::OnSessionError);
|
| }
|
|
|
| JingleSession::~JingleSession() {
|
| @@ -74,15 +54,11 @@ JingleSession::~JingleSession() {
|
| jingle_session_manager_->SessionDestroyed(this);
|
| }
|
|
|
| -void JingleSession::Init(cricket::Session* cricket_session) {
|
| - DCHECK(CalledOnValidThread());
|
| -
|
| - cricket_session_ = cricket_session;
|
| - jid_ = cricket_session_->remote_name();
|
| - cricket_session_->SignalState.connect(
|
| - this, &JingleSession::OnSessionState);
|
| - cricket_session_->SignalError.connect(
|
| - this, &JingleSession::OnSessionError);
|
| +void JingleSession::Initiate() {
|
| + DCHECK_EQ(authenticator_->state(), Authenticator::MESSAGE_READY);
|
| + cricket_session_->Initiate(
|
| + jid_, CreateSessionDescription(candidate_config()->Clone(),
|
| + authenticator_->GetNextMessage()));
|
| }
|
|
|
| void JingleSession::CloseInternal(int result, Error error) {
|
| @@ -201,11 +177,6 @@ void JingleSession::set_candidate_config(
|
| candidate_config_.reset(candidate_config);
|
| }
|
|
|
| -const std::string& JingleSession::local_certificate() const {
|
| - DCHECK(CalledOnValidThread());
|
| - return local_cert_;
|
| -}
|
| -
|
| const SessionConfig& JingleSession::config() {
|
| DCHECK(CalledOnValidThread());
|
| DCHECK(config_set_);
|
| @@ -219,37 +190,6 @@ void JingleSession::set_config(const SessionConfig& config) {
|
| config_set_ = true;
|
| }
|
|
|
| -const std::string& JingleSession::initiator_token() {
|
| - DCHECK(CalledOnValidThread());
|
| - return initiator_token_;
|
| -}
|
| -
|
| -void JingleSession::set_initiator_token(const std::string& initiator_token) {
|
| - DCHECK(CalledOnValidThread());
|
| - initiator_token_ = initiator_token;
|
| -}
|
| -
|
| -const std::string& JingleSession::receiver_token() {
|
| - DCHECK(CalledOnValidThread());
|
| - return receiver_token_;
|
| -}
|
| -
|
| -void JingleSession::set_receiver_token(const std::string& receiver_token) {
|
| - DCHECK(CalledOnValidThread());
|
| - 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());
|
|
|
| @@ -310,13 +250,6 @@ void JingleSession::OnInitiate() {
|
| DCHECK(CalledOnValidThread());
|
| jid_ = cricket_session_->remote_name();
|
|
|
| - if (!cricket_session_->initiator()) {
|
| - const protocol::ContentDescription* content_description =
|
| - static_cast<const protocol::ContentDescription*>(
|
| - GetContentInfo()->description);
|
| - CHECK(content_description);
|
| - }
|
| -
|
| if (cricket_session_->initiator()) {
|
| // Set state to CONNECTING if this is an outgoing message. We need
|
| // to post this task because channel creation works only after we
|
| @@ -347,9 +280,22 @@ bool JingleSession::InitializeConfigFromDescription(
|
| static_cast<const protocol::ContentDescription*>(content->description);
|
| CHECK(content_description);
|
|
|
| - remote_cert_ = content_description->certificate();
|
| - if (remote_cert_.empty()) {
|
| - LOG(ERROR) << "Connection response does not specify certificate";
|
| + // Process authenticator message.
|
| + const buzz::XmlElement* auth_message =
|
| + content_description->authenticator_message();
|
| + if (!auth_message) {
|
| + DLOG(WARNING) << "Received session-accept without authentication message "
|
| + << auth_message->Str();
|
| + return false;
|
| + }
|
| +
|
| + 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::ACCEPTED) {
|
| return false;
|
| }
|
|
|
| @@ -391,7 +337,25 @@ void JingleSession::OnTerminate() {
|
| void JingleSession::AcceptConnection() {
|
| SetState(CONNECTING);
|
|
|
| - if (!jingle_session_manager_->AcceptConnection(this, cricket_session_)) {
|
| + const cricket::SessionDescription* session_description =
|
| + cricket_session_->remote_description();
|
| + const cricket::ContentInfo* content =
|
| + session_description->FirstContentByType(kChromotingXmlNamespace);
|
| +
|
| + CHECK(content);
|
| + const ContentDescription* content_description =
|
| + static_cast<const ContentDescription*>(content->description);
|
| + candidate_config_.reset(content_description->config()->Clone());
|
| +
|
| + SessionManager::IncomingSessionResponse response =
|
| + jingle_session_manager_->AcceptConnection(this);
|
| + if (response != SessionManager::ACCEPT) {
|
| + if (response == SessionManager::INCOMPATIBLE) {
|
| + cricket_session_->TerminateWithReason(
|
| + cricket::STR_TERMINATE_INCOMPATIBLE_PARAMETERS);
|
| + } else {
|
| + cricket_session_->TerminateWithReason(cricket::STR_TERMINATE_DECLINE);
|
| + }
|
| Close();
|
| // Release session so that JingleSessionManager::SessionDestroyed()
|
| // doesn't try to call cricket::SessionManager::DestroySession() for it.
|
| @@ -400,8 +364,40 @@ void JingleSession::AcceptConnection() {
|
| return;
|
| }
|
|
|
| - if (!VerifySupportAuthToken(jid_, shared_secret_, initiator_token()))
|
| + const buzz::XmlElement* auth_message =
|
| + content_description->authenticator_message();
|
| + if (!auth_message) {
|
| + DLOG(WARNING) << "Received session-initiate without authenticator message.";
|
| + CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL);
|
| + return;
|
| + }
|
| +
|
| + authenticator_.reset(
|
| + jingle_session_manager_->CreateAuthenticator(jid(), auth_message));
|
| + if (!authenticator_.get()) {
|
| + CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL);
|
| + return;
|
| + }
|
| +
|
| + 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);
|
| + if (authenticator_->state() == Authenticator::REJECTED) {
|
| CloseInternal(net::ERR_CONNECTION_FAILED, AUTHENTICATION_FAILED);
|
| + return;
|
| + }
|
| +
|
| + // Connection must be configured by the AcceptConnection() callback.
|
| + CandidateSessionConfig* candidate_config =
|
| + CandidateSessionConfig::CreateFrom(config());
|
| +
|
| + buzz::XmlElement* auth_reply = NULL;
|
| + if (authenticator_->state() == Authenticator::MESSAGE_READY)
|
| + auth_reply = authenticator_->GetNextMessage();
|
| + DCHECK_EQ(authenticator_->state(), Authenticator::ACCEPTED);
|
| + cricket_session_->Accept(
|
| + CreateSessionDescription(candidate_config, auth_reply));
|
| }
|
|
|
| void JingleSession::AddChannelConnector(
|
| @@ -420,14 +416,8 @@ void JingleSession::AddChannelConnector(
|
| }
|
|
|
| channel_connectors_[name] = connector;
|
| - ChannelAuthenticator* authenticator;
|
| - if (cricket_session_->initiator()) {
|
| - authenticator = new V1ClientChannelAuthenticator(
|
| - remote_cert_, shared_secret_);
|
| - } else {
|
| - authenticator = new V1HostChannelAuthenticator(
|
| - local_cert_, local_private_key_.get(), shared_secret_);
|
| - }
|
| + ChannelAuthenticator* authenticator =
|
| + authenticator_->CreateChannelAuthenticator();
|
| connector->Connect(authenticator, raw_channel);
|
|
|
| // Workaround bug in libjingle - it doesn't connect channels if they
|
| @@ -471,5 +461,16 @@ void JingleSession::SetState(State new_state) {
|
| }
|
| }
|
|
|
| +// static
|
| +cricket::SessionDescription* JingleSession::CreateSessionDescription(
|
| + const CandidateSessionConfig* config,
|
| + const buzz::XmlElement* authenticator_message) {
|
| + cricket::SessionDescription* desc = new cricket::SessionDescription();
|
| + desc->AddContent(
|
| + ContentDescription::kChromotingContentName, kChromotingXmlNamespace,
|
| + new ContentDescription(config, authenticator_message));
|
| + return desc;
|
| +}
|
| +
|
| } // namespace protocol
|
| } // namespace remoting
|
|
|