This source file includes following definitions.
- weak_factory_
- state
- rejection_reason
- ProcessMessage
- GetNextMessage
- CreateChannelAuthenticator
- MaybeAddErrorMessage
- HasErrorMessage
- CheckForFailedSpakeExchange
- SetAuthenticatorAndProcessMessage
#include "remoting/protocol/pairing_authenticator_base.h"
#include "base/bind.h"
#include "remoting/base/constants.h"
#include "remoting/protocol/channel_authenticator.h"
namespace remoting {
namespace protocol {
const buzz::StaticQName PairingAuthenticatorBase::kPairingInfoTag =
{ kChromotingXmlNamespace, "pairing-info" };
const buzz::StaticQName PairingAuthenticatorBase::kClientIdAttribute =
{ "", "client-id" };
namespace {
const buzz::StaticQName kPairingFailedTag =
{ kChromotingXmlNamespace, "pairing-failed" };
const buzz::StaticQName kPairingErrorAttribute = { "", "error" };
}
PairingAuthenticatorBase::PairingAuthenticatorBase()
: using_paired_secret_(false),
waiting_for_authenticator_(false),
weak_factory_(this) {
}
PairingAuthenticatorBase::~PairingAuthenticatorBase() {
}
Authenticator::State PairingAuthenticatorBase::state() const {
if (waiting_for_authenticator_) {
return PROCESSING_MESSAGE;
}
return v2_authenticator_->state();
}
Authenticator::RejectionReason
PairingAuthenticatorBase::rejection_reason() const {
if (!v2_authenticator_) {
return PROTOCOL_ERROR;
}
return v2_authenticator_->rejection_reason();
}
void PairingAuthenticatorBase::ProcessMessage(
const buzz::XmlElement* message,
const base::Closure& resume_callback) {
DCHECK_EQ(state(), WAITING_MESSAGE);
DCHECK(v2_authenticator_);
if (using_paired_secret_ && HasErrorMessage(message)) {
using_paired_secret_ = false;
waiting_for_authenticator_ = true;
v2_authenticator_.reset();
SetAuthenticatorCallback set_authenticator = base::Bind(
&PairingAuthenticatorBase::SetAuthenticatorAndProcessMessage,
weak_factory_.GetWeakPtr(), base::Owned(new buzz::XmlElement(*message)),
resume_callback);
CreateV2AuthenticatorWithPIN(WAITING_MESSAGE, set_authenticator);
return;
}
v2_authenticator_->ProcessMessage(
message,
base::Bind(&PairingAuthenticatorBase::CheckForFailedSpakeExchange,
weak_factory_.GetWeakPtr(), resume_callback));
}
scoped_ptr<buzz::XmlElement> PairingAuthenticatorBase::GetNextMessage() {
DCHECK_EQ(state(), MESSAGE_READY);
scoped_ptr<buzz::XmlElement> result = v2_authenticator_->GetNextMessage();
AddPairingElements(result.get());
MaybeAddErrorMessage(result.get());
return result.Pass();
}
scoped_ptr<ChannelAuthenticator>
PairingAuthenticatorBase::CreateChannelAuthenticator() const {
return v2_authenticator_->CreateChannelAuthenticator();
}
void PairingAuthenticatorBase::MaybeAddErrorMessage(buzz::XmlElement* message) {
if (!error_message_.empty()) {
buzz::XmlElement* pairing_failed_tag =
new buzz::XmlElement(kPairingFailedTag);
pairing_failed_tag->AddAttr(kPairingErrorAttribute, error_message_);
message->AddElement(pairing_failed_tag);
error_message_.clear();
}
}
bool PairingAuthenticatorBase::HasErrorMessage(
const buzz::XmlElement* message) const {
const buzz::XmlElement* pairing_failed_tag =
message->FirstNamed(kPairingFailedTag);
if (pairing_failed_tag) {
std::string error = pairing_failed_tag->Attr(kPairingErrorAttribute);
LOG(ERROR) << "Pairing failed: " << error;
}
return pairing_failed_tag != NULL;
}
void PairingAuthenticatorBase::CheckForFailedSpakeExchange(
const base::Closure& resume_callback) {
if (v2_authenticator_->state() == REJECTED &&
v2_authenticator_->rejection_reason() == INVALID_CREDENTIALS &&
using_paired_secret_) {
using_paired_secret_ = false;
error_message_ = "invalid-shared-secret";
v2_authenticator_.reset();
buzz::XmlElement* no_message = NULL;
SetAuthenticatorCallback set_authenticator = base::Bind(
&PairingAuthenticatorBase::SetAuthenticatorAndProcessMessage,
weak_factory_.GetWeakPtr(), no_message, resume_callback);
CreateV2AuthenticatorWithPIN(MESSAGE_READY, set_authenticator);
return;
}
resume_callback.Run();
}
void PairingAuthenticatorBase::SetAuthenticatorAndProcessMessage(
const buzz::XmlElement* message,
const base::Closure& resume_callback,
scoped_ptr<Authenticator> authenticator) {
DCHECK(!v2_authenticator_);
DCHECK(authenticator);
waiting_for_authenticator_ = false;
v2_authenticator_ = authenticator.Pass();
if (message) {
ProcessMessage(message, resume_callback);
} else {
resume_callback.Run();
}
}
}
}