// Copyright 2015 The Chromium OS 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 "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-client/tpm_manager/dbus-constants.h>

#include "tpm_manager/common/tpm_nvram_dbus_interface.h"

namespace tpm_manager {

using brillo::dbus_utils::DBusObject;

DBusService::DBusService(
    std::unique_ptr<TpmManagerService>&& tpm_manager_service,
    LocalDataStore* local_data_store)
    : DBusService(tpm_manager_service.get(),
                  tpm_manager_service.get(),
                  local_data_store) {
  tpm_manager_service->SetOwnershipTakenCallback(
      base::Bind(&DBusService::NotifyOwnershipIsTaken, base::Unretained(this)));
  tpm_manager_service_ = std::move(tpm_manager_service);
}

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(kTpmManagerInterface);

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

  ownership_dbus_interface->AddMethodHandler(
      kGetTpmNonsensitiveStatus, base::Unretained(this),
      &DBusService::HandleOwnershipDBusMethod<
          GetTpmNonsensitiveStatusRequest, GetTpmNonsensitiveStatusReply,
          &TpmOwnershipInterface::GetTpmNonsensitiveStatus>);

  ownership_dbus_interface->AddMethodHandler(
      kGetVersionInfo, base::Unretained(this),
      &DBusService::HandleOwnershipDBusMethod<
          GetVersionInfoRequest, GetVersionInfoReply,
          &TpmOwnershipInterface::GetVersionInfo>);

  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));
}

int DBusService::OnInit() {
  int ret = brillo::DBusServiceDaemon::OnInit();
  // Initializes TpmManagerService only when we have ownership of it. This must
  // go after brillo::DBusServiceDaemon::OnInit() so the asynchronous signal
  // handling works as expected.
  if (tpm_manager_service_) {
    CHECK(tpm_manager_service_->Initialize());
  }
  return ret;
}

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;
  }

  // Currently we just keep the entirety of local data sent with the signal, but
  // ideally the sercrets should not be exposed unless it's necessary.
  // TODO(b/168852740): Wipe out the unnecessarily visible auth values before
  // sending the signal.
  OwnershipTakenSignal payload;
  *payload.mutable_local_data() = local_data;

  // 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
