// Copyright 2019 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 "kerberos/kerberos_adaptor.h"

#include <string>
#include <unordered_set>
#include <utility>

#include <base/check.h>
#include <base/compiler_specific.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/optional.h>
#include <base/threading/thread_task_runner_handle.h>
#include <base/time/time.h>
#include <brillo/dbus/dbus_object.h>
#include <brillo/errors/error.h>
#include <dbus/login_manager/dbus-constants.h>
#include <libpasswordprovider/password_provider.h>
#include <session_manager/dbus-proxies.h>

#include "kerberos/account_manager.h"
#include "kerberos/error_strings.h"
#include "kerberos/kerberos_metrics.h"
#include "kerberos/krb5_interface.h"
#include "kerberos/krb5_interface_impl.h"
#include "kerberos/krb5_jail_wrapper.h"
#include "kerberos/platform_helper.h"

namespace kerberos {

namespace {

constexpr base::TimeDelta kTicketExpiryCheckDelay =
    base::TimeDelta::FromSeconds(3);

using ByteArray = KerberosAdaptor::ByteArray;

// Serializes |proto| to a vector of bytes. CHECKs for success (should
// never fail if there are no required proto fields).
ByteArray SerializeProto(const google::protobuf::MessageLite& proto) {
  ByteArray proto_blob(proto.ByteSizeLong());
  CHECK(proto.SerializeToArray(proto_blob.data(), proto_blob.size()));
  return proto_blob;
}

// Parses a proto from an array of bytes |proto_blob|. Returns
// ERROR_PARSE_REQUEST_FAILED on error.
WARN_UNUSED_RESULT ErrorType ParseProto(google::protobuf::MessageLite* proto,
                                        const ByteArray& proto_blob) {
  if (!proto->ParseFromArray(proto_blob.data(), proto_blob.size())) {
    LOG(ERROR) << "Failed to parse proto";
    return ERROR_PARSE_REQUEST_FAILED;
  }
  return ERROR_NONE;
}

void PrintRequest(const char* method_name) {
  LOG(INFO) << ">>> " << method_name;
}

void PrintResult(const char* method_name, ErrorType error) {
  if (error == ERROR_NONE)
    LOG(INFO) << "<<< " << method_name << " succeeded";
  else
    LOG(ERROR) << "<<< " << method_name << " failed: " << GetErrorString(error);
}

// Calls Session Manager to get the user hash for the primary session. Returns
// an empty string and logs on error.
std::string GetSanitizedUsername(brillo::dbus_utils::DBusObject* dbus_object) {
  std::string username;
  std::string sanitized_username;
  brillo::ErrorPtr error;
  org::chromium::SessionManagerInterfaceProxy proxy(dbus_object->GetBus());
  if (!proxy.RetrievePrimarySession(&username, &sanitized_username, &error)) {
    const char* error_msg =
        error ? error->GetMessage().c_str() : "Unknown error.";
    LOG(ERROR) << "Call to RetrievePrimarySession failed. " << error_msg;
    return std::string();
  }
  return sanitized_username;
}

}  // namespace

KerberosAdaptor::KerberosAdaptor(
    std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object)
    : org::chromium::KerberosAdaptor(this),
      dbus_object_(std::move(dbus_object)) {}

KerberosAdaptor::~KerberosAdaptor() = default;

void KerberosAdaptor::RegisterAsync(
    const brillo::dbus_utils::AsyncEventSequencer::CompletionAction&
        completion_callback) {
  RegisterWithDBusObject(dbus_object_.get());
  dbus_object_->RegisterAsync(completion_callback);

  // Get the sanitized username (aka user hash). It's needded to determine the
  // daemon store directory where account data is stored.
  base::FilePath storage_dir;
  if (storage_dir_for_testing_) {
    storage_dir = *storage_dir_for_testing_;
  } else {
    const std::string sanitized_username =
        GetSanitizedUsername(dbus_object_.get());
    if (!sanitized_username.empty()) {
      storage_dir = base::FilePath("/run/daemon-store/kerberosd/")
                        .Append(sanitized_username);
    } else {
      // /tmp is a tmpfs and the daemon is shut down on logout, so data is
      // cleared on logout. Better than nothing, though.
      storage_dir = base::FilePath("/tmp");
      LOG(ERROR) << "Failed to retrieve user hash to determine storage "
                    "directory. Falling back to "
                 << storage_dir.value() << ".";
    }
  }

  // Might have already been set for testing.
  if (!metrics_)
    metrics_ = std::make_unique<KerberosMetrics>(storage_dir);

  // Create krb5 or use the one given for testing.
  auto krb5 = krb5_for_testing_ ? std::move(krb5_for_testing_)
                                : std::make_unique<Krb5JailWrapper>(
                                      std::make_unique<Krb5InterfaceImpl>());

  manager_ = std::make_unique<AccountManager>(
      storage_dir,
      base::BindRepeating(&KerberosAdaptor::OnKerberosFilesChanged,
                          base::Unretained(this)),
      base::BindRepeating(&KerberosAdaptor::OnKerberosTicketExpiring,
                          base::Unretained(this)),
      std::move(krb5), std::make_unique<password_provider::PasswordProvider>(),
      metrics_.get());
  manager_->LoadAccounts();

  // Wait a little before calling StartObservingTickets. Apparently, signals
  // are not quite wired up properly at this point. If signals are emitted here,
  // they never reach Chrome, even if Chrome made sure it connected to the
  // signal.
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::BindRepeating(&KerberosAdaptor::StartObservingTickets,
                          weak_ptr_factory_.GetWeakPtr()),
      kTicketExpiryCheckDelay);
}

