Home | History | Annotate | Download | only in protocol
      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
      3 // found in the LICENSE file.
      4 
      5 #include "remoting/protocol/negotiating_authenticator_base.h"
      6 
      7 #include <algorithm>
      8 #include <sstream>
      9 
     10 #include "base/bind.h"
     11 #include "base/callback.h"
     12 #include "base/logging.h"
     13 #include "base/strings/string_split.h"
     14 #include "remoting/base/rsa_key_pair.h"
     15 #include "remoting/protocol/channel_authenticator.h"
     16 #include "remoting/protocol/v2_authenticator.h"
     17 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
     18 
     19 namespace remoting {
     20 namespace protocol {
     21 
     22 const buzz::StaticQName NegotiatingAuthenticatorBase::kMethodAttributeQName =
     23     { "", "method" };
     24 const buzz::StaticQName
     25 NegotiatingAuthenticatorBase::kSupportedMethodsAttributeQName =
     26     { "", "supported-methods" };
     27 const char NegotiatingAuthenticatorBase::kSupportedMethodsSeparator = ',';
     28 
     29 NegotiatingAuthenticatorBase::NegotiatingAuthenticatorBase(
     30     Authenticator::State initial_state)
     31     : current_method_(AuthenticationMethod::Invalid()),
     32       state_(initial_state),
     33       rejection_reason_(INVALID_CREDENTIALS) {
     34 }
     35 
     36 NegotiatingAuthenticatorBase::~NegotiatingAuthenticatorBase() {
     37 }
     38 
     39 Authenticator::State NegotiatingAuthenticatorBase::state() const {
     40   return state_;
     41 }
     42 
     43 Authenticator::RejectionReason
     44 NegotiatingAuthenticatorBase::rejection_reason() const {
     45   return rejection_reason_;
     46 }
     47 
     48 void NegotiatingAuthenticatorBase::ProcessMessageInternal(
     49     const buzz::XmlElement* message,
     50     const base::Closure& resume_callback) {
     51   if (current_authenticator_->state() == WAITING_MESSAGE) {
     52     // If the message was not discarded and the authenticator is waiting for it,
     53     // give it to the underlying authenticator to process.
     54     // |current_authenticator_| is owned, so Unretained() is safe here.
     55     state_ = PROCESSING_MESSAGE;
     56     current_authenticator_->ProcessMessage(message, base::Bind(
     57         &NegotiatingAuthenticatorBase::UpdateState,
     58         base::Unretained(this), resume_callback));
     59   } else {
     60     // Otherwise, just discard the message and run the callback.
     61     resume_callback.Run();
     62   }
     63 }
     64 
     65 void NegotiatingAuthenticatorBase::UpdateState(
     66     const base::Closure& resume_callback) {
     67   // After the underlying authenticator finishes processing the message, the
     68   // NegotiatingAuthenticatorBase must update its own state before running the
     69   // |resume_callback| to resume the session negotiation.
     70   state_ = current_authenticator_->state();
     71   if (state_ == REJECTED)
     72     rejection_reason_ = current_authenticator_->rejection_reason();
     73   resume_callback.Run();
     74 }
     75 
     76 scoped_ptr<buzz::XmlElement>
     77 NegotiatingAuthenticatorBase::GetNextMessageInternal() {
     78   DCHECK_EQ(state(), MESSAGE_READY);
     79   DCHECK(current_method_.is_valid());
     80 
     81   scoped_ptr<buzz::XmlElement> result;
     82   if (current_authenticator_->state() == MESSAGE_READY) {
     83     result = current_authenticator_->GetNextMessage();
     84   } else {
     85     result = CreateEmptyAuthenticatorMessage();
     86   }
     87   state_ = current_authenticator_->state();
     88   DCHECK(state_ == ACCEPTED || state_ == WAITING_MESSAGE);
     89   result->AddAttr(kMethodAttributeQName, current_method_.ToString());
     90   return result.Pass();
     91 }
     92 
     93 void NegotiatingAuthenticatorBase::AddMethod(
     94     const AuthenticationMethod& method) {
     95   DCHECK(method.is_valid());
     96   methods_.push_back(method);
     97 }
     98 
     99 scoped_ptr<ChannelAuthenticator>
    100 NegotiatingAuthenticatorBase::CreateChannelAuthenticator() const {
    101   DCHECK_EQ(state(), ACCEPTED);
    102   return current_authenticator_->CreateChannelAuthenticator();
    103 }
    104 
    105 }  // namespace protocol
    106 }  // namespace remoting
    107