// 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 <utility>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/strcat.h"
#include "base/test/multiprocess_test.h"
#include "base/test/scoped_task_environment.h"
#include "base/win/scoped_handle.h"
#include "chrome/chrome_cleaner/constants/quarantine_constants.h"
#include "chrome/chrome_cleaner/interfaces/zip_archiver.mojom.h"
#include "chrome/chrome_cleaner/ipc/mojo_task_runner.h"
#include "chrome/chrome_cleaner/os/disk_util.h"
#include "chrome/chrome_cleaner/zip_archiver/broker/sandbox_setup.h"
#include "chrome/chrome_cleaner/zip_archiver/sandboxed_zip_archiver.h"
#include "chrome/chrome_cleaner/zip_archiver/target/sandbox_setup.h"
#include "chrome/chrome_cleaner/zip_archiver/test_zip_archiver_util.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

namespace chrome_cleaner {

namespace {

using mojom::ZipArchiverResultCode;

constexpr char kTestPassword[] = "1234";
constexpr char kTestSymlink[] = "a.link";
constexpr uint32_t kProhibitedAccessPermissions[] = {
    DELETE,       READ_CONTROL,     WRITE_DAC,
    WRITE_OWNER,  FILE_APPEND_DATA, FILE_EXECUTE,
    FILE_READ_EA, FILE_WRITE_EA,    FILE_WRITE_ATTRIBUTES};

void OnArchiveDone(ZipArchiverResultCode* test_result_code,
                   base::OnceClosure done_callback,
                   ZipArchiverResultCode result_code) {
  *test_result_code = result_code;
  std::move(done_callback).Run();
}

class ZipArchiverSandboxedArchiverTest : public base::MultiProcessTest {
 public:
  void SetUp() override {
    scoped_refptr<MojoTaskRunner> mojo_task_runner = MojoTaskRunner::Create();
    ZipArchiverSandboxSetupHooks setup_hooks(
        mojo_task_runner.get(), base::BindOnce([] {
          FAIL() << "ZipArchiver sandbox connection error";
        }));
    ASSERT_EQ(RESULT_CODE_SUCCESS,
              StartSandboxTarget(MakeCmdLine("SandboxedZipArchiverTargetMain"),
                                 &setup_hooks, SandboxType::kTest));
    UniqueZipArchiverPtr zip_archiver_ptr = setup_hooks.TakeZipArchiverPtr();

    test_file_.Initialize();
    const base::FilePath& src_file_path = test_file_.GetSourceFilePath();

    std::string src_file_hash;
    ComputeSHA256DigestOfPath(src_file_path, &src_file_hash);

    const base::string16 zip_filename = internal::ConstructZipArchiveFileName(
        src_file_path.BaseName().value(), src_file_hash);

    const base::FilePath& dst_archive_folder = test_file_.GetTempDirPath();
    expect_zip_file_path_ = dst_archive_folder.Append(zip_filename);

    zip_archiver_ = std::make_unique<SandboxedZipArchiver>(
        mojo_task_runner, std::move(zip_archiver_ptr), dst_archive_folder,
        kTestPassword);
  }

 protected:
  ZipArchiverResultCode Archive(const base::FilePath& path) {
    ZipArchiverResultCode result_code;
    base::RunLoop loop;
    // Unretained pointer is safe here since we will wait for the task.
    zip_archiver_->Archive(
        path, base::BindOnce(OnArchiveDone, base::Unretained(&result_code),
                             loop.QuitClosure()));
    loop.Run();
    return result_code;
  }

  ZipArchiverTestFile test_file_;
  base::FilePath expect_zip_file_path_;

 private:
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  std::unique_ptr<SandboxedZipArchiver> zip_archiver_;
};

// ArgumentVerifyingFakeArchiver runs and handles Archive requests in the
// sandbox child process. It checks if the parameters passed in the sandbox are
// configured correctly and if some checks are done in SandboxedZipArchiver
// before sending requests to the sandbox. It doesn't do real archiving.
class ArgumentVerifyingFakeArchiver : public mojom::ZipArchiver {
 public:
  explicit ArgumentVerifyingFakeArchiver(mojom::ZipArchiverRequest request)
      : binding_(this, std::move(request)) {
    binding_.set_connection_error_handler(base::BindOnce(
        [] { FAIL() << "ZipArchiver sandbox connection error"; }));
  }

  ~ArgumentVerifyingFakeArchiver() override = default;

