//
// 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 <stdio.h>
#include <stdlib.h>
#include <sysexits.h>

#include <memory>
#include <string>

#include <base/command_line.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/message_loop/message_loop.h>
#include <brillo/bind_lambda.h>
#if defined(USE_BINDER_IPC)
#include <brillo/binder_watcher.h>
#endif
#include <brillo/daemons/daemon.h>
#include <brillo/syslog_logging.h>
#include <crypto/sha2.h>

#if defined(USE_BINDER_IPC)
#include "tpm_manager/client/tpm_nvram_binder_proxy.h"
#include "tpm_manager/client/tpm_ownership_binder_proxy.h"
#else
#include "tpm_manager/client/tpm_nvram_dbus_proxy.h"
#include "tpm_manager/client/tpm_ownership_dbus_proxy.h"
#endif
#include "tpm_manager/common/print_tpm_manager_proto.h"
#include "tpm_manager/common/tpm_manager.pb.h"
#include "trunks/tpm_generated.h"

namespace tpm_manager {

constexpr char kGetTpmStatusCommand[] = "status";
constexpr char kTakeOwnershipCommand[] = "take_ownership";
constexpr char kRemoveOwnerDependencyCommand[] = "remove_dependency";
constexpr char kDefineSpaceCommand[] = "define_space";
constexpr char kDestroySpaceCommand[] = "destroy_space";
constexpr char kWriteSpaceCommand[] = "write_space";
constexpr char kReadSpaceCommand[] = "read_space";
constexpr char kLockSpaceCommand[] = "lock_space";
constexpr char kListSpacesCommand[] = "list_spaces";
constexpr char kGetSpaceInfoCommand[] = "get_space_info";

constexpr char kDependencySwitch[] = "dependency";
constexpr char kIndexSwitch[] = "index";
constexpr char kSizeSwitch[] = "size";
constexpr char kAttributesSwitch[] = "attributes";
constexpr char kPasswordSwitch[] = "password";
constexpr char kBindToPCR0Switch[] = "bind_to_pcr0";
constexpr char kFileSwitch[] = "file";
constexpr char kUseOwnerSwitch[] = "use_owner_authorization";
constexpr char kLockRead[] = "lock_read";
constexpr char kLockWrite[] = "lock_write";

constexpr char kUsage[] = R"(
Usage: tpm_manager_client <command> [<arguments>]
Commands:
  status
      Prints TPM status information.
  take_ownership
      Takes ownership of the Tpm with a random password.
  remove_dependency --dependency=<owner_dependency>
      Removes the named Tpm owner dependency. E.g. \"Nvram\" or \"Attestation\".
  define_space --index=<index> --size=<size> [--attributes=<attribute_list>]
               [--password=<password>] [--bind_to_pcr0]
      Defines an NV space. The attribute format is a '|' separated list of:
          PERSISTENT_WRITE_LOCK: Allow write lock; stay locked until destroyed.
          BOOT_WRITE_LOCK: Allow write lock; stay locked until next boot.
          BOOT_READ_LOCK: Allow read lock; stay locked until next boot.
          WRITE_AUTHORIZATION: Require authorization to write.
          READ_AUTHORIZATION: Require authorization to read.
          WRITE_EXTEND: Allow only extend operations, not direct writes.
          GLOBAL_LOCK: Engage write lock when the global lock is engaged.
          PLATFORM_WRITE: Allow write only with 'platform' authorization. This
                          is similar to the TPM 1.2 'physical presence' notion.
          OWNER_WRITE: Allow write only with TPM owner authorization.
          OWNER_READ: Allow read only with TPM owner authorization.
      This command requires that owner authorization is available. If a password
      is given it will be required only as specified by the attributes. E.g. if
      READ_AUTHORIZATION is not listed, then the password will not be required
      in order to read. Similarly, if the --bind_to_pcr0 option is given, the
      current PCR0 value will be required only as specified by the attributes.
  destroy_space --index=<index>
      Destroys an NV space. This command requires that owner authorization is
      available.
  write_space --index=<index> --file=<input_file> [--password=<password>]
              [--use_owner_authorization]
      Writes data from a file to an NV space. Any existing data will be
      overwritten.
  read_space --index=<index> --file=<output_file> [--password=<password>]
             [--use_owner_authorization]
      Reads the entire contents of an NV space to a file.
  lock_space --index=<index> [--lock_read] [--lock_write]
             [--password=<password>] [--use_owner_authorization]
      Locks an NV space for read and / or write.
  list_spaces
      Prints a list of all defined index values.
  get_space_info --index=<index>
      Prints public information about an NV space.
)";

