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/webrtc/libjingle/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 bool NegotiatingAuthenticatorBase::started() const {
     44   if (!current_authenticator_) {
     45     return false;
     46   }
     47   return current_authenticator_->started();
     48 }
     49 
     50 Authenticator::RejectionReason
     51 NegotiatingAuthenticatorBase::rejection_reason() const {
     52   return rejection_reason_;
     53 }
     54 
     55 void NegotiatingAuthenticatorBase::ProcessMessageInternal(
     56     const buzz::XmlElement* message,
     57     const base::Closure& resume_callback) {
     58   if (current_authenticator_->state() == WAITING_MESSAGE) {
     59     // If the message was not discarded and the authenticator is waiting for it,
     60     // give it to the underlying authenticator to process.
     61     // |current_authenticator_| is owned, so Unretained() is safe here.
     62     state_ = PROCESSING_MESSAGE;
     63     current_authenticator_->ProcessMessage(message, base::Bind(
     64         &NegotiatingAuthenticatorBase::UpdateState,
     65         base::Unretained(this), resume_callback));
     66   } else {
     67     // Otherwise, just discard the message and run the callback.
     68     resume_callback.Run();
     69   }
     70 }
     71 
     72 void NegotiatingAuthenticatorBase::UpdateState(
     73     const base::Closure& resume_callback) {
     74   // After the underlying authenticator finishes processing the message, the
     75   // NegotiatingAuthenticatorBase must update its own state before running the
     76   // |resume_callback| to resume the session negotiation.
     77   state_ = current_authenticator_->state();
     78   if (state_ == REJECTED)
     79     rejection_reason_ = current_authenticator_->rejection_reason();
     80   resume_callback.Run();
     81 }
     82 
     83 scoped_ptr<buzz::XmlElement>
     84 NegotiatingAuthenticatorBase::GetNextMessageInternal() {
     85   DCHECK_EQ(state(), MESSAGE_READY);
     86   DCHECK(current_method_.is_valid());
     87 
     88   scoped_ptr<buzz::XmlElement> result;
     89   if (current_authenticator_->state() == MESSAGE_READY) {
     90     result = current_authenticator_->GetNextMessage();
     91   } else {
     92     result = CreateEmptyAuthenticatorMessage();
     93   }
     94   state_ = current_authenticator_->state();
     95   DCHECK(state_ == ACCEPTED || state_ == WAITING_MESSAGE);
     96   result->AddAttr(kMethodAttributeQName, current_method_.ToString());
     97   return result.Pass();
     98 }
     99 
    100 void NegotiatingAuthenticatorBase::AddMethod(
    101     const AuthenticationMethod& method) {
    102   DCHECK(method.is_valid());
    103   methods_.push_back(method);
    104 }
    105 
    106 scoped_ptr<ChannelAuthenticator>
    107 NegotiatingAuthenticatorBase::CreateChannelAuthenticator() const {
    108   DCHECK_EQ(state(), ACCEPTED);
    109   return current_authenticator_->CreateChannelAuthenticator();
    110 }
    111 
    112 }  // namespace protocol
    113 }  // namespace remoting
    114