ByteArray KerberosAdaptor::AddAccount(const ByteArray& request_blob) {
  PrintRequest(__FUNCTION__);
  AddAccountRequest request;
  ErrorType error = ParseProto(&request, request_blob);

  if (error == ERROR_NONE) {
    error =
        manager_->AddAccount(request.principal_name(), request.is_managed());
  }

  PrintResult(__FUNCTION__, error);
  metrics_->ReportDBusCallResult(__FUNCTION__, error);
  AddAccountResponse response;
  response.set_error(error);
  return SerializeProto(response);
}

ByteArray KerberosAdaptor::RemoveAccount(const ByteArray& request_blob) {
  PrintRequest(__FUNCTION__);
  RemoveAccountRequest request;
  ErrorType error = ParseProto(&request, request_blob);

  RemoveAccountResponse response;
  if (error == ERROR_NONE) {
    error = manager_->RemoveAccount(request.principal_name());
    GetAccountsList(response.mutable_accounts());
  }

  PrintResult(__FUNCTION__, error);
  metrics_->ReportDBusCallResult(__FUNCTION__, error);
  response.set_error(error);
  return SerializeProto(response);
}

ByteArray KerberosAdaptor::ClearAccounts(const ByteArray& request_blob) {
  PrintRequest(__FUNCTION__);
  ClearAccountsRequest request;
  ErrorType error = ParseProto(&request, request_blob);

  ClearAccountsResponse response;
  if (error == ERROR_NONE) {
    std::unordered_set<std::string> keep_list(
        request.principal_names_to_ignore_size());
    for (int n = 0; n < request.principal_names_to_ignore_size(); ++n)
      keep_list.insert(request.principal_names_to_ignore(n));

    error = manager_->ClearAccounts(request.mode(), std::move(keep_list));
    GetAccountsList(response.mutable_accounts());
  }

  PrintResult(__FUNCTION__, error);
  metrics_->ReportDBusCallResult(__FUNCTION__, error);
  response.set_error(error);
  return SerializeProto(response);
}

ByteArray KerberosAdaptor::ListAccounts(const ByteArray& request_blob) {
  PrintRequest(__FUNCTION__);
  ListAccountsRequest request;
  ErrorType error = ParseProto(&request, request_blob);

  // Note: request is empty right now, but keeping it for future changes.
  std::vector<Account> accounts;
  ListAccountsResponse response;
  if (error == ERROR_NONE)
    GetAccountsList(response.mutable_accounts());

  PrintResult(__FUNCTION__, error);
  metrics_->ReportDBusCallResult(__FUNCTION__, error);
  response.set_error(error);
  return SerializeProto(response);
}

