// Copyright 2017 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 "chrome_elf/third_party_dlls/packed_list_file.h"

#include <windows.h>

#include <assert.h>
#include <stdio.h>

#include <algorithm>
#include <limits>

#include "chrome/install_static/install_util.h"
#include "chrome_elf/nt_registry/nt_registry.h"
#include "chrome_elf/third_party_dlls/packed_list_format.h"

namespace third_party_dlls {
namespace {

// No concern about concurrency control in chrome_elf.
bool g_initialized = false;

// This will hold a packed blacklist module array, read directly from a
// data file during InitFromFile().
PackedListModule* g_bl_module_array = nullptr;
size_t g_bl_module_array_size = 0;

// NOTE: this "global" is only initialized once on first access.
// NOTE: it is wrapped in a function to prevent exit-time dtors.
std::wstring& GetBlFilePath() {
  static std::wstring* const file_path = new std::wstring();
  return *file_path;
}

//------------------------------------------------------------------------------
// Private functions
//------------------------------------------------------------------------------

// Binary predicate compare function for use with
// std::equal_range/std::is_sorted. Must return TRUE if lhs < rhs.
bool HashBinaryPredicate(const PackedListModule& lhs,
                         const PackedListModule& rhs) {
  return lhs.basename_hash < rhs.basename_hash;
}

// Given a file opened for read, pull in the packed list.
ThirdPartyStatus ReadInArray(HANDLE file,
                             size_t* array_size,
                             PackedListModule** array_ptr) {
  PackedListMetadata metadata;
  DWORD bytes_read = 0;

  if (!::ReadFile(file, &metadata, sizeof(PackedListMetadata), &bytes_read,
                  FALSE) ||
      bytes_read != sizeof(PackedListMetadata)) {
    // If |bytes_read| is actually 0, then the file was empty.
    if (!bytes_read)
      return ThirdPartyStatus::kFileEmpty;
    return ThirdPartyStatus::kFileMetadataReadFailure;
  }

  // Careful of versioning.  For now, only support the latest version.
  if (metadata.version != PackedListVersion::kCurrent)
    return ThirdPartyStatus::kFileInvalidFormatVersion;

  *array_size = metadata.module_count;
  // Check for size 0.
  if (!*array_size)
    return ThirdPartyStatus::kFileArraySizeZero;

  // Sanity check the array fits in a DWORD.
  if (*array_size >
      (std::numeric_limits<DWORD>::max() / sizeof(PackedListModule))) {
    assert(false);
    return ThirdPartyStatus::kFileArrayTooBig;
  }

  DWORD buffer_size =
      static_cast<DWORD>(*array_size * sizeof(PackedListModule));
  *array_ptr = reinterpret_cast<PackedListModule*>(new uint8_t[buffer_size]);

  // Read in the array.
  // NOTE: Ignore the rest of the file - other data could be stored at the end.
  if (!::ReadFile(file, *array_ptr, buffer_size, &bytes_read, FALSE) ||
      bytes_read != buffer_size) {
    delete[] * array_ptr;
    *array_ptr = nullptr;
    *array_size = 0;
    return ThirdPartyStatus::kFileArrayReadFailure;
  }

  // Ensure array is sorted (as expected).
  if (!std::is_sorted(*array_ptr, *array_ptr + *array_size,
                      HashBinaryPredicate)) {
    delete[] * array_ptr;
    *array_ptr = nullptr;
    *array_size = 0;
    return ThirdPartyStatus::kFileArrayNotSorted;
  }

  return ThirdPartyStatus::kSuccess;
}

// Reads the path to the blacklist file from the registry into |file_path|.
//
// - Returns false if the value is not found, is not a REG_SZ, or is empty.
bool GetFilePathFromRegistry(std::wstring* file_path) {
  file_path->clear();
  HANDLE key_handle = nullptr;

  if (!nt::CreateRegKey(nt::HKCU,
                        install_static::GetRegistryPath()
                            .append(kThirdPartyRegKeyName)
                            .c_str(),
                        KEY_QUERY_VALUE, &key_handle)) {
    return false;
  }

  bool found = nt::QueryRegValueSZ(key_handle, kBlFilePathRegValue, file_path);
  nt::CloseRegKey(key_handle);

  return found && !file_path->empty();
}

// Open a packed data file.
ThirdPartyStatus OpenDataFile(HANDLE* file_handle) {
  *file_handle = INVALID_HANDLE_VALUE;
  std::wstring& file_path = GetBlFilePath();

  // The path may have been overridden for testing.
  if (file_path.empty() && !GetFilePathFromRegistry(&file_path))
    return ThirdPartyStatus::kFilePathNotFoundInRegistry;

  // See if file exists.  INVALID_HANDLE_VALUE alert!
  *file_handle =
      ::CreateFileW(file_path.c_str(), FILE_READ_DATA,
                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                    nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  if (*file_handle == INVALID_HANDLE_VALUE) {
    switch (::GetLastError()) {
      case ERROR_FILE_NOT_FOUND:
      case ERROR_PATH_NOT_FOUND:
        return ThirdPartyStatus::kFileNotFound;
      case ERROR_ACCESS_DENIED:
        return ThirdPartyStatus::kFileAccessDenied;
      default:
        return ThirdPartyStatus::kFileUnexpectedFailure;
    }
  }

  return ThirdPartyStatus::kSuccess;
}

// Find the packed blacklist file and read in the array.
ThirdPartyStatus InitInternal() {
  HANDLE handle = INVALID_HANDLE_VALUE;
  ThirdPartyStatus status = OpenDataFile(&handle);
  if (status != ThirdPartyStatus::kSuccess)
    return status;

  status = ReadInArray(handle, &g_bl_module_array_size, &g_bl_module_array);
  ::CloseHandle(handle);

  return status;
}

}  // namespace

//------------------------------------------------------------------------------
// Public defines & functions
//------------------------------------------------------------------------------

bool IsModuleListed(const elf_sha1::Digest& basename_hash,
                    const elf_sha1::Digest& fingerprint_hash) {
  assert(g_initialized);

  if (!g_bl_module_array_size)
    return false;

  PackedListModule target = {};
  target.basename_hash = basename_hash;
  target.code_id_hash = fingerprint_hash;

  // Binary search for primary hash (basename).  There can be more than one
  // match.
  auto pair = std::equal_range(g_bl_module_array,
                               g_bl_module_array + g_bl_module_array_size,
                               target, HashBinaryPredicate);

  // Search for secondary hash.
  for (PackedListModule* i = pair.first; i != pair.second; ++i) {
    if (target.code_id_hash == i->code_id_hash)
      return true;
  }

  // No match.
  return false;
}

std::wstring GetBlFilePathUsed() {
  assert(g_initialized);
  return GetBlFilePath();
}

ThirdPartyStatus InitFromFile() {
  // Debug check: InitFromFile should not be called more than once.
  assert(!g_initialized);

  ThirdPartyStatus status = InitInternal();

  if (IsStatusCodeSuccessful(status))
    g_initialized = true;

  return status;
}

bool IsStatusCodeSuccessful(ThirdPartyStatus code) {
  if (code == ThirdPartyStatus::kSuccess ||
      code == ThirdPartyStatus::kFilePathNotFoundInRegistry ||
      code == ThirdPartyStatus::kFileNotFound ||
      code == ThirdPartyStatus::kFileEmpty ||
      code == ThirdPartyStatus::kFileArraySizeZero) {
    return true;
  }

  return false;
}

void DeinitFromFile() {
  if (!g_initialized)
    return;

  delete[] g_bl_module_array;
  g_bl_module_array = nullptr;
  g_bl_module_array_size = 0;
  GetBlFilePath().clear();

  g_initialized = false;
}

void OverrideFilePathForTesting(const std::wstring& new_bl_path) {
  GetBlFilePath().assign(new_bl_path);
}

}  // namespace third_party_dlls
