// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/protocol/negotiating_client_authenticator.h"

#include <algorithm>
#include <sstream>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "remoting/protocol/auth_util.h"
#include "remoting/protocol/channel_authenticator.h"
#include "remoting/protocol/pairing_client_authenticator.h"
#include "remoting/protocol/spake2_authenticator.h"
#include "remoting/protocol/v2_authenticator.h"
#include "third_party/webrtc/libjingle/xmllite/xmlelement.h"

namespace remoting {
namespace protocol {

NegotiatingClientAuthenticator::NegotiatingClientAuthenticator(
    const std::string& local_id,
    const std::string& remote_id,
    const ClientAuthenticationConfig& config)
    : NegotiatingAuthenticatorBase(MESSAGE_READY),
      local_id_(local_id),
      remote_id_(remote_id),
      config_(config),
      weak_factory_(this) {
  if (!config_.fetch_third_party_token_callback.is_null()) {
    AddMethod(Method::THIRD_PARTY_SPAKE2_CURVE25519);
    AddMethod(Method::THIRD_PARTY_SPAKE2_P224);
  }

  AddMethod(Method::PAIRED_SPAKE2_CURVE25519);
  AddMethod(Method::PAIRED_SPAKE2_P224);

  AddMethod(Method::SHARED_SECRET_SPAKE2_CURVE25519);
  AddMethod(Method::SHARED_SECRET_SPAKE2_P224);
}

NegotiatingClientAuthenticator::~NegotiatingClientAuthenticator() {}

void NegotiatingClientAuthenticator::ProcessMessage(
    const buzz::XmlElement* message,
    const base::Closure& resume_callback) {
  DCHECK_EQ(state(), WAITING_MESSAGE);
  state_ = PROCESSING_MESSAGE;

  std::string method_attr = message->Attr(kMethodAttributeQName);
  Method method = ParseMethodString(method_attr);

  // The host picked a method different from the one the client had selected.
  if (method != current_method_) {
    // The host must pick a method that is valid and supported by the client,
    // and it must not change methods after it has picked one.
    if (method_set_by_host_ || method == Method::INVALID ||
        std::find(methods_.begin(), methods_.end(), method) == methods_.end()) {
      state_ = REJECTED;
      rejection_reason_ = PROTOCOL_ERROR;
      resume_callback.Run();
      return;
    }

    current_method_ = method;
    method_set_by_host_ = true;

    // Copy the message since the authenticator may process it asynchronously.
    base::Closure callback = base::Bind(
        &NegotiatingAuthenticatorBase::ProcessMessageInternal,
        base::Unretained(this), base::Owned(new buzz::XmlElement(*message)),
        resume_callback);
    CreateAuthenticatorForCurrentMethod(WAITING_MESSAGE, callback);
    return;
  }
  ProcessMessageInternal(message, resume_callback);
}

scoped_ptr<buzz::XmlElement> NegotiatingClientAuthenticator::GetNextMessage() {
  DCHECK_EQ(state(), MESSAGE_READY);

  // This is the first message to the host, send a list of supported methods.
  if (current_method_ == Method::INVALID) {
    // If no authentication method has been chosen, see if we can optimistically
    // choose one.
    scoped_ptr<buzz::XmlElement> result;
    CreatePreferredAuthenticator();
    if (current_authenticator_) {
      DCHECK(current_authenticator_->state() == MESSAGE_READY);
      result = GetNextMessageInternal();
    } else {
      result = CreateEmptyAuthenticatorMessage();
    }

    if (is_paired()) {
      // If the client is paired with the host then attach pairing client_id to
      // the message.
      buzz::XmlElement* pairing_tag = new buzz::XmlElement(kPairingInfoTag);
      result->AddElement(pairing_tag);
      pairing_tag->AddAttr(kClientIdAttribute, config_.pairing_client_id);
    }

    // Include a list of supported methods.
    std::string supported_methods;
    for (Method method : methods_) {
      if (!supported_methods.empty())
        supported_methods += kSupportedMethodsSeparator;
      supported_methods += MethodToString(method);
    }
    result->AddAttr(kSupportedMethodsAttributeQName, supported_methods);
    state_ = WAITING_MESSAGE;
    return result;
  }
  return GetNextMessageInternal();
}

void NegotiatingClientAuthenticator::CreateAuthenticatorForCurrentMethod(
    Authenticator::State preferred_initial_state,
    const base::Closure& resume_callback) {
  DCHECK_EQ(state(), PROCESSING_MESSAGE);
  DCHECK(current_method_ != Method::INVALID);
  switch (current_method_) {
    case Method::INVALID:
      NOTREACHED();
      break;

    case Method::THIRD_PARTY_SPAKE2_P224:
      current_authenticator_.reset(new ThirdPartyClientAuthenticator(
          base::Bind(&V2Authenticator::CreateForClient),
          config_.fetch_third_party_token_callback));
      resume_callback.Run();
      break;

    case Method::THIRD_PARTY_SPAKE2_CURVE25519:
      current_authenticator_.reset(new ThirdPartyClientAuthenticator(
          base::Bind(&Spake2Authenticator::CreateForClient, local_id_,
                     remote_id_),
          config_.fetch_third_party_token_callback));
      resume_callback.Run();
      break;

    case Method::PAIRED_SPAKE2_P224: {
      PairingClientAuthenticator* pairing_authenticator =
          new PairingClientAuthenticator(
              config_, base::Bind(&V2Authenticator::CreateForClient));
      current_authenticator_ = make_scoped_ptr(pairing_authenticator);
      pairing_authenticator->Start(preferred_initial_state, resume_callback);
      break;
    }

    case Method::PAIRED_SPAKE2_CURVE25519: {
      PairingClientAuthenticator* pairing_authenticator =
          new PairingClientAuthenticator(
              config_, base::Bind(&Spake2Authenticator::CreateForClient,
                                  local_id_, remote_id_));
      current_authenticator_ = make_scoped_ptr(pairing_authenticator);
      pairing_authenticator->Start(preferred_initial_state, resume_callback);
      break;
    }

    case Method::SHARED_SECRET_SPAKE2_P224:
    case Method::SHARED_SECRET_SPAKE2_CURVE25519:
      config_.fetch_secret_callback.Run(
          false,
          base::Bind(
              &NegotiatingClientAuthenticator::CreateSharedSecretAuthenticator,
              weak_factory_.GetWeakPtr(), preferred_initial_state,
              resume_callback));
      break;
  }
}

void NegotiatingClientAuthenticator::CreatePreferredAuthenticator() {
  if (is_paired() &&
      std::find(methods_.begin(), methods_.end(), Method::PAIRED_SPAKE2_P224) !=
          methods_.end()) {
    PairingClientAuthenticator* pairing_authenticator =
        new PairingClientAuthenticator(
            config_, base::Bind(&V2Authenticator::CreateForClient));
    current_authenticator_ = make_scoped_ptr(pairing_authenticator);
    pairing_authenticator->StartPaired(MESSAGE_READY);
    current_method_ = Method::PAIRED_SPAKE2_P224;
  }
}

void NegotiatingClientAuthenticator::CreateSharedSecretAuthenticator(
    Authenticator::State initial_state,
    const base::Closure& resume_callback,
    const std::string& shared_secret) {
  std::string shared_secret_hash =
      GetSharedSecretHash(config_.host_id, shared_secret);
  if (current_method_ == Method::SHARED_SECRET_SPAKE2_CURVE25519) {
    current_authenticator_ = Spake2Authenticator::CreateForClient(
        local_id_, remote_id_, shared_secret_hash, initial_state);
  } else {
    current_authenticator_ =
        V2Authenticator::CreateForClient(shared_secret_hash, initial_state);
  }
  resume_callback.Run();
}

bool NegotiatingClientAuthenticator::is_paired() {
  return !config_.pairing_client_id.empty() && !config_.pairing_secret.empty();
}

}  // namespace protocol
}  // namespace remoting