  void Archive(mojo::ScopedHandle src_file_handle,
               mojo::ScopedHandle zip_file_handle,
               const std::string& filename_in_zip,
               const std::string& password,
               ArchiveCallback callback) override {
    HANDLE raw_src_file_handle;
    if (mojo::UnwrapPlatformFile(std::move(src_file_handle),
                                 &raw_src_file_handle) != MOJO_RESULT_OK) {
      std::move(callback).Run(ZipArchiverResultCode::kErrorInvalidParameter);
      return;
    }
    base::File src_file(raw_src_file_handle);
    if (!src_file.IsValid()) {
      std::move(callback).Run(ZipArchiverResultCode::kErrorInvalidParameter);
      return;
    }

    // Test if the size of the source file has been checked.
    if (src_file.GetLength() > kQuarantineSourceSizeLimit) {
      std::move(callback).Run(ZipArchiverResultCode::kErrorInvalidParameter);
      return;
    }

    HANDLE raw_zip_file_handle;
    if (mojo::UnwrapPlatformFile(std::move(zip_file_handle),
                                 &raw_zip_file_handle) != MOJO_RESULT_OK) {
      std::move(callback).Run(ZipArchiverResultCode::kErrorInvalidParameter);
      return;
    }
    base::File zip_file(raw_zip_file_handle);
    if (!zip_file.IsValid()) {
      std::move(callback).Run(ZipArchiverResultCode::kErrorInvalidParameter);
      return;
    }

    // Test general prohibited file access permissions.
    for (uint32_t permission : kProhibitedAccessPermissions) {
      if (HasPermission(src_file, permission) ||
          HasPermission(zip_file, permission)) {
        std::move(callback).Run(ZipArchiverResultCode::kErrorInvalidParameter);
        return;
      }
    }

    // Check if |src_file| and |zip_file| have incorrect file access
    // permissions.
    if (HasPermission(src_file, FILE_WRITE_DATA) ||
        HasPermission(zip_file, FILE_READ_DATA)) {
      std::move(callback).Run(ZipArchiverResultCode::kErrorInvalidParameter);
      return;
    }

    std::move(callback).Run(ZipArchiverResultCode::kSuccess);
  }

 private:
  static bool HasPermission(const base::File& file, uint32_t permission) {
    HANDLE temp_handle;
    if (::DuplicateHandle(::GetCurrentProcess(), file.GetPlatformFile(),
                          ::GetCurrentProcess(), &temp_handle, permission,
                          false, 0)) {
      CloseHandle(temp_handle);
      return true;
    }
    return false;
  }

  mojo::Binding<mojom::ZipArchiver> binding_;

  DISALLOW_COPY_AND_ASSIGN(ArgumentVerifyingFakeArchiver);
};

}  // namespace

MULTIPROCESS_TEST_MAIN(SandboxedZipArchiverTargetMain) {
  sandbox::TargetServices* sandbox_target_services =
      sandbox::SandboxFactory::GetTargetServices();
  CHECK(sandbox_target_services);

  // |RunZipArchiverSandboxTarget| won't return. The mojo error handler will
  // abort this process when the connection is broken.
  RunZipArchiverSandboxTarget(*base::CommandLine::ForCurrentProcess(),
                              sandbox_target_services);

  return 0;
}

TEST_F(ZipArchiverSandboxedArchiverTest, Archive) {
  EXPECT_EQ(ZipArchiverResultCode::kSuccess,
            Archive(test_file_.GetSourceFilePath()));

  test_file_.ExpectValidZipFile(
      expect_zip_file_path_,
      test_file_.GetSourceFilePath().BaseName().AsUTF8Unsafe(), kTestPassword);
}

TEST_F(ZipArchiverSandboxedArchiverTest, SourceFileNotFound) {
  ASSERT_TRUE(base::DeleteFile(test_file_.GetSourceFilePath(), false));

  EXPECT_EQ(ZipArchiverResultCode::kErrorCannotOpenSourceFile,
            Archive(test_file_.GetSourceFilePath()));
}

TEST_F(ZipArchiverSandboxedArchiverTest, ZipFileExists) {
  base::File zip_file(expect_zip_file_path_, base::File::FLAG_CREATE);
  ASSERT_TRUE(zip_file.IsValid());

  EXPECT_EQ(ZipArchiverResultCode::kZipFileExists,
            Archive(test_file_.GetSourceFilePath()));
}

TEST_F(ZipArchiverSandboxedArchiverTest, SourceIsSymbolicLink) {
  base::FilePath symlink_path =
      test_file_.GetTempDirPath().AppendASCII(kTestSymlink);
  ASSERT_TRUE(::CreateSymbolicLink(
      symlink_path.AsUTF16Unsafe().c_str(),
      test_file_.GetSourceFilePath().AsUTF16Unsafe().c_str(), 0));

  EXPECT_EQ(ZipArchiverResultCode::kIgnoredSourceFile, Archive(symlink_path));
}

TEST_F(ZipArchiverSandboxedArchiverTest, SourceIsDirectory) {
  EXPECT_EQ(ZipArchiverResultCode::kIgnoredSourceFile,
            Archive(test_file_.GetTempDirPath()));
}

TEST_F(ZipArchiverSandboxedArchiverTest, SourceIsDefaultFileStream) {
  base::FilePath stream_path(base::StrCat(
      {test_file_.GetSourceFilePath().AsUTF16Unsafe(), L"::$data"}));

  EXPECT_EQ(ZipArchiverResultCode::kSuccess, Archive(stream_path));

  test_file_.ExpectValidZipFile(
      expect_zip_file_path_,
      test_file_.GetSourceFilePath().BaseName().AsUTF8Unsafe(), kTestPassword);
}

TEST_F(ZipArchiverSandboxedArchiverTest, SourceIsNonDefaultFileStream) {
  base::FilePath stream_path(base::StrCat(
      {test_file_.GetSourceFilePath().AsUTF16Unsafe(), L":stream:$data"}));
  base::File stream_file(stream_path, base::File::FLAG_CREATE);
  ASSERT_TRUE(stream_file.IsValid());

  EXPECT_EQ(ZipArchiverResultCode::kIgnoredSourceFile, Archive(stream_path));
}

TEST_F(ZipArchiverSandboxedArchiverTest, ArchiveOpenedFileWithSharingAccess) {
  const base::FilePath path = test_file_.GetSourceFilePath();
  base::File opened_file(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
                                   base::File::FLAG_WRITE |
                                   base::File::FLAG_DELETE_ON_CLOSE);
  ASSERT_TRUE(opened_file.IsValid());

  EXPECT_EQ(ZipArchiverResultCode::kSuccess, Archive(path));

  test_file_.ExpectValidZipFile(expect_zip_file_path_,
                                path.BaseName().AsUTF8Unsafe(), kTestPassword);
}

namespace {

// ZipArchiverSandboxCheckTest uses ArgumentVerifyingFakeArchiver to check the
// sandbox configuration and if some checks are done in SandboxedZipArchiver
// before sending requests to the sandbox.
class ZipArchiverSandboxCheckTest : public base::MultiProcessTest {
 public:
  ZipArchiverSandboxCheckTest()
      : mojo_task_runner_(MojoTaskRunner::Create()),
        impl_ptr_(nullptr, base::OnTaskRunnerDeleter(mojo_task_runner_)) {
    UniqueZipArchiverPtr zip_archiver_ptr(
        new mojom::ZipArchiverPtr(),
        base::OnTaskRunnerDeleter(mojo_task_runner_));

    // Initialize the |impl_ptr_| in the mojo task and wait until it completed.
    base::RunLoop loop;
    mojo_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&ZipArchiverSandboxCheckTest::
                                      InitializeArgumentVerifyingFakeArchiver,
                                  base::Unretained(this),
                                  zip_archiver_ptr.get(), loop.QuitClosure()));
    loop.Run();

