// Copyright 2016 The Chromium OS 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 "imageloader/component.h"

#include <stdint.h>

#include <list>
#include <memory>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <crypto/secure_hash.h>
#include <crypto/sha2.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "imageloader/imageloader_impl.h"
#include "imageloader/mock_helper_process_proxy.h"
#include "imageloader/test_utilities.h"

namespace imageloader {

using testing::_;

class ComponentTest : public testing::Test {
 public:
  ComponentTest() {
    keys_.push_back(std::vector<uint8_t>(std::begin(kDevPublicKey),
                                         std::end(kDevPublicKey)));
    CHECK(scoped_temp_dir_.CreateUniqueTempDir());
    temp_dir_ = scoped_temp_dir_.GetPath();
    CHECK(base::SetPosixFilePermissions(temp_dir_, kComponentDirPerms));
  }

  bool TestCopyWithCorruptFile(const std::string& component_name,
                               const std::string& file_name) {
    base::FilePath bad_component_dir = temp_dir_.Append(component_name);
    if (!base::CreateDirectory(bad_component_dir))
      return false;
    if (!base::SetPosixFilePermissions(bad_component_dir, kComponentDirPerms))
      return false;

    std::unique_ptr<Component> component =
        Component::Create(GetTestComponentPath(), keys_);
    if (!component || !component->CopyTo(bad_component_dir))
      return false;

    std::unique_ptr<Component> bad_component =
        Component::Create(bad_component_dir, keys_);
    if (!bad_component)
      return false;

    base::FilePath file = bad_component_dir.Append(file_name);
    const char data[] = "c";
    if (!base::AppendToFile(file, data, sizeof(data)))
      return false;

    base::FilePath bad_component_dest =
        temp_dir_.Append(component_name + "invalid");
    if (!base::CreateDirectory(bad_component_dest))
      return false;

    if (!base::SetPosixFilePermissions(bad_component_dest, kComponentDirPerms))
      return false;
    return bad_component->CopyTo(bad_component_dest) == false;
  }

  bool TestInitComponentWithCorruptFile(const std::string& component_name,
                                        const std::string& file_name) {
    base::FilePath bad_component_dir = temp_dir_.Append(component_name);
    if (!base::CreateDirectory(bad_component_dir))
      return false;
    if (!base::SetPosixFilePermissions(bad_component_dir, kComponentDirPerms))
      return false;

    std::unique_ptr<Component> component =
        Component::Create(GetTestComponentPath(), keys_);
    if (!component || !component->CopyTo(bad_component_dir))
      return false;

    base::FilePath file = bad_component_dir.Append(file_name);
    // Read the file out and change the last byte.
    std::string file_contents;
    if (!base::ReadFileToString(file, &file_contents))
      return false;
    file_contents[file_contents.size() - 1] =
        ~file_contents[file_contents.size() - 1];

    if (!base::WriteFile(file, file_contents.data(), file_contents.size())) {
      return false;
    }

    std::unique_ptr<Component> bad_component =
        Component::Create(bad_component_dir, keys_);
    return bad_component == nullptr;
  }

  bool CompareFileContents(const base::FilePath& src,
                           const base::FilePath& dest,
                           const std::list<std::string>& filenames) {
    for (const std::string& name : filenames) {
      std::string source_file_contents;
      std::string dest_file_contents;
      if (!base::ReadFileToString(src.Append(name), &source_file_contents))
        return false;
      if (!base::ReadFileToString(dest.Append(name), &dest_file_contents))
        return false;
      if (source_file_contents != dest_file_contents) {
        LOG(ERROR) << "File contents does not match for file: " << name;
        return false;
      }
    }
    return true;
  }