constexpr char kKnownNVRAMSpaces[] = R"(
NVRAM Index Reference:
 TPM 1.2 (32-bit values)
  0x00001007 - Chrome OS Firmware Version Rollback Protection
  0x00001008 - Chrome OS Kernel Version Rollback Protection
  0x00001009 - Chrome OS Firmware Backup
  0x0000100A - Chrome OS Firmware Management Parameters
  0x20000004 - Chrome OS Install Attributes (aka LockBox)
  0x10000001 - Standard TPM_NV_INDEX_DIR (Permanent)
  0x1000F000 - Endorsement Certificate (Permanent)
  0x30000001 - Endorsement Authority Certificate (Permanent)
  0x0000F004 - Standard Test Index (for testing TPM_NV_DefineSpace)

 TPM 2.0 (24-bit values)
  0x400000 and following - Reserved for Firmware
  0x800000 and following - Reserved for Software
  0xC00000 and following - Endorsement Certificates
)";

bool ReadFileToString(const std::string& filename, std::string* data) {
  return base::ReadFileToString(base::FilePath(filename), data);
}

bool WriteStringToFile(const std::string& data, const std::string& filename) {
  int result =
      base::WriteFile(base::FilePath(filename), data.data(), data.size());
  return (result != -1 && static_cast<size_t>(result) == data.size());
}

uint32_t StringToUint32(const std::string& s) {
  return strtoul(s.c_str(), nullptr, 0);
}

uint32_t StringToNvramIndex(const std::string& s) {
  return trunks::HR_HANDLE_MASK & StringToUint32(s);
}

using ClientLoopBase = brillo::Daemon;
class ClientLoop : public ClientLoopBase {
 public:
  ClientLoop() = default;
  ~ClientLoop() override = default;

 protected:
  int OnInit() override {
    int exit_code = ClientLoopBase::OnInit();
    if (exit_code != EX_OK) {
      LOG(ERROR) << "Error initializing tpm_manager_client.";
      return exit_code;
    }
#if defined(USE_BINDER_IPC)
    if (!binder_watcher_.Init()) {
      LOG(ERROR) << "Error initializing binder watcher.";
      return EX_UNAVAILABLE;
    }
    std::unique_ptr<TpmNvramBinderProxy> nvram_proxy =
        base::MakeUnique<TpmNvramBinderProxy>();
    std::unique_ptr<TpmOwnershipBinderProxy> ownership_proxy =
        base::MakeUnique<TpmOwnershipBinderProxy>();
#else
    std::unique_ptr<TpmNvramDBusProxy> nvram_proxy =
        base::MakeUnique<TpmNvramDBusProxy>();
    std::unique_ptr<TpmOwnershipDBusProxy> ownership_proxy =
        base::MakeUnique<TpmOwnershipDBusProxy>();
#endif
    if (!nvram_proxy->Initialize()) {
      LOG(ERROR) << "Error initializing nvram proxy.";
      return EX_UNAVAILABLE;
    }
    if (!ownership_proxy->Initialize()) {
      LOG(ERROR) << "Error initializing ownership proxy.";
      return EX_UNAVAILABLE;
    }
    tpm_nvram_ = std::move(nvram_proxy);
    tpm_ownership_ = std::move(ownership_proxy);
    exit_code = ScheduleCommand();
    if (exit_code == EX_USAGE) {
      printf("%s%s", kUsage, kKnownNVRAMSpaces);
    }
    return exit_code;
  }

  void OnShutdown(int* exit_code) override {
    tpm_nvram_.reset();
    tpm_ownership_.reset();
    ClientLoopBase::OnShutdown(exit_code);
  }

