//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "tpm_manager/server/dbus_service.h"

#include <memory>
#include <utility>

#include <base/bind.h>
#include <brillo/daemons/dbus_daemon.h>
#include <brillo/dbus/async_event_sequencer.h>
#include <dbus/bus.h>
#include <dbus/object_path.h>

#include "tpm_manager/common/tpm_manager_constants.h"
#include "tpm_manager/common/tpm_nvram_dbus_interface.h"
#include "tpm_manager/common/tpm_ownership_dbus_interface.h"

namespace tpm_manager {

using brillo::dbus_utils::DBusObject;

DBusService::DBusService(TpmNvramInterface* nvram_service,
                         TpmOwnershipInterface* ownership_service,
                         LocalDataStore* local_data_store)
    : brillo::DBusServiceDaemon(tpm_manager::kTpmManagerServiceName),
      nvram_service_(nvram_service),
      ownership_service_(ownership_service),
      local_data_store_(local_data_store) {
  CHECK(nvram_service_);
  CHECK(ownership_service_);
  CHECK(local_data_store_);
}

DBusService::DBusService(scoped_refptr<dbus::Bus> bus,
                         TpmNvramInterface* nvram_service,
                         TpmOwnershipInterface* ownership_service,
                         LocalDataStore* local_data_store)
    : brillo::DBusServiceDaemon(tpm_manager::kTpmManagerServiceName),
      dbus_object_(new DBusObject(nullptr,
                                  bus,
                                  dbus::ObjectPath(kTpmManagerServicePath))),
      nvram_service_(nvram_service),
      ownership_service_(ownership_service),
      local_data_store_(local_data_store)
      {}

void DBusService::RegisterDBusObjectsAsync(
    brillo::dbus_utils::AsyncEventSequencer* sequencer) {
  if (!dbus_object_.get()) {
    // At this point bus_ should be valid.
    CHECK(bus_.get());
    dbus_object_.reset(new DBusObject(
        nullptr, bus_, dbus::ObjectPath(kTpmManagerServicePath)));
  }
  brillo::dbus_utils::DBusInterface* ownership_dbus_interface =
      dbus_object_->AddOrGetInterface(kTpmOwnershipInterface);

  ownership_dbus_interface->AddMethodHandler(
      kGetTpmStatus, base::Unretained(this),
      &DBusService::HandleOwnershipDBusMethod<
          GetTpmStatusRequest, GetTpmStatusReply,
          &TpmOwnershipInterface::GetTpmStatus>);

  ownership_dbus_interface->AddMethodHandler(
      kGetDictionaryAttackInfo, base::Unretained(this),
      &DBusService::HandleOwnershipDBusMethod<
          GetDictionaryAttackInfoRequest, GetDictionaryAttackInfoReply,
          &TpmOwnershipInterface::GetDictionaryAttackInfo>);

  ownership_dbus_interface->AddMethodHandler(
      kResetDictionaryAttackLock, base::Unretained(this),
      &DBusService::HandleOwnershipDBusMethod<
          ResetDictionaryAttackLockRequest, ResetDictionaryAttackLockReply,
          &TpmOwnershipInterface::ResetDictionaryAttackLock>);

  ownership_dbus_interface->AddMethodHandler(
      kTakeOwnership, base::Unretained(this),
      &DBusService::HandleOwnershipDBusMethod<
          TakeOwnershipRequest, TakeOwnershipReply,
          &TpmOwnershipInterface::TakeOwnership>);

  ownership_dbus_interface->AddMethodHandler(
      kRemoveOwnerDependency, base::Unretained(this),
      &DBusService::HandleOwnershipDBusMethod<
          RemoveOwnerDependencyRequest, RemoveOwnerDependencyReply,
          &TpmOwnershipInterface::RemoveOwnerDependency>);

  ownership_dbus_interface->AddMethodHandler(
      kClearStoredOwnerPassword, base::Unretained(this),
      &DBusService::HandleOwnershipDBusMethod<
          ClearStoredOwnerPasswordRequest, ClearStoredOwnerPasswordReply,
          &TpmOwnershipInterface::ClearStoredOwnerPassword>);

  ownership_taken_signal_ =
      ownership_dbus_interface->RegisterSignal<OwnershipTakenSignal>(
          kOwnershipTakenSignal);

  brillo::dbus_utils::DBusInterface* nvram_dbus_interface =
      dbus_object_->AddOrGetInterface(kTpmNvramInterface);

  nvram_dbus_interface->AddMethodHandler(
      kDefineSpace, base::Unretained(this),
      &DBusService::HandleNvramDBusMethod<DefineSpaceRequest, DefineSpaceReply,
                                          &TpmNvramInterface::DefineSpace>);

  nvram_dbus_interface->AddMethodHandler(
      kDestroySpace, base::Unretained(this),
      &DBusService::HandleNvramDBusMethod<DestroySpaceRequest,
                                          DestroySpaceReply,
                                          &TpmNvramInterface::DestroySpace>);

  nvram_dbus_interface->AddMethodHandler(
      kWriteSpace, base::Unretained(this),
      &DBusService::HandleNvramDBusMethod<WriteSpaceRequest, WriteSpaceReply,
                                          &TpmNvramInterface::WriteSpace>);

  nvram_dbus_interface->AddMethodHandler(
      kReadSpace, base::Unretained(this),
      &DBusService::HandleNvramDBusMethod<ReadSpaceRequest, ReadSpaceReply,
                                          &TpmNvramInterface::ReadSpace>);

  nvram_dbus_interface->AddMethodHandler(
      kLockSpace, base::Unretained(this),
      &DBusService::HandleNvramDBusMethod<LockSpaceRequest, LockSpaceReply,
                                          &TpmNvramInterface::LockSpace>);

  nvram_dbus_interface->AddMethodHandler(
      kListSpaces, base::Unretained(this),
      &DBusService::HandleNvramDBusMethod<ListSpacesRequest, ListSpacesReply,
                                          &TpmNvramInterface::ListSpaces>);

  nvram_dbus_interface->AddMethodHandler(
      kGetSpaceInfo, base::Unretained(this),
      &DBusService::HandleNvramDBusMethod<GetSpaceInfoRequest,
                                          GetSpaceInfoReply,
                                          &TpmNvramInterface::GetSpaceInfo>);

  dbus_object_->RegisterAsync(
      sequencer->GetHandler("Failed to register D-Bus object.", true));
}

void DBusService::NotifyOwnershipIsTaken() {
  ownership_already_taken_ = true;

  // Send the signal if it's registered in the ownership dbus interface.
  MaybeSendOwnershipTakenSignal();
}

bool DBusService::MaybeSendOwnershipTakenSignal() {
  if (already_sent_ownership_taken_signal_) {
    return false;
  }

  if (!ownership_already_taken_) {
    return false;
  }

  // We have to check if ownership_taken_signal_ is ready here because
  // TpmInitializer may try to take TPM ownership in another thread before
  // RegisterDBusObjectsAsync is called.
  auto signal = ownership_taken_signal_.lock();
  if (!signal) {
    LOG(INFO) << "Ownership taken signal has not been initialized yet.";
    return false;
  }

  LocalData local_data;
  if (!local_data_store_->Read(&local_data)) {
    LOG(ERROR) << "Failed to read local data.";
    return false;
  }

  OwnershipTakenSignal payload;
  payload.set_owner_password(local_data.owner_password());
  payload.set_endorsement_password(local_data.endorsement_password());

  // The proto message |payload| will be converted to array of bytes by Send().
  if (!signal->Send(payload)) {
    LOG(ERROR) << "Failed to send ownership taken signal!";
    return false;
  }

  already_sent_ownership_taken_signal_ = true;
  LOG(INFO) << "Ownership taken signal is sent.";
  return true;
}

template <typename RequestProtobufType,
          typename ReplyProtobufType,
          DBusService::HandlerFunction<RequestProtobufType,
                                       ReplyProtobufType,
                                       TpmNvramInterface> func>
void DBusService::HandleNvramDBusMethod(
    std::unique_ptr<DBusMethodResponse<const ReplyProtobufType&>> response,
    const RequestProtobufType& request) {
  // Convert |response| to a shared_ptr so |nvram_service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const ReplyProtobufType&>>;
  // A callback that sends off the reply protobuf.
  auto callback = [](const SharedResponsePointer& response,
                     const ReplyProtobufType& reply) {
    response->Return(reply);
  };
  (nvram_service_->*func)(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

template <typename RequestProtobufType,
          typename ReplyProtobufType,
          DBusService::HandlerFunction<RequestProtobufType,
                                       ReplyProtobufType,
                                       TpmOwnershipInterface> func>
void DBusService::HandleOwnershipDBusMethod(
    std::unique_ptr<DBusMethodResponse<const ReplyProtobufType&>> response,
    const RequestProtobufType& request) {
  // Convert |response| to a shared_ptr so |ownership_service_| can safely
  // copy the callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const ReplyProtobufType&>>;
  // A callback that sends off the reply protobuf.
  auto callback = [](const SharedResponsePointer& response,
                     const ReplyProtobufType& reply) {
    response->Return(reply);
  };
  (ownership_service_->*func)(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

}  // namespace tpm_manager
