// 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 "libpasswordprovider/password_provider.h"

#include <grp.h>
#include <keyutils.h>
#include <vector>

#include "base/logging.h"
#include "libpasswordprovider/password.h"

namespace password_provider {

namespace {

constexpr int kDefaultGroupStringsLength = 1024;

constexpr char kKeyringDescription[] = "password keyring";
constexpr char kKeyringKeyType[] = "keyring";
constexpr char kPasswordKeyDescription[] = "password";
constexpr char kPasswordKeyType[] = "user";
constexpr char kPasswordViewersGroupName[] = "password-viewers";

key_serial_t RequestKey(const char* type, const char* description) {
  key_serial_t keyring_serial =
      find_key_by_type_and_desc(kKeyringKeyType, kKeyringDescription, 0);
  if (keyring_serial == -1) {
    // This is also called in cases where keys might not exist (e.g., cleaning
    // up on logout) so not finding any keys is not an error.
    VLOG(1) << "Error finding keyring. errno: " << errno;
    return keyring_serial;
  }

  return keyctl_search(keyring_serial, type, description, 0);
}

int RevokeKey(const char* type, const char* description) {
  key_serial_t key_serial = RequestKey(type, description);
  if (key_serial == -1) {
    return errno;
  }

  int result = keyctl_revoke(key_serial);
  if (result == -1) {
    return errno;
  }

  return result;
}

void HandleKeyError(const char* type, const char* description) {
  int result = RevokeKey(type, description);
  if (result != 0) {
    PLOG(ERROR) << "Error revoking key: " << description;
  }
}

}  // namespace

PasswordProvider::PasswordProvider() {}

bool PasswordProvider::SavePassword(const Password& password) const {
  DCHECK_GT(password.size(), 0);
  DCHECK(password.GetRaw());

  // Get the group ID for password-viewers
  long group_name_length = sysconf(_SC_GETGR_R_SIZE_MAX);  // NOLINT long
  if (group_name_length == -1) {
    group_name_length = kDefaultGroupStringsLength;
  }
  struct group group_info, *group_infop;
  std::vector<char> group_name_buf(group_name_length);
  int result =
      getgrnam_r(kPasswordViewersGroupName, &group_info, group_name_buf.data(),
                 group_name_length, &group_infop);
  if (result) {
    LOG(WARNING) << "Error retrieving group ID for "
                 << kPasswordViewersGroupName << " error: " << result;
    group_info.gr_gid = -1;
  } else if (group_infop == NULL) {
    LOG(WARNING) << "Could not find group ID for " << kPasswordViewersGroupName;
    group_info.gr_gid = -1;
  }

  key_serial_t keyring_id = add_key(kKeyringKeyType, kKeyringDescription, NULL,
                                    0, KEY_SPEC_PROCESS_KEYRING);
  if (keyring_id == -1) {
    PLOG(ERROR) << "Error creating keyring.";
    return false;
  }

  result = keyctl_chown(keyring_id, -1, group_info.gr_gid);
  if (result == -1) {
    // Don't return false here. Failing to change the group means that the key
    // can't be retrieved by the users in the specified group. The security of
    // the key is not compromised. Unit tests are not run as a superuser, and so
    // can't chown the key and this call will always fail.
    PLOG(ERROR) << "Could not change keyring group.";
  }

  result =
      keyctl_setperm(keyring_id, KEY_POS_ALL | KEY_GRP_VIEW | KEY_GRP_READ |
                                     KEY_GRP_SEARCH | KEY_GRP_WRITE);

  if (result == -1) {
    PLOG(ERROR) << "Error setting permissions on keyring. ";
    return false;
  }

  key_serial_t key_serial =
      add_key(kPasswordKeyType, kPasswordKeyDescription, password.GetRaw(),
              password.size(), keyring_id);

  if (key_serial == -1) {
    PLOG(ERROR) << "Error adding key to keyring.";
    return false;
  }

  result = keyctl_chown(key_serial, -1, group_info.gr_gid);
  if (result == -1) {
    // Don't return false here. Failing to change the group means that the key
    // can't be retrieved by the users in the specified group. The security of
    // the key is not compromised. Unit tests are not run as a superuser, and so
    // can't chown the key and this call will always fail.
    PLOG(ERROR) << "Could not change key group.";
  }

  result =
      keyctl_setperm(key_serial, KEY_POS_ALL | KEY_GRP_VIEW | KEY_GRP_READ |
                                     KEY_GRP_SEARCH | KEY_GRP_WRITE);

  if (result == -1) {
    PLOG(ERROR) << "Error setting permissions on key. ";
    HandleKeyError(kPasswordKeyType, kPasswordKeyDescription);
    return false;
  }

  return true;
}

std::unique_ptr<Password> PasswordProvider::GetPassword() const {
  key_serial_t key_serial =
      RequestKey(kPasswordKeyType, kPasswordKeyDescription);
  if (key_serial == -1) {
    PLOG(WARNING) << "Could not find key.";
    return nullptr;
  }

  auto password = std::make_unique<Password>();
  if (!password->Init()) {
    LOG(ERROR) << "Error allocating buffer for password";
    return nullptr;
  }

  int result =
      keyctl_read(key_serial, password->GetMutableRaw(), password->max_size());
  if (result > password->max_size()) {
    LOG(ERROR) << "Password too large for buffer. Max size: "
               << password->max_size();
    return nullptr;
  }

  if (result == -1) {
    PLOG(ERROR) << "Error reading key.";
    return nullptr;
  }

  password->SetSize(result);
  return password;
}

bool PasswordProvider::DiscardPassword() const {
  int result = RevokeKey(kPasswordKeyType, kPasswordKeyDescription);
  if (result != 0) {
    // This is also called in cases where keys might not exist (e.g., cleaning
    // up on logout) so not finding any keys is not an error.
    VLOG(1) << "Error revoking key. errno: " << errno;
    return false;
  }

  return true;
}

}  // namespace password_provider
