// Copyright 2014 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 "cryptohome/platform.h"

#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/xattr.h>

#include <linux/fs.h>

#include <fcntl.h>
#include <string>

#include <base/files/file.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

using base::FilePath;

namespace cryptohome {

class PlatformTest : public ::testing::Test {
 public:
  virtual ~PlatformTest() {}
 protected:
  std::string GetRandomSuffix() {
    return platform_.GetRandomSuffix();
  }
  FilePath GetTempName() {
    FilePath temp_directory;
    EXPECT_TRUE(base::GetTempDir(&temp_directory));
    return temp_directory.Append(GetRandomSuffix());
  }

  Platform platform_;
};

TEST_F(PlatformTest, DataSyncFileHasSaneReturnCodes) {
  const FilePath filename(GetTempName());
  const FilePath dirname(GetTempName());
  platform_.CreateDirectory(dirname);
  EXPECT_FALSE(platform_.DataSyncFile(dirname));
  EXPECT_FALSE(platform_.DataSyncFile(filename));
  EXPECT_TRUE(platform_.WriteStringToFile(filename, "bla"));
  EXPECT_TRUE(platform_.DataSyncFile(filename));
  platform_.DeleteFile(filename, false /* recursive */);
  platform_.DeleteFile(dirname, true /* recursive */);
}

TEST_F(PlatformTest, SyncFileHasSaneReturnCodes) {
  const FilePath filename(GetTempName());
  const FilePath dirname(GetTempName());
  platform_.CreateDirectory(dirname);
  EXPECT_FALSE(platform_.SyncFile(dirname));
  EXPECT_FALSE(platform_.SyncFile(filename));
  EXPECT_TRUE(platform_.WriteStringToFile(filename, "bla"));
  EXPECT_TRUE(platform_.SyncFile(filename));
  platform_.DeleteFile(filename, false /* recursive */);
  platform_.DeleteFile(dirname, true /* recursive */);
}

TEST_F(PlatformTest, SyncDirectoryHasSaneReturnCodes) {
  const FilePath filename(GetTempName());
  const FilePath dirname(GetTempName());
  platform_.WriteStringToFile(filename, "bla");
  EXPECT_FALSE(platform_.SyncDirectory(filename));
  EXPECT_FALSE(platform_.SyncDirectory(dirname));
  EXPECT_TRUE(platform_.CreateDirectory(dirname));
  EXPECT_TRUE(platform_.SyncDirectory(dirname));
  platform_.DeleteFile(filename, false /* recursive */);
  platform_.DeleteFile(dirname, true /* recursive */);
}

TEST_F(PlatformTest, HasExtendedFileAttribute) {
  const FilePath filename(GetTempName());
  const std::string content("blablabla");
  ASSERT_TRUE(platform_.WriteStringToFile(filename, content));
  const std::string name("user.foo");
  const std::string value("bar");

  ASSERT_EQ(0, setxattr(filename.value().c_str(), name.c_str(), value.c_str(),
                        value.length(), 0));

  EXPECT_TRUE(platform_.HasExtendedFileAttribute(filename, name));

  EXPECT_FALSE(platform_.HasExtendedFileAttribute(
        FilePath("file_not_exist"), name));
  EXPECT_FALSE(platform_.HasExtendedFileAttribute(
        filename, "user.name_not_exist"));
  platform_.DeleteFile(filename, false /* recursive */);
}

TEST_F(PlatformTest, ListExtendedFileAttribute) {
  const FilePath filename(GetTempName());
  const std::string content("blablabla");
  ASSERT_TRUE(platform_.WriteStringToFile(filename, content));
  const std::string name("user.foo");
  const std::string value("bar");
  const std::string name2("user.foo2");
  const std::string value2("bar2");

  ASSERT_EQ(0,
            setxattr(filename.value().c_str(),
                     name.c_str(),
                     value.c_str(),
                     value.length(),
                     0));
  ASSERT_EQ(0,
            setxattr(filename.value().c_str(),
                     name2.c_str(),
                     value2.c_str(),
                     value2.length(),
                     0));

  std::vector<std::string> attrs;

  EXPECT_TRUE(platform_.ListExtendedFileAttributes(filename, &attrs));
  EXPECT_THAT(attrs, testing::UnorderedElementsAre(name, name2));

  attrs.clear();
  EXPECT_FALSE(
      platform_.ListExtendedFileAttributes(FilePath("file_not_exist"), &attrs));
  EXPECT_TRUE(attrs.empty());
  platform_.DeleteFile(filename, false /* recursive */);
}

TEST_F(PlatformTest, GetExtendedAttributeAsString) {
  const FilePath filename(GetTempName());
  const std::string content("blablabla");
  ASSERT_TRUE(platform_.WriteStringToFile(filename, content));
  const std::string name("user.foo");
  const std::string value("bar");

  ASSERT_EQ(0,
            setxattr(filename.value().c_str(),
                     name.c_str(),
                     value.c_str(),
                     value.length(),
                     0));

  std::string got;
  EXPECT_TRUE(platform_.GetExtendedFileAttributeAsString(filename, name, &got));
  EXPECT_EQ(value, got);

  EXPECT_FALSE(platform_.GetExtendedFileAttributeAsString(
      FilePath("file_not_exist"), name, &got));
  EXPECT_FALSE(platform_.GetExtendedFileAttributeAsString(
      filename, "user.name_not_exist", &got));
  platform_.DeleteFile(filename, false /* recursive */);
}

TEST_F(PlatformTest, GetExtendedAttribute) {
  const FilePath filename(GetTempName());
  const std::string content("blablabla");
  ASSERT_TRUE(platform_.WriteStringToFile(filename, content));
  const std::string name("user.foo");
  const int value = 42;

  ASSERT_EQ(
      0,
      setxattr(
          filename.value().c_str(), name.c_str(), &value, sizeof(value), 0));

  int got;
  EXPECT_TRUE(platform_.GetExtendedFileAttribute(
      filename, name, reinterpret_cast<char*>(&got), sizeof(got)));
  EXPECT_EQ(value, got);

  EXPECT_FALSE(platform_.GetExtendedFileAttribute(FilePath("file_not_exist"),
                                                  name,
                                                  reinterpret_cast<char*>(&got),
                                                  sizeof(got)));
  EXPECT_FALSE(platform_.GetExtendedFileAttribute(filename,
                                                  "user.name_not_exist",
                                                  reinterpret_cast<char*>(&got),
                                                  sizeof(got)));
  EXPECT_FALSE(platform_.GetExtendedFileAttribute(
      filename, name, reinterpret_cast<char*>(&got), sizeof(got) - 1));
  EXPECT_FALSE(platform_.GetExtendedFileAttribute(
      filename, name, reinterpret_cast<char*>(&got), sizeof(got) + 1));
  platform_.DeleteFile(filename, false /* recursive */);
}

TEST_F(PlatformTest, SetExtendedAttribute) {
  const FilePath filename(GetTempName());
  const std::string content("blablabla");
  ASSERT_TRUE(platform_.WriteStringToFile(filename, content));
  const std::string name("user.foo");
  std::string value("bar");
  EXPECT_TRUE(platform_.SetExtendedFileAttribute(
      filename, name, value.c_str(), value.length()));

  std::vector<char> got(value.length());
  EXPECT_EQ(
      value.length(),
      getxattr(
          filename.value().c_str(), name.c_str(), got.data(), value.length()));

  EXPECT_EQ(value, std::string(got.data(), got.size()));

  EXPECT_FALSE(platform_.SetExtendedFileAttribute(
      FilePath("file_not_exist"), name, value.c_str(), sizeof(value)));
  platform_.DeleteFile(filename, false /* recursive */);
}

TEST_F(PlatformTest, RemoveExtendedAttribute) {
  const FilePath filename(GetTempName());
  const std::string content("blablabla");
  ASSERT_TRUE(platform_.WriteStringToFile(filename, content));
  const std::string name("user.foo");
  std::string value("bar");
  ASSERT_EQ(0,
            setxattr(filename.value().c_str(),
                     name.c_str(),
                     value.c_str(),
                     value.length(),
                     0));
  EXPECT_TRUE(platform_.RemoveExtendedFileAttribute(filename, name));
  EXPECT_EQ(-1, getxattr(filename.value().c_str(), name.c_str(), nullptr, 0));
  EXPECT_EQ(ENODATA, errno);

  EXPECT_FALSE(
      platform_.RemoveExtendedFileAttribute(FilePath("file_not_exist"), name));
  EXPECT_FALSE(
      platform_.RemoveExtendedFileAttribute(filename, "attribute_not_exist"));
  platform_.DeleteFile(filename, false /* recursive */);
}

TEST_F(PlatformTest, GetExtFileAttributes) {
  const FilePath filename(GetTempName());
  const std::string content("blablabla");
  ASSERT_TRUE(platform_.WriteStringToFile(filename, content));

  int fd;
  ASSERT_GT(fd = HANDLE_EINTR(open(filename.value().c_str(), O_RDONLY)), 0);
  int flags = FS_UNRM_FL | FS_NODUMP_FL;
  ASSERT_GE(ioctl(fd, FS_IOC_SETFLAGS, &flags), 0);

  int got;
  EXPECT_TRUE(platform_.GetExtFileAttributes(filename, &got));
  EXPECT_EQ(flags, got);
  close(fd);
  platform_.DeleteFile(filename, false /* recursive */);
}

TEST_F(PlatformTest, SetExtFileAttributes) {
  const FilePath filename(GetTempName());
  const std::string content("blablabla");
  ASSERT_TRUE(platform_.WriteStringToFile(filename, content));

  int flags = FS_UNRM_FL | FS_NODUMP_FL;
  EXPECT_TRUE(platform_.SetExtFileAttributes(filename, flags));

  int fd;
  ASSERT_GT(fd = HANDLE_EINTR(open(filename.value().c_str(), O_RDONLY)), 0);
  int new_flags;
  ASSERT_GE(ioctl(fd, FS_IOC_GETFLAGS, &new_flags), 0);

  EXPECT_EQ(flags, new_flags);
  close(fd);
  platform_.DeleteFile(filename, false /* recursive */);
}

TEST_F(PlatformTest, HasNoDumpFileAttribute) {
  const FilePath filename(GetTempName());
  const std::string content("blablabla");
  ASSERT_TRUE(platform_.WriteStringToFile(filename, content));

  EXPECT_FALSE(platform_.HasNoDumpFileAttribute(filename));

  int fd;
  ASSERT_GT(fd = open(filename.value().c_str(), O_RDONLY), 0);
  int flags = FS_UNRM_FL | FS_NODUMP_FL;
  ASSERT_GE(ioctl(fd, FS_IOC_SETFLAGS, &flags), 0);

  EXPECT_TRUE(platform_.HasNoDumpFileAttribute(filename));
  close(fd);
  platform_.DeleteFile(filename, false /* recursive */);
}

TEST_F(PlatformTest, ReadMountInfoFileGood) {
  const base::FilePath mount_info(GetTempName());
  std::string mount_info_contents;

  mount_info_contents.append("73 24 179:1 /beg/uid1/mount/user ");
  mount_info_contents.append("/home/user/uid1 rw,nodev,relatime - ext4 ");
  mount_info_contents.append("/dev/mmcblk0p1 rw,commit=600,data=ordered");

  EXPECT_TRUE(platform_.WriteStringToFile(mount_info, mount_info_contents));
  platform_.set_mount_info_path(mount_info);

  std::vector<DecodedProcMountInfo> decoded_info =
      platform_.ReadMountInfoFile();
  EXPECT_EQ(decoded_info.size(), 1);
  EXPECT_EQ(decoded_info[0].root, "/beg/uid1/mount/user");
  EXPECT_EQ(decoded_info[0].mount_point, "/home/user/uid1");
  EXPECT_EQ(decoded_info[0].filesystem_type, "ext4");
  EXPECT_EQ(decoded_info[0].mount_source, "/dev/mmcblk0p1");
}

TEST_F(PlatformTest, ReadMountInfoFileCorruptedMountInfo) {
  const base::FilePath mount_info(GetTempName());
  std::string mount_info_contents;

  mount_info_contents.append("73 24 179:1 /beg/uid1/mount/user ");
  mount_info_contents.append("/home/user/uid1 rw,nodev,relatime hypen ext4 ");
  mount_info_contents.append("/dev/mmcblk0p1 rw,commit=600,data=ordered");

  EXPECT_TRUE(platform_.WriteStringToFile(mount_info, mount_info_contents));
  platform_.set_mount_info_path(mount_info);

  std::vector<DecodedProcMountInfo> decoded_info =
      platform_.ReadMountInfoFile();
  EXPECT_EQ(decoded_info.size(), 0);
}

TEST_F(PlatformTest, ReadMountInfoFileIncompleteMountInfo) {
  const base::FilePath mount_info(GetTempName());
  std::string mount_info_contents;

  mount_info_contents.append("73 24 179:1 /beg/uid1/mount/user ");

  EXPECT_TRUE(platform_.WriteStringToFile(mount_info, mount_info_contents));
  platform_.set_mount_info_path(mount_info);

  std::vector<DecodedProcMountInfo> decoded_info =
      platform_.ReadMountInfoFile();
  EXPECT_EQ(decoded_info.size(), 0);
}

TEST_F(PlatformTest, GetLoopDeviceMounts) {
  const base::FilePath mount_info(GetTempName());
  std::string mount_info_contents;

  mount_info_contents.append("73 24 179:1 /beg/uid1/mount/user ");
  mount_info_contents.append("/home/root/uid1 rw,nodev,relatime - ext4 ");
  mount_info_contents.append("/dev/loop7 rw,commit=600,data=ordered\n");
  mount_info_contents.append("73 24 179:1 /beg/uid1/mount/user ");
  mount_info_contents.append("/home/root/uid1 rw,nodev,relatime - ext4 ");
  mount_info_contents.append("/dev/mmcblk0p1 rw,commit=600,data=ordered\n");
  mount_info_contents.append("73 24 179:1 /beg/uid1/mount/user ");
  mount_info_contents.append("/home/user/uid2 rw,nodev,relatime - ext4 ");
  mount_info_contents.append("/dev/loop6 rw,commit=600,data=ordered\n");

  EXPECT_TRUE(platform_.WriteStringToFile(mount_info, mount_info_contents));

  platform_.set_mount_info_path(mount_info);

  std::multimap<const FilePath, const FilePath> mounts;
  EXPECT_TRUE(platform_.GetLoopDeviceMounts(&mounts));
  ASSERT_EQ(mounts.size(), 2);
  auto it = mounts.begin();
  EXPECT_EQ(it->first.value(), "/dev/loop6");
  EXPECT_EQ(it->second.value(), "/home/user/uid2");
  ++it;
  EXPECT_EQ(it->first.value(), "/dev/loop7");
  EXPECT_EQ(it->second.value(), "/home/root/uid1");

  /* Clean up. */
  EXPECT_TRUE(base::DeleteFile(mount_info, false));
}

TEST_F(PlatformTest, GetMountsBySourcePrefixExt4) {
  base::FilePath mount_info;
  FILE *fp;
  std::string filesystem, device_in, device_out, mount_info_contents;

  mount_info_contents.append("73 24 179:1 /beg/uid1/mount/user ");
  mount_info_contents.append("/home/user/uid1 rw,nodev,relatime - ext4 ");
  mount_info_contents.append("/dev/mmcblk0p1 rw,commit=600,data=ordered");

  fp = base::CreateAndOpenTemporaryFile(&mount_info);
  ASSERT_TRUE(fp != NULL);
  EXPECT_EQ(fwrite(mount_info_contents.c_str(),
            mount_info_contents.length(), 1, fp), 1);
  EXPECT_EQ(fclose(fp), 0);

  platform_.set_mount_info_path(mount_info);

  /* Fails if item is missing. */
  std::multimap<const FilePath, const FilePath> mounts;
  EXPECT_FALSE(platform_.GetMountsBySourcePrefix(FilePath("monkey"), &mounts));

  /* Works normally. */
  mounts.clear();
  EXPECT_TRUE(platform_.GetMountsBySourcePrefix(FilePath("/beg"), &mounts));
  EXPECT_EQ(mounts.size(), 1);
  auto it = mounts.begin();
  EXPECT_EQ(it->first.value(), "/beg/uid1/mount/user");
  EXPECT_EQ(it->second.value(), "/home/user/uid1");

  /* Clean up. */
  EXPECT_TRUE(base::DeleteFile(mount_info, false));
}

TEST_F(PlatformTest, GetMountsBySourcePrefixECryptFs) {
  base::FilePath mount_info;
  FILE *fp;
  std::string filesystem, device_in, device_out, mount_info_contents;

  mount_info_contents.append("84 24 0:29 /user /home/user/uid2 ");
  mount_info_contents.append("rw,nosuid,nodev,noexec,relatime - ecryptfs ");
  mount_info_contents.append("/beg/uid2/vault rw,ecryp...");

  fp = base::CreateAndOpenTemporaryFile(&mount_info);
  ASSERT_TRUE(fp != NULL);
  EXPECT_EQ(fwrite(mount_info_contents.c_str(),
            mount_info_contents.length(), 1, fp), 1);
  EXPECT_EQ(fclose(fp), 0);

  platform_.set_mount_info_path(mount_info);

  /* Fails if item is missing. */
  std::multimap<const FilePath, const FilePath> mounts;
  EXPECT_FALSE(platform_.GetMountsBySourcePrefix(FilePath("monkey"), &mounts));

  /* Works normally. */
  mounts.clear();
  EXPECT_TRUE(platform_.GetMountsBySourcePrefix(FilePath("/beg"), &mounts));
  EXPECT_EQ(mounts.size(), 1);
  auto it = mounts.begin();
  EXPECT_EQ(it->first.value(), "/beg/uid2/vault");
  EXPECT_EQ(it->second.value(), "/home/user/uid2");

  /* Clean up. */
  EXPECT_TRUE(base::DeleteFile(mount_info, false));
}

TEST_F(PlatformTest, CreateSymbolicLink) {
  const base::FilePath link(GetTempName());
  const base::FilePath target(GetTempName());
  const base::FilePath existing_file(GetTempName());
  ASSERT_TRUE(platform_.TouchFileDurable(existing_file));
  EXPECT_TRUE(platform_.CreateSymbolicLink(link, target));
  EXPECT_FALSE(platform_.CreateSymbolicLink(existing_file, target));
  base::FilePath read_target;
  ASSERT_TRUE(base::ReadSymbolicLink(link, &read_target));
  EXPECT_EQ(target.value(), read_target.value());
}

TEST_F(PlatformTest, ReadLink) {
  const base::FilePath valid_link(GetTempName());
  const base::FilePath not_link(GetTempName());
  const base::FilePath target(GetTempName());
  ASSERT_TRUE(base::CreateSymbolicLink(target, valid_link));
  ASSERT_TRUE(platform_.TouchFileDurable(not_link));
  base::FilePath read_target;
  EXPECT_TRUE(platform_.ReadLink(valid_link, &read_target));
  EXPECT_EQ(target.value(), read_target.value());
  EXPECT_FALSE(platform_.ReadLink(not_link, &read_target));
}

TEST_F(PlatformTest, SetFileTimes) {
  struct timespec atime1 = {123, 45};
  struct timespec mtime1 = {234, 56};
  struct timespec atime2 = {345, 67};
  struct timespec mtime2 = {456, 78};
  const base::FilePath regular_file(GetTempName());
  const base::FilePath link(GetTempName());
  ASSERT_TRUE(platform_.TouchFileDurable(regular_file));
  ASSERT_TRUE(platform_.CreateSymbolicLink(link, regular_file));

  EXPECT_TRUE(platform_.SetFileTimes(regular_file, atime1, mtime1, true));
  struct stat stat;
  ASSERT_TRUE(platform_.Stat(regular_file, &stat));
  EXPECT_EQ(atime1.tv_sec, stat.st_atim.tv_sec);
  EXPECT_EQ(atime1.tv_nsec, stat.st_atim.tv_nsec);
  EXPECT_EQ(mtime1.tv_sec, stat.st_mtim.tv_sec);
  EXPECT_EQ(mtime1.tv_nsec, stat.st_mtim.tv_nsec);

  EXPECT_TRUE(platform_.SetFileTimes(link, atime2, mtime2, true));
  ASSERT_TRUE(platform_.Stat(regular_file, &stat));
  EXPECT_EQ(atime2.tv_sec, stat.st_atim.tv_sec);
  EXPECT_EQ(atime2.tv_nsec, stat.st_atim.tv_nsec);
  EXPECT_EQ(mtime2.tv_sec, stat.st_mtim.tv_sec);
  EXPECT_EQ(mtime2.tv_nsec, stat.st_mtim.tv_nsec);
  ASSERT_TRUE(platform_.Stat(link, &stat));
  EXPECT_NE(atime2.tv_sec, stat.st_atim.tv_sec);
  EXPECT_NE(atime2.tv_nsec, stat.st_atim.tv_nsec);
  EXPECT_NE(mtime2.tv_sec, stat.st_mtim.tv_sec);
  EXPECT_NE(mtime2.tv_nsec, stat.st_mtim.tv_nsec);
}

TEST_F(PlatformTest, SendFile) {
  const base::FilePath from(GetTempName());
  const base::FilePath to(GetTempName());
  const std::string contents = "0123456789";
  ASSERT_TRUE(platform_.WriteStringToFile(from, contents));

  const int offset = 5;
  const int read_size = contents.length() - offset;
  base::File from_file(from, base::File::FLAG_OPEN | base::File::FLAG_READ);
  base::File to_file(to, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
  EXPECT_TRUE(platform_.SendFile(to_file.GetPlatformFile(),
                                 from_file.GetPlatformFile(),
                                 offset, read_size));
  std::string to_contents;
  ASSERT_TRUE(platform_.ReadFileToString(to, &to_contents));
  EXPECT_EQ(contents.substr(offset, read_size), to_contents);

  EXPECT_FALSE(platform_.SendFile(-1, from_file.GetPlatformFile(), offset,
                                  read_size));
  EXPECT_FALSE(platform_.SendFile(to_file.GetPlatformFile(),
                                  from_file.GetPlatformFile(),
                                  offset, read_size + 1));
  platform_.DeleteFile(from, false /* recursive */);
  platform_.DeleteFile(to, false /* recursive */);
}

TEST_F(PlatformTest, CreateSparseFile) {
  const base::FilePath sparse_name(GetTempName());
  size_t file_size = 1024 * 32;
  EXPECT_TRUE(platform_.CreateSparseFile(sparse_name, file_size));
  base::File sparse_file(sparse_name,
                         base::File::FLAG_OPEN | base::File::FLAG_READ);
  EXPECT_EQ(file_size, sparse_file.GetLength());
  struct stat stat;
  EXPECT_TRUE(platform_.Stat(sparse_name, &stat));
  // No blocks allocated for a sparse file.
  EXPECT_EQ(0, stat.st_blocks);
  platform_.DeleteFile(sparse_name, false /* recursive */);
}

}  // namespace cryptohome
