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

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

Issue 12389010: Refactor of Authenticator to allow it to ProcessMessage asynchronously and then call a callback (Closed) Base URL: http://git.chromium.org/chromium/src.git@host_key_pair
Patch Set: Rebase missed one include Created 7 years, 9 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
« no previous file with comments | « remoting/protocol/negotiating_authenticator.h ('k') | remoting/protocol/session.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/protocol/negotiating_authenticator.h" 5 #include "remoting/protocol/negotiating_authenticator.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "base/bind.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/string_split.h" 12 #include "base/string_split.h"
12 #include "crypto/rsa_private_key.h" 13 #include "crypto/rsa_private_key.h"
13 #include "remoting/protocol/channel_authenticator.h" 14 #include "remoting/protocol/channel_authenticator.h"
14 #include "remoting/protocol/v2_authenticator.h" 15 #include "remoting/protocol/v2_authenticator.h"
15 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 16 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
16 17
17 namespace remoting { 18 namespace remoting {
18 namespace protocol { 19 namespace protocol {
19 20
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 84
84 Authenticator::State NegotiatingAuthenticator::state() const { 85 Authenticator::State NegotiatingAuthenticator::state() const {
85 return state_; 86 return state_;
86 } 87 }
87 88
88 Authenticator::RejectionReason 89 Authenticator::RejectionReason
89 NegotiatingAuthenticator::rejection_reason() const { 90 NegotiatingAuthenticator::rejection_reason() const {
90 return rejection_reason_; 91 return rejection_reason_;
91 } 92 }
92 93
93 void NegotiatingAuthenticator::ProcessMessage(const buzz::XmlElement* message) { 94 void NegotiatingAuthenticator::ProcessMessage(
95 const buzz::XmlElement* message,
96 const base::Closure& resume_callback) {
94 DCHECK_EQ(state(), WAITING_MESSAGE); 97 DCHECK_EQ(state(), WAITING_MESSAGE);
95 98
96 std::string method_attr = message->Attr(kMethodAttributeQName); 99 std::string method_attr = message->Attr(kMethodAttributeQName);
97 AuthenticationMethod method = AuthenticationMethod::FromString(method_attr); 100 AuthenticationMethod method = AuthenticationMethod::FromString(method_attr);
98 101
99 // Check if the remote end specified a method that is not supported locally. 102 // Check if the remote end specified a method that is not supported locally.
100 if (method.is_valid() && 103 if (method.is_valid() &&
101 std::find(methods_.begin(), methods_.end(), method) == methods_.end()) { 104 std::find(methods_.begin(), methods_.end(), method) == methods_.end()) {
102 method = AuthenticationMethod::Invalid(); 105 method = AuthenticationMethod::Invalid();
103 } 106 }
104 107
105 // If the remote peer did not specify auth method or specified unknown 108 // If the remote peer did not specify auth method or specified unknown
106 // method then select the first known method from the supported-methods 109 // method then select the first known method from the supported-methods
107 // attribute. 110 // attribute.
108 if (!method.is_valid()) { 111 if (!method.is_valid()) {
109 std::string supported_methods_attr = 112 std::string supported_methods_attr =
110 message->Attr(kSupportedMethodsAttributeQName); 113 message->Attr(kSupportedMethodsAttributeQName);
111 if (supported_methods_attr.empty()) { 114 if (supported_methods_attr.empty()) {
112 // Message contains neither method nor supported-methods attributes. 115 // Message contains neither method nor supported-methods attributes.
113 state_ = REJECTED; 116 state_ = REJECTED;
114 rejection_reason_ = PROTOCOL_ERROR; 117 rejection_reason_ = PROTOCOL_ERROR;
118 resume_callback.Run();
115 return; 119 return;
116 } 120 }
117 121
118 // Find the first mutually-supported method in the peer's list of 122 // Find the first mutually-supported method in the peer's list of
119 // supported-methods. 123 // supported-methods.
120 std::vector<std::string> supported_methods_strs; 124 std::vector<std::string> supported_methods_strs;
121 base::SplitString(supported_methods_attr, kSupportedMethodsSeparator, 125 base::SplitString(supported_methods_attr, kSupportedMethodsSeparator,
122 &supported_methods_strs); 126 &supported_methods_strs);
123 for (std::vector<std::string>::iterator it = supported_methods_strs.begin(); 127 for (std::vector<std::string>::iterator it = supported_methods_strs.begin();
124 it != supported_methods_strs.end(); ++it) { 128 it != supported_methods_strs.end(); ++it) {
125 AuthenticationMethod list_value = AuthenticationMethod::FromString(*it); 129 AuthenticationMethod list_value = AuthenticationMethod::FromString(*it);
126 if (list_value.is_valid() && 130 if (list_value.is_valid() &&
127 std::find(methods_.begin(), 131 std::find(methods_.begin(),
128 methods_.end(), list_value) != methods_.end()) { 132 methods_.end(), list_value) != methods_.end()) {
129 // Found common method. 133 // Found common method.
130 method = list_value; 134 method = list_value;
131 break; 135 break;
132 } 136 }
133 } 137 }
134 138
135 if (!method.is_valid()) { 139 if (!method.is_valid()) {
136 // Failed to find a common auth method. 140 // Failed to find a common auth method.
137 state_ = REJECTED; 141 state_ = REJECTED;
138 rejection_reason_ = PROTOCOL_ERROR; 142 rejection_reason_ = PROTOCOL_ERROR;
143 resume_callback.Run();
139 return; 144 return;
140 } 145 }
141 146
142 // Drop the current message because we've chosen a different 147 // Drop the current message because we've chosen a different
143 // method. 148 // method.
144 state_ = MESSAGE_READY; 149 state_ = MESSAGE_READY;
145 } 150 }
146 151
147 DCHECK(method.is_valid()); 152 DCHECK(method.is_valid());
148 153
149 // Replace current authenticator if the method has changed. 154 // Replace current authenticator if the method has changed.
150 if (method != current_method_) { 155 if (method != current_method_) {
151 current_method_ = method; 156 current_method_ = method;
152 CreateAuthenticator(state_); 157 CreateAuthenticator(state_);
153 } 158 }
159 if (state_ == WAITING_MESSAGE) {
160 // |current_authenticator_| is owned, so Unretained() is safe here.
161 current_authenticator_->ProcessMessage(message, base::Bind(
162 &NegotiatingAuthenticator::UpdateState,
163 base::Unretained(this), resume_callback));
164 } else {
165 UpdateState(resume_callback);
166 }
167 }
154 168
155 if (state_ == WAITING_MESSAGE) { 169 void NegotiatingAuthenticator::UpdateState(
156 current_authenticator_->ProcessMessage(message); 170 const base::Closure& resume_callback) {
157 state_ = current_authenticator_->state(); 171 // After the underlying authenticator finishes processing the message, the
158 if (state_ == REJECTED) 172 // NegotiatingAuthenticator must update its own state before running the
159 rejection_reason_ = current_authenticator_->rejection_reason(); 173 // |resume_callback| to resume the session negotiation.
160 } 174 state_ = current_authenticator_->state();
175 if (state_ == REJECTED)
176 rejection_reason_ = current_authenticator_->rejection_reason();
177 resume_callback.Run();
161 } 178 }
162 179
163 scoped_ptr<buzz::XmlElement> NegotiatingAuthenticator::GetNextMessage() { 180 scoped_ptr<buzz::XmlElement> NegotiatingAuthenticator::GetNextMessage() {
164 DCHECK_EQ(state(), MESSAGE_READY); 181 DCHECK_EQ(state(), MESSAGE_READY);
165 182
166 bool add_supported_methods_attr = false; 183 bool add_supported_methods_attr = false;
167 184
168 // Initialize current method in case it is not initialized 185 // Initialize current method in case it is not initialized
169 // yet. Normally happens only on client. 186 // yet. Normally happens only on client.
170 if (!current_method_.is_valid()) { 187 if (!current_method_.is_valid()) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 current_authenticator_ = V2Authenticator::CreateForClient( 238 current_authenticator_ = V2Authenticator::CreateForClient(
222 AuthenticationMethod::ApplyHashFunction( 239 AuthenticationMethod::ApplyHashFunction(
223 current_method_.hash_function(), 240 current_method_.hash_function(),
224 authentication_tag_, shared_secret_), 241 authentication_tag_, shared_secret_),
225 initial_state); 242 initial_state);
226 } 243 }
227 } 244 }
228 245
229 } // namespace protocol 246 } // namespace protocol
230 } // namespace remoting 247 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/negotiating_authenticator.h ('k') | remoting/protocol/session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698