Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: remoting/protocol/pairing_host_authenticator.cc

Issue 14793021: PairingAuthenticator implementation and plumbing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reviewer comments and unit tests. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/protocol/pairing_host_authenticator.h"
6
7 #include "base/logging.h"
8 #include "remoting/base/constants.h"
9 #include "remoting/base/rsa_key_pair.h"
10 #include "remoting/protocol/channel_authenticator.h"
11 #include "remoting/protocol/pairing_registry.h"
12 #include "remoting/protocol/v2_authenticator.h"
13 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
14
15 namespace remoting {
16 namespace protocol {
17
18 namespace {
19 // These definitions must be kept in sync with pairing_client_authenticator.cc.
20 const buzz::StaticQName kPairingInfoTag =
21 { kChromotingXmlNamespace, "pairing-info" };
22 const buzz::StaticQName kClientIdAttribute =
23 { "", "client-id" };
24 const buzz::StaticQName kPairingFailedTag =
25 { kChromotingXmlNamespace, "pairing-failed" };
26 const buzz::StaticQName kPairingErrorAttribute =
27 { "", "error" };
28 }
29
30 PairingHostAuthenticator::PairingHostAuthenticator(
31 scoped_refptr<PairingRegistry> pairing_registry,
32 const std::string& local_cert,
33 scoped_refptr<RsaKeyPair> key_pair,
34 const std::string& shared_secret,
35 State initial_state)
36 : pairing_registry_(pairing_registry),
37 local_cert_(local_cert),
38 key_pair_(key_pair),
39 shared_secret_(shared_secret),
40 protocol_error_(false) {
41 // If the client didn't specify an initial message, use the PIN as the shared
42 // secret. If it did, the authenticator will be created in ProcessMessage with
43 // the appropriate secret from the pairing registry.
44 if (initial_state != WAITING_MESSAGE) {
45 DCHECK_EQ(initial_state, MESSAGE_READY);
46 CreateV2AuthenticatorWithPIN(initial_state);
47 }
48 }
49
50 Authenticator::State PairingHostAuthenticator::state() const {
51 if (protocol_error_) {
52 return REJECTED;
53 } else if (!error_message_.empty()) {
54 return MESSAGE_READY;
55 } else if (v2_authenticator_) {
56 return v2_authenticator_->state();
57 } else {
58 return WAITING_MESSAGE;
59 }
60 }
61
62 Authenticator::RejectionReason
63 PairingHostAuthenticator::rejection_reason() const {
64 DCHECK(v2_authenticator_);
rmsousa 2013/05/16 00:46:25 if (!v2_authenticator_) return PROTOCOL_ERROR
rmsousa 2013/05/16 20:11:02 Did you miss this one?
Jamie 2013/05/16 21:09:10 I did, but looking at it, it seems redundant given
rmsousa 2013/05/16 22:16:37 Yes, that's what I meant - you needed to handle th
65 return v2_authenticator_->rejection_reason();
66 }
67
68 void PairingHostAuthenticator::ProcessMessage(
69 const buzz::XmlElement* message,
70 const base::Closure& resume_callback) {
71 DCHECK_EQ(state(), WAITING_MESSAGE);
72
73 // If there's already an underlying authenticator, defer to it.
74 if (v2_authenticator_) {
75 DCHECK_EQ(v2_authenticator_->state(), WAITING_MESSAGE);
76 v2_authenticator_->ProcessMessage(message, resume_callback);
77 return;
78 }
79
80 // If not, then create one based on the contents of the first message.
81 std::string client_id;
82 const buzz::XmlElement* pairing_tag = message->FirstNamed(kPairingInfoTag);
83 if (pairing_tag) {
rmsousa 2013/05/16 00:46:25 Lack of pairing tag should be an error as well.
rmsousa 2013/05/16 20:11:02 Did you miss this one?
Jamie 2013/05/16 21:09:10 Sorry, yes. Done.
84 client_id = pairing_tag->Attr(kClientIdAttribute);
85 if (client_id.empty()) {
86 LOG(ERROR) << "No client id specified.";
87 protocol_error_ = true;
88 resume_callback.Run();
89 return;
90 }
91 }
92
93 std::string paired_secret = pairing_registry_->GetSecret(client_id);
94
95 if (paired_secret.empty()) {
96 LOG(INFO) << "Unknown client id";
97 error_message_ = "unknown-client-id";
98 CreateV2AuthenticatorWithPIN(WAITING_MESSAGE);
99 resume_callback.Run();
100 return;
101 }
102
103 v2_authenticator_ = V2Authenticator::CreateForHost(
104 local_cert_, key_pair_, paired_secret, MESSAGE_READY);
105 resume_callback.Run();
106 }
107
108 scoped_ptr<buzz::XmlElement> PairingHostAuthenticator::GetNextMessage() {
109 DCHECK_EQ(state(), MESSAGE_READY);
110
111 if (!error_message_.empty()) {
112 scoped_ptr<buzz::XmlElement> result = CreateEmptyAuthenticatorMessage();
113 buzz::XmlElement* pairing_failed_tag =
114 new buzz::XmlElement(kPairingFailedTag);
115 pairing_failed_tag->AddAttr(kPairingErrorAttribute, error_message_);
116 result->AddElement(pairing_failed_tag);
117 error_message_.clear();
118 return result.Pass();
119
120 } else {
121 DCHECK(v2_authenticator_);
122 return v2_authenticator_->GetNextMessage();
123 }
124 }
125
126 scoped_ptr<ChannelAuthenticator>
127 PairingHostAuthenticator::CreateChannelAuthenticator() const {
128 DCHECK(v2_authenticator_);
129 return v2_authenticator_->CreateChannelAuthenticator();
130 }
131
132 void PairingHostAuthenticator::CreateV2AuthenticatorWithPIN(
133 State initial_state) {
134 DCHECK(!v2_authenticator_);
135 v2_authenticator_ = V2Authenticator::CreateForHost(
136 local_cert_, key_pair_, shared_secret_, initial_state);
137 }
138
139 } // namespace protocol
140 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698