This source file includes following definitions.
- local_key_pair_
- CreateWithSharedSecret
- CreateWithThirdPartyAuth
- ProcessMessage
- GetNextMessage
- CreateAuthenticator
#include "remoting/protocol/negotiating_host_authenticator.h"
#include <algorithm>
#include <sstream>
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "remoting/base/rsa_key_pair.h"
#include "remoting/protocol/channel_authenticator.h"
#include "remoting/protocol/pairing_host_authenticator.h"
#include "remoting/protocol/pairing_registry.h"
#include "remoting/protocol/token_validator.h"
#include "remoting/protocol/v2_authenticator.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
namespace remoting {
namespace protocol {
NegotiatingHostAuthenticator::NegotiatingHostAuthenticator(
const std::string& local_cert,
scoped_refptr<RsaKeyPair> key_pair)
: NegotiatingAuthenticatorBase(WAITING_MESSAGE),
local_cert_(local_cert),
local_key_pair_(key_pair) {
}
scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateWithSharedSecret(
const std::string& local_cert,
scoped_refptr<RsaKeyPair> key_pair,
const std::string& shared_secret_hash,
AuthenticationMethod::HashFunction hash_function,
scoped_refptr<PairingRegistry> pairing_registry) {
scoped_ptr<NegotiatingHostAuthenticator> result(
new NegotiatingHostAuthenticator(local_cert, key_pair));
result->shared_secret_hash_ = shared_secret_hash;
result->pairing_registry_ = pairing_registry;
result->AddMethod(AuthenticationMethod::Spake2(hash_function));
if (pairing_registry.get()) {
result->AddMethod(AuthenticationMethod::Spake2Pair());
}
return scoped_ptr<Authenticator>(result.Pass());
}
scoped_ptr<Authenticator>
NegotiatingHostAuthenticator::CreateWithThirdPartyAuth(
const std::string& local_cert,
scoped_refptr<RsaKeyPair> key_pair,
scoped_ptr<TokenValidator> token_validator) {
scoped_ptr<NegotiatingHostAuthenticator> result(
new NegotiatingHostAuthenticator(local_cert, key_pair));
result->token_validator_ = token_validator.Pass();
result->AddMethod(AuthenticationMethod::ThirdParty());
return scoped_ptr<Authenticator>(result.Pass());
}
NegotiatingHostAuthenticator::~NegotiatingHostAuthenticator() {
}
void NegotiatingHostAuthenticator::ProcessMessage(
const buzz::XmlElement* message,
const base::Closure& resume_callback) {
DCHECK_EQ(state(), WAITING_MESSAGE);
std::string method_attr = message->Attr(kMethodAttributeQName);
AuthenticationMethod method = AuthenticationMethod::FromString(method_attr);
if (current_method_.is_valid() && method != current_method_) {
state_ = REJECTED;
rejection_reason_ = PROTOCOL_ERROR;
resume_callback.Run();
return;
}
if (!method.is_valid() ||
std::find(methods_.begin(), methods_.end(), method) == methods_.end()) {
method = AuthenticationMethod::Invalid();
std::string supported_methods_attr =
message->Attr(kSupportedMethodsAttributeQName);
if (supported_methods_attr.empty()) {
state_ = REJECTED;
rejection_reason_ = PROTOCOL_ERROR;
resume_callback.Run();
return;
}
std::vector<std::string> supported_methods_strs;
base::SplitString(supported_methods_attr, kSupportedMethodsSeparator,
&supported_methods_strs);
for (std::vector<std::string>::iterator it = supported_methods_strs.begin();
it != supported_methods_strs.end(); ++it) {
AuthenticationMethod list_value = AuthenticationMethod::FromString(*it);
if (list_value.is_valid() &&
std::find(methods_.begin(),
methods_.end(), list_value) != methods_.end()) {
method = list_value;
break;
}
}
if (!method.is_valid()) {
state_ = REJECTED;
rejection_reason_ = PROTOCOL_ERROR;
resume_callback.Run();
return;
}
current_method_ = method;
state_ = PROCESSING_MESSAGE;
CreateAuthenticator(MESSAGE_READY, base::Bind(
&NegotiatingHostAuthenticator::UpdateState,
base::Unretained(this), resume_callback));
return;
}
if (!current_method_.is_valid()) {
current_method_ = method;
state_ = PROCESSING_MESSAGE;
CreateAuthenticator(WAITING_MESSAGE, base::Bind(
&NegotiatingAuthenticatorBase::ProcessMessageInternal,
base::Unretained(this), base::Owned(new buzz::XmlElement(*message)),
resume_callback));
return;
}
ProcessMessageInternal(message, resume_callback);
}
scoped_ptr<buzz::XmlElement> NegotiatingHostAuthenticator::GetNextMessage() {
return GetNextMessageInternal();
}
void NegotiatingHostAuthenticator::CreateAuthenticator(
Authenticator::State preferred_initial_state,
const base::Closure& resume_callback) {
DCHECK(current_method_.is_valid());
if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) {
DCHECK(token_validator_);
current_authenticator_.reset(new ThirdPartyHostAuthenticator(
local_cert_, local_key_pair_, token_validator_.Pass()));
} else if (current_method_ == AuthenticationMethod::Spake2Pair() &&
preferred_initial_state == WAITING_MESSAGE) {
current_authenticator_.reset(new PairingHostAuthenticator(
pairing_registry_, local_cert_, local_key_pair_, shared_secret_hash_));
} else {
DCHECK(current_method_.type() == AuthenticationMethod::SPAKE2 ||
current_method_.type() == AuthenticationMethod::SPAKE2_PAIR);
current_authenticator_ = V2Authenticator::CreateForHost(
local_cert_, local_key_pair_, shared_secret_hash_,
preferred_initial_state);
}
resume_callback.Run();
}
}
}