    test_file_.Initialize();

    zip_archiver_ = std::make_unique<SandboxedZipArchiver>(
        mojo_task_runner_, std::move(zip_archiver_ptr),
        test_file_.GetTempDirPath(), kTestPassword);
  }

 protected:
  ZipArchiverResultCode Archive(const base::FilePath& path) {
    ZipArchiverResultCode result_code;
    base::RunLoop loop;
    // Unretained pointer is safe here since we will wait for the task.
    zip_archiver_->Archive(
        path, base::BindOnce(OnArchiveDone, base::Unretained(&result_code),
                             loop.QuitClosure()));
    loop.Run();
    return result_code;
  }

  ZipArchiverTestFile test_file_;

 private:
  void InitializeArgumentVerifyingFakeArchiver(
      mojom::ZipArchiverPtr* zip_archiver_ptr,
      base::OnceClosure callback) {
    impl_ptr_.reset(
        new ArgumentVerifyingFakeArchiver(mojo::MakeRequest(zip_archiver_ptr)));
    std::move(callback).Run();
  }

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  scoped_refptr<MojoTaskRunner> mojo_task_runner_;
  std::unique_ptr<SandboxedZipArchiver> zip_archiver_;
  std::unique_ptr<ArgumentVerifyingFakeArchiver, base::OnTaskRunnerDeleter>
      impl_ptr_;
};

}  // namespace

TEST_F(ZipArchiverSandboxCheckTest, CheckPermission) {
  // Let ArgumentVerifyingFakeArchiver check if file handles are opened with
  // correct permissions.
  EXPECT_EQ(ZipArchiverResultCode::kSuccess,
            Archive(test_file_.GetSourceFilePath()));
}

TEST_F(ZipArchiverSandboxCheckTest, SourceIsTooBig) {
  const base::FilePath path = test_file_.GetSourceFilePath();
  base::File src_file(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE);
  ASSERT_TRUE(src_file.IsValid());
  // Increase the size of source file to one byte more than limit.
  ASSERT_TRUE(src_file.SetLength(kQuarantineSourceSizeLimit + 1));
  src_file.Close();

  // Expect SandboxedZipArchiver to check file size before sending a request to
  // ArgumentVerifyingFakeArchiver. ArgumentVerifyingFakeArchiver will return
  // kErrorInvalidParameter if the file size isn't checked first.
  EXPECT_EQ(ZipArchiverResultCode::kErrorSourceFileTooBig, Archive(path));
}

}  // namespace chrome_cleaner
