// 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/check.h>
#include <base/check_op.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/secure_blob.h>
#include <brillo/syslog_logging.h>
#include <brillo/userdb_utils.h>
#include <dbus/attestation/dbus-constants.h>
#include <libminijail.h>
#include <scoped_minijail.h>

#include "attestation/server/attestation_service.h"
#include "attestation/server/dbus_service.h"
#include "attestation/server/google_keys.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.";

  ScopedMinijail j(minijail_new());
  minijail_log_seccomp_filter_failures(j.get());
  minijail_no_new_privs(j.get());
  minijail_use_seccomp_filter(j.get());
  minijail_parse_seccomp_filters(j.get(), kAttestationSeccompPath);
  minijail_change_user(j.get(), kAttestationUser);
  minijail_change_group(j.get(), kAttestationGroup);
  minijail_inherit_usergroups(j.get());
  minijail_enter(j.get());

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