Index: remoting/protocol/negotiating_authenticator.cc |
diff --git a/remoting/protocol/negotiating_authenticator.cc b/remoting/protocol/negotiating_authenticator.cc |
index ae994f491c3c0196859f1bf0e32862c1c61ee6a4..ecc465fde9dfe94bfbc292319e871f2c31e4a1a7 100644 |
--- a/remoting/protocol/negotiating_authenticator.cc |
+++ b/remoting/protocol/negotiating_authenticator.cc |
@@ -13,6 +13,7 @@ |
#include "base/string_split.h" |
#include "remoting/protocol/channel_authenticator.h" |
#include "remoting/protocol/key_pair.h" |
+#include "remoting/protocol/third_party_authenticator.h" |
#include "remoting/protocol/v2_authenticator.h" |
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
@@ -39,11 +40,15 @@ bool NegotiatingAuthenticator::IsNegotiableMessage( |
scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForClient( |
const std::string& authentication_tag, |
const std::string& shared_secret, |
- const std::vector<AuthenticationMethod>& methods) { |
+ const std::string& host_public_key, |
+ const std::vector<AuthenticationMethod>& methods, |
+ ThirdPartyAuthenticator::TokenFetcher* third_party_token_fetcher) { |
scoped_ptr<NegotiatingAuthenticator> result( |
new NegotiatingAuthenticator(MESSAGE_READY)); |
result->authentication_tag_ = authentication_tag; |
+ result->host_public_key_ = host_public_key; |
result->shared_secret_ = shared_secret; |
+ result->third_party_token_fetcher_ = third_party_token_fetcher; |
DCHECK(!methods.empty()); |
for (std::vector<AuthenticationMethod>::const_iterator it = methods.begin(); |
@@ -55,7 +60,7 @@ scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForClient( |
} |
// static |
-scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForHost( |
+scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForHostSharedSecret( |
const std::string& local_cert, |
scoped_ptr<KeyPair> key_pair, |
const std::string& shared_secret_hash, |
@@ -71,6 +76,29 @@ scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForHost( |
return scoped_ptr<Authenticator>(result.Pass()); |
} |
+// static |
+scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForHostThirdPartyAuth( |
+ const std::string& local_cert, |
+ scoped_ptr<KeyPair> key_pair, |
+ const std::string& third_party_token_url, |
+ const std::string& third_party_token_validation_url, |
+ const std::string& third_party_token_scope, |
+ ThirdPartyAuthenticator::TokenValidatorFactory* |
+ third_party_token_validator_factory) { |
+ scoped_ptr<NegotiatingAuthenticator> result( |
+ new NegotiatingAuthenticator(WAITING_MESSAGE)); |
+ result->local_cert_ = local_cert; |
+ result->key_pair_ = key_pair.Pass(); |
+ result->third_party_token_url_ = third_party_token_url; |
+ result->third_party_token_validation_url_ = third_party_token_validation_url; |
+ result->third_party_token_scope_ = third_party_token_scope; |
+ result->third_party_token_validator_factory_ = |
+ third_party_token_validator_factory; |
+ result->AddMethod(AuthenticationMethod::ThirdParty()); |
+ |
+ return scoped_ptr<Authenticator>(result.Pass()); |
+} |
+ |
NegotiatingAuthenticator::NegotiatingAuthenticator( |
Authenticator::State initial_state) |
: current_method_(AuthenticationMethod::Invalid()), |
@@ -214,16 +242,54 @@ bool NegotiatingAuthenticator::is_host_side() const { |
void NegotiatingAuthenticator::CreateAuthenticator(State initial_state) { |
if (is_host_side()) { |
- current_authenticator_ = V2Authenticator::CreateForHost( |
- local_cert_, key_pair_->Copy(), |
- shared_secret_hash_, initial_state); |
+ if (current_method_.requires_token()) { |
+ current_authenticator_ = ThirdPartyAuthenticator::CreateForHost( |
+ local_cert_, key_pair_->Copy(), third_party_token_url_, |
+ third_party_token_validation_url_, third_party_token_scope_, |
+ third_party_token_validator_factory_->CreateTokenValidator(), |
+ initial_state); |
+ } else { |
+ current_authenticator_ = V2Authenticator::CreateForHost( |
+ local_cert_, key_pair_->Copy(), |
+ shared_secret_hash_, initial_state); |
+ } |
} else { |
- current_authenticator_ = V2Authenticator::CreateForClient( |
- AuthenticationMethod::ApplyHashFunction( |
- current_method_.hash_function(), |
- authentication_tag_, shared_secret_), initial_state); |
+ if (current_method_.requires_token()) { |
+ current_authenticator_ = ThirdPartyAuthenticator::CreateForClient( |
+ host_public_key_, third_party_token_fetcher_, initial_state); |
+ } else { |
+ current_authenticator_ = V2Authenticator::CreateForClient( |
+ AuthenticationMethod::ApplyHashFunction( |
+ current_method_.hash_function(), |
+ authentication_tag_, shared_secret_), initial_state); |
+ } |
} |
} |
+void NegotiatingAuthenticator::PerformExternalAction( |
+ const base::Closure& resume_callback) { |
+ DCHECK_EQ(state_, WAITING_EXTERNAL); |
+ |
+ current_authenticator_->PerformExternalAction( |
+ base::Bind( |
+ &NegotiatingAuthenticator::UpdateState, |
+ // This object is guaranteed to outlive the underlying authenticator. |
+ base::Unretained(this), |
+ resume_callback)); |
+} |
+ |
+void NegotiatingAuthenticator::UpdateState( |
+ const base::Closure& resume_callback) { |
+ DCHECK_EQ(state_, WAITING_EXTERNAL); |
+ |
+ // After the underlying authenticator finishes performing its external action, |
+ // the NegotiatingAuthenticator must update its own state before running the |
+ // |resume_callback| to resume the session negotiation. |
+ state_ = current_authenticator_->state(); |
+ if (state_ == REJECTED) |
+ rejection_reason_ = current_authenticator_->rejection_reason(); |
+ resume_callback.Run(); |
+} |
+ |
} // namespace protocol |
} // namespace remoting |