// Copyright 2018 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/elevation_service/elevated_recovery_impl.h"

#include <objbase.h>
#include <string>
#include <utility>

#include "base/base_paths.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/strings/utf_string_conversions.h"
#include "base/version.h"
#include "base/win/scoped_process_information.h"
#include "chrome/install_static/install_util.h"
#include "third_party/zlib/google/zip.h"

namespace elevation_service {

namespace {

// The hard-coded Recovery subdirectory where the CRX is unpacked and executed.
constexpr base::FilePath::CharType kRecoveryDirectory[] =
    FILE_PATH_LITERAL("ChromeRecovery");

// The hard-coded Recovery executable. This file comes from the CRX, and we
// create an elevated process from it.
constexpr base::FilePath::CharType kRecoveryExeName[] =
    FILE_PATH_LITERAL("ChromeRecovery.exe");

// The hard-coded SHA256 of the SubjectPublicKeyInfo used to sign the Recovery
// CRX which contains ChromeRecovery.exe.
std::vector<uint8_t> GetRecoveryCRXHash() {
  return std::vector<uint8_t>{0x5f, 0x94, 0xe0, 0x3c, 0x64, 0x30, 0x9f, 0xbc,
                              0xfe, 0x00, 0x9a, 0x27, 0x3e, 0x52, 0xbf, 0xa5,
                              0x84, 0xb9, 0xb3, 0x75, 0x07, 0x29, 0xde, 0xfa,
                              0x32, 0x76, 0xd9, 0x93, 0xb5, 0xa3, 0xce, 0x02};
}

// This function is only meant to be called when a Windows API function errors
// out, and the corresponding ::GetLastResult is expected to be set to an error.
// There could be cases where ::GetLastError() is not set correctly, this
// function returns E_FAIL in those cases.
HRESULT HRESULTFromLastError() {
  const auto error_code = ::GetLastError();
  return (error_code != ERROR_SUCCESS) ? HRESULT_FROM_WIN32(error_code)
                                       : E_FAIL;
}

// Opens and returns the COM caller's |process| given the process id, or the
// current process if |proc_id| is 0.
HRESULT OpenCallingProcess(uint32_t proc_id, base::Process* process) {
  DCHECK(process);

  if (!proc_id) {
    *process = base::Process::Current();
    return S_OK;
  }

  HRESULT hr = ::CoImpersonateClient();
  if (FAILED(hr))
    return hr;

  base::ScopedClosureRunner revert_to_self(
      base::BindOnce(base::IgnoreResult(&::CoRevertToSelf)));

  *process = base::Process::OpenWithAccess(proc_id, PROCESS_DUP_HANDLE);
  return process->IsValid() ? S_OK : HRESULTFromLastError();
}

// Validates the provided CRX using the |crx_hash|, and if validation succeeds,
// unpacks the CRX under |unpack_under_path|. Returns the unpacked CRX
// directory in |unpacked_crx_dir|.
HRESULT ValidateAndUnpackCRX(const base::FilePath& from_crx_path,
                             const crx_file::VerifierFormat& crx_format,
                             const std::vector<uint8_t>& crx_hash,
                             const base::FilePath& unpack_under_path,
                             base::ScopedTempDir* unpacked_crx_dir) {
  DCHECK(unpacked_crx_dir);

  base::ScopedTempDir to_dir;
  if (!to_dir.CreateUniqueTempDirUnderPath(unpack_under_path))
    return HRESULTFromLastError();

  const base::FilePath to_crx_path =
      to_dir.GetPath().Append(from_crx_path.BaseName());

  if (!base::CopyFile(from_crx_path, to_crx_path))
    return HRESULTFromLastError();

  std::string public_key;
  if (crx_file::Verify(to_crx_path, crx_format, {crx_hash}, {}, &public_key,
                       nullptr) != crx_file::VerifierResult::OK_FULL) {
    return CRYPT_E_NO_MATCH;
  }

  if (!zip::Unzip(to_crx_path, to_dir.GetPath()))
    return E_UNEXPECTED;

  LOG_IF(WARNING, !base::DeleteFile(to_crx_path, false));

  LOG_IF(WARNING, !unpacked_crx_dir->Set(to_dir.Take()));
  return S_OK;
}

// Runs the executable |path_and_name| with the provided |args|. The returned
// |proc_handle| is a process handle that is valid for the |calling_process|
// process.
HRESULT LaunchCmd(const base::CommandLine& command_line,
                  const base::Process& calling_process,
                  base::win::ScopedHandle* proc_handle) {
  DCHECK(!command_line.GetCommandLineString().empty());
  DCHECK(proc_handle);

  base::LaunchOptions options = {};
  options.feedback_cursor_off = true;
  base::GetTempDir(&options.current_directory);
  base::Process proc = base::LaunchProcess(command_line, options);
  if (!proc.IsValid())
    return HRESULTFromLastError();

  HANDLE duplicate_proc_handle = nullptr;
  constexpr DWORD desired_access =
      PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE;
  bool res = ::DuplicateHandle(
                 ::GetCurrentProcess(),     // Current process.
                 proc.Handle(),             // Process handle to duplicate.
                 calling_process.Handle(),  // Process receiving the handle.
                 &duplicate_proc_handle,    // Duplicated handle.
                 desired_access,  // Access requested for the new handle.
                 FALSE,           // Don't inherit the new handle.
                 0) != 0;
  if (!res)
    return HRESULTFromLastError();

  proc_handle->Set(duplicate_proc_handle);
  return S_OK;
}

HRESULT ValidateCRXArgs(const base::string16& browser_appid,
                        const base::string16& browser_version,
                        const base::string16& session_id) {
  if (!browser_appid.empty()) {
    GUID guid = {};
    HRESULT hr = ::IIDFromString(browser_appid.c_str(), &guid);
    if (FAILED(hr))
      return hr;
  }

  const base::Version version(base::UTF16ToASCII(browser_version));
  if (!version.IsValid())
    return E_INVALIDARG;

  GUID session_guid = {};
  return ::IIDFromString(session_id.c_str(), &session_guid);
}

// Deletes all the files and subdirectories within |directory_path|. Errors are
// ignored.
void DeleteDirectoryFiles(const base::FilePath& directory_path) {
  base::FileEnumerator file_enum(
      directory_path, false,
      base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
  for (base::FilePath current = file_enum.Next(); !current.empty();
       current = file_enum.Next()) {
    base::DeleteFile(current, true);
  }
}

// Schedules deletion after reboot of |dir_name| as well as all the files and
// subdirectories within |dir_name|. Errors are ignored.
void ScheduleDirectoryForDeletion(const base::FilePath& dir_name) {
  // First schedule all the files within |dir_name| for deletion.
  base::FileEnumerator file_enum(dir_name, false, base::FileEnumerator::FILES);
  for (base::FilePath file = file_enum.Next(); !file.empty();
       file = file_enum.Next()) {
    base::DeleteFileAfterReboot(file);
  }

  // Then recurse to all the subdirectories.
  base::FileEnumerator dir_enum(dir_name, false,
                                base::FileEnumerator::DIRECTORIES);
  for (base::FilePath sub_dir = dir_enum.Next(); !sub_dir.empty();
       sub_dir = dir_enum.Next()) {
    ScheduleDirectoryForDeletion(sub_dir);
  }

  // Now schedule the empty directory itself.
  base::DeleteFileAfterReboot(dir_name);
}

// Returns the ChromeRecovery directory under Google\Chrome. For machine
// installs, this directory is under %ProgramFiles%, which is writeable only by
// adminstrators. We use this secure directory to validate and unpack the CRX to
// prevent tampering.
HRESULT GetChromeRecoveryDirectory(base::FilePath* dir) {
  base::FilePath recovery_dir;
  if (!base::PathService::Get(base::DIR_EXE, &recovery_dir))
    return HRESULTFromLastError();

  recovery_dir = recovery_dir.DirName().DirName().Append(kRecoveryDirectory);
  *dir = std::move(recovery_dir);
  return S_OK;
}

}  // namespace

HRESULT CleanupChromeRecoveryDirectory() {
  base::FilePath recovery_dir;
  HRESULT hr = GetChromeRecoveryDirectory(&recovery_dir);
  if (FAILED(hr))
    return hr;

  DeleteDirectoryFiles(recovery_dir);

  return S_OK;
}

HRESULT RunChromeRecoveryCRX(const base::FilePath& crx_path,
                             const base::string16& browser_appid,
                             const base::string16& browser_version,
                             const base::string16& session_id,
                             uint32_t caller_proc_id,
                             base::win::ScopedHandle* proc_handle) {
  if (crx_path.empty() || !proc_handle)
    return E_INVALIDARG;

  HRESULT hr = ValidateCRXArgs(browser_appid, browser_version, session_id);
  if (FAILED(hr))
    return hr;

  base::CommandLine args(base::CommandLine::NO_PROGRAM);
  if (!browser_appid.empty())
    args.AppendSwitchNative("appguid", browser_appid);
  args.AppendSwitchNative("browser-version", browser_version);
  args.AppendSwitchNative("sessionid", session_id);
  args.AppendSwitch("system");

  base::FilePath unpack_dir;
  hr = GetChromeRecoveryDirectory(&unpack_dir);
  if (FAILED(hr))
    return hr;

  return RunCRX(crx_path, args,
                crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF,
                GetRecoveryCRXHash(), unpack_dir,
                base::FilePath(kRecoveryExeName), caller_proc_id, proc_handle);
}

HRESULT RunCRX(const base::FilePath& crx_path,
               const base::CommandLine& args,
               const crx_file::VerifierFormat& crx_format,
               const std::vector<uint8_t>& crx_hash,
               const base::FilePath& unpack_under_path,
               const base::FilePath& exe_filename,
               uint32_t caller_proc_id,
               base::win::ScopedHandle* proc_handle) {
  DCHECK(proc_handle);
  DCHECK(!crx_path.empty());
  DCHECK(!crx_hash.empty());
  DCHECK(!unpack_under_path.empty());
  DCHECK(!exe_filename.empty());

  base::Process calling_process;
  HRESULT hr = OpenCallingProcess(caller_proc_id, &calling_process);
  if (FAILED(hr))
    return hr;

  base::ScopedTempDir unpacked_crx_dir;
  hr = ValidateAndUnpackCRX(crx_path, crx_format, crx_hash, unpack_under_path,
                            &unpacked_crx_dir);
  if (FAILED(hr))
    return hr;

  const base::FilePath path_and_name =
      unpacked_crx_dir.GetPath().Append(exe_filename);
  base::CommandLine command_line(path_and_name);
  command_line.AppendArguments(args, false);

  base::win::ScopedHandle scoped_proc_handle;
  hr = LaunchCmd(command_line, calling_process, &scoped_proc_handle);
  if (FAILED(hr))
    return hr;

  ScheduleDirectoryForDeletion(unpacked_crx_dir.Take());
  *proc_handle = std::move(scoped_proc_handle);
  return hr;
}

}  // namespace elevation_service
