Chromium Code Reviews| Index: remoting/protocol/negotiating_authenticator.cc |
| diff --git a/remoting/protocol/negotiating_authenticator.cc b/remoting/protocol/negotiating_authenticator.cc |
| index 7b794d2a05f69a1f8de26ea3dc64b6d80b4773fe..a59241bdd3ff45c21271d11f8d2368eefe1385e5 100644 |
| --- a/remoting/protocol/negotiating_authenticator.cc |
| +++ b/remoting/protocol/negotiating_authenticator.cc |
| @@ -30,20 +30,14 @@ const char kSupportedMethodsSeparator = ','; |
| } // namespace |
| // static |
| -bool NegotiatingAuthenticator::IsNegotiableMessage( |
| - const buzz::XmlElement* message) { |
| - return message->HasAttr(kSupportedMethodsAttributeQName); |
| -} |
| - |
| -// static |
| scoped_ptr<Authenticator> NegotiatingAuthenticator::CreateForClient( |
| const std::string& authentication_tag, |
| - const std::string& shared_secret, |
| + const FetchSecretCallback& fetch_secret_callback, |
| const std::vector<AuthenticationMethod>& methods) { |
| scoped_ptr<NegotiatingAuthenticator> result( |
| new NegotiatingAuthenticator(MESSAGE_READY)); |
| result->authentication_tag_ = authentication_tag; |
| - result->shared_secret_ = shared_secret; |
| + result->fetch_secret_callback_ = fetch_secret_callback; |
| DCHECK(!methods.empty()); |
| for (std::vector<AuthenticationMethod>::const_iterator it = methods.begin(); |
| @@ -75,7 +69,8 @@ NegotiatingAuthenticator::NegotiatingAuthenticator( |
| Authenticator::State initial_state) |
| : current_method_(AuthenticationMethod::Invalid()), |
| state_(initial_state), |
| - rejection_reason_(INVALID_CREDENTIALS) { |
| + rejection_reason_(INVALID_CREDENTIALS), |
| + weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| } |
| NegotiatingAuthenticator::~NegotiatingAuthenticator() { |
| @@ -145,23 +140,36 @@ void NegotiatingAuthenticator::ProcessMessage( |
| // Drop the current message because we've chosen a different |
| // method. |
| - state_ = MESSAGE_READY; |
| - } |
| - |
| - DCHECK(method.is_valid()); |
| - |
| - // Replace current authenticator if the method has changed. |
| - if (method != current_method_) { |
| current_method_ = method; |
| - CreateAuthenticator(state_); |
| + state_ = PROCESSING_MESSAGE; |
| + CreateAuthenticator(MESSAGE_READY, base::Bind( |
| + &NegotiatingAuthenticator::UpdateState, |
| + base::Unretained(this), resume_callback)); |
| + } else { |
|
Sergey Ulanov
2013/03/20 05:49:05
nit: add return above and then you won't need "els
rmsousa
2013/03/20 20:17:16
Done.
|
| + if (method != current_method_) { |
| + current_method_ = method; |
| + state_ = PROCESSING_MESSAGE; |
| + // Copy the message since the authenticator may process it asynchronously. |
| + CreateAuthenticator(WAITING_MESSAGE, base::Bind( |
| + &NegotiatingAuthenticator::ProcessMessageInternal, |
| + base::Unretained(this), base::Owned(new buzz::XmlElement(*message)), |
| + resume_callback)); |
| + } else { |
| + ProcessMessageInternal(message, resume_callback); |
| + } |
| } |
| - if (state_ == WAITING_MESSAGE) { |
| +} |
| + |
| +void NegotiatingAuthenticator::ProcessMessageInternal( |
|
Sergey Ulanov
2013/03/20 05:49:05
Move this below so order of functions here matches
rmsousa
2013/03/20 20:17:16
Done.
|
| + const buzz::XmlElement* message, |
| + const base::Closure& resume_callback) { |
| + if (current_authenticator_->state() == WAITING_MESSAGE) { |
| + // If the message was not discarded and the authenticator is waiting for it, |
| + // give it to the underlying authenticator to process. |
| // |current_authenticator_| is owned, so Unretained() is safe here. |
| current_authenticator_->ProcessMessage(message, base::Bind( |
| &NegotiatingAuthenticator::UpdateState, |
| base::Unretained(this), resume_callback)); |
| - } else { |
| - UpdateState(resume_callback); |
| } |
| } |
| @@ -179,27 +187,12 @@ void NegotiatingAuthenticator::UpdateState( |
| scoped_ptr<buzz::XmlElement> NegotiatingAuthenticator::GetNextMessage() { |
| DCHECK_EQ(state(), MESSAGE_READY); |
| - bool add_supported_methods_attr = false; |
| + scoped_ptr<buzz::XmlElement> result; |
| - // Initialize current method in case it is not initialized |
| - // yet. Normally happens only on client. |
| + // No method yet, just send a message with the list of supported methods. |
| + // Normally happens only on client. |
| if (!current_method_.is_valid()) { |
| - CHECK(!methods_.empty()); |
| - |
| - // Initially try the first method. |
| - current_method_ = methods_[0]; |
| - CreateAuthenticator(MESSAGE_READY); |
| - add_supported_methods_attr = true; |
| - } |
| - |
| - scoped_ptr<buzz::XmlElement> result = |
| - current_authenticator_->GetNextMessage(); |
| - state_ = current_authenticator_->state(); |
| - DCHECK_NE(state_, REJECTED); |
| - |
| - result->AddAttr(kMethodAttributeQName, current_method_.ToString()); |
| - |
| - if (add_supported_methods_attr) { |
| + result = CreateEmptyAuthenticatorMessage(); |
| std::stringstream supported_methods(std::stringstream::out); |
| for (std::vector<AuthenticationMethod>::iterator it = methods_.begin(); |
| it != methods_.end(); ++it) { |
| @@ -208,6 +201,17 @@ scoped_ptr<buzz::XmlElement> NegotiatingAuthenticator::GetNextMessage() { |
| supported_methods << it->ToString(); |
| } |
| result->AddAttr(kSupportedMethodsAttributeQName, supported_methods.str()); |
| + state_ = WAITING_MESSAGE; |
| + } else { |
| + if (current_authenticator_->state() == MESSAGE_READY) { |
| + result = current_authenticator_->GetNextMessage(); |
| + } else { |
| + result = CreateEmptyAuthenticatorMessage(); |
| + } |
| + state_ = current_authenticator_->state(); |
| + DCHECK_NE(state_, REJECTED); |
|
Sergey Ulanov
2013/03/20 05:49:05
here state can be either WAITING_MESSAGE or ACCEPT
rmsousa
2013/03/20 20:17:16
Done.
|
| + DCHECK_NE(state_, MESSAGE_READY); |
| + result->AddAttr(kMethodAttributeQName, current_method_.ToString()); |
| } |
| return result.Pass(); |
| @@ -228,17 +232,32 @@ bool NegotiatingAuthenticator::is_host_side() const { |
| return local_key_pair_.get() != NULL; |
| } |
| -void NegotiatingAuthenticator::CreateAuthenticator(State initial_state) { |
| + |
|
Sergey Ulanov
2013/03/20 05:49:05
nit: remove empty line
rmsousa
2013/03/20 20:17:16
Done.
|
| +void NegotiatingAuthenticator::CreateAuthenticator( |
| + Authenticator::State preferred_initial_state, |
| + const base::Closure& resume_callback) { |
| if (is_host_side()) { |
| current_authenticator_ = V2Authenticator::CreateForHost( |
| - local_cert_, local_key_pair_, shared_secret_hash_, initial_state); |
| + local_cert_, local_key_pair_, shared_secret_hash_, |
| + preferred_initial_state); |
| + resume_callback.Run(); |
|
Sergey Ulanov
2013/03/20 05:49:05
Do you need to set state_ here to something other
rmsousa
2013/03/20 20:17:16
The callbacks passed in here all call UpdateState
|
| } else { |
| - current_authenticator_ = V2Authenticator::CreateForClient( |
| - AuthenticationMethod::ApplyHashFunction( |
| - current_method_.hash_function(), |
| - authentication_tag_, shared_secret_), initial_state); |
| + fetch_secret_callback_.Run(base::Bind( |
| + &NegotiatingAuthenticator::CreateV2AuthenticatorWithSecret, |
| + weak_factory_.GetWeakPtr(), preferred_initial_state, resume_callback)); |
| } |
| } |
| +void NegotiatingAuthenticator::CreateV2AuthenticatorWithSecret( |
| + Authenticator::State initial_state, |
| + const base::Closure& resume_callback, |
| + const std::string& shared_secret) { |
| + current_authenticator_ = V2Authenticator::CreateForClient( |
| + AuthenticationMethod::ApplyHashFunction( |
| + current_method_.hash_function(), authentication_tag_, shared_secret), |
| + initial_state); |
| + resume_callback.Run(); |
|
Sergey Ulanov
2013/03/20 05:49:05
Set state_ to MESSAGE_READY?
rmsousa
2013/03/20 20:17:16
Same applies, there's an UpdateState in the callba
|
| +} |
| + |
| } // namespace protocol |
| } // namespace remoting |