// Copyright 2014 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 <sysexits.h>
#include <unistd.h>

#include <cstdlib>
#include <memory>
#include <string>

#include <attestation/proto_bindings/google_key.pb.h>
#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/optional.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/cryptohome.h>
#include <brillo/daemons/dbus_daemon.h>
#include <brillo/dbus/async_event_sequencer.h>
#include <brillo/minijail/minijail.h>
#include <brillo/secure_blob.h>
#include <brillo/syslog_logging.h>
#include <brillo/userdb_utils.h>
#include <dbus/attestation/dbus-constants.h>

#include "attestation/server/attestation_service.h"
#include "attestation/server/dbus_service.h"
#include "attestation/server/google_keys.h"

#include <chromeos/libminijail.h>

namespace {

const uid_t kRootUID = 0;
const char kAttestationUser[] = "attestation";
const char kAttestationGroup[] = "attestation";
const char kAttestationSeccompPath[] =
    "/usr/share/policy/attestationd-seccomp.policy";
constexpr char kGoogleKeysPath[] = "/run/attestation/google_keys.data";

namespace env {
static const char kAttestationBasedEnrollmentDataFile[] = "ABE_DATA_FILE";
}  // namespace env

// Returns the contents of the attestation-based enrollment data file.
std::string ReadAbeDataFileContents() {
  std::string data;

  const char* abe_data_file =
      std::getenv(env::kAttestationBasedEnrollmentDataFile);
  if (!abe_data_file) {
    return data;
  }

  base::FilePath file_path(abe_data_file);
  if (!base::ReadFileToString(file_path, &data)) {
    LOG(FATAL) << "Could not read attestation-based enterprise enrollment data"
                  " in: "
               << file_path.value();
  }

  return data;
}

base::Optional<attestation::GoogleKeys> ReadGoogleKeysIfExists() {
  base::FilePath file_path(kGoogleKeysPath);
  std::string data;
  if (!base::ReadFileToString(file_path, &data)) {
    return {};
  }
  LOG(INFO) << "Found key set to be injected.";
  attestation::DefaultGoogleRsaPublicKeySet default_key_set;
  if (!default_key_set.ParseFromString(data)) {
    LOG(WARNING) << "Failed ot parse google keys to be injected.";
    return {};
  }
  return attestation::GoogleKeys(default_key_set);
}

bool GetAttestationEnrollmentData(const std::string& abe_data_hex,
                                  brillo::SecureBlob* abe_data) {
  abe_data->clear();
  if (abe_data_hex.empty())
    return true;  // no data is ok.
  // The data must be a valid 32-byte hex string.
  return brillo::SecureBlob::HexStringToSecureBlob(abe_data_hex, abe_data) &&
         abe_data->size() == 32;
}

void InitMinijailSandbox() {
  uid_t attestation_uid;
  gid_t attestation_gid;
  CHECK(brillo::userdb::GetUserInfo(kAttestationUser, &attestation_uid,
                                    &attestation_gid))
      << "Error getting attestation uid and gid.";
  CHECK_EQ(getuid(), kRootUID) << "AttestationDaemon not initialized as root.";
  brillo::Minijail* minijail = brillo::Minijail::GetInstance();
  struct minijail* jail = minijail->New();

  minijail_log_seccomp_filter_failures(jail);
  minijail->DropRoot(jail, kAttestationUser, kAttestationGroup);
  minijail_inherit_usergroups(jail);
  minijail->UseSeccompFilter(jail, kAttestationSeccompPath);
  minijail->Enter(jail);
  minijail->Destroy(jail);
  CHECK_EQ(getuid(), attestation_uid)
      << "AttestationDaemon was not able to drop to attestation user.";
  CHECK_EQ(getgid(), attestation_gid)
      << "AttestationDaemon was not able to drop to attestation group.";
}

}  // namespace

using brillo::dbus_utils::AsyncEventSequencer;

class AttestationDaemon : public brillo::DBusServiceDaemon {
 public:
  AttestationDaemon(brillo::SecureBlob abe_data,
                    base::Optional<attestation::GoogleKeys> google_keys)
      : brillo::DBusServiceDaemon(attestation::kAttestationServiceName),
        abe_data_(std::move(abe_data)),
        attestation_service_(&abe_data_) {
    if (google_keys) {
      attestation_service_.set_google_keys(*google_keys);
    }
  }
  AttestationDaemon(const AttestationDaemon&) = delete;
  AttestationDaemon& operator=(const AttestationDaemon&) = delete;

 protected:
  int OnInit() override {
    int result = brillo::DBusServiceDaemon::OnInit();
    if (result != EX_OK) {
      LOG(ERROR) << "Error starting attestation dbus daemon.";
      return result;
    }
    attestation_service_.Initialize();
    return EX_OK;
  }

  void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
    dbus_service_.reset(
        new attestation::DBusService(bus_, &attestation_service_));
    dbus_service_->Register(sequencer->GetHandler("Register() failed.", true));
  }

 private:
  brillo::SecureBlob abe_data_;
  attestation::AttestationService attestation_service_;
  std::unique_ptr<attestation::DBusService> dbus_service_;
};

int main(int argc, char* argv[]) {
  base::CommandLine::Init(argc, argv);
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  int flags = brillo::kLogToSyslog;
  if (cl->HasSwitch("log_to_stderr")) {
    flags |= brillo::kLogToStderr;
  }
  brillo::InitLog(flags);
  // read whole abe_data_file before we init minijail.
  std::string abe_data_hex = ReadAbeDataFileContents();
  // Reads the system salt before we init minijail.
  if (!brillo::cryptohome::home::EnsureSystemSaltIsLoaded()) {
    LOG(FATAL) << "Failed to ensure system salt to be loaded into memory.";
  }

  PLOG_IF(FATAL, daemon(0, 0) == -1) << "Failed to daemonize";
  brillo::SecureBlob abe_data;
  if (!GetAttestationEnrollmentData(abe_data_hex, &abe_data)) {
    LOG(ERROR) << "Invalid attestation-based enterprise enrollment data.";
  }
  AttestationDaemon daemon(abe_data, ReadGoogleKeysIfExists());
  LOG(INFO) << "Attestation Daemon Started.";
  InitMinijailSandbox();
  return daemon.Run();
}
