// Copyright 2017 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 "biod/biod_storage.h"

#include <sys/resource.h>

#include <algorithm>
#include <memory>
#include <unordered_set>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/check.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <testing/gtest/include/gtest/gtest.h>
#include <base/strings/string_util.h>
#include <base/files/important_file_writer.h>
#include <base/json/json_string_value_serializer.h>

namespace biod {

namespace {

const char kBiometricsManagerName[] = "BiometricsManager";

const base::FilePath kFilePath("TestFile");

constexpr int kInvalidRecordFormatVersion = -1;

const char kRecordId1[] = "00000000_0000_0000_0000_000000000001";
const char kUserId1[] = "0000000000000000000000000000000000000001";
const char kLabel1[] = "record1";
const std::vector<uint8_t> kValidationVal1 = {0x00, 0x01};
const char kData1[] = "Hello, world1!";

const char kRecordId2[] = "00000000_0000_0000_0000_000000000002";
const char kUserId2[] = "0000000000000000000000000000000000000002";
const char kLabel2[] = "record2";
const std::vector<uint8_t> kValidationVal2 = {0x00, 0x02};
const char kData2[] = "Hello, world2!";

const char kRecordId3[] = "00000000_0000_0000_0000_000000000003";
const char kLabel3[] = "record3";
const std::vector<uint8_t> kValidationVal3 = {0x00, 0x03};
const char kData3[] = "Hello, world3!";

constexpr int kPermissions600 =
    base::FILE_PERMISSION_READ_BY_USER | base::FILE_PERMISSION_WRITE_BY_USER;
constexpr int kPermissions700 = base::FILE_PERMISSION_USER_MASK;

const char kInvalidUTF8[] = "\xed\xa0\x80\xed\xbf\xbf";

constexpr int kFpc1145TemplateSizeBytes = 47616;
constexpr int kFpc1025TemplateSizeBytes = 5156;
constexpr int kElan80TemplateSizeBytes = 41024;
constexpr int kElan515TemplateSizeBytes = 67064;

/**
 * "Max locked memory" value from reading /proc/<PID>/limits on DUT
 *
 * This matches the default value in the kernel:
 * https://chromium.googlesource.com/chromiumos/third_party/kernel/+/a5746cdefaed35de0a85ede48a47e9a340a6f7e6/include/uapi/linux/resource.h#72
 *
 * The default can be overridden in /etc/security/limits.conf:
 * https://access.redhat.com/solutions/61334
 *
 * or in the upstart script http://upstart.ubuntu.com/cookbook/#limit:
 *
 * limit memlock <soft> <hard>
 */
constexpr int kRlimitMemlockBytes = 65536;

// Flag to control whether to run tests with positive match secret support.
// This can't be a member of the test fixture because it's accessed in the
// TestRecord class in anonymous namespace.
bool test_record_supports_positive_match_secret = true;

class TestRecord : public BiometricsManagerRecord {
 public:
  TestRecord(const std::string& id,
             const std::string& user_id,
             const std::string& label,
             const std::vector<uint8_t>& validation_val,
             const std::string& data)
      : id_(id),
        user_id_(user_id),
        label_(label),
        validation_val_(validation_val),
        data_(data) {}

  // BiometricsManager::Record overrides:
  const std::string& GetId() const override { return id_; }
  const std::string& GetUserId() const override { return user_id_; }
  const std::string& GetLabel() const override { return label_; }
  const std::vector<uint8_t>& GetValidationVal() const override {
    return validation_val_;
  }
  const std::string& GetData() const { return data_; }
  bool SetLabel(std::string label) override { return true; }
  bool Remove() override { return true; }
  bool SupportsPositiveMatchSecret() const override {
    return test_record_supports_positive_match_secret;
  }

  void ClearValidationValue() { validation_val_.clear(); }

  friend bool operator==(const TestRecord& lhs, const TestRecord& rhs) {
    return lhs.id_ == rhs.id_ && lhs.user_id_ == rhs.user_id_ &&
           lhs.validation_val_ == rhs.validation_val_ &&
           lhs.label_ == rhs.label_ && lhs.data_ == rhs.data_;
  }
  friend inline bool operator!=(const TestRecord& lhs, const TestRecord& rhs) {
    return !(lhs == rhs);
  }