ByteArray KerberosAdaptor::SetConfig(const ByteArray& request_blob) {
  PrintRequest(__FUNCTION__);
  SetConfigRequest request;
  ErrorType error = ParseProto(&request, request_blob);

  if (error == ERROR_NONE)
    error = manager_->SetConfig(request.principal_name(), request.krb5conf());

  PrintResult(__FUNCTION__, error);
  metrics_->ReportDBusCallResult(__FUNCTION__, error);
  SetConfigResponse response;
  response.set_error(error);
  return SerializeProto(response);
}

ByteArray KerberosAdaptor::ValidateConfig(const ByteArray& request_blob) {
  PrintRequest(__FUNCTION__);
  ValidateConfigRequest request;
  ErrorType error = ParseProto(&request, request_blob);

  ConfigErrorInfo error_info;
  if (error == ERROR_NONE) {
    error = manager_->ValidateConfig(request.krb5conf(), &error_info);
  }

  PrintResult(__FUNCTION__, error);
  metrics_->ReportDBusCallResult(__FUNCTION__, error);
  metrics_->ReportValidateConfigErrorCode(error_info.code());
  ValidateConfigResponse response;
  response.set_error(error);
  *response.mutable_error_info() = error_info;
  return SerializeProto(response);
}

ByteArray KerberosAdaptor::AcquireKerberosTgt(
    const ByteArray& request_blob, const base::ScopedFD& password_fd) {
  PrintRequest(__FUNCTION__);
  AcquireKerberosTgtRequest request;
  ErrorType error = ParseProto(&request, request_blob);

  base::Optional<std::string> password;
  if (error == ERROR_NONE) {
    password = ReadPipeToString(password_fd.get());
    if (!password.has_value()) {
      LOG(ERROR) << "Failed to read password pipe";
      error = ERROR_LOCAL_IO;
    }
  }

  if (error == ERROR_NONE) {
    metrics_->StartAcquireTgtTimer();
    error = manager_->AcquireTgt(request.principal_name(), password.value(),
                                 request.remember_password(),
                                 request.use_login_password());
    metrics_->StopAcquireTgtTimerAndReport();
  }

  PrintResult(__FUNCTION__, error);
  metrics_->ReportDBusCallResult(__FUNCTION__, error);
  AcquireKerberosTgtResponse response;
  response.set_error(error);
  return SerializeProto(response);
}

ByteArray KerberosAdaptor::GetKerberosFiles(const ByteArray& request_blob) {
  PrintRequest(__FUNCTION__);
  GetKerberosFilesRequest request;
  ErrorType error = ParseProto(&request, request_blob);

  GetKerberosFilesResponse response;
  if (error == ERROR_NONE) {
    error = manager_->GetKerberosFiles(request.principal_name(),
                                       response.mutable_files());
  }

  PrintResult(__FUNCTION__, error);
  metrics_->ReportDBusCallResult(__FUNCTION__, error);
  response.set_error(error);
  return SerializeProto(response);
}

void KerberosAdaptor::set_storage_dir_for_testing(const base::FilePath& dir) {
  DCHECK(!manager_);
  storage_dir_for_testing_ = dir;
}

void KerberosAdaptor::set_krb5_for_testing(
    std::unique_ptr<Krb5Interface> krb5) {
  DCHECK(!manager_);
  krb5_for_testing_ = std::move(krb5);
}

void KerberosAdaptor::set_metrics_for_testing(
    std::unique_ptr<KerberosMetrics> metrics) {
  DCHECK(!manager_);
  metrics_ = std::move(metrics);
}

void KerberosAdaptor::StartObservingTickets() {
  manager_->StartObservingTickets();
}

void KerberosAdaptor::OnKerberosFilesChanged(
    const std::string& principal_name) {
  LOG(INFO) << "Firing signal KerberosFilesChanged";
  SendKerberosFilesChangedSignal(principal_name);
}

void KerberosAdaptor::OnKerberosTicketExpiring(
    const std::string& principal_name) {
  LOG(INFO) << "Firing signal KerberosTicketExpiring";
  SendKerberosTicketExpiringSignal(principal_name);
}

void KerberosAdaptor::GetAccountsList(RepeatedAccountField* repeated_accounts) {
  std::vector<Account> accounts = manager_->ListAccounts();
  for (const auto& account : accounts)
    *repeated_accounts->Add() = account;
}

}  // namespace kerberos