  Keys keys_;
  base::ScopedTempDir scoped_temp_dir_;
  base::FilePath temp_dir_;
};

TEST_F(ComponentTest, InitComponentAndCheckManifest) {
  std::unique_ptr<Component> component =
      Component::Create(GetTestComponentPath(), keys_);
  ASSERT_NE(nullptr, component);

  EXPECT_EQ(1, component->manifest().manifest_version());
  EXPECT_EQ(kTestDataVersion, component->manifest().version());
  // Don't hardcode the sha256 hashes, but run some sanity checks.
  EXPECT_EQ(crypto::kSHA256Length, component->manifest().image_sha256().size());
  EXPECT_EQ(crypto::kSHA256Length, component->manifest().table_sha256().size());
  EXPECT_NE(component->manifest().image_sha256(),
            component->manifest().table_sha256());
}

TEST_F(ComponentTest, TestCopyAndMountComponentExt4) {
  std::unique_ptr<Component> component =
      Component::Create(GetTestDataPath("ext4_component"), keys_);
  ASSERT_NE(nullptr, component);

  const base::FilePath copied_dir = temp_dir_.Append("dest");
  ASSERT_TRUE(base::CreateDirectory(copied_dir));
  ASSERT_TRUE(base::SetPosixFilePermissions(copied_dir, kComponentDirPerms));

  ASSERT_TRUE(component->CopyTo(copied_dir));

  std::unique_ptr<Component> copied_component =
      Component::Create(copied_dir, keys_);
  ASSERT_NE(nullptr, copied_component);

  const base::FilePath mount_dir = temp_dir_.Append("mount");
  ASSERT_TRUE(base::CreateDirectory(copied_dir));
  ASSERT_TRUE(base::SetPosixFilePermissions(copied_dir, kComponentDirPerms));

  // Note: this fails to test the actual mounting process since it is just a
  // mock here. The platform_ImageLoader autotest tests the real helper
  // process running as a dbus service.
  auto helper_mock = std::make_unique<MockHelperProcessProxy>();
  EXPECT_CALL(*helper_mock, SendMountCommand(_, _, FileSystem::kExt4, _))
      .Times(1);
  ON_CALL(*helper_mock, SendMountCommand(_, _, _, _))
      .WillByDefault(testing::Return(true));
  ASSERT_TRUE(copied_component->Mount(helper_mock.get(), mount_dir));
}

TEST_F(ComponentTest, TestCopyAndMountComponentSquashfs) {
  std::unique_ptr<Component> component =
      Component::Create(GetTestComponentPath(), keys_);
  ASSERT_NE(nullptr, component);

  const base::FilePath copied_dir = temp_dir_.Append("dest");
  ASSERT_TRUE(base::CreateDirectory(copied_dir));
  ASSERT_TRUE(base::SetPosixFilePermissions(copied_dir, kComponentDirPerms));

  ASSERT_TRUE(component->CopyTo(copied_dir));

  std::unique_ptr<Component> copied_component =
      Component::Create(copied_dir, keys_);
  ASSERT_NE(nullptr, copied_component);

  const base::FilePath mount_dir = temp_dir_.Append("mount");
  ASSERT_TRUE(base::CreateDirectory(copied_dir));
  ASSERT_TRUE(base::SetPosixFilePermissions(copied_dir, kComponentDirPerms));

  // Note: this fails to test the actual mounting process since it is just a
  // mock here. The platform_ImageLoader autotest tests the real helper
  // process running as a dbus service.
  auto helper_mock = std::make_unique<MockHelperProcessProxy>();
  EXPECT_CALL(*helper_mock, SendMountCommand(_, _, FileSystem::kSquashFS, _))
      .Times(1);
  ON_CALL(*helper_mock, SendMountCommand(_, _, _, _))
      .WillByDefault(testing::Return(true));
  ASSERT_TRUE(copied_component->Mount(helper_mock.get(), mount_dir));
}

TEST_F(ComponentTest, CheckFilesAfterCopy) {
  std::unique_ptr<Component> component =
      Component::Create(GetTestComponentPath(), keys_);
  ASSERT_NE(nullptr, component);

  const base::FilePath copied_dir = temp_dir_.Append("dest");
  ASSERT_TRUE(base::CreateDirectory(copied_dir));
  ASSERT_TRUE(base::SetPosixFilePermissions(copied_dir, kComponentDirPerms));

  ASSERT_TRUE(component->CopyTo(copied_dir));

  std::unique_ptr<Component> copied_component =
      Component::Create(copied_dir, keys_);
  ASSERT_NE(nullptr, copied_component);

  // Check that all the files are present, except for the manifest.json which
  // should be discarded.
  std::list<std::string> original_files;
  std::list<std::string> copied_files;
  GetFilesInDir(GetTestComponentPath(), &original_files);
  GetFilesInDir(copied_dir, &copied_files);

  EXPECT_THAT(original_files,
              testing::UnorderedElementsAre(
                  "imageloader.json", "imageloader.sig.1", "manifest.json",
                  "table", "image.squash", "manifest.fingerprint"));
  ASSERT_THAT(copied_files,
              testing::UnorderedElementsAre(
                  "imageloader.json", "imageloader.sig.1", "table",
                  "image.squash", "manifest.fingerprint"));
  EXPECT_TRUE(
      CompareFileContents(GetTestComponentPath(), copied_dir, copied_files));
}

TEST_F(ComponentTest, IsValidFingerprintFile) {
  const std::string valid_manifest =
      "1.3464353b1ed78574e05f3ffe84b52582572b2fe7202f3824a3761e54ace8bb1";
  EXPECT_TRUE(Component::IsValidFingerprintFile(valid_manifest));

  const std::string invalid_unicode_manifest = "Ё Ђ Ѓ Є Ѕ І Ї Ј Љ ";
  EXPECT_FALSE(Component::IsValidFingerprintFile(invalid_unicode_manifest));

  EXPECT_FALSE(Component::IsValidFingerprintFile("\x49\x34\x19-43.*+abc"));
}

TEST_F(ComponentTest, InitComponentWithBadFiles) {
  EXPECT_TRUE(
      TestInitComponentWithCorruptFile("bad-component1", "imageloader.json"));
  EXPECT_TRUE(
      TestInitComponentWithCorruptFile("bad-component2", "imageloader.sig.1"));
}

// Now corrupt the manifest of an already initialized component to verify that
// the copy operation fails.
TEST_F(ComponentTest, CopyWithBadFiles) {
  EXPECT_TRUE(TestCopyWithCorruptFile("bad-component1", "image.squash"));
  EXPECT_TRUE(TestCopyWithCorruptFile("bad-component2", "table"));
  EXPECT_TRUE(
      TestCopyWithCorruptFile("bad-component3", "manifest.fingerprint"));
}

TEST_F(ComponentTest, CopyValidImage) {
  const int image_size = 4096 * 4;

  base::FilePath image_path = temp_dir_.Append("image");
  std::vector<char> image(image_size,
                          0xBB);  // large enough to test streaming read.
  ASSERT_EQ(image_size,
            base::WriteFile(image_path, image.data(), image.size()));

  std::vector<uint8_t> hash(crypto::kSHA256Length);

  std::unique_ptr<crypto::SecureHash> sha256(
      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
  sha256->Update(image.data(), image.size());
  sha256->Finish(hash.data(), hash.size());

  Component component(GetTestComponentPath(), 1);
  base::FilePath image_dest = temp_dir_.Append("image.copied");
  ASSERT_TRUE(component.CopyComponentFile(image_path, image_dest, hash));

  // Check if the image file actually exists and has the correct contents.
  std::string resulting_image;
  ASSERT_TRUE(base::ReadFileToStringWithMaxSize(image_dest, &resulting_image,
                                                image_size));

  EXPECT_EQ(0, memcmp(image.data(), resulting_image.data(), image_size));
}

}  // namespace imageloader
