// Copyright 2016 The Chromium 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 "components/os_crypt/key_storage_libsecret.h"

#include "base/base64.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "components/os_crypt/libsecret_util_linux.h"

namespace {

#if defined(GOOGLE_CHROME_BUILD)
const char kApplicationName[] = "chrome";
#else
const char kApplicationName[] = "chromium";
#endif

// Deprecated in M55 (crbug.com/639298)
const SecretSchema kKeystoreSchemaV1 = {
    "chrome_libsecret_os_crypt_password",
    SECRET_SCHEMA_NONE,
    {
        {nullptr, SECRET_SCHEMA_ATTRIBUTE_STRING},
    }};

const SecretSchema kKeystoreSchemaV2 = {
    "chrome_libsecret_os_crypt_password_v2",
    SECRET_SCHEMA_DONT_MATCH_NAME,
    {
        {"application", SECRET_SCHEMA_ATTRIBUTE_STRING},
        {nullptr, SECRET_SCHEMA_ATTRIBUTE_STRING},
    }};

// From a search result, extracts a SecretValue, asserting that there was at
// most one result. Returns nullptr if there are no results.
SecretValue* ToSingleSecret(GList* secret_items) {
  GList* first = g_list_first(secret_items);
  if (first == nullptr)
    return nullptr;
  if (g_list_next(first) != nullptr) {
    VLOG(1) << "OSCrypt found more than one encryption keys.";
  }
  SecretItem* secret_item = static_cast<SecretItem*>(first->data);
  SecretValue* secret_value =
      LibsecretLoader::secret_item_get_secret(secret_item);
  return secret_value;
}

}  // namespace

std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() {
  std::string password;
  base::Base64Encode(base::RandBytesAsString(16), &password);
  GError* error = nullptr;
  bool success = LibsecretLoader::secret_password_store_sync(
      &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(),
      nullptr, &error, "application", kApplicationName, nullptr);
  if (error) {
    VLOG(1) << "Libsecret lookup failed: " << error->message;
    g_error_free(error);
    return std::string();
  }
  if (!success) {
    VLOG(1) << "Libsecret lookup failed.";
    return std::string();
  }

  VLOG(1) << "OSCrypt generated a new password.";
  return password;
}

std::string KeyStorageLibsecret::GetKeyImpl() {
  LibsecretAttributesBuilder attrs;
  attrs.Append("application", kApplicationName);

  LibsecretLoader::SearchHelper helper;
  helper.Search(&kKeystoreSchemaV2, attrs.Get(),
                SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS);
  if (!helper.success()) {
    VLOG(1) << "Libsecret lookup failed: " << helper.error()->message;
    return std::string();
  }

  SecretValue* password_libsecret = ToSingleSecret(helper.results());
  if (!password_libsecret) {
    std::string password = Migrate();
    if (!password.empty())
      return password;
    return AddRandomPasswordInLibsecret();
  }
  std::string password(
      LibsecretLoader::secret_value_get_text(password_libsecret));
  LibsecretLoader::secret_value_unref(password_libsecret);
  return password;
}

bool KeyStorageLibsecret::Init() {
  bool loaded = LibsecretLoader::EnsureLibsecretLoaded();
  if (loaded)
    LibsecretLoader::EnsureKeyringUnlocked();
  return loaded;
}

std::string KeyStorageLibsecret::Migrate() {
  LibsecretAttributesBuilder attrs;

  // Detect old entry.
  LibsecretLoader::SearchHelper helper;
  helper.Search(&kKeystoreSchemaV1, attrs.Get(),
                SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS);
  if (!helper.success())
    return std::string();

  SecretValue* password_libsecret = ToSingleSecret(helper.results());
  if (!password_libsecret)
    return std::string();

  VLOG(1) << "OSCrypt detected a deprecated password in Libsecret.";
  std::string password(
      LibsecretLoader::secret_value_get_text(password_libsecret));
  LibsecretLoader::secret_value_unref(password_libsecret);

  // Create new entry.
  GError* error = nullptr;
  bool success = LibsecretLoader::secret_password_store_sync(
      &kKeystoreSchemaV2, nullptr, KeyStorageLinux::kKey, password.c_str(),
      nullptr, &error, "application", kApplicationName, nullptr);
  if (error) {
    VLOG(1) << "Failed to store migrated password. " << error->message;
    g_error_free(error);
    return std::string();
  }
  if (!success) {
    VLOG(1) << "Failed to store migrated password.";
    return std::string();
  }

  // Delete old entry.
  // Even if deletion failed, we have to use the password that we created.
  success = LibsecretLoader::secret_password_clear_sync(
      &kKeystoreSchemaV1, nullptr, &error, nullptr);
  if (error) {
    VLOG(1) << "OSCrypt failed to delete deprecated password. "
            << error->message;
    g_error_free(error);
  }

  VLOG(1) << "OSCrypt migrated from deprecated password.";

  return password;
}
