// Copyright 2017 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 <memory>
#include <string>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <brillo/daemons/daemon.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include <dbus/bus.h>
#include <policy/device_policy.h>
#include <policy/libpolicy.h>
#include <sysexits.h>

#include "bindings/chrome_device_policy.pb.h"
#include "power_manager-client/power_manager/dbus-proxies.h"
#include "u2fd/tpm_vendor_cmd.h"
#include "u2fd/u2fhid.h"
#include "u2fd/uhid_device.h"

#ifndef VCSID
#define VCSID "<unknown>"
#endif

namespace {

constexpr char kDeviceName[] = "Integrated U2F";
constexpr uint32_t kDefaultVendorId = 0x18d1;
constexpr uint32_t kDefaultProductId = 0x502c;

namespace em = enterprise_management;

enum class U2fMode : uint8_t {
  kUnset = em::DeviceSecondFactorAuthenticationProto_U2fMode_UNSET,
  kDisabled = em::DeviceSecondFactorAuthenticationProto_U2fMode_DISABLED,
  kU2f = em::DeviceSecondFactorAuthenticationProto_U2fMode_U2F,
  kU2fExtended = em::DeviceSecondFactorAuthenticationProto_U2fMode_U2F_EXTENDED,
};

U2fMode ReadU2fPolicy() {
  policy::PolicyProvider policy_provider;

  // No available policy.
  if (!policy_provider.Reload())
    return U2fMode::kUnset;

  int mode = 0;
  const policy::DevicePolicy* policy = &policy_provider.GetDevicePolicy();
  if (!policy->GetSecondFactorAuthenticationMode(&mode))
    return U2fMode::kUnset;

  return static_cast<U2fMode>(mode);
}

U2fMode GetU2fMode(bool force_u2f, bool force_g2f) {
  U2fMode policy_mode = ReadU2fPolicy();

  // Always honor the administrator request to disable even if given
  // contradictory override flags.
  if (policy_mode == U2fMode::kDisabled) {
    return U2fMode::kDisabled;
  }

  if (force_g2f || policy_mode == U2fMode::kU2fExtended) {
    return U2fMode::kU2fExtended;
  }

  if (force_u2f || policy_mode == U2fMode::kU2f) {
    return U2fMode::kU2f;
  }

  return U2fMode::kDisabled;
}

const char* U2fModeToString(U2fMode mode) {
  switch (mode) {
    case U2fMode::kUnset:
      return "disabled (no policy)";
    case U2fMode::kDisabled:
      return "disabled";
    case U2fMode::kU2f:
      return "U2F";
    case U2fMode::kU2fExtended:
      return "U2F+extensions";
  }
  return "unknown";
}

class U2fDaemon : public brillo::Daemon {
 public:
  U2fDaemon(U2fMode mode, uint32_t vendor_id, uint32_t product_id)
      : u2f_mode_(mode), vendor_id_(vendor_id), product_id_(product_id) {}

 private:
  int OnInit() override {
    std::string version;
    if (!tpm_proxy_.Init()) {
      LOG(ERROR) << "Failed to initialize D-Bus proxy with trunksd.";
      return EX_IOERR;
    }
    int rc = tpm_proxy_.SetU2fVendorMode(static_cast<uint8_t>(u2f_mode_));
    if (!rc)
      rc = tpm_proxy_.GetU2fVersion(&version);
    if (rc == u2f::kVendorRcNoSuchCommand) {
      LOG(WARNING) << "U2F Feature not available in firmware.";
      // Will exit gracefully as we don't want to re-spawn.
      return EX_UNAVAILABLE;
    }
    if (rc != 0) {
      LOG(ERROR) << "Cannot get U2F version from TPM.";
      return EX_PROTOCOL;
    }
    LOG(INFO) << "version " << version;

    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    bus_ = new dbus::Bus(options);
    if (!bus_->Connect()) {
      LOG(ERROR) << "Cannot connect to D-Bus.";
      return EX_IOERR;
    }
    pm_proxy_ = std::make_unique<org::chromium::PowerManagerProxy>(bus_.get());

    u2fhid_ = std::make_unique<u2f::U2fHid>(
        std::make_unique<u2f::UHidDevice>(
            vendor_id_, product_id_, kDeviceName, "u2fd-tpm-cr50"),
        base::Bind(&u2f::TpmVendorCommandProxy::SendU2fApdu,
                   base::Unretained(&tpm_proxy_)),
        base::Bind(
            &org::chromium::PowerManagerProxy::IgnoreNextPowerButtonPress,
            base::Unretained(pm_proxy_.get())));

    return u2fhid_->Init() ? EX_OK : EX_PROTOCOL;
  }

  U2fMode u2f_mode_;
  uint32_t vendor_id_;
  uint32_t product_id_;
  u2f::TpmVendorCommandProxy tpm_proxy_;
  scoped_refptr<dbus::Bus> bus_;
  std::unique_ptr<org::chromium::PowerManagerProxy> pm_proxy_;
  std::unique_ptr<u2f::U2fHid> u2fhid_;

  DISALLOW_COPY_AND_ASSIGN(U2fDaemon);
};

}  // namespace

int main(int argc, char* argv[]) {
  DEFINE_bool(force_u2f, false, "force U2F mode even if disabled by policy");
  DEFINE_bool(
      force_g2f, false, "force U2F mode plus extensions regardless of policy");
  DEFINE_int32(product_id, kDefaultProductId, "Product ID for the HID device");
  DEFINE_int32(vendor_id, kDefaultVendorId, "Vendor ID for the HID device");
  DEFINE_bool(verbose, false, "verbose logging");

  brillo::FlagHelper::Init(argc, argv, "u2fd, U2FHID emulation daemon.");

  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogHeader |
                  brillo::kLogToStderrIfTty);
  if (FLAGS_verbose)
    logging::SetMinLogLevel(-1);

  LOG(INFO) << "Daemon version " << VCSID;

  U2fMode mode = GetU2fMode(FLAGS_force_u2f, FLAGS_force_g2f);
  LOG(INFO) << "Mode: " << U2fModeToString(mode)
            << " (force_u2f=" << FLAGS_force_u2f
            << " force_g2f=" << FLAGS_force_g2f << ")";
  if (mode == U2fMode::kDisabled) {
    LOG(INFO) << "U2F disabled, exiting...";
    // Exit gracefully as we don't want to re-spawn.
    return EX_OK;
  }

  U2fDaemon daemon(mode, FLAGS_vendor_id, FLAGS_product_id);
  int rc = daemon.Run();

  return rc == EX_UNAVAILABLE ? EX_OK : rc;
}
