// Copyright 2014 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/browser/safe_browsing/incident_reporting/environment_data_collection_win.h"

#include <windows.h>
#include <set>

#include "base/i18n/case_conversion.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "chrome/browser/install_verification/win/module_info.h"
#include "chrome/browser/install_verification/win/module_verification_common.h"
#include "chrome/browser/net/service_providers_win.h"
#include "chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.h"
#include "chrome/browser/safe_browsing/path_sanitizer.h"
#include "chrome/common/safe_browsing/csd.pb.h"
#include "chrome_elf/chrome_elf_constants.h"

namespace safe_browsing {

namespace {

// The modules on which we will run VerifyModule.
const wchar_t* const kModulesToVerify[] = {
    L"chrome.dll",
    L"chrome_elf.dll",
    L"ntdll.dll",
};

// Helper function for expanding all environment variables in |path|.
std::wstring ExpandEnvironmentVariables(const std::wstring& path) {
  static const DWORD kMaxBuffer = 32 * 1024;  // Max according to MSDN.
  std::wstring path_expanded;
  DWORD path_len = MAX_PATH;
  do {
    DWORD result = ExpandEnvironmentStrings(
        path.c_str(), WriteInto(&path_expanded, path_len), path_len);
    if (!result) {
      // Failed to expand variables. Return the original string.
      DPLOG(ERROR) << path;
      break;
    }
    if (result <= path_len)
      return path_expanded.substr(0, result - 1);
    path_len = result;
  } while (path_len < kMaxBuffer);

  return path;
}

}  // namespace

bool CollectDlls(ClientIncidentReport_EnvironmentData_Process* process) {
  // Retrieve the module list.
  std::set<ModuleInfo> loaded_modules;
  if (!GetLoadedModules(&loaded_modules))
    return false;

  // Sanitize path of each module and add it to the incident report.
  PathSanitizer path_sanitizer;
  for (std::set<ModuleInfo>::const_iterator it = loaded_modules.begin();
       it != loaded_modules.end();
       ++it) {
    base::FilePath dll_path(it->name);
    path_sanitizer.StripHomeDirectory(&dll_path);

    ClientIncidentReport_EnvironmentData_Process_Dll* dll = process->add_dll();
    dll->set_path(base::WideToUTF8(base::i18n::ToLower(dll_path.value())));
    dll->set_base_address(it->base_address);
    dll->set_length(it->size);
  }

  return true;
}

void RecordLspFeature(ClientIncidentReport_EnvironmentData_Process* process) {
  WinsockLayeredServiceProviderList lsp_list;
  GetWinsockLayeredServiceProviders(&lsp_list);

  // For each LSP, we extract and sanitize the path.
  PathSanitizer path_sanitizer;
  std::set<std::wstring> lsp_paths;
  for (size_t i = 0; i < lsp_list.size(); ++i) {
    base::FilePath lsp_path(ExpandEnvironmentVariables(lsp_list[i].path));
    path_sanitizer.StripHomeDirectory(&lsp_path);
    lsp_paths.insert(base::i18n::ToLower(lsp_path.value()));
  }

  // Look for a match between LSPs and loaded dlls.
  for (int i = 0; i < process->dll_size(); ++i) {
    if (lsp_paths.count(base::UTF8ToWide(process->dll(i).path()))) {
      process->mutable_dll(i)
          ->add_feature(ClientIncidentReport_EnvironmentData_Process_Dll::LSP);
    }
  }
}

void CollectDllBlacklistData(
    ClientIncidentReport_EnvironmentData_Process* process) {
  PathSanitizer path_sanitizer;
  base::win::RegistryValueIterator iter(HKEY_CURRENT_USER,
                                        blacklist::kRegistryFinchListPath);
  for (; iter.Valid(); ++iter) {
    base::FilePath dll_name(iter.Value());
    path_sanitizer.StripHomeDirectory(&dll_name);
    process->add_blacklisted_dll(dll_name.AsUTF8Unsafe());
  }
}

void CollectModuleVerificationData(
    const wchar_t* const modules_to_verify[],
    size_t num_modules_to_verify,
    ClientIncidentReport_EnvironmentData_Process* process) {
  for (size_t i = 0; i < num_modules_to_verify; ++i) {
    std::set<std::string> modified_exports;
    int modified = VerifyModule(modules_to_verify[i], &modified_exports);

    if (modified == MODULE_STATE_UNMODIFIED)
      continue;

    ClientIncidentReport_EnvironmentData_Process_ModuleState* module_state =
        process->add_module_state();

    module_state->set_name(
        base::WideToUTF8(std::wstring(modules_to_verify[i])));
    // Add 1 to the ModuleState enum to get the corresponding value in the
    // protobuf's ModuleState enum.
    module_state->set_modified_state(static_cast<
        ClientIncidentReport_EnvironmentData_Process_ModuleState_ModifiedState>(
        modified + 1));
    for (std::set<std::string>::iterator it = modified_exports.begin();
         it != modified_exports.end();
         ++it) {
      module_state->add_modified_export(*it);
    }
  }
}

void CollectPlatformProcessData(
    ClientIncidentReport_EnvironmentData_Process* process) {
  CollectDlls(process);
  RecordLspFeature(process);
  CollectDllBlacklistData(process);
  CollectModuleVerificationData(
      kModulesToVerify, arraysize(kModulesToVerify), process);
}

}  // namespace safe_browsing
