OLD | NEW |
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/bind.h" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/string_split.h" | 13 #include "base/string_split.h" |
14 #include "remoting/protocol/channel_authenticator.h" | 14 #include "remoting/protocol/channel_authenticator.h" |
15 #include "remoting/protocol/key_pair.h" | 15 #include "remoting/protocol/key_pair.h" |
| 16 #include "remoting/protocol/third_party_authenticator.h" |
16 #include "remoting/protocol/v2_authenticator.h" | 17 #include "remoting/protocol/v2_authenticator.h" |
17 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 18 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
18 | 19 |
19 namespace remoting { | 20 namespace remoting { |
20 namespace protocol { | 21 namespace protocol { |
21 | 22 |
22 namespace { | 23 namespace { |
23 | 24 |
24 const buzz::StaticQName kMethodAttributeQName = { "", "method" }; | 25 const buzz::StaticQName kMethodAttributeQName = { "", "method" }; |
25 const buzz::StaticQName kSupportedMethodsAttributeQName = | 26 const buzz::StaticQName kSupportedMethodsAttributeQName = |
26 { "", "supported-methods" }; | 27 { "", "supported-methods" }; |
27 | 28 |
28 const char kSupportedMethodsSeparator = ','; | 29 const char kSupportedMethodsSeparator = ','; |
29 | 30 |
30 } // namespace | 31 } // namespace |
31 | 32 |
32 // static | 33 // static |
33 bool NegotiatingAuthenticator::IsNegotiableMessage( | 34 bool NegotiatingAuthenticator::IsNegotiableMessage( |
34 const buzz::XmlElement* message) { | 35 const buzz::XmlElement* message) { |
35 return message->HasAttr(kSupportedMethodsAttributeQName); | 36 return message->HasAttr(kSupportedMethodsAttributeQName); |
36 } | 37 } |
37 | 38 |
38 // static | 39 // static |
39 scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForClient( | 40 scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForClient( |
40 const std::string& authentication_tag, | 41 const std::string& authentication_tag, |
41 const std::string& shared_secret, | 42 const std::string& shared_secret, |
42 const std::vector<AuthenticationMethod>& methods) { | 43 const std::string& host_public_key, |
| 44 const std::vector<AuthenticationMethod>& methods, |
| 45 ThirdPartyAuthenticator::TokenFetcher* third_party_token_fetcher) { |
43 scoped_ptr<NegotiatingAuthenticator> result( | 46 scoped_ptr<NegotiatingAuthenticator> result( |
44 new NegotiatingAuthenticator(MESSAGE_READY)); | 47 new NegotiatingAuthenticator(MESSAGE_READY)); |
45 result->authentication_tag_ = authentication_tag; | 48 result->authentication_tag_ = authentication_tag; |
| 49 result->host_public_key_ = host_public_key; |
46 result->shared_secret_ = shared_secret; | 50 result->shared_secret_ = shared_secret; |
| 51 result->third_party_token_fetcher_ = third_party_token_fetcher; |
47 | 52 |
48 DCHECK(!methods.empty()); | 53 DCHECK(!methods.empty()); |
49 for (std::vector<AuthenticationMethod>::const_iterator it = methods.begin(); | 54 for (std::vector<AuthenticationMethod>::const_iterator it = methods.begin(); |
50 it != methods.end(); ++it) { | 55 it != methods.end(); ++it) { |
51 result->AddMethod(*it); | 56 result->AddMethod(*it); |
52 } | 57 } |
53 | 58 |
54 return scoped_ptr<Authenticator>(result.Pass()); | 59 return scoped_ptr<Authenticator>(result.Pass()); |
55 } | 60 } |
56 | 61 |
57 // static | 62 // static |
58 scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForHost( | 63 scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForHostSharedSecret( |
59 const std::string& local_cert, | 64 const std::string& local_cert, |
60 scoped_ptr<KeyPair> key_pair, | 65 scoped_ptr<KeyPair> key_pair, |
61 const std::string& shared_secret_hash, | 66 const std::string& shared_secret_hash, |
62 AuthenticationMethod::HashFunction hash_function) { | 67 AuthenticationMethod::HashFunction hash_function) { |
63 scoped_ptr<NegotiatingAuthenticator> result( | 68 scoped_ptr<NegotiatingAuthenticator> result( |
64 new NegotiatingAuthenticator(WAITING_MESSAGE)); | 69 new NegotiatingAuthenticator(WAITING_MESSAGE)); |
65 result->local_cert_ = local_cert; | 70 result->local_cert_ = local_cert; |
66 result->key_pair_ = key_pair.Pass(); | 71 result->key_pair_ = key_pair.Pass(); |
67 result->shared_secret_hash_ = shared_secret_hash; | 72 result->shared_secret_hash_ = shared_secret_hash; |
68 | 73 |
69 result->AddMethod(AuthenticationMethod::Spake2(hash_function)); | 74 result->AddMethod(AuthenticationMethod::Spake2(hash_function)); |
70 | 75 |
71 return scoped_ptr<Authenticator>(result.Pass()); | 76 return scoped_ptr<Authenticator>(result.Pass()); |
72 } | 77 } |
73 | 78 |
| 79 // static |
| 80 scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForHostThirdPartyAuth( |
| 81 const std::string& local_cert, |
| 82 scoped_ptr<KeyPair> key_pair, |
| 83 const std::string& third_party_token_url, |
| 84 const std::string& third_party_token_validation_url, |
| 85 const std::string& third_party_token_scope, |
| 86 ThirdPartyAuthenticator::TokenValidatorFactory* |
| 87 third_party_token_validator_factory) { |
| 88 scoped_ptr<NegotiatingAuthenticator> result( |
| 89 new NegotiatingAuthenticator(WAITING_MESSAGE)); |
| 90 result->local_cert_ = local_cert; |
| 91 result->key_pair_ = key_pair.Pass(); |
| 92 result->third_party_token_url_ = third_party_token_url; |
| 93 result->third_party_token_validation_url_ = third_party_token_validation_url; |
| 94 result->third_party_token_scope_ = third_party_token_scope; |
| 95 result->third_party_token_validator_factory_ = |
| 96 third_party_token_validator_factory; |
| 97 result->AddMethod(AuthenticationMethod::ThirdParty()); |
| 98 |
| 99 return scoped_ptr<Authenticator>(result.Pass()); |
| 100 } |
| 101 |
74 NegotiatingAuthenticator::NegotiatingAuthenticator( | 102 NegotiatingAuthenticator::NegotiatingAuthenticator( |
75 Authenticator::State initial_state) | 103 Authenticator::State initial_state) |
76 : current_method_(AuthenticationMethod::Invalid()), | 104 : current_method_(AuthenticationMethod::Invalid()), |
77 state_(initial_state), | 105 state_(initial_state), |
78 rejection_reason_(INVALID_CREDENTIALS) { | 106 rejection_reason_(INVALID_CREDENTIALS) { |
79 } | 107 } |
80 | 108 |
81 NegotiatingAuthenticator::~NegotiatingAuthenticator() { | 109 NegotiatingAuthenticator::~NegotiatingAuthenticator() { |
82 } | 110 } |
83 | 111 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 DCHECK_EQ(state(), ACCEPTED); | 235 DCHECK_EQ(state(), ACCEPTED); |
208 return current_authenticator_->CreateChannelAuthenticator(); | 236 return current_authenticator_->CreateChannelAuthenticator(); |
209 } | 237 } |
210 | 238 |
211 bool NegotiatingAuthenticator::is_host_side() const { | 239 bool NegotiatingAuthenticator::is_host_side() const { |
212 return key_pair_.get() != NULL; | 240 return key_pair_.get() != NULL; |
213 } | 241 } |
214 | 242 |
215 void NegotiatingAuthenticator::CreateAuthenticator(State initial_state) { | 243 void NegotiatingAuthenticator::CreateAuthenticator(State initial_state) { |
216 if (is_host_side()) { | 244 if (is_host_side()) { |
217 current_authenticator_ = V2Authenticator::CreateForHost( | 245 if (current_method_.requires_token()) { |
218 local_cert_, key_pair_->Copy(), | 246 current_authenticator_ = ThirdPartyAuthenticator::CreateForHost( |
219 shared_secret_hash_, initial_state); | 247 local_cert_, key_pair_->Copy(), third_party_token_url_, |
| 248 third_party_token_validation_url_, third_party_token_scope_, |
| 249 third_party_token_validator_factory_->CreateTokenValidator(), |
| 250 initial_state); |
| 251 } else { |
| 252 current_authenticator_ = V2Authenticator::CreateForHost( |
| 253 local_cert_, key_pair_->Copy(), |
| 254 shared_secret_hash_, initial_state); |
| 255 } |
220 } else { | 256 } else { |
221 current_authenticator_ = V2Authenticator::CreateForClient( | 257 if (current_method_.requires_token()) { |
222 AuthenticationMethod::ApplyHashFunction( | 258 current_authenticator_ = ThirdPartyAuthenticator::CreateForClient( |
223 current_method_.hash_function(), | 259 host_public_key_, third_party_token_fetcher_, initial_state); |
224 authentication_tag_, shared_secret_), initial_state); | 260 } else { |
| 261 current_authenticator_ = V2Authenticator::CreateForClient( |
| 262 AuthenticationMethod::ApplyHashFunction( |
| 263 current_method_.hash_function(), |
| 264 authentication_tag_, shared_secret_), initial_state); |
| 265 } |
225 } | 266 } |
226 } | 267 } |
227 | 268 |
| 269 void NegotiatingAuthenticator::PerformExternalAction( |
| 270 const base::Closure& resume_callback) { |
| 271 DCHECK_EQ(state_, WAITING_EXTERNAL); |
| 272 |
| 273 current_authenticator_->PerformExternalAction( |
| 274 base::Bind( |
| 275 &NegotiatingAuthenticator::UpdateState, |
| 276 // This object is guaranteed to outlive the underlying authenticator. |
| 277 base::Unretained(this), |
| 278 resume_callback)); |
| 279 } |
| 280 |
| 281 void NegotiatingAuthenticator::UpdateState( |
| 282 const base::Closure& resume_callback) { |
| 283 DCHECK_EQ(state_, WAITING_EXTERNAL); |
| 284 |
| 285 // After the underlying authenticator finishes performing its external action, |
| 286 // the NegotiatingAuthenticator must update its own state before running the |
| 287 // |resume_callback| to resume the session negotiation. |
| 288 state_ = current_authenticator_->state(); |
| 289 if (state_ == REJECTED) |
| 290 rejection_reason_ = current_authenticator_->rejection_reason(); |
| 291 resume_callback.Run(); |
| 292 } |
| 293 |
228 } // namespace protocol | 294 } // namespace protocol |
229 } // namespace remoting | 295 } // namespace remoting |
OLD | NEW |