 private:
  std::string id_;
  std::string user_id_;
  std::string label_;
  std::vector<uint8_t> validation_val_;
  std::string data_;
};

struct MemlockTestParams {
  int rlimit_bytes;
  int template_size_bytes;
};

}  // namespace

class BiodStorageBaseTest : public ::testing::Test {
 public:
  BiodStorageBaseTest() {
    CHECK(temp_dir_.CreateUniqueTempDir());
    root_path_ = temp_dir_.GetPath().AppendASCII("biod_storage_unittest_root");
    biod_storage_ = std::make_unique<BiodStorage>(kBiometricsManagerName);
    // Since there is no session manager, allow accesses by default.
    biod_storage_->set_allow_access(true);
    biod_storage_->SetRootPathForTesting(root_path_);
  }
  BiodStorageBaseTest(const BiodStorageBaseTest&) = delete;
  BiodStorageBaseTest& operator=(const BiodStorageBaseTest&) = delete;

  ~BiodStorageBaseTest() override {
    EXPECT_TRUE(base::DeletePathRecursively(temp_dir_.GetPath()));
  }

  base::Value CreateRecordDictionary(
      const std::vector<uint8_t>& validation_val) {
    base::Value record_dictionary(base::Value::Type::DICTIONARY);
    std::string validation_value_str(validation_val.begin(),
                                     validation_val.end());
    base::Base64Encode(validation_value_str, &validation_value_str);
    record_dictionary.SetStringKey("match_validation_value",
                                   validation_value_str);
    return record_dictionary;
  }

 protected:
  base::ScopedTempDir temp_dir_;
  base::FilePath root_path_;
  std::unique_ptr<BiodStorage> biod_storage_;
};

class BiodStorageTest : public BiodStorageBaseTest,
                        public ::testing::WithParamInterface<bool> {
 public:
  BiodStorageTest() { test_record_supports_positive_match_secret = GetParam(); }
};

TEST_P(BiodStorageTest, WriteAndReadRecords) {
  const std::vector<uint8_t> kEmpty;
  const std::vector<TestRecord> kRecords = {
      TestRecord(
          kRecordId1, kUserId1, kLabel1,
          test_record_supports_positive_match_secret ? kValidationVal1 : kEmpty,
          kData1),
      TestRecord(
          kRecordId2, kUserId2, kLabel2,
          test_record_supports_positive_match_secret ? kValidationVal2 : kEmpty,
          kData2),
      TestRecord(
          kRecordId3, kUserId2, kLabel3,
          test_record_supports_positive_match_secret ? kValidationVal3 : kEmpty,
          kData3)};

  // Write the record.
  for (auto const& record : kRecords) {
    EXPECT_TRUE(
        biod_storage_->WriteRecord(record, base::Value(record.GetData())));
  }

  // Read the record.
  std::unordered_set<std::string> user_ids({kUserId1, kUserId2});
  auto read_result = biod_storage_->ReadRecords(user_ids);
  EXPECT_TRUE(read_result.invalid_records.empty());

  std::vector<TestRecord> records;
  for (const auto& record : read_result.valid_records) {
    records.emplace_back(
        TestRecord(record.metadata.record_id, record.metadata.user_id,
                   record.metadata.label, record.metadata.validation_val,
                   std::string(record.data.cbegin(), record.data.cend())));
  }
  EXPECT_EQ(records.size(), kRecords.size());
  EXPECT_TRUE(
      std::is_permutation(kRecords.begin(), kRecords.end(), records.begin()));
}

TEST_F(BiodStorageBaseTest, WriteRecord_InvalidAbsolutePath) {
  auto record =
      TestRecord(kRecordId1, "/absolutepath", kLabel1, kValidationVal1, kData1);

  EXPECT_FALSE(
      biod_storage_->WriteRecord(record, base::Value(record.GetData())));
}

TEST_F(BiodStorageBaseTest, WriteRecord_RecordIdNotUTF8) {
  EXPECT_FALSE(base::IsStringUTF8(kInvalidUTF8));

  auto record =
      TestRecord(kInvalidUTF8, kUserId1, kLabel1, kValidationVal1, kData1);

  EXPECT_FALSE(record.IsValidUTF8());
  EXPECT_FALSE(
      biod_storage_->WriteRecord(record, base::Value(record.GetData())));
}

TEST_F(BiodStorageBaseTest, WriteRecord_UserIdNotUTF8) {
  EXPECT_FALSE(base::IsStringUTF8(kInvalidUTF8));

  auto record =
      TestRecord(kRecordId1, kInvalidUTF8, kLabel1, kValidationVal1, kData1);

  EXPECT_FALSE(record.IsValidUTF8());
  EXPECT_FALSE(
      biod_storage_->WriteRecord(record, base::Value(record.GetData())));
}

TEST_F(BiodStorageBaseTest, WriteRecord_LabelNotUTF8) {
  EXPECT_FALSE(base::IsStringUTF8(kInvalidUTF8));

  auto record =
      TestRecord(kRecordId1, kUserId1, kInvalidUTF8, kValidationVal1, kData1);

  EXPECT_FALSE(record.IsValidUTF8());
  EXPECT_FALSE(
      biod_storage_->WriteRecord(record, base::Value(record.GetData())));
}

TEST_F(BiodStorageBaseTest, WriteRecord_CheckUmask) {
  auto record =
      TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1);

  const base::FilePath kRecordStorageFilename =
      root_path_.Append("biod")
          .Append(record.GetUserId())
          .Append(kBiometricsManagerName)
          .Append("Record" + record.GetId());

  ASSERT_FALSE(base::PathExists(kRecordStorageFilename));
  ASSERT_FALSE(base::PathExists(kRecordStorageFilename.DirName()));

  EXPECT_TRUE(
      biod_storage_->WriteRecord(record, base::Value(record.GetData())));

  // Check permissions of directory
  int actual_permissions;
  EXPECT_TRUE(base::GetPosixFilePermissions(kRecordStorageFilename.DirName(),
                                            &actual_permissions));
  EXPECT_EQ(kPermissions700, actual_permissions);

  // Check permissions of record
  EXPECT_TRUE(base::GetPosixFilePermissions(kRecordStorageFilename,
                                            &actual_permissions));
  EXPECT_EQ(kPermissions600, actual_permissions);
}

TEST_P(BiodStorageTest, DeleteRecord) {
  const std::vector<uint8_t> kEmpty;
  const TestRecord kRecord(
      kRecordId1, kUserId1, kLabel1,
      test_record_supports_positive_match_secret ? kValidationVal1 : kEmpty,
      kData1);

  // Delete a non-existent record.
  EXPECT_TRUE(biod_storage_->DeleteRecord(kUserId1, kRecordId1));

  EXPECT_TRUE(
      biod_storage_->WriteRecord(kRecord, base::Value(kRecord.GetData())));

  // Check this record is properly written.
  std::unordered_set<std::string> user_ids({kUserId1});
  auto read_result = biod_storage_->ReadRecords(user_ids);
  EXPECT_TRUE(read_result.invalid_records.empty());
  EXPECT_EQ(read_result.valid_records.size(), 1);
  const auto& record = read_result.valid_records[0];
  auto test_record =
      TestRecord(record.metadata.record_id, record.metadata.user_id,
                 record.metadata.label, record.metadata.validation_val,
                 std::string(record.data.cbegin(), record.data.cend()));
  EXPECT_EQ(test_record, kRecord);

  EXPECT_TRUE(biod_storage_->DeleteRecord(kUserId1, kRecordId1));

  // Check this record is properly deleted.
  read_result = biod_storage_->ReadRecords(user_ids);
  EXPECT_TRUE(read_result.valid_records.empty());
  EXPECT_TRUE(read_result.invalid_records.empty());
}

TEST_F(BiodStorageBaseTest, GenerateNewRecordId) {
  // Check the two record ids are different.
  std::string record_id1(biod_storage_->GenerateNewRecordId());
  std::string record_id2(biod_storage_->GenerateNewRecordId());
  EXPECT_NE(record_id1, record_id2);
}

TEST_F(BiodStorageBaseTest, TestEqualOperator) {
  EXPECT_EQ(TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1),
            TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1));

  EXPECT_NE(TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1),
            TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal2, kData1));
}

TEST_F(BiodStorageBaseTest, TestReadValidationValueFromRecord) {
  auto record_dictionary = CreateRecordDictionary(kValidationVal1);
  auto ret = biod_storage_->ReadValidationValueFromRecord(
      kRecordFormatVersion, record_dictionary, kFilePath);
  EXPECT_TRUE(ret != nullptr);
  EXPECT_EQ(*ret, kValidationVal1);
}

TEST_F(BiodStorageBaseTest, TestReadValidationValueFromRecordOldVersion) {
  auto record_dictionary = CreateRecordDictionary(kValidationVal1);
  std::vector<uint8_t> empty;
  auto ret = biod_storage_->ReadValidationValueFromRecord(
      kRecordFormatVersionNoValidationValue, record_dictionary, kFilePath);
  EXPECT_TRUE(ret != nullptr);
  EXPECT_EQ(*ret, empty);
}

TEST_F(BiodStorageBaseTest, TestReadValidationValueFromRecordInvalidVersion) {
  auto record_dictionary = CreateRecordDictionary(kValidationVal1);
  std::vector<uint8_t> empty;
  auto ret = biod_storage_->ReadValidationValueFromRecord(
      kInvalidRecordFormatVersion, record_dictionary, kFilePath);
  EXPECT_EQ(ret, nullptr);
}

INSTANTIATE_TEST_SUITE_P(RecordsSupportPositiveMatchSecret,
                         BiodStorageTest,
                         ::testing::Values(true, false));

/**
 * Tests for invalid records. In general records will be correctly formatted
 * since we follow a specific format when writing them, but we should be able
 * to handle invalid records from bugs, disk corruption, etc.
 */
class BiodStorageInvalidRecordTest : public ::testing::Test {
 public:
  BiodStorageInvalidRecordTest() {
    CHECK(temp_dir_.CreateUniqueTempDir());
    root_path_ = temp_dir_.GetPath().AppendASCII(
        "biod_storage_invalid_record_test_root");
    biod_storage_ = std::make_unique<BiodStorage>(kBiometricsManagerName);
    // Since there is no session manager, allow accesses by default.
    biod_storage_->set_allow_access(true);
    biod_storage_->SetRootPathForTesting(root_path_);

    auto record =
        TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1);
    record_name_ = biod_storage_->GetRecordFilename(record);
    EXPECT_FALSE(record_name_.empty());
    EXPECT_TRUE(base::CreateDirectory(record_name_.DirName()));
  }

 protected:
  base::ScopedTempDir temp_dir_;
  base::FilePath root_path_;
  base::FilePath record_name_;
  std::unique_ptr<BiodStorage> biod_storage_;
};

TEST_F(BiodStorageInvalidRecordTest, InvalidJSON) {
  EXPECT_TRUE(base::ImportantFileWriter::WriteFileAtomically(record_name_,
                                                             "this is not "
                                                             "JSON"));
  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.valid_records.size(), 0);
  EXPECT_EQ(read_result.invalid_records.size(), 1);
}

TEST_F(BiodStorageInvalidRecordTest, MissingFormatVersion) {
  auto record = R"({
    "record_id": "1234",
    "label": "some_label",
    "data": "some_data",
    "match_validation_value": "4567"
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.valid_records.size(), 0);
  EXPECT_EQ(read_result.invalid_records.size(), 1);
}

TEST_F(BiodStorageInvalidRecordTest, MissingRecordId) {
  auto record = R"({
    "label": "some_label",
    "data": "some_data",
    "match_validation_value": "4567",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.valid_records.size(), 0);
  EXPECT_EQ(read_result.invalid_records.size(), 1);
}

TEST_F(BiodStorageInvalidRecordTest, MissingRecordLabel) {
  auto record = R"({
    "record_id": "1234",
    "data": "some_data",
    "match_validation_value": "4567",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.valid_records.size(), 0);
  EXPECT_EQ(read_result.invalid_records.size(), 1);
}

TEST_F(BiodStorageInvalidRecordTest, MissingRecordData) {
  auto record = R"({
    "record_id": "1234",
    "label": "some_label",
    "match_validation_value": "4567",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.valid_records.size(), 0);
  EXPECT_EQ(read_result.invalid_records.size(), 1);
}

TEST_F(BiodStorageInvalidRecordTest, MissingValidationValue) {
  auto record = R"({
    "record_id": "1234",
    "label": "some_label",
    "data": "some_data",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.valid_records.size(), 0);
  EXPECT_EQ(read_result.invalid_records.size(), 1);
}

TEST_F(BiodStorageInvalidRecordTest, ValidationValueNotBase64) {
  auto record = R"({
    "record_id": "1234",
    "label": "some_label",
    "data": "some_data",
    "match_validation_value": "not valid base64",
    "version": 2
  })";

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));

  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.valid_records.size(), 0);
  EXPECT_EQ(read_result.invalid_records.size(), 1);
}

/**
 * Tests to make sure we do not crash due to hitting the RLIMIT_MEMLOCK limit.
 * See http://b/181281782, http://b/175158241, and http://b/173655013.
 */
class BiodStorageMemlockTest
    : public testing::TestWithParam<MemlockTestParams> {
 public:
  BiodStorageMemlockTest() : params_(GetParam()) {
    CHECK(temp_dir_.CreateUniqueTempDir());
    root_path_ =
        temp_dir_.GetPath().AppendASCII("biod_storage_memlock_test_root");
    biod_storage_ = std::make_unique<BiodStorage>(kBiometricsManagerName);
    // Since there is no session manager, allow accesses by default.
    biod_storage_->set_allow_access(true);
    biod_storage_->SetRootPathForTesting(root_path_);

    auto record =
        TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1);
    record_name_ = biod_storage_->GetRecordFilename(record);
    EXPECT_FALSE(record_name_.empty());
    EXPECT_TRUE(base::CreateDirectory(record_name_.DirName()));

    struct rlimit limit;

    EXPECT_EQ(getrlimit(RLIMIT_MEMLOCK, &limit), 0);
    orig_limit_ = limit;

    limit.rlim_cur = params_.rlimit_bytes;
    EXPECT_LT(limit.rlim_cur, limit.rlim_max);
    EXPECT_EQ(setrlimit(RLIMIT_MEMLOCK, &limit), 0);

    EXPECT_EQ(getrlimit(RLIMIT_MEMLOCK, &limit), 0);
    EXPECT_EQ(limit.rlim_cur, params_.rlimit_bytes);
  }

  ~BiodStorageMemlockTest() override {
    // Restore original limits.
    EXPECT_EQ(setrlimit(RLIMIT_MEMLOCK, &orig_limit_), 0);
  }

 protected:
  const MemlockTestParams params_;
  base::ScopedTempDir temp_dir_;
  base::FilePath root_path_;
  base::FilePath record_name_;
  std::unique_ptr<BiodStorage> biod_storage_;
  struct rlimit orig_limit_;
};

TEST_P(BiodStorageMemlockTest, ReadReadRecords) {
  base::Value record_value(base::Value::Type::DICTIONARY);
  record_value.SetStringKey("record_id", "1234");
  record_value.SetStringKey("label", "some_label");
  record_value.SetStringKey("match_validation_value", "4567");
  record_value.SetIntKey("version", 2);
  std::vector<uint8_t> data(params_.template_size_bytes, 'a');
  record_value.SetStringKey("data", base::Base64Encode(data));

  std::string record;
  JSONStringValueSerializer json_serializer(&record);
  EXPECT_TRUE(json_serializer.Serialize(record_value));

  EXPECT_TRUE(
      base::ImportantFileWriter::WriteFileAtomically(record_name_, record));
  auto read_result = biod_storage_->ReadRecordsForSingleUser(kUserId1);
  EXPECT_EQ(read_result.valid_records.size(), 1);
  EXPECT_EQ(read_result.invalid_records.size(), 0);
}

INSTANTIATE_TEST_SUITE_P(
    BiodStorageMemlock,
    BiodStorageMemlockTest,
    testing::Values(
        MemlockTestParams{
            .rlimit_bytes = kRlimitMemlockBytes,
            .template_size_bytes = kElan515TemplateSizeBytes,
        },
        MemlockTestParams{
            .rlimit_bytes = kRlimitMemlockBytes,
            .template_size_bytes = kElan80TemplateSizeBytes,
        },
        MemlockTestParams{
            .rlimit_bytes = kRlimitMemlockBytes,
            .template_size_bytes = kFpc1145TemplateSizeBytes,
        },
        MemlockTestParams{
            .rlimit_bytes = kRlimitMemlockBytes,
            .template_size_bytes = kFpc1025TemplateSizeBytes,
        }));

}  // namespace biod
