| 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 |