1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
// Copyright 2013 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.
#include "remoting/protocol/pairing_host_authenticator.h"
#include "base/bind.h"
#include "base/logging.h"
#include "remoting/base/constants.h"
#include "remoting/base/rsa_key_pair.h"
#include "remoting/protocol/channel_authenticator.h"
#include "remoting/protocol/v2_authenticator.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
namespace remoting {
namespace protocol {
PairingHostAuthenticator::PairingHostAuthenticator(
scoped_refptr<PairingRegistry> pairing_registry,
const std::string& local_cert,
scoped_refptr<RsaKeyPair> key_pair,
const std::string& pin)
: pairing_registry_(pairing_registry),
local_cert_(local_cert),
key_pair_(key_pair),
pin_(pin),
protocol_error_(false),
waiting_for_paired_secret_(false),
weak_factory_(this) {
}
PairingHostAuthenticator::~PairingHostAuthenticator() {
}
Authenticator::State PairingHostAuthenticator::state() const {
if (protocol_error_) {
return REJECTED;
} else if (waiting_for_paired_secret_) {
return PROCESSING_MESSAGE;
} else if (!v2_authenticator_) {
return WAITING_MESSAGE;
}
return PairingAuthenticatorBase::state();
}
Authenticator::RejectionReason
PairingHostAuthenticator::rejection_reason() const {
if (protocol_error_) {
return PROTOCOL_ERROR;
}
return PairingAuthenticatorBase::rejection_reason();
}
void PairingHostAuthenticator::CreateV2AuthenticatorWithPIN(
State initial_state,
const SetAuthenticatorCallback& callback) {
callback.Run(V2Authenticator::CreateForHost(
local_cert_, key_pair_, pin_, initial_state));
}
void PairingHostAuthenticator::ProcessMessage(
const buzz::XmlElement* message,
const base::Closure& resume_callback) {
if (!v2_authenticator_) {
std::string client_id;
const buzz::XmlElement* pairing_tag = message->FirstNamed(kPairingInfoTag);
if (pairing_tag) {
client_id = pairing_tag->Attr(kClientIdAttribute);
}
if (client_id.empty()) {
LOG(ERROR) << "No client id specified.";
protocol_error_ = true;
} else {
waiting_for_paired_secret_ = true;
pairing_registry_->GetPairing(
client_id,
base::Bind(&PairingHostAuthenticator::ProcessMessageWithPairing,
weak_factory_.GetWeakPtr(),
base::Owned(new buzz::XmlElement(*message)),
resume_callback));
return;
}
}
PairingAuthenticatorBase::ProcessMessage(message, resume_callback);
}
void PairingHostAuthenticator::AddPairingElements(buzz::XmlElement* message) {
// Nothing to do here
}
void PairingHostAuthenticator::ProcessMessageWithPairing(
const buzz::XmlElement* message,
const base::Closure& resume_callback,
PairingRegistry::Pairing pairing) {
waiting_for_paired_secret_ = false;
std::string paired_secret = pairing.shared_secret();
if (paired_secret.empty()) {
VLOG(0) << "Unknown client id";
error_message_ = "unknown-client-id";
}
using_paired_secret_ = !paired_secret.empty();
if (using_paired_secret_) {
v2_authenticator_ = V2Authenticator::CreateForHost(
local_cert_, key_pair_, paired_secret, WAITING_MESSAGE);
PairingAuthenticatorBase::ProcessMessage(message, resume_callback);
} else {
v2_authenticator_ = V2Authenticator::CreateForHost(
local_cert_, key_pair_, pin_, MESSAGE_READY);
// The client's optimistic SPAKE message is using a Paired Secret to
// which the host doesn't have access, so don't bother processing it.
resume_callback.Run();
}
}
} // namespace protocol
} // namespace remoting
|