 private:
  // Posts tasks on to the message loop based on command line flags.
  int ScheduleCommand() {
    base::Closure task;
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
    if (command_line->HasSwitch("help") || command_line->HasSwitch("h") ||
        command_line->GetArgs().size() == 0) {
      return EX_USAGE;
    }
    std::string command = command_line->GetArgs()[0];
    if (command == kGetTpmStatusCommand) {
      task = base::Bind(&ClientLoop::HandleGetTpmStatus,
                        weak_factory_.GetWeakPtr());
    } else if (command == kTakeOwnershipCommand) {
      task = base::Bind(&ClientLoop::HandleTakeOwnership,
                        weak_factory_.GetWeakPtr());
    } else if (command == kRemoveOwnerDependencyCommand) {
      if (!command_line->HasSwitch(kDependencySwitch)) {
        return EX_USAGE;
      }
      task = base::Bind(&ClientLoop::HandleRemoveOwnerDependency,
                        weak_factory_.GetWeakPtr(),
                        command_line->GetSwitchValueASCII(kDependencySwitch));
    } else if (command == kDefineSpaceCommand) {
      if (!command_line->HasSwitch(kIndexSwitch) ||
          !command_line->HasSwitch(kSizeSwitch)) {
        return EX_USAGE;
      }
      task = base::Bind(
          &ClientLoop::HandleDefineSpace, weak_factory_.GetWeakPtr(),
          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)),
          StringToUint32(command_line->GetSwitchValueASCII(kSizeSwitch)),
          command_line->GetSwitchValueASCII(kAttributesSwitch),
          command_line->GetSwitchValueASCII(kPasswordSwitch),
          command_line->HasSwitch(kBindToPCR0Switch));
    } else if (command == kDestroySpaceCommand) {
      if (!command_line->HasSwitch(kIndexSwitch)) {
        return EX_USAGE;
      }
      task = base::Bind(
          &ClientLoop::HandleDestroySpace, weak_factory_.GetWeakPtr(),
          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)));
    } else if (command == kWriteSpaceCommand) {
      if (!command_line->HasSwitch(kIndexSwitch) ||
          !command_line->HasSwitch(kFileSwitch)) {
        return EX_USAGE;
      }
      task = base::Bind(
          &ClientLoop::HandleWriteSpace, weak_factory_.GetWeakPtr(),
          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)),
          command_line->GetSwitchValueASCII(kFileSwitch),
          command_line->GetSwitchValueASCII(kPasswordSwitch),
          command_line->HasSwitch(kUseOwnerSwitch));
    } else if (command == kReadSpaceCommand) {
      if (!command_line->HasSwitch(kIndexSwitch) ||
          !command_line->HasSwitch(kFileSwitch)) {
        return EX_USAGE;
      }
      task = base::Bind(
          &ClientLoop::HandleReadSpace, weak_factory_.GetWeakPtr(),
          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)),
          command_line->GetSwitchValueASCII(kFileSwitch),
          command_line->GetSwitchValueASCII(kPasswordSwitch),
          command_line->HasSwitch(kUseOwnerSwitch));
    } else if (command == kLockSpaceCommand) {
      if (!command_line->HasSwitch(kIndexSwitch)) {
        return EX_USAGE;
      }
      task = base::Bind(
          &ClientLoop::HandleLockSpace, weak_factory_.GetWeakPtr(),
          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)),
          command_line->HasSwitch(kLockRead),
          command_line->HasSwitch(kLockWrite),
          command_line->GetSwitchValueASCII(kPasswordSwitch),
          command_line->HasSwitch(kUseOwnerSwitch));
    } else if (command == kListSpacesCommand) {
      task =
          base::Bind(&ClientLoop::HandleListSpaces, weak_factory_.GetWeakPtr());
    } else if (command == kGetSpaceInfoCommand) {
      if (!command_line->HasSwitch(kIndexSwitch)) {
        return EX_USAGE;
      }
      task = base::Bind(
          &ClientLoop::HandleGetSpaceInfo, weak_factory_.GetWeakPtr(),
          StringToNvramIndex(command_line->GetSwitchValueASCII(kIndexSwitch)));
    } else {
      // Command line arguments did not match any valid commands.
      return EX_USAGE;
    }
    base::MessageLoop::current()->PostTask(FROM_HERE, task);
    return EX_OK;
  }

  // Template to print reply protobuf.
  template <typename ProtobufType>
  void PrintReplyAndQuit(const ProtobufType& reply) {
    LOG(INFO) << "Message Reply: " << GetProtoDebugString(reply);
    Quit();
  }

  void HandleGetTpmStatus() {
    GetTpmStatusRequest request;
    tpm_ownership_->GetTpmStatus(
        request, base::Bind(&ClientLoop::PrintReplyAndQuit<GetTpmStatusReply>,
                            weak_factory_.GetWeakPtr()));
  }

  void HandleTakeOwnership() {
    TakeOwnershipRequest request;
    tpm_ownership_->TakeOwnership(
        request, base::Bind(&ClientLoop::PrintReplyAndQuit<TakeOwnershipReply>,
                            weak_factory_.GetWeakPtr()));
  }

  void HandleRemoveOwnerDependency(const std::string& owner_dependency) {
    RemoveOwnerDependencyRequest request;
    request.set_owner_dependency(owner_dependency);
    tpm_ownership_->RemoveOwnerDependency(
        request,
        base::Bind(&ClientLoop::PrintReplyAndQuit<RemoveOwnerDependencyReply>,
                   weak_factory_.GetWeakPtr()));
  }

  bool DecodeAttribute(const std::string& attribute_str,
                       NvramSpaceAttribute* attribute) {
    if (attribute_str == "PERSISTENT_WRITE_LOCK") {
      *attribute = NVRAM_PERSISTENT_WRITE_LOCK;
      return true;
    }
    if (attribute_str == "BOOT_WRITE_LOCK") {
      *attribute = NVRAM_BOOT_WRITE_LOCK;
      return true;
    }
    if (attribute_str == "BOOT_READ_LOCK") {
      *attribute = NVRAM_BOOT_READ_LOCK;
      return true;
    }
    if (attribute_str == "WRITE_AUTHORIZATION") {
      *attribute = NVRAM_WRITE_AUTHORIZATION;
      return true;
    }
    if (attribute_str == "READ_AUTHORIZATION") {
      *attribute = NVRAM_READ_AUTHORIZATION;
      return true;
    }
    if (attribute_str == "WRITE_EXTEND") {
      *attribute = NVRAM_WRITE_EXTEND;
      return true;
    }
    if (attribute_str == "GLOBAL_LOCK") {
      *attribute = NVRAM_GLOBAL_LOCK;
      return true;
    }
    if (attribute_str == "PLATFORM_WRITE") {
      *attribute = NVRAM_PLATFORM_WRITE;
      return true;
    }
    if (attribute_str == "OWNER_WRITE") {
      *attribute = NVRAM_OWNER_WRITE;
      return true;
    }
    if (attribute_str == "OWNER_READ") {
      *attribute = NVRAM_OWNER_READ;
      return true;
    }
    LOG(ERROR) << "Unrecognized attribute: " << attribute_str;
    return false;
  }

  void HandleDefineSpace(uint32_t index,
                         size_t size,
                         const std::string& attributes,
                         const std::string& password,
                         bool bind_to_pcr0) {
    DefineSpaceRequest request;
    request.set_index(index);
    request.set_size(size);
    std::string::size_type pos = 0;
    std::string::size_type next_pos = 0;
    while (next_pos != std::string::npos) {
      next_pos = attributes.find('|', pos);
      std::string attribute_str;
      if (next_pos == std::string::npos) {
        attribute_str = attributes.substr(pos);
      } else {
        attribute_str = attributes.substr(pos, next_pos - pos);
      }
      if (!attribute_str.empty()) {
        NvramSpaceAttribute attribute;
        if (!DecodeAttribute(attribute_str, &attribute)) {
          Quit();
          return;
        }
        request.add_attributes(attribute);
      }
      pos = next_pos + 1;
    }
    request.set_authorization_value(crypto::SHA256HashString(password));
    request.set_policy(bind_to_pcr0 ? NVRAM_POLICY_PCR0 : NVRAM_POLICY_NONE);
    tpm_nvram_->DefineSpace(
        request, base::Bind(&ClientLoop::PrintReplyAndQuit<DefineSpaceReply>,
                            weak_factory_.GetWeakPtr()));
  }

  void HandleDestroySpace(uint32_t index) {
    DestroySpaceRequest request;
    request.set_index(index);
    tpm_nvram_->DestroySpace(
        request, base::Bind(&ClientLoop::PrintReplyAndQuit<DestroySpaceReply>,
                            weak_factory_.GetWeakPtr()));
  }

  void HandleWriteSpace(uint32_t index,
                        const std::string& input_file,
                        const std::string& password,
                        bool use_owner_authorization) {
    WriteSpaceRequest request;
    request.set_index(index);
    std::string data;
    if (!ReadFileToString(input_file, &data)) {
      LOG(ERROR) << "Failed to read input file.";
      Quit();
      return;
    }
    request.set_data(data);
    request.set_authorization_value(crypto::SHA256HashString(password));
    request.set_use_owner_authorization(use_owner_authorization);
    tpm_nvram_->WriteSpace(
        request, base::Bind(&ClientLoop::PrintReplyAndQuit<WriteSpaceReply>,
                            weak_factory_.GetWeakPtr()));
  }

  void HandleReadSpaceReply(const std::string& output_file,
                            const ReadSpaceReply& reply) {
    if (!WriteStringToFile(reply.data(), output_file)) {
      LOG(ERROR) << "Failed to write output file.";
    }
    LOG(INFO) << "Message Reply: " << GetProtoDebugString(reply);
    Quit();
  }

  void HandleReadSpace(uint32_t index,
                       const std::string& output_file,
                       const std::string& password,
                       bool use_owner_authorization) {
    ReadSpaceRequest request;
    request.set_index(index);
    request.set_authorization_value(crypto::SHA256HashString(password));
    request.set_use_owner_authorization(use_owner_authorization);
    tpm_nvram_->ReadSpace(request,
                          base::Bind(&ClientLoop::HandleReadSpaceReply,
                                     weak_factory_.GetWeakPtr(), output_file));
  }

  void HandleLockSpace(uint32_t index,
                       bool lock_read,
                       bool lock_write,
                       const std::string& password,
                       bool use_owner_authorization) {
    LockSpaceRequest request;
    request.set_index(index);
    request.set_lock_read(lock_read);
    request.set_lock_write(lock_write);
    request.set_authorization_value(crypto::SHA256HashString(password));
    request.set_use_owner_authorization(use_owner_authorization);
    tpm_nvram_->LockSpace(
        request, base::Bind(&ClientLoop::PrintReplyAndQuit<LockSpaceReply>,
                            weak_factory_.GetWeakPtr()));
  }

  void HandleListSpaces() {
    printf("%s\n", kKnownNVRAMSpaces);
    ListSpacesRequest request;
    tpm_nvram_->ListSpaces(
        request, base::Bind(&ClientLoop::PrintReplyAndQuit<ListSpacesReply>,
                            weak_factory_.GetWeakPtr()));
  }

  void HandleGetSpaceInfo(uint32_t index) {
    GetSpaceInfoRequest request;
    request.set_index(index);
    tpm_nvram_->GetSpaceInfo(
        request, base::Bind(&ClientLoop::PrintReplyAndQuit<GetSpaceInfoReply>,
                            weak_factory_.GetWeakPtr()));
  }

  // IPC proxy interfaces.
  std::unique_ptr<tpm_manager::TpmNvramInterface> tpm_nvram_;
  std::unique_ptr<tpm_manager::TpmOwnershipInterface> tpm_ownership_;

#if defined(USE_BINDER_IPC)
  brillo::BinderWatcher binder_watcher_;
#endif

  // Declared last so that weak pointers will be destroyed first.
  base::WeakPtrFactory<ClientLoop> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(ClientLoop);
};

}  // namespace tpm_manager

int main(int argc, char* argv[]) {
  base::CommandLine::Init(argc, argv);
  brillo::InitLog(brillo::kLogToStderr);
  tpm_manager::ClientLoop loop;
  return loop.Run();
}
