summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 04:43:17 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 04:43:17 +0000
commitf4453851934ac99908286f195ac0a4379c2b9852 (patch)
treeebf7aff9bfa148994ca1cfc2cce325c0d599514f /remoting
parentdc51d1ccc18135493f01464e38ed462825ae8e35 (diff)
downloadchromium_src-f4453851934ac99908286f195ac0a4379c2b9852.zip
chromium_src-f4453851934ac99908286f195ac0a4379c2b9852.tar.gz
chromium_src-f4453851934ac99908286f195ac0a4379c2b9852.tar.bz2
Use Authenticator interface in Session and SessionManager.
BUG=105214 Review URL: http://codereview.chromium.org/8619011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112127 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/host/chromoting_host.cc28
-rw-r--r--remoting/host/chromoting_host.h10
-rw-r--r--remoting/host/plugin/host_script_object.cc2
-rw-r--r--remoting/host/simple_host_process.cc2
-rw-r--r--remoting/protocol/connection_to_host.cc12
-rw-r--r--remoting/protocol/content_description.cc72
-rw-r--r--remoting/protocol/content_description.h16
-rw-r--r--remoting/protocol/fake_session.cc24
-rw-r--r--remoting/protocol/fake_session.h13
-rw-r--r--remoting/protocol/jingle_session.cc191
-rw-r--r--remoting/protocol/jingle_session.h57
-rw-r--r--remoting/protocol/jingle_session_manager.cc125
-rw-r--r--remoting/protocol/jingle_session_manager.h33
-rw-r--r--remoting/protocol/jingle_session_unittest.cc192
-rw-r--r--remoting/protocol/pepper_session.cc77
-rw-r--r--remoting/protocol/pepper_session.h16
-rw-r--r--remoting/protocol/pepper_session_manager.cc18
-rw-r--r--remoting/protocol/pepper_session_manager.h10
-rw-r--r--remoting/protocol/session.h10
-rw-r--r--remoting/protocol/session_manager.h20
20 files changed, 425 insertions, 503 deletions
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc
index b5365c6..9e3d514 100644
--- a/remoting/host/chromoting_host.cc
+++ b/remoting/host/chromoting_host.cc
@@ -18,7 +18,6 @@
#include "remoting/host/desktop_environment.h"
#include "remoting/host/event_executor.h"
#include "remoting/host/host_config.h"
-#include "remoting/host/host_key_pair.h"
#include "remoting/host/screen_recorder.h"
#include "remoting/jingle_glue/xmpp_signal_strategy.h"
#include "remoting/protocol/connection_to_client.h"
@@ -27,6 +26,7 @@
#include "remoting/protocol/input_stub.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/session_config.h"
+#include "remoting/protocol/v1_authenticator.h"
using remoting::protocol::ConnectionToClient;
using remoting::protocol::InputStub;
@@ -77,6 +77,12 @@ void ChromotingHost::Start() {
return;
state_ = kStarted;
+ // Assign key and certificate to server.
+ if (!key_pair_.Load(config_)) {
+ LOG(ERROR) << "Failed to load key pair for the host.";
+ return;
+ }
+
// Use an XMPP connection to the Talk network for session signalling.
std::string xmpp_login;
std::string xmpp_auth_token;
@@ -155,6 +161,14 @@ void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) {
status_observers_.push_back(observer);
}
+void ChromotingHost::SetSharedSecret(const std::string& shared_secret) {
+ DCHECK(context_->network_message_loop()->BelongsToCurrentThread());
+ session_manager_->set_authenticator_factory(
+ new protocol::V1HostAuthenticatorFactory(
+ key_pair_.GenerateCertificate(), key_pair_.CopyPrivateKey(),
+ shared_secret));
+}
+
////////////////////////////////////////////////////////////////////////////
// protocol::ClientSession::EventHandler implementation.
void ChromotingHost::OnSessionAuthenticated(ClientSession* client) {
@@ -260,14 +274,8 @@ void ChromotingHost::OnStateChange(
protocol::JingleSessionManager* server =
new protocol::JingleSessionManager(context_->network_message_loop());
- // Assign key and certificate to server.
- HostKeyPair key_pair;
- CHECK(key_pair.Load(config_))
- << "Failed to load server authentication data";
-
- server->Init(local_jid_, signal_strategy_.get(), this,
- key_pair.CopyPrivateKey(), key_pair.GenerateCertificate(),
- allow_nat_traversal_);
+ server->Init(local_jid_, signal_strategy_.get(),
+ this, allow_nat_traversal_);
session_manager_.reset(server);
@@ -330,8 +338,6 @@ void ChromotingHost::OnIncomingSession(
}
session->set_config(config);
- // Provide the Access Code as shared secret for SSL channel authentication.
- session->set_shared_secret(access_code_);
*response = protocol::SessionManager::ACCEPT;
diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h
index 0f112e5..290859ef3 100644
--- a/remoting/host/chromoting_host.h
+++ b/remoting/host/chromoting_host.h
@@ -14,6 +14,7 @@
#include "remoting/host/capturer.h"
#include "remoting/host/client_session.h"
#include "remoting/host/desktop_environment.h"
+#include "remoting/host/host_key_pair.h"
#include "remoting/host/host_status_observer.h"
#include "remoting/host/ui_strings.h"
#include "remoting/jingle_glue/jingle_thread.h"
@@ -91,6 +92,11 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
// started.
void AddStatusObserver(HostStatusObserver* observer);
+ // Sets shared secret for the host. All incoming connections are
+ // rejected if shared secret isn't set. Must be called on the
+ // network thread after the host is started.
+ void SetSharedSecret(const std::string& shared_secret);
+
////////////////////////////////////////////////////////////////////////////
// SignalStrategy::StatusObserver implementation.
virtual void OnStateChange(
@@ -119,9 +125,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.
@@ -183,6 +186,7 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>,
ChromotingHostContext* context_;
DesktopEnvironment* desktop_environment_;
scoped_refptr<MutableHostConfig> config_;
+ HostKeyPair key_pair_;
bool allow_nat_traversal_;
// Connection objects.
diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc
index d835da8..f826b8b 100644
--- a/remoting/host/plugin/host_script_object.cc
+++ b/remoting/host/plugin/host_script_object.cc
@@ -653,7 +653,7 @@ void HostNPScriptObject::OnReceivedSupportID(
std::string host_secret = GenerateSupportHostSecret();
std::string access_code = support_id + host_secret;
- host_->set_access_code(access_code);
+ host_->SetSharedSecret(access_code);
{
base::AutoLock lock(access_code_lock_);
diff --git a/remoting/host/simple_host_process.cc b/remoting/host/simple_host_process.cc
index 293ad27..c19a73c 100644
--- a/remoting/host/simple_host_process.cc
+++ b/remoting/host/simple_host_process.cc
@@ -223,7 +223,7 @@ class SimpleHost {
std::cout << "Support id: " << access_code << std::endl;
// Tell the ChromotingHost the access code, to use as shared-secret.
- host_->set_access_code(access_code);
+ host_->SetSharedSecret(access_code);
} else {
LOG(ERROR) << "If you haven't done so recently, try running"
<< " remoting/tools/register_host.py.";
diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc
index 84c2a3f..c1145a7 100644
--- a/remoting/protocol/connection_to_host.cc
+++ b/remoting/protocol/connection_to_host.cc
@@ -17,6 +17,7 @@
#include "remoting/protocol/client_stub.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/pepper_session_manager.h"
+#include "remoting/protocol/v1_authenticator.h"
#include "remoting/protocol/video_reader.h"
#include "remoting/protocol/video_stub.h"
#include "remoting/protocol/util.h"
@@ -100,7 +101,7 @@ void ConnectionToHost::InitSession() {
session_manager_.reset(new PepperSessionManager(pp_instance_));
session_manager_->Init(
- local_jid_, signal_strategy_.get(), this, NULL, "", allow_nat_traversal_);
+ local_jid_, signal_strategy_.get(), this, allow_nat_traversal_);
}
const SessionConfig& ConnectionToHost::config() {
@@ -132,15 +133,12 @@ void ConnectionToHost::OnSessionManagerInitialized() {
// After SessionManager is initialized we can try to connect to the host.
CandidateSessionConfig* candidate_config =
CandidateSessionConfig::CreateDefault();
- std::string client_token =
- protocol::GenerateSupportAuthToken(local_jid_, access_code_);
+ V1ClientAuthenticator* authenticator =
+ new V1ClientAuthenticator(local_jid_, access_code_);
session_.reset(session_manager_->Connect(
- host_jid_, host_public_key_, client_token, candidate_config,
+ host_jid_, authenticator, candidate_config,
base::Bind(&ConnectionToHost::OnSessionStateChange,
base::Unretained(this))));
-
- // Set the shared-secret for securing SSL channels.
- session_->set_shared_secret(access_code_);
}
void ConnectionToHost::OnIncomingSession(
diff --git a/remoting/protocol/content_description.cc b/remoting/protocol/content_description.cc
index 7cfeac5..d6947d7 100644
--- a/remoting/protocol/content_description.cc
+++ b/remoting/protocol/content_description.cc
@@ -4,7 +4,6 @@
#include "remoting/protocol/content_description.h"
-#include "base/base64.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "remoting/base/constants.h"
@@ -29,8 +28,6 @@ const char kEventTag[] = "event";
const char kVideoTag[] = "video";
const char kResolutionTag[] = "initial-resolution";
const char kAuthenticationTag[] = "authentication";
-const char kCertificateTag[] = "certificate";
-const char kAuthTokenTag[] = "auth-token";
const char kTransportAttr[] = "transport";
const char kVersionAttr[] = "version";
@@ -150,11 +147,9 @@ bool ParseChannelConfig(const XmlElement* element, bool codec_required,
ContentDescription::ContentDescription(
const CandidateSessionConfig* candidate_config,
- const std::string& auth_token,
- const std::string& certificate)
+ const buzz::XmlElement* authenticator_message)
: candidate_config_(candidate_config),
- auth_token_(auth_token),
- certificate_(certificate) {
+ authenticator_message_(authenticator_message) {
}
ContentDescription::~ContentDescription() { }
@@ -167,8 +162,7 @@ ContentDescription::~ContentDescription() { }
// <video transport="srtp" codec="vp8" version="1" />
// <initial-resolution width="800" height="600" />
// <authentication>
-// <certificate>[BASE64 Encoded Certificate]</certificate>
-// <auth-token>...</auth-token> // IT2Me only.
+// Message created by Authenticator implementation.
// </authentication>
// </description>
//
@@ -203,31 +197,10 @@ XmlElement* ContentDescription::ToXml() const {
config()->initial_resolution().height));
root->AddElement(resolution_tag);
- if (!certificate().empty() || !auth_token().empty()) {
- XmlElement* authentication_tag = new XmlElement(
- QName(kChromotingXmlNamespace, kAuthenticationTag));
-
- if (!certificate().empty()) {
- XmlElement* certificate_tag = new XmlElement(
- QName(kChromotingXmlNamespace, kCertificateTag));
-
- std::string base64_cert;
- if (!base::Base64Encode(certificate(), &base64_cert)) {
- LOG(DFATAL) << "Cannot perform base64 encode on certificate";
- }
-
- certificate_tag->SetBodyText(base64_cert);
- authentication_tag->AddElement(certificate_tag);
- }
-
- if (!auth_token().empty()) {
- XmlElement* auth_token_tag = new XmlElement(
- QName(kChromotingXmlNamespace, kAuthTokenTag));
- auth_token_tag->SetBodyText(auth_token());
- authentication_tag->AddElement(auth_token_tag);
- }
-
- root->AddElement(authentication_tag);
+ if (authenticator_message_.get()) {
+ DCHECK(authenticator_message_->Name() ==
+ QName(kChromotingXmlNamespace, kAuthenticationTag));
+ root->AddElement(new XmlElement(*authenticator_message_));
}
return root;
@@ -287,38 +260,19 @@ ContentDescription* ContentDescription::ParseXml(
return NULL;
}
ScreenResolution resolution(width, height);
- if (!resolution.IsValid()) {
+ if (!resolution.IsValid())
return NULL;
- }
*config->mutable_initial_resolution() = resolution;
- // Parse authentication information.
- std::string certificate;
- std::string auth_token;
+ scoped_ptr<XmlElement> authenticator_message;
child = element->FirstNamed(QName(kChromotingXmlNamespace,
kAuthenticationTag));
- if (child) {
- // Parse the certificate.
- const XmlElement* cert_tag =
- child->FirstNamed(QName(kChromotingXmlNamespace, kCertificateTag));
- if (cert_tag) {
- std::string base64_cert = cert_tag->BodyText();
- if (!base::Base64Decode(base64_cert, &certificate)) {
- LOG(ERROR) << "Failed to decode certificate received from the peer.";
- return NULL;
- }
- }
-
- // Parse auth-token.
- const XmlElement* auth_token_tag =
- child->FirstNamed(QName(kChromotingXmlNamespace, kAuthTokenTag));
- if (auth_token_tag) {
- auth_token = auth_token_tag->BodyText();
- }
- }
+ if (child)
+ authenticator_message.reset(new XmlElement(*child));
- return new ContentDescription(config.release(), auth_token, certificate);
+ return new ContentDescription(
+ config.release(), authenticator_message.release());
}
LOG(ERROR) << "Invalid description: " << element->Str();
return NULL;
diff --git a/remoting/protocol/content_description.h b/remoting/protocol/content_description.h
index 5e4053f..95ccf60 100644
--- a/remoting/protocol/content_description.h
+++ b/remoting/protocol/content_description.h
@@ -28,17 +28,18 @@ class ContentDescription : public cricket::ContentDescription {
public:
static const char kChromotingContentName[];
+ // Takes ownership of |config| and |authenticator_message|.
ContentDescription(const CandidateSessionConfig* config,
- const std::string& auth_token,
- const std::string& certificate);
+ const buzz::XmlElement* authenticator_message);
virtual ~ContentDescription();
const CandidateSessionConfig* config() const {
return candidate_config_.get();
}
- const std::string& auth_token() const { return auth_token_; }
- const std::string& certificate() const { return certificate_; }
+ const buzz::XmlElement* authenticator_message() const {
+ return authenticator_message_.get();
+ }
buzz::XmlElement* ToXml() const;
@@ -46,12 +47,7 @@ class ContentDescription : public cricket::ContentDescription {
private:
scoped_ptr<const CandidateSessionConfig> candidate_config_;
-
- // This may contain the initiating, or the accepting token depending on
- // context.
- std::string auth_token_;
-
- std::string certificate_;
+ scoped_ptr<const buzz::XmlElement> authenticator_message_;
};
} // namespace protocol
diff --git a/remoting/protocol/fake_session.cc b/remoting/protocol/fake_session.cc
index f8f1e97..c09a62a5 100644
--- a/remoting/protocol/fake_session.cc
+++ b/remoting/protocol/fake_session.cc
@@ -261,30 +261,6 @@ void FakeSession::set_config(const SessionConfig& config) {
config_ = config;
}
-const std::string& FakeSession::initiator_token() {
- return initiator_token_;
-}
-
-void FakeSession::set_initiator_token(const std::string& initiator_token) {
- initiator_token_ = initiator_token;
-}
-
-const std::string& FakeSession::receiver_token() {
- return receiver_token_;
-}
-
-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 2516a78..7eaab6b 100644
--- a/remoting/protocol/fake_session.h
+++ b/remoting/protocol/fake_session.h
@@ -156,14 +156,6 @@ class FakeSession : public Session {
virtual const SessionConfig& config() OVERRIDE;
virtual void set_config(const SessionConfig& config) OVERRIDE;
- virtual const std::string& initiator_token() OVERRIDE;
- 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;
public:
@@ -175,11 +167,6 @@ class FakeSession : public Session {
std::map<std::string, FakeSocket*> stream_channels_;
std::map<std::string, FakeUdpSocket*> datagram_channels_;
- std::string initiator_token_;
- std::string receiver_token_;
-
- std::string shared_secret_;
-
std::string jid_;
Session::Error error_;
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc
index b008bb4a..dd66e04 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() {
@@ -75,15 +55,11 @@ JingleSession::~JingleSession() {
DCHECK(channel_connectors_.empty());
}
-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::SendSessionInitiate() {
+ DCHECK_EQ(authenticator_->state(), Authenticator::MESSAGE_READY);
+ cricket_session_->Initiate(
+ jid_, CreateSessionDescription(candidate_config()->Clone(),
+ authenticator_->GetNextMessage()));
}
void JingleSession::CloseInternal(int result, Error error) {
@@ -199,11 +175,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_);
@@ -217,37 +188,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());
@@ -308,13 +248,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
@@ -345,9 +278,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;
}
@@ -389,7 +335,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.
@@ -398,8 +362,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(
@@ -418,14 +414,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
@@ -469,5 +459,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
diff --git a/remoting/protocol/jingle_session.h b/remoting/protocol/jingle_session.h
index b2f831b..75f061f 100644
--- a/remoting/protocol/jingle_session.h
+++ b/remoting/protocol/jingle_session.h
@@ -7,16 +7,15 @@
#include "base/memory/ref_counted.h"
#include "base/task.h"
-#include "crypto/rsa_private_key.h"
#include "net/base/completion_callback.h"
#include "remoting/protocol/session.h"
#include "third_party/libjingle/source/talk/base/sigslot.h"
#include "third_party/libjingle/source/talk/p2p/base/session.h"
namespace remoting {
-
namespace protocol {
+class Authenticator;
class JingleChannelConnector;
class JingleSessionManager;
@@ -41,12 +40,6 @@ class JingleSession : public protocol::Session,
virtual const CandidateSessionConfig* candidate_config() OVERRIDE;
virtual const SessionConfig& config() OVERRIDE;
virtual void set_config(const SessionConfig& config) OVERRIDE;
- virtual const std::string& initiator_token() OVERRIDE;
- 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:
@@ -56,31 +49,17 @@ class JingleSession : public protocol::Session,
typedef std::map<std::string, JingleChannelConnector*> ChannelConnectorsMap;
- // Create a JingleSession used in client mode. A server certificate is
- // required.
- static JingleSession* CreateClientSession(JingleSessionManager* manager,
- const std::string& host_public_key);
-
- // Create a JingleSession used in server mode. A server certificate and
- // private key is provided. |key| is copied in the constructor.
- //
- // TODO(sergeyu): Remove |certificate| and |key| when we stop using TLS.
- static JingleSession* CreateServerSession(
- JingleSessionManager* manager,
- const std::string& certificate,
- crypto::RSAPrivateKey* key);
-
- // TODO(sergeyu): Change type of |peer_public_key| to RSAPublicKey.
+ // Takes ownership of |authenticator|.
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);
virtual ~JingleSession();
// Called by JingleSessionManager.
void set_candidate_config(const CandidateSessionConfig* candidate_config);
- const std::string& local_certificate() const;
- void Init(cricket::Session* cricket_session);
+
+ // Sends session-initiate for new session.
+ void SendSessionInitiate();
// Close all the channels and terminate the session. |result|
// defines error code that should returned to currently opened
@@ -123,24 +102,15 @@ class JingleSession : public protocol::Session,
void SetState(State new_state);
+ static cricket::SessionDescription* CreateSessionDescription(
+ const CandidateSessionConfig* candidate_config,
+ const buzz::XmlElement* authenticator_message);
+
// JingleSessionManager that created this session. Guaranteed to
// exist throughout the lifetime of the session.
JingleSessionManager* jingle_session_manager_;
- // Certificates used for connection. Currently only receiving side
- // has a certificate.
- std::string local_cert_;
- std::string remote_cert_;
-
- // Private key used in SSL server sockets.
- scoped_ptr<crypto::RSAPrivateKey> local_private_key_;
-
- // Public key of the peer.
- std::string peer_public_key_;
-
- // Shared secret to use in channel authentication. This is currently only
- // used in IT2Me.
- std::string shared_secret_;
+ scoped_ptr<Authenticator> authenticator_;
State state_;
StateChangeCallback state_change_callback_;
@@ -159,9 +129,6 @@ class JingleSession : public protocol::Session,
SessionConfig config_;
bool config_set_;
- std::string initiator_token_;
- std::string receiver_token_;
-
// These data members are only set on the receiving side.
scoped_ptr<const CandidateSessionConfig> candidate_config_;
diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc
index 8408f94..2a24441 100644
--- a/remoting/protocol/jingle_session_manager.cc
+++ b/remoting/protocol/jingle_session_manager.cc
@@ -6,6 +6,7 @@
#include <limits>
+#include "base/base64.h"
#include "base/bind.h"
#include "base/message_loop_proxy.h"
#include "base/string_util.h"
@@ -14,6 +15,7 @@
#include "remoting/jingle_glue/jingle_info_request.h"
#include "remoting/jingle_glue/jingle_signaling_connector.h"
#include "remoting/jingle_glue/signal_strategy.h"
+#include "remoting/protocol/authenticator.h"
#include "third_party/libjingle/source/talk/base/basicpacketsocketfactory.h"
#include "third_party/libjingle/source/talk/p2p/base/constants.h"
#include "third_party/libjingle/source/talk/p2p/base/sessionmanager.h"
@@ -46,8 +48,6 @@ void JingleSessionManager::Init(
const std::string& local_jid,
SignalStrategy* signal_strategy,
Listener* listener,
- crypto::RSAPrivateKey* private_key,
- const std::string& certificate,
bool allow_nat_traversal) {
DCHECK(CalledOnValidThread());
@@ -57,8 +57,6 @@ void JingleSessionManager::Init(
local_jid_ = local_jid;
signal_strategy_ = signal_strategy;
listener_ = listener;
- private_key_.reset(private_key);
- certificate_ = certificate;
allow_nat_traversal_ = allow_nat_traversal;
if (!network_manager_.get()) {
@@ -119,30 +117,30 @@ void JingleSessionManager::Close() {
}
}
+void JingleSessionManager::set_authenticator_factory(
+ AuthenticatorFactory* authenticator_factory) {
+ DCHECK(CalledOnValidThread());
+ authenticator_factory_.reset(authenticator_factory);
+}
+
Session* JingleSessionManager::Connect(
const std::string& host_jid,
- const std::string& host_public_key,
- const std::string& receiver_token,
+ Authenticator* authenticator,
CandidateSessionConfig* candidate_config,
const Session::StateChangeCallback& state_change_callback) {
DCHECK(CalledOnValidThread());
- // Can be called from any thread.
- JingleSession* jingle_session =
- JingleSession::CreateClientSession(this, host_public_key);
- jingle_session->set_candidate_config(candidate_config);
- jingle_session->set_receiver_token(receiver_token);
-
cricket::Session* cricket_session = cricket_session_manager_->CreateSession(
local_jid_, kChromotingXmlNamespace);
+ cricket_session->set_remote_name(host_jid);
- // Initialize connection object before we send initiate stanza.
+ JingleSession* jingle_session =
+ new JingleSession(this, cricket_session, authenticator);
+ jingle_session->set_candidate_config(candidate_config);
jingle_session->SetStateChangeCallback(state_change_callback);
- jingle_session->Init(cricket_session);
sessions_.push_back(jingle_session);
- cricket_session->Initiate(host_jid, CreateClientSessionDescription(
- jingle_session->candidate_config()->Clone(), receiver_token));
+ jingle_session->SendSessionInitiate();
return jingle_session;
}
@@ -154,15 +152,10 @@ void JingleSessionManager::OnSessionCreate(
// Allow local connections.
cricket_session->set_allow_local_ips(true);
- // If this is an incoming session, create a JingleSession on top of it.
if (incoming) {
- DCHECK(!certificate_.empty());
- DCHECK(private_key_.get());
-
- JingleSession* jingle_session = JingleSession::CreateServerSession(
- this, certificate_, private_key_.get());
+ JingleSession* jingle_session =
+ new JingleSession(this, cricket_session, NULL);
sessions_.push_back(jingle_session);
- jingle_session->Init(cricket_session);
}
}
@@ -178,63 +171,26 @@ void JingleSessionManager::OnSessionDestroy(cricket::Session* cricket_session) {
}
}
-bool JingleSessionManager::AcceptConnection(
- JingleSession* jingle_session,
- cricket::Session* cricket_session) {
+SessionManager::IncomingSessionResponse JingleSessionManager::AcceptConnection(
+ JingleSession* jingle_session) {
DCHECK(CalledOnValidThread());
// Reject connection if we are closed.
- if (closed_) {
- cricket_session->Reject(cricket::STR_TERMINATE_DECLINE);
- return false;
- }
-
- const cricket::SessionDescription* session_description =
- cricket_session->remote_description();
- const cricket::ContentInfo* content =
- session_description->FirstContentByType(kChromotingXmlNamespace);
-
- CHECK(content);
+ if (closed_)
+ return SessionManager::DECLINE;
- const ContentDescription* content_description =
- static_cast<const ContentDescription*>(content->description);
- jingle_session->set_candidate_config(content_description->config()->Clone());
- jingle_session->set_initiator_token(content_description->auth_token());
-
- // Always reject connection if there is no callback.
- IncomingSessionResponse response = protocol::SessionManager::DECLINE;
-
- // Use the callback to generate a response.
+ IncomingSessionResponse response = SessionManager::DECLINE;
listener_->OnIncomingSession(jingle_session, &response);
+ return response;
+}
- switch (response) {
- case SessionManager::ACCEPT: {
- // Connection must be configured by the callback.
- CandidateSessionConfig* candidate_config =
- CandidateSessionConfig::CreateFrom(jingle_session->config());
- cricket_session->Accept(
- CreateHostSessionDescription(candidate_config,
- jingle_session->local_certificate()));
- break;
- }
-
- case SessionManager::INCOMPATIBLE: {
- cricket_session->TerminateWithReason(
- cricket::STR_TERMINATE_INCOMPATIBLE_PARAMETERS);
- return false;
- }
-
- case SessionManager::DECLINE: {
- cricket_session->TerminateWithReason(cricket::STR_TERMINATE_DECLINE);
- return false;
- }
-
- default: {
- NOTREACHED();
- }
- }
+Authenticator* JingleSessionManager::CreateAuthenticator(
+ const std::string& jid, const buzz::XmlElement* auth_message) {
+ DCHECK(CalledOnValidThread());
- return true;
+ if (!authenticator_factory_.get())
+ return NULL;
+ return authenticator_factory_->CreateAuthenticator(jid, auth_message);
}
void JingleSessionManager::SessionDestroyed(JingleSession* jingle_session) {
@@ -293,28 +249,5 @@ bool JingleSessionManager::WriteContent(
return true;
}
-// static
-cricket::SessionDescription*
-JingleSessionManager::CreateClientSessionDescription(
- const CandidateSessionConfig* config,
- const std::string& auth_token) {
- cricket::SessionDescription* desc = new cricket::SessionDescription();
- desc->AddContent(
- ContentDescription::kChromotingContentName, kChromotingXmlNamespace,
- new ContentDescription(config, auth_token, ""));
- return desc;
-}
-
-// static
-cricket::SessionDescription* JingleSessionManager::CreateHostSessionDescription(
- const CandidateSessionConfig* config,
- const std::string& certificate) {
- cricket::SessionDescription* desc = new cricket::SessionDescription();
- desc->AddContent(
- ContentDescription::kChromotingContentName, kChromotingXmlNamespace,
- new ContentDescription(config, "", certificate));
- return desc;
-}
-
} // namespace protocol
} // namespace remoting
diff --git a/remoting/protocol/jingle_session_manager.h b/remoting/protocol/jingle_session_manager.h
index 2f2125e..a72d9a3 100644
--- a/remoting/protocol/jingle_session_manager.h
+++ b/remoting/protocol/jingle_session_manager.h
@@ -43,16 +43,15 @@ class JingleSessionManager
virtual void Init(const std::string& local_jid,
SignalStrategy* signal_strategy,
Listener* listener,
- crypto::RSAPrivateKey* private_key,
- const std::string& certificate,
bool allow_nat_traversal) OVERRIDE;
virtual Session* Connect(
const std::string& host_jid,
- const std::string& host_public_key,
- const std::string& client_token,
+ Authenticator* authenticator,
CandidateSessionConfig* config,
const Session::StateChangeCallback& state_change_callback) OVERRIDE;
virtual void Close() OVERRIDE;
+ virtual void set_authenticator_factory(
+ AuthenticatorFactory* authenticator_factory) OVERRIDE;
// cricket::SessionClient interface.
virtual void OnSessionCreate(cricket::Session* cricket_session,
@@ -71,10 +70,16 @@ class JingleSessionManager
private:
friend class JingleSession;
- // Called by JingleSession when a new connection is
- // initiated. Returns true if session is accepted.
- bool AcceptConnection(JingleSession* jingle_session,
- cricket::Session* cricket_session);
+ // Called by JingleSession when a new connection is initiated.
+ SessionManager::IncomingSessionResponse AcceptConnection(
+ JingleSession* jingle_session);
+
+ // Creates authenticator for incoming session. Returns NULL if
+ // authenticator cannot be created, e.g. if |auth_message| is
+ // invalid. Caller reatins ownership of |auth_message| and must
+ // accept ownership of the result.
+ Authenticator* CreateAuthenticator(const std::string& jid,
+ const buzz::XmlElement* auth_message);
// Called by JingleSession when it is being destroyed.
void SessionDestroyed(JingleSession* jingle_session);
@@ -85,15 +90,6 @@ class JingleSessionManager
const std::vector<std::string>& relay_hosts,
const std::vector<talk_base::SocketAddress>& stun_hosts);
- // Creates session description for outgoing session.
- static cricket::SessionDescription* CreateClientSessionDescription(
- const CandidateSessionConfig* candidate_config,
- const std::string& auth_token);
- // Creates session description for incoming session.
- static cricket::SessionDescription* CreateHostSessionDescription(
- const CandidateSessionConfig* candidate_config,
- const std::string& certificate);
-
scoped_refptr<base::MessageLoopProxy> message_loop_;
scoped_ptr<talk_base::NetworkManager> network_manager_;
@@ -101,9 +97,8 @@ class JingleSessionManager
std::string local_jid_; // Full jid for the local side of the session.
SignalStrategy* signal_strategy_;
+ scoped_ptr<AuthenticatorFactory> authenticator_factory_;
Listener* listener_;
- std::string certificate_;
- scoped_ptr<crypto::RSAPrivateKey> private_key_;
bool allow_nat_traversal_;
scoped_ptr<cricket::PortAllocator> port_allocator_;
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc
index 4b91b13..9dd5143 100644
--- a/remoting/protocol/jingle_session_unittest.cc
+++ b/remoting/protocol/jingle_session_unittest.cc
@@ -10,14 +10,19 @@
#include "base/time.h"
#include "base/test/test_timeouts.h"
#include "crypto/nss_util.h"
+#include "crypto/rsa_private_key.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/socket/socket.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_session.h"
#include "remoting/protocol/jingle_session_manager.h"
+#include "remoting/protocol/v1_authenticator.h"
#include "remoting/jingle_glue/jingle_thread.h"
#include "remoting/jingle_glue/fake_signal_strategy.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -108,6 +113,124 @@ class MockSessionCallback {
MOCK_METHOD1(OnStateChange, void(Session::State));
};
+class FakeChannelAuthenticator : public ChannelAuthenticator {
+ public:
+ FakeChannelAuthenticator(bool accept)
+ : accept_(accept) {
+ }
+ virtual ~FakeChannelAuthenticator() {}
+
+ virtual void SecureAndAuthenticate(
+ net::StreamSocket* socket, const DoneCallback& done_callback) OVERRIDE {
+ if (accept_) {
+ done_callback.Run(net::OK, socket);
+ } else {
+ delete socket;
+ done_callback.Run(net::ERR_FAILED, NULL);
+ }
+ }
+
+ private:
+ bool accept_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeChannelAuthenticator);
+};
+
+class FakeClientAuthenticator : public Authenticator {
+ public:
+ FakeClientAuthenticator(bool accept, bool accept_channel)
+ : accept_(accept),
+ accept_channel_(accept_channel),
+ state_(MESSAGE_READY) {
+ }
+ virtual ~FakeClientAuthenticator() {}
+
+ virtual State state() const OVERRIDE {
+ return state_;
+ }
+
+ virtual void ProcessMessage(const buzz::XmlElement* message) OVERRIDE {
+ EXPECT_EQ(WAITING_MESSAGE, state_);
+ state_ = accept_ ? ACCEPTED : REJECTED;
+ }
+
+ virtual buzz::XmlElement* GetNextMessage() OVERRIDE {
+ EXPECT_EQ(MESSAGE_READY, state_);
+ state_ = WAITING_MESSAGE;
+ return new buzz::XmlElement(
+ buzz::QName(kChromotingXmlNamespace, "authentication"));
+ }
+
+ virtual ChannelAuthenticator* CreateChannelAuthenticator() const OVERRIDE {
+ return new FakeChannelAuthenticator(accept_channel_);
+ }
+
+ protected:
+ bool accept_;
+ bool accept_channel_;
+ State state_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeClientAuthenticator);
+};
+
+class FakeHostAuthenticator : public Authenticator {
+ public:
+ FakeHostAuthenticator(bool accept, bool accept_channel)
+ : accept_(accept),
+ accept_channel_(accept_channel),
+ state_(WAITING_MESSAGE) {
+ }
+ virtual ~FakeHostAuthenticator() {}
+
+ virtual State state() const OVERRIDE {
+ return state_;
+ }
+
+ virtual void ProcessMessage(const buzz::XmlElement* message) OVERRIDE {
+ EXPECT_EQ(WAITING_MESSAGE, state_);
+ state_ = MESSAGE_READY;
+ }
+
+ virtual buzz::XmlElement* GetNextMessage() OVERRIDE {
+ EXPECT_EQ(MESSAGE_READY, state_);
+ state_ = accept_ ? ACCEPTED : REJECTED;
+ return new buzz::XmlElement(
+ buzz::QName(kChromotingXmlNamespace, "authentication"));
+ }
+
+ virtual ChannelAuthenticator* CreateChannelAuthenticator() const OVERRIDE {
+ return new FakeChannelAuthenticator(accept_channel_);
+ }
+
+ protected:
+ bool accept_;
+ bool accept_channel_;
+ State state_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeHostAuthenticator);
+};
+
+class FakeHostAuthenticatorFactory : public AuthenticatorFactory {
+ public:
+ FakeHostAuthenticatorFactory(bool accept, bool accept_channel)
+ : accept_(accept),
+ accept_channel_(accept_channel) {
+ }
+ virtual ~FakeHostAuthenticatorFactory() {}
+
+ virtual Authenticator* CreateAuthenticator(
+ const std::string& remote_jid,
+ const buzz::XmlElement* first_message) OVERRIDE {
+ return new FakeHostAuthenticator(accept_, accept_channel_);
+ }
+
+ private:
+ bool accept_;
+ bool accept_channel_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeHostAuthenticatorFactory);
+};
+
} // namespace
class JingleSessionTest : public testing::Test {
@@ -125,7 +248,6 @@ class JingleSessionTest : public testing::Test {
base::Unretained(&host_connection_callback_)));
session->set_config(SessionConfig::GetDefault());
- session->set_shared_secret(kTestSharedSecret);
}
protected:
@@ -148,7 +270,7 @@ class JingleSessionTest : public testing::Test {
}
}
- void CreateServerPair() {
+ void CreateServerPair(bool use_fake_auth) {
FilePath certs_dir;
PathService::Get(base::DIR_SOURCE_ROOT, &certs_dir);
certs_dir = certs_dir.AppendASCII("net");
@@ -180,16 +302,24 @@ class JingleSessionTest : public testing::Test {
host_server_.reset(new JingleSessionManager(
base::MessageLoopProxy::current()));
host_server_->Init(
- kHostJid, host_signal_strategy_.get(), &host_server_listener_,
- private_key.release(), cert_der, false);
+ kHostJid, host_signal_strategy_.get(), &host_server_listener_, false);
+
+ if (use_fake_auth) {
+ host_server_->set_authenticator_factory(
+ new FakeHostAuthenticatorFactory(true, false));
+ } else {
+ host_server_->set_authenticator_factory(
+ new V1HostAuthenticatorFactory(
+ cert_der, private_key.release(), kTestSharedSecret));
+ }
EXPECT_CALL(client_server_listener_, OnSessionManagerInitialized())
.Times(1);
client_server_.reset(new JingleSessionManager(
base::MessageLoopProxy::current()));
client_server_->Init(
- kClientJid, client_signal_strategy_.get(), &client_server_listener_,
- NULL, "", false);
+ kClientJid, client_signal_strategy_.get(),
+ &client_server_listener_, false);
}
void CloseSessionManager() {
@@ -205,7 +335,7 @@ class JingleSessionTest : public testing::Test {
client_signal_strategy_.reset();
}
- bool InitiateConnection(const char* shared_secret) {
+ bool InitiateConnection(bool use_fake_auth) {
int not_connected_peers = 2;
EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
@@ -243,15 +373,18 @@ class JingleSessionTest : public testing::Test {
.Times(AtMost(1));
}
+ Authenticator* authenticator;
+ if (use_fake_auth) {
+ authenticator = new FakeClientAuthenticator(true, true);
+ } else {
+ authenticator = new V1ClientAuthenticator(kClientJid, kTestSharedSecret);
+ }
client_session_.reset(client_server_->Connect(
- kHostJid, kTestHostPublicKey,
- GenerateSupportAuthToken(kClientJid, kTestSharedSecret),
+ kHostJid, authenticator,
CandidateSessionConfig::CreateDefault(),
base::Bind(&MockSessionCallback::OnStateChange,
base::Unretained(&client_connection_callback_))));
- client_session_->set_shared_secret(shared_secret);
-
return RunMessageLoopWithTimeout(TestTimeouts::action_max_timeout_ms());
}
@@ -370,6 +503,8 @@ class TCPChannelTester : public ChannelTesterBase {
void OnChannelReady(int id, net::StreamSocket* socket) {
if (!socket) {
+ host_session_->CancelChannelCreation(kChannelName);
+ client_session_->CancelChannelCreation(kChannelName);
Done();
return;
}
@@ -645,13 +780,13 @@ class UDPChannelTester : public ChannelTesterBase {
// Verify that we can create and destory server objects without a connection.
TEST_F(JingleSessionTest, CreateAndDestoy) {
- CreateServerPair();
+ CreateServerPair(false);
}
// Verify that incoming session can be rejected, and that the status
// of the connection is set to CLOSED in this case.
TEST_F(JingleSessionTest, RejectConnection) {
- CreateServerPair();
+ CreateServerPair(false);
// Reject incoming session.
EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _))
@@ -669,9 +804,10 @@ TEST_F(JingleSessionTest, RejectConnection) {
.WillOnce(InvokeWithoutArgs(&QuitCurrentThread));
}
+ Authenticator* authenticator =
+ new V1ClientAuthenticator(kClientJid, kTestSharedSecretBad);
client_session_.reset(client_server_->Connect(
- kHostJid, kTestHostPublicKey,
- GenerateSupportAuthToken(kClientJid, kTestSharedSecret),
+ kHostJid, authenticator,
CandidateSessionConfig::CreateDefault(),
base::Bind(&MockSessionCallback::OnStateChange,
base::Unretained(&client_connection_callback_))));
@@ -681,14 +817,14 @@ TEST_F(JingleSessionTest, RejectConnection) {
// Verify that we can connect two endpoints.
TEST_F(JingleSessionTest, Connect) {
- CreateServerPair();
- ASSERT_TRUE(InitiateConnection(kTestSharedSecret));
+ CreateServerPair(false);
+ ASSERT_TRUE(InitiateConnection(false));
}
// Verify that we can't connect two endpoints with mismatched secrets.
TEST_F(JingleSessionTest, ConnectBadChannelAuth) {
- CreateServerPair();
- ASSERT_TRUE(InitiateConnection(kTestSharedSecretBad));
+ CreateServerPair(true);
+ ASSERT_TRUE(InitiateConnection(true));
scoped_refptr<TCPChannelTester> tester(
new TCPChannelTester(host_session_.get(), client_session_.get(),
kMessageSize, kMessages));
@@ -701,8 +837,8 @@ TEST_F(JingleSessionTest, ConnectBadChannelAuth) {
// Verify that data can be transmitted over the event channel.
TEST_F(JingleSessionTest, TestTcpChannel) {
- CreateServerPair();
- ASSERT_TRUE(InitiateConnection(kTestSharedSecret));
+ CreateServerPair(false);
+ ASSERT_TRUE(InitiateConnection(false));
scoped_refptr<TCPChannelTester> tester(
new TCPChannelTester(host_session_.get(), client_session_.get(),
kMessageSize, kMessages));
@@ -716,8 +852,8 @@ TEST_F(JingleSessionTest, TestTcpChannel) {
// Verify that data can be transmitted over the video RTP channel.
TEST_F(JingleSessionTest, TestUdpChannel) {
- CreateServerPair();
- ASSERT_TRUE(InitiateConnection(kTestSharedSecret));
+ CreateServerPair(false);
+ ASSERT_TRUE(InitiateConnection(false));
scoped_refptr<UDPChannelTester> tester(
new UDPChannelTester(host_session_.get(), client_session_.get()));
tester->Start();
@@ -731,8 +867,8 @@ TEST_F(JingleSessionTest, TestUdpChannel) {
// Send packets of different size to get the latency for sending data
// using sockets from JingleSession.
TEST_F(JingleSessionTest, FLAKY_TestSpeed) {
- CreateServerPair();
- ASSERT_TRUE(InitiateConnection(kTestSharedSecret));
+ CreateServerPair(false);
+ ASSERT_TRUE(InitiateConnection(false));
scoped_refptr<ChannelSpeedTester> tester;
tester = new ChannelSpeedTester(host_session_.get(),
@@ -743,7 +879,7 @@ TEST_F(JingleSessionTest, FLAKY_TestSpeed) {
<< tester->GetElapsedTime().InMilliseconds() << " ms.";
CloseSessions();
- ASSERT_TRUE(InitiateConnection(kTestSharedSecret));
+ ASSERT_TRUE(InitiateConnection(false));
tester = new ChannelSpeedTester(host_session_.get(),
client_session_.get(), 1024);
@@ -753,7 +889,7 @@ TEST_F(JingleSessionTest, FLAKY_TestSpeed) {
<< tester->GetElapsedTime().InMilliseconds() << " ms.";
CloseSessions();
- ASSERT_TRUE(InitiateConnection(kTestSharedSecret));
+ ASSERT_TRUE(InitiateConnection(false));
tester = new ChannelSpeedTester(host_session_.get(),
client_session_.get(), 51200);
@@ -763,7 +899,7 @@ TEST_F(JingleSessionTest, FLAKY_TestSpeed) {
<< tester->GetElapsedTime().InMilliseconds() << " ms.";
CloseSessions();
- ASSERT_TRUE(InitiateConnection(kTestSharedSecret));
+ ASSERT_TRUE(InitiateConnection(false));
tester = new ChannelSpeedTester(host_session_.get(),
client_session_.get(), 512000);
diff --git a/remoting/protocol/pepper_session.cc b/remoting/protocol/pepper_session.cc
index 138993b..735d7ad 100644
--- a/remoting/protocol/pepper_session.cc
+++ b/remoting/protocol/pepper_session.cc
@@ -10,6 +10,7 @@
#include "base/string_number_conversions.h"
#include "remoting/base/constants.h"
#include "remoting/jingle_glue/iq_sender.h"
+#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/content_description.h"
#include "remoting/protocol/jingle_messages.h"
#include "remoting/protocol/pepper_session_manager.h"
@@ -56,15 +57,15 @@ Session::Error PepperSession::error() {
void PepperSession::StartConnection(
const std::string& peer_jid,
- const std::string& peer_public_key,
- const std::string& client_token,
+ Authenticator* authenticator,
CandidateSessionConfig* config,
const StateChangeCallback& state_change_callback) {
DCHECK(CalledOnValidThread());
+ DCHECK(authenticator);
+ DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY);
peer_jid_ = peer_jid;
- peer_public_key_ = peer_public_key;
- initiator_token_ = client_token;
+ authenticator_.reset(authenticator);
candidate_config_.reset(config);
state_change_callback_ = state_change_callback;
@@ -79,7 +80,8 @@ void PepperSession::StartConnection(
session_id_);
message.from = session_manager_->local_jid_;
message.description.reset(
- new ContentDescription(candidate_config_->Clone(), initiator_token_, ""));
+ new ContentDescription(candidate_config_->Clone(),
+ authenticator_->GetNextMessage()));
initiate_request_.reset(session_manager_->iq_sender()->SendIq(
message.ToXml(),
base::Bind(&PepperSession::OnSessionInitiateResponse,
@@ -112,12 +114,14 @@ void PepperSession::CreateStreamChannel(
const StreamChannelCallback& callback) {
DCHECK(!channels_[name]);
- PepperStreamChannel* channel = new PepperStreamChannel(this, name, callback);
+ ChannelAuthenticator* channel_authenticator =
+ authenticator_->CreateChannelAuthenticator();
+ PepperStreamChannel* channel = new PepperStreamChannel(
+ this, name, callback);
channels_[name] = channel;
channel->Connect(session_manager_->pp_instance_,
session_manager_->transport_config_,
- new V1ClientChannelAuthenticator(
- remote_cert_, shared_secret_));
+ channel_authenticator);
}
void PepperSession::CreateDatagramChannel(
@@ -156,37 +160,6 @@ void PepperSession::set_config(const SessionConfig& config) {
NOTREACHED();
}
-const std::string& PepperSession::initiator_token() {
- DCHECK(CalledOnValidThread());
- return initiator_token_;
-}
-
-void PepperSession::set_initiator_token(const std::string& initiator_token) {
- DCHECK(CalledOnValidThread());
- initiator_token_ = initiator_token;
-}
-
-const std::string& PepperSession::receiver_token() {
- DCHECK(CalledOnValidThread());
- return receiver_token_;
-}
-
-void PepperSession::set_receiver_token(const std::string& receiver_token) {
- DCHECK(CalledOnValidThread());
- // set_receiver_token() should not be called on the client side.
- NOTREACHED();
-}
-
-void PepperSession::set_shared_secret(const std::string& secret) {
- DCHECK(CalledOnValidThread());
- shared_secret_ = secret;
-}
-
-const std::string& PepperSession::shared_secret() {
- DCHECK(CalledOnValidThread());
- return shared_secret_;
-}
-
void PepperSession::Close() {
DCHECK(CalledOnValidThread());
@@ -237,6 +210,26 @@ void PepperSession::OnAccept(const JingleMessage& message,
return;
}
+ const buzz::XmlElement* auth_message =
+ message.description->authenticator_message();
+ if (!auth_message) {
+ DLOG(WARNING) << "Received session-accept without authentication message "
+ << auth_message->Str();
+ OnError(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 &&
+ authenticator_->state() != Authenticator::MESSAGE_READY);
+
+ if (authenticator_->state() == Authenticator::REJECTED) {
+ OnError(AUTHENTICATION_FAILED);
+ return;
+ }
+
if (!InitializeConfigFromDescription(message.description.get())) {
OnError(INCOMPATIBLE_PROTOCOL);
return;
@@ -297,12 +290,6 @@ bool PepperSession::InitializeConfigFromDescription(
const ContentDescription* description) {
DCHECK(description);
- remote_cert_ = description->certificate();
- if (remote_cert_.empty()) {
- LOG(ERROR) << "session-accept does not specify certificate";
- return false;
- }
-
if (!description->config()->GetFinalConfig(&config_)) {
LOG(ERROR) << "session-accept does not specify configuration";
return false;
diff --git a/remoting/protocol/pepper_session.h b/remoting/protocol/pepper_session.h
index 7e06687..e13b875 100644
--- a/remoting/protocol/pepper_session.h
+++ b/remoting/protocol/pepper_session.h
@@ -28,6 +28,7 @@ class IqRequest;
namespace protocol {
+class Authenticator;
class PepperChannel;
class PepperSessionManager;
@@ -53,12 +54,6 @@ class PepperSession : public Session {
virtual const CandidateSessionConfig* candidate_config() OVERRIDE;
virtual const SessionConfig& config() OVERRIDE;
virtual void set_config(const SessionConfig& config) OVERRIDE;
- virtual const std::string& initiator_token() OVERRIDE;
- 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:
@@ -71,8 +66,7 @@ class PepperSession : public Session {
// Start cs connection by sending session-initiate message.
void StartConnection(const std::string& peer_jid,
- const std::string& peer_public_key,
- const std::string& client_token,
+ Authenticator* authenticator,
CandidateSessionConfig* config,
const StateChangeCallback& state_change_callback);
@@ -110,7 +104,6 @@ class PepperSession : public Session {
PepperSessionManager* session_manager_;
std::string peer_jid_;
- std::string peer_public_key_;
scoped_ptr<CandidateSessionConfig> candidate_config_;
StateChangeCallback state_change_callback_;
@@ -118,12 +111,9 @@ class PepperSession : public Session {
State state_;
Error error_;
- std::string remote_cert_;
SessionConfig config_;
- std::string shared_secret_;
- std::string initiator_token_;
- std::string receiver_token_;
+ scoped_ptr<Authenticator> authenticator_;
scoped_ptr<IqRequest> initiate_request_;
scoped_ptr<IqRequest> transport_info_request_;
diff --git a/remoting/protocol/pepper_session_manager.cc b/remoting/protocol/pepper_session_manager.cc
index ea095c3..2e558a7 100644
--- a/remoting/protocol/pepper_session_manager.cc
+++ b/remoting/protocol/pepper_session_manager.cc
@@ -8,6 +8,7 @@
#include "remoting/jingle_glue/iq_sender.h"
#include "remoting/jingle_glue/jingle_info_request.h"
#include "remoting/jingle_glue/signal_strategy.h"
+#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/jingle_messages.h"
#include "remoting/protocol/pepper_session.h"
#include "third_party/libjingle/source/talk/base/socketaddress.h"
@@ -33,15 +34,11 @@ void PepperSessionManager::Init(
const std::string& local_jid,
SignalStrategy* signal_strategy,
SessionManager::Listener* listener,
- crypto::RSAPrivateKey* private_key,
- const std::string& certificate,
bool allow_nat_traversal) {
listener_ = listener;
local_jid_ = local_jid;
signal_strategy_ = signal_strategy;
iq_sender_.reset(new IqSender(signal_strategy_));
- private_key_.reset(private_key);
- certificate_ = certificate;
allow_nat_traversal_ = allow_nat_traversal;
signal_strategy_->AddListener(this);
@@ -76,13 +73,12 @@ void PepperSessionManager::OnJingleInfo(
Session* PepperSessionManager::Connect(
const std::string& host_jid,
- const std::string& host_public_key,
- const std::string& client_token,
+ Authenticator* authenticator,
CandidateSessionConfig* config,
const Session::StateChangeCallback& state_change_callback) {
PepperSession* session = new PepperSession(this);
- session->StartConnection(host_jid, host_public_key, client_token,
- config, state_change_callback);
+ session->StartConnection(host_jid, authenticator, config,
+ state_change_callback);
sessions_[session->session_id_] = session;
return session;
}
@@ -99,6 +95,12 @@ void PepperSessionManager::Close() {
signal_strategy_->RemoveListener(this);
}
+void PepperSessionManager::set_authenticator_factory(
+ AuthenticatorFactory* authenticator_factory) {
+ DCHECK(CalledOnValidThread());
+ authenticator_factory_.reset(authenticator_factory);
+}
+
bool PepperSessionManager::OnIncomingStanza(const buzz::XmlElement* stanza) {
if (!JingleMessage::IsJingleMessage(stanza))
return false;
diff --git a/remoting/protocol/pepper_session_manager.h b/remoting/protocol/pepper_session_manager.h
index 41c06f6..3ae1823 100644
--- a/remoting/protocol/pepper_session_manager.h
+++ b/remoting/protocol/pepper_session_manager.h
@@ -51,16 +51,15 @@ class PepperSessionManager : public SessionManager,
virtual void Init(const std::string& local_jid,
SignalStrategy* signal_strategy,
SessionManager::Listener* listener,
- crypto::RSAPrivateKey* private_key,
- const std::string& certificate,
bool allow_nat_traversal) OVERRIDE;
virtual Session* Connect(
const std::string& host_jid,
- const std::string& host_public_key,
- const std::string& client_token,
+ Authenticator* authenticator,
CandidateSessionConfig* config,
const Session::StateChangeCallback& state_change_callback) OVERRIDE;
virtual void Close() OVERRIDE;
+ virtual void set_authenticator_factory(
+ AuthenticatorFactory* authenticator_factory) OVERRIDE;
// SignalStrategy::Listener interface.
virtual bool OnIncomingStanza(const buzz::XmlElement* stanza) OVERRIDE;
@@ -86,10 +85,9 @@ class PepperSessionManager : public SessionManager,
std::string local_jid_;
SignalStrategy* signal_strategy_;
+ scoped_ptr<AuthenticatorFactory> authenticator_factory_;
scoped_ptr<IqSender> iq_sender_;
SessionManager::Listener* listener_;
- scoped_ptr<crypto::RSAPrivateKey> private_key_;
- std::string certificate_;
bool allow_nat_traversal_;
TransportConfig transport_config_;
diff --git a/remoting/protocol/session.h b/remoting/protocol/session.h
index de85666..4640fad 100644
--- a/remoting/protocol/session.h
+++ b/remoting/protocol/session.h
@@ -110,16 +110,6 @@ class Session : public base::NonThreadSafe {
// ChromotocolServer::IncomingConnectionCallback.
virtual void set_config(const SessionConfig& config) = 0;
- // The raw auth tokens from the session-initiate, or session-accept stanzas.
- virtual const std::string& initiator_token() = 0;
- virtual void set_initiator_token(const std::string& initiator_token) = 0;
- 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.
diff --git a/remoting/protocol/session_manager.h b/remoting/protocol/session_manager.h
index f36abd2..7a02c3d 100644
--- a/remoting/protocol/session_manager.h
+++ b/remoting/protocol/session_manager.h
@@ -52,16 +52,15 @@
#include "base/threading/non_thread_safe.h"
#include "remoting/protocol/session.h"
-namespace crypto {
-class RSAPrivateKey;
-} // namespace base
-
namespace remoting {
class SignalStrategy;
namespace protocol {
+class Authenticator;
+class AuthenticatorFactory;
+
// Generic interface for Chromoting session manager.
//
// TODO(sergeyu): Split this into two separate interfaces: one for the
@@ -113,8 +112,6 @@ class SessionManager : public base::NonThreadSafe {
virtual void Init(const std::string& local_jid,
SignalStrategy* signal_strategy,
Listener* listener,
- crypto::RSAPrivateKey* private_key,
- const std::string& certificate,
bool allow_nat_traversal) = 0;
// Tries to create a session to the host |jid|. Must be called only
@@ -123,15 +120,14 @@ class SessionManager : public base::NonThreadSafe {
//
// |host_jid| is the full jid of the host to connect to.
// |host_public_key| is used to for authentication.
- // |client_oauth_token| is a short-lived OAuth token identify the client.
+ // |authenticator| is a client authenticator for the session.
// |config| contains the session configurations that the client supports.
// |state_change_callback| is called when the connection state changes.
//
// Ownership of the |config| is passed to the new session.
virtual Session* Connect(
const std::string& host_jid,
- const std::string& host_public_key,
- const std::string& client_token,
+ Authenticator* authenticator,
CandidateSessionConfig* config,
const Session::StateChangeCallback& state_change_callback) = 0;
@@ -140,6 +136,12 @@ class SessionManager : public base::NonThreadSafe {
// returns.
virtual void Close() = 0;
+ // Set authenticator factory that should be used to authenticate
+ // incoming connection. No connections will be accepted if
+ // authenticator factory isn't set.
+ virtual void set_authenticator_factory(
+ AuthenticatorFactory* authenticator_factory) = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(SessionManager);
};