// Copyright (c) 2013 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.

// Creates credential stores for testing

#include "cryptohome/make_tests.h"

#include <openssl/evp.h>
#include <stdint.h>

#include <algorithm>
#include <memory>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/memory/ref_counted.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/cryptohome.h>
#include <brillo/secure_blob.h>
#include <policy/libpolicy.h>
#include <policy/mock_device_policy.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "cryptohome/crypto.h"
#include "cryptohome/mock_crypto.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.h"
#include "cryptohome/mount.h"
#include "cryptohome/mount_helper.h"
#include "cryptohome/user_oldest_activity_timestamp_cache.h"
#include "cryptohome/vault_keyset.h"

using base::FilePath;
using brillo::SecureBlob;
using ::testing::AnyOf;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Mock;
using ::testing::Property;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgPointee;
using ::testing::StartsWith;
using ::testing::_;

namespace cryptohome {

// struct TestUserInfo {
//   const char* username;
//   const char* password;
//   bool create;
// };

const TestUserInfo kDefaultUsers[] = {
  {"testuser0@invalid.domain", "zero", true, false},
  {"testuser1@invalid.domain", "one", true, false},
  {"testuser2@invalid.domain", "two", true, false},
  {"testuser3@invalid.domain", "three", true, false},
  {"testuser4@invalid.domain", "four", true, false},
  {"testuser5@invalid.domain", "five", false, false},
  {"testuser6@invalid.domain", "six", true, false},
  {"testuser7@invalid.domain", "seven", true, false},
  {"testuser8@invalid.domain", "eight", true, false},
  {"testuser9@invalid.domain", "nine", true, false},
  {"testuser10@invalid.domain", "ten", true, false},
  {"testuser11@invalid.domain", "eleven", true, false},
  {"testuser12@invalid.domain", "twelve", false, false},
  {"testuser13@invalid.domain", "thirteen", true, false},
  {"testuser14@invalid.domain", "0014", true, true},
};
const size_t kDefaultUserCount = arraysize(kDefaultUsers);

MakeTests::MakeTests() { }

void MakeTests::InitTestData(const FilePath& image_dir,
                             const TestUserInfo* test_users,
                             size_t test_user_count,
                             bool force_ecryptfs) {
  CHECK(system_salt.size()) << "Call SetUpSystemSalt() first";
  users.clear();
  users.resize(test_user_count);
  const TestUserInfo* user_info = test_users;
  for (size_t id = 0; id < test_user_count; ++id, ++user_info) {
    TestUser* user = &users[id];
    user->FromInfo(user_info, image_dir);
    user->GenerateCredentials(force_ecryptfs);
  }
}

void MakeTests::SetUpSystemSalt() {
  std::string* salt = new std::string(CRYPTOHOME_DEFAULT_SALT_LENGTH, 'A');
  system_salt.resize(salt->size());
  memcpy(&system_salt[0], salt->data(), salt->size());
  brillo::cryptohome::home::SetSystemSalt(salt);
}

void MakeTests::TearDownSystemSalt() {
  std::string* salt = brillo::cryptohome::home::GetSystemSalt();
  brillo::cryptohome::home::SetSystemSalt(NULL);
  delete salt;
}

void MakeTests::InjectSystemSalt(MockPlatform* platform, const FilePath& path) {
  CHECK(brillo::cryptohome::home::GetSystemSalt());
  EXPECT_CALL(*platform, FileExists(path)).WillRepeatedly(Return(true));
  EXPECT_CALL(*platform, GetFileSize(path, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<1>(system_salt.size()), Return(true)));

  EXPECT_CALL(*platform, ReadFileToSecureBlob(path, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(system_salt), Return(true)));
}

void MakeTests::InjectEphemeralSkeleton(MockPlatform* platform,
                                        const FilePath& root) {
  EXPECT_CALL(
      *platform,
      SetOwnership(
          Property(&FilePath::value, StartsWith(root.value())), _, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*platform,
      DirectoryExists(
        Property(&FilePath::value, StartsWith(root.value()))))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(*platform,
      FileExists(
        Property(&FilePath::value, StartsWith(root.value()))))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(*platform,
      SetGroupAccessible(
        Property(&FilePath::value, StartsWith(root.value())),
        _, _))
    .WillRepeatedly(Return(true));
}


void TestUser::FromInfo(const struct TestUserInfo* info,
                        const FilePath& image_dir) {
  username = info->username;
  password = info->password;
  create = info->create;
  is_le_credential = info->is_le_credential;
  use_key_data = is_le_credential ? true : false;
  // Stub system salt must already be in place. See MountTest::SetUp().
  // Sanitized usernames and obfuscated ones differ by case. Accomodate both.
  // TODO(ellyjones) fix this discrepancy!
  sanitized_username = brillo::cryptohome::home::SanitizeUserName(username);
  obfuscated_username = sanitized_username;
  std::transform(obfuscated_username.begin(),
                 obfuscated_username.end(),
                 obfuscated_username.begin(),
                 ::tolower);
  // Both pass this check though.
  DCHECK(brillo::cryptohome::home::IsSanitizedUserName(
           obfuscated_username));
  shadow_root = image_dir;
  skel_dir = image_dir.Append("skel");
  base_path = image_dir.Append(obfuscated_username);
  image_path = base_path.Append("image");
  vault_path = base_path.Append("vault");
  vault_mount_path = base_path.Append("mount");
  ephemeral_mount_path = FilePath(kEphemeralCryptohomeDir)
      .Append("ephemeral_mount").Append(obfuscated_username);
  tracked_directories_json_path = base_path.Append("tracked_directories.json");
  root_vault_path = vault_path.Append("root");
  user_vault_path = vault_path.Append("user");
  root_vault_mount_path = vault_mount_path.Append("root");
  user_vault_mount_path = vault_mount_path.Append("user");
  root_ephemeral_mount_path = ephemeral_mount_path.Append("root");
  user_ephemeral_mount_path = ephemeral_mount_path.Append("user");
  keyset_path = base_path.Append("master.0");
  salt_path = base_path.Append("master.0.salt");
  user_salt.assign('A', PKCS5_SALT_LEN);
  mount_prefix = brillo::cryptohome::home::GetUserPathPrefix().DirName();
  legacy_user_mount_path = FilePath("/home/chronos/user");
  user_mount_path = brillo::cryptohome::home::GetUserPath(username)
    .StripTrailingSeparators();
  user_mount_prefix = brillo::cryptohome::home::GetUserPathPrefix()
    .StripTrailingSeparators();
  root_mount_path = brillo::cryptohome::home::GetRootPath(username)
    .StripTrailingSeparators();
  root_mount_prefix = brillo::cryptohome::home::GetRootPathPrefix()
    .StripTrailingSeparators();
}

void TestUser::GenerateCredentials(bool force_ecryptfs) {
  std::string* system_salt = brillo::cryptohome::home::GetSystemSalt();
  brillo::Blob salt(system_salt->begin(), system_salt->end());
  SecureBlob sec_salt(*system_salt);
  NiceMock<MockTpm> tpm;
  NiceMock<MockPlatform> platform;
  Crypto crypto(&platform);
  crypto.set_use_tpm(false);
  crypto.set_scrypt_max_encrypt_time(0.001);
  UserOldestActivityTimestampCache timestamp_cache;

  scoped_refptr<Mount> mount = new Mount();
  mount->set_shadow_root(shadow_root);
  mount->set_skel_source(skel_dir);
  mount->set_use_tpm(false);
  NiceMock<policy::MockDevicePolicy>* device_policy =
    new NiceMock<policy::MockDevicePolicy>;
  EXPECT_CALL(*device_policy, LoadPolicy())
    .WillRepeatedly(Return(true));
  mount->set_policy_provider(new policy::PolicyProvider(
      std::unique_ptr<NiceMock<policy::MockDevicePolicy>>(device_policy)));
  FilePath salt_path = shadow_root.Append("salt");
  int64_t salt_size = salt.size();
  EXPECT_CALL(platform, FileExists(salt_path))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform, GetFileSize(salt_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(salt_size), Return(true)));
  EXPECT_CALL(platform, ReadFile(salt_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(salt), Return(true)));
  EXPECT_CALL(platform, ReadFileToSecureBlob(salt_path, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(sec_salt), Return(true)));
  EXPECT_CALL(platform, DirectoryExists(shadow_root))
    .WillRepeatedly(Return(true));
  mount->Init(&platform, &crypto, &timestamp_cache,
              base::DoNothing());

  cryptohome::Crypto::PasswordToPasskey(password,
                                        sec_salt,
                                        &passkey);
  Credentials local_credentials(username, passkey);
  if (use_key_data) {
    if (is_le_credential)
        key_data.set_label("PIN");
    local_credentials.set_key_data(key_data);
  }
  bool created;
  // NOTE! This code gives us generated credentials for credentials tests NOT
  // NOTE! golden credentials to test against.  This means we won't see problems
  // NOTE! if the credentials generation and checking code break together.
  // TODO(wad,ellyjones) Add golden credential tests too.

  // "Old" image path
  EXPECT_CALL(platform, FileExists(image_path))
    .WillRepeatedly(Return(false));
  // Use 'stat' failures to trigger default-allow the creation of the paths.
  EXPECT_CALL(platform,
      Stat(
        Property(&FilePath::value,
          AnyOf("/home",
                "/home/root",
                brillo::cryptohome::home::GetRootPath(username).value(),
                "/home/user",
                brillo::cryptohome::home::GetUserPath(username).value())),
        _))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform,
      Stat(
        Property(&FilePath::value,
          AnyOf("/home/chronos",
                MountHelper::GetNewUserPath(username).value())),
          _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform, DirectoryExists(vault_path))
    .WillOnce(Return(false));
  EXPECT_CALL(platform, DirectoryExists(vault_mount_path))
    .WillOnce(Return(false));
  EXPECT_CALL(platform, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  // Grab the generated credential
  EXPECT_CALL(platform, WriteFileAtomicDurable(keyset_path, _, _))
    .WillOnce(DoAll(SaveArg<1>(&credentials), Return(true)));
  Mount::MountArgs mount_args;
  mount_args.create_as_ecryptfs = force_ecryptfs;
  mount->EnsureCryptohome(local_credentials, mount_args, &created);
  DCHECK(created && credentials.size());
}

void TestUser::InjectKeyset(MockPlatform* platform, bool enumerate) {
  // TODO(wad) Update to support multiple keys
  EXPECT_CALL(*platform,
      FileExists(
        Property(&FilePath::value, StartsWith(keyset_path.value()))))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(*platform, ReadFile(keyset_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(credentials),
                          Return(true)));
  if (enumerate) {
    EXPECT_CALL(*platform, GetFileEnumerator(base_path, false, _))
        .WillRepeatedly(Invoke([&](base::FilePath path, bool rec, int type) {
          MockFileEnumerator* files = new NiceMock<MockFileEnumerator>();
          // Single key.
          files->AddFileEntry(keyset_path);
          return files;
        }));
  }
}

void TestUser::InjectUserPaths(MockPlatform* platform,
                               uid_t chronos_uid,
                               gid_t chronos_gid,
                               gid_t chronos_access_gid,
                               gid_t daemon_gid,
                               bool is_ecryptfs) {
  scoped_refptr<Mount> temp_mount = new Mount();
  EXPECT_CALL(*platform, FileExists(image_path))
    .WillRepeatedly(Return(false));
  struct stat root_dir;
  memset(&root_dir, 0, sizeof(root_dir));
  root_dir.st_mode = S_IFDIR|S_ISVTX;
  EXPECT_CALL(*platform,
      Stat(AnyOf(mount_prefix,
                 root_mount_prefix,
                 user_mount_prefix,
                 root_mount_path,
                 user_vault_path),
           _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(root_dir), Return(true)));
  // Avoid triggering vault migration.  (Is there another test for that?)
  struct stat root_vault_dir;
  memset(&root_vault_dir, 0, sizeof(root_vault_dir));
  root_vault_dir.st_mode = S_IFDIR|S_ISVTX;
  root_vault_dir.st_uid = 0;
  root_vault_dir.st_gid = daemon_gid;
  EXPECT_CALL(*platform,
              Stat(is_ecryptfs ? root_vault_path : root_vault_mount_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(root_vault_dir), Return(true)));
  struct stat user_dir;
  memset(&user_dir, 0, sizeof(user_dir));
  user_dir.st_mode = S_IFDIR;
  user_dir.st_uid = chronos_uid;
  user_dir.st_gid = chronos_access_gid;
  EXPECT_CALL(*platform,
      Stat(AnyOf(user_mount_path,
                 MountHelper::GetNewUserPath(username)), _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user_dir), Return(true)));
  if (!is_ecryptfs) {
    EXPECT_CALL(*platform,
        Stat(Property(&FilePath::value,
                      StartsWith(user_vault_mount_path.value())), _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(user_dir), Return(true)));
  }
  struct stat chronos_dir;
  memset(&chronos_dir, 0, sizeof(chronos_dir));
  chronos_dir.st_mode = S_IFDIR;
  chronos_dir.st_uid = chronos_uid;
  chronos_dir.st_gid = chronos_gid;
  EXPECT_CALL(*platform,
      Stat(FilePath("/home/chronos"), _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(chronos_dir),
                            Return(true)));
  EXPECT_CALL(*platform,
      DirectoryExists(
        Property(&FilePath::value,
          AnyOf(shadow_root.value(),
                mount_prefix.value(),
                StartsWith(legacy_user_mount_path.value()),
                StartsWith(vault_mount_path.value())))))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(*platform, DirectoryExists(
      Property(&FilePath::value, StartsWith(vault_path.value()))))
      .WillRepeatedly(Return(is_ecryptfs));
  FilePath new_user_path = MountHelper::GetNewUserPath(username);
  EXPECT_CALL(*platform,
      FileExists(
        Property(&FilePath::value,
          AnyOf(StartsWith(legacy_user_mount_path.value()),
                StartsWith(vault_mount_path.value()),
                StartsWith(user_mount_path.value()),
                StartsWith(root_mount_path.value()),
                StartsWith(new_user_path.value()),
                StartsWith(keyset_path.value())))))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(*platform,
      SetGroupAccessible(
        Property(&FilePath::value,
          AnyOf(StartsWith(legacy_user_mount_path.value()),
                StartsWith(user_vault_mount_path.value()))),
        chronos_access_gid, _))
    .WillRepeatedly(Return(true));
  if (!is_ecryptfs) {
    EXPECT_CALL(*platform, GetDirCryptoKeyState(vault_mount_path))
        .WillRepeatedly(Return(dircrypto::KeyState::ENCRYPTED));
  }
}

}  // namespace cryptohome
