// Copyright 2020 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cryptohome/filesystem_layout.h"

#include <string>
#include <utility>

#include <base/check.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/cryptohome.h>
#include <brillo/secure_blob.h>
#include <libhwsec-foundation/crypto/secure_blob_util.h>
#include <libstorage/platform/platform.h>

#include "cryptohome/auth_factor/label.h"
#include "cryptohome/cryptohome_common.h"
#include "cryptohome/cryptohome_metrics.h"
#include "cryptohome/username.h"

using ::hwsec_foundation::CreateSecureRandomBlob;

namespace cryptohome {
namespace {

constexpr char kShadowRoot[] = "/home/.shadow";

constexpr char kLegacySystemSaltFile[] = "/home/.shadow/salt";
constexpr char kSystemSaltFile[] = "/var/lib/system_salt";
constexpr char kPublicMountSaltFilePath[] = "/var/lib/public_mount_salt";

constexpr int64_t kSystemSaltMaxSize = (1 << 20);  // 1 MB
constexpr mode_t kSaltFilePermissions = 0644;

constexpr char kRecoverableKeyStoreDir[] = "key_store_certs";

constexpr char kSkelPath[] = "/etc/skel";
constexpr char kLogicalVolumePrefix[] = "cryptohome";
constexpr char kDmcryptVolumePrefix[] = "dmcrypt";
constexpr char kLogicalVolumeSnapshotSuffix[] = "-rw";

// Storage for serialized RecoveryId.
constexpr char kRecoveryIdFile[] = "recovery_id";

// Attempt to get an existing salt from the specified path. Returns false if the
// salt does not exist or is invalid. If the salt does exist but is invalid, it
// will also attempt to remove the file.
bool GetOrRemoveSalt(libstorage::Platform* platform,
                     const base::FilePath& salt_file,
                     brillo::SecureBlob* salt) {
  // If the file doesn't exist, fail immediately. This isn't logged as this can
  // be an expected condition.
  if (!platform->FileExists(salt_file)) {
    return false;
  }

  int64_t file_len = 0;
  if (!platform->GetFileSize(salt_file, &file_len)) {
    LOG(ERROR) << "Can't get file len for " << salt_file.value();
    return false;
  }

  if (file_len > 0 && file_len <= kSystemSaltMaxSize) {
    brillo::SecureBlob local_salt(file_len);
    if (platform->ReadFileToSecureBlob(salt_file, &local_salt)) {
      // This is the success case: the size is valid and the file is readable.
      if (salt) {
        *salt = std::move(local_salt);
      }
      return true;
    }
    LOG(ERROR) << "Could not read salt file " << salt_file << " of length "
               << file_len;
  }

  // If we get here then the file exists but is invalid or unreadable for some
  // reason. Try to remove it. If the removal fails we log it, but we return
  // false either way.
  LOG(ERROR) << "Existing salt file at " << salt_file
             << " is invalid or unreadable, attempting to delete it";
  if (!platform->DeleteFile(salt_file)) {
    LOG(ERROR) << "Salt file at " << salt_file << " could not be deleted";
  }
  return false;
}

// Attempt to get an existing salt from the specified path. If the file does not
// exist or does not contain a valid salt, this will attempt to generate a new
// salt. If that also fails, this will return false. Otherwise, it will return
// true with the salt (existing or newly created).
bool GetOrCreateSalt(libstorage::Platform* platform,
                     const base::FilePath& salt_file,
                     brillo::SecureBlob* salt) {
  int64_t file_len = 0;
  if (platform->FileExists(salt_file)) {
    if (!platform->GetFileSize(salt_file, &file_len)) {
      LOG(ERROR) << "Can't get file len for " << salt_file;
      return false;
    }
  }

  brillo::SecureBlob local_salt;
  if (file_len == 0 || file_len > kSystemSaltMaxSize) {
    LOG(INFO) << "Creating new salt at " << salt_file << " (existing length "
              << file_len << ")";
    // If this salt doesn't exist, automatically create it.
    local_salt = CreateSecureRandomBlob(kCryptohomeDefaultSaltLength);
    if (!platform->WriteSecureBlobToFileAtomicDurable(salt_file, local_salt,
                                                      kSaltFilePermissions)) {
      LOG(ERROR) << "Could not write new salt to " << salt_file;
      return false;
    }
  } else {
    local_salt.resize(file_len);
    if (!platform->ReadFileToSecureBlob(salt_file, &local_salt)) {
      LOG(ERROR) << "Could not read salt file " << salt_file << " of length "
                 << file_len;
      return false;
    }
  }
  if (salt) {
    *salt = std::move(local_salt);
  }
  return true;
}

// Get the Account ID for an AccountIdentifier proto.
Username GetAccountId(const AccountIdentifier& id) {
  if (id.has_account_id()) {
    return Username(id.account_id());
  }
  return Username(id.email());
}

}  // namespace

base::FilePath ShadowRoot() {
  return base::FilePath(kShadowRoot);
}

base::FilePath LegacySystemSaltFile() {
  return base::FilePath(kLegacySystemSaltFile);
}

base::FilePath SystemSaltFile() {
  return base::FilePath(kSystemSaltFile);
}

base::FilePath PublicMountSaltFile() {
  return base::FilePath(kPublicMountSaltFilePath);
}

base::FilePath SkelDir() {
  return base::FilePath(kSkelPath);
}

base::FilePath RecoverableKeyStoreBackendCertDir() {
  return ShadowRoot().Append(kRecoverableKeyStoreDir);
}

base::FilePath UserPath(const ObfuscatedUsername& obfuscated) {
  return ShadowRoot().Append(*obfuscated);
}

base::FilePath VaultKeysetPath(const ObfuscatedUsername& obfuscated,
                               int index) {
  return UserPath(obfuscated)
      .Append(kKeyFile)
      .AddExtension(base::NumberToString(index));
}

base::FilePath UserSecretStashPath(
    const ObfuscatedUsername& obfuscated_username, int slot) {
  CHECK_GE(slot, 0);
  return UserPath(obfuscated_username)
      .Append(kUserSecretStashDir)
      .Append(kUserSecretStashFileBase)
      .AddExtension(std::to_string(slot));
}

base::FilePath AuthFactorsDirPath(
    const ObfuscatedUsername& obfuscated_username) {
  return UserPath(obfuscated_username).Append(kAuthFactorsDir);
}

base::FilePath AuthFactorPath(const ObfuscatedUsername& obfuscated_username,
                              const std::string& auth_factor_type_string,
                              const std::string& auth_factor_label) {
  // The caller must make sure the label was sanitized.
  CHECK(IsValidAuthFactorLabel(auth_factor_label));
  return UserPath(obfuscated_username)
      .Append(kAuthFactorsDir)
      .Append(auth_factor_type_string)
      .AddExtension(auth_factor_label);
}

base::FilePath UserActivityPerIndexTimestampPath(
    const ObfuscatedUsername& obfuscated, int index) {
  return VaultKeysetPath(obfuscated, index).AddExtension(kTsFile);
}

base::FilePath UserActivityTimestampPath(const ObfuscatedUsername& obfuscated) {
  return UserPath(obfuscated).Append(kTsFile);
}

base::FilePath GetEcryptfsUserVaultPath(const ObfuscatedUsername& obfuscated) {
  return UserPath(obfuscated).Append(kEcryptfsVaultDir);
}

base::FilePath GetUserMountDirectory(
    const ObfuscatedUsername& obfuscated_username) {
  return UserPath(obfuscated_username).Append(kMountDir);
}

base::FilePath GetUserPolicyPath(
    const ObfuscatedUsername& obfuscated_username) {
  return UserPath(obfuscated_username)
      .Append(kUserPolicyDir)
      .Append(kPolicyFile);
}

base::FilePath GetUserTemporaryMountDirectory(
    const ObfuscatedUsername& obfuscated_username) {
  return UserPath(obfuscated_username).Append(kTemporaryMountDir);
}

base::FilePath GetDmcryptUserCacheDirectory(
    const ObfuscatedUsername& obfuscated_username) {
  return UserPath(obfuscated_username).Append(kDmcryptCacheDir);
}

std::string LogicalVolumePrefix(const ObfuscatedUsername& obfuscated_username) {
  return std::string(kLogicalVolumePrefix) + "-" +
         obfuscated_username->substr(0, 8) + "-";
}

std::string DmcryptVolumePrefix(const ObfuscatedUsername& obfuscated_username) {
  return std::string(kDmcryptVolumePrefix) + "-" +
         obfuscated_username->substr(0, 8) + "-";
}

base::FilePath GetDmcryptDataVolume(
    const ObfuscatedUsername& obfuscated_username) {
  return base::FilePath(kDeviceMapperDir)
      .Append(DmcryptVolumePrefix(obfuscated_username)
                  .append(kDmcryptDataContainerSuffix));
}

base::FilePath GetDmcryptCacheVolume(
    const ObfuscatedUsername& obfuscated_username) {
  return base::FilePath(kDeviceMapperDir)
      .Append(DmcryptVolumePrefix(obfuscated_username)
                  .append(kDmcryptCacheContainerSuffix));
}

base::FilePath LogicalVolumeSnapshotPath(
    const ObfuscatedUsername& obfuscated_username,
    const std::string& container_name) {
  std::string name = LogicalVolumePrefix(obfuscated_username) + container_name +
                     kLogicalVolumeSnapshotSuffix;

  return base::FilePath(kDeviceMapperDir).Append(name);
}

bool GetSystemSalt(libstorage::Platform* platform, brillo::SecureBlob* salt) {
  // Only new installations get the system salt file in the new location.
  // If the legacy salt file can be loaded, the system should keep using it.
  return GetOrRemoveSalt(platform, LegacySystemSaltFile(), salt) ||
         GetOrCreateSalt(platform, SystemSaltFile(), salt);
}

bool GetPublicMountSalt(libstorage::Platform* platform,
                        brillo::SecureBlob* salt) {
  return GetOrCreateSalt(platform, PublicMountSaltFile(), salt);
}

base::FilePath GetRecoveryIdPath(const AccountIdentifier& account_id) {
  ObfuscatedUsername obfuscated =
      brillo::cryptohome::home::SanitizeUserName(GetAccountId(account_id));
  if (obfuscated->empty()) {
    return base::FilePath();
  }
  return brillo::cryptohome::home::GetHashedUserPath(obfuscated)
      .Append(kRecoveryIdFile);
}

bool InitializeFilesystemLayout(libstorage::Platform* platform,
                                brillo::SecureBlob* salt) {
  const base::FilePath shadow_root = ShadowRoot();
  if (!platform->DirectoryExists(shadow_root)) {
    platform->CreateDirectory(shadow_root);
    if (platform->RestoreSELinuxContexts(shadow_root, true /*recursive*/)) {
      ReportRestoreSELinuxContextResultForShadowDir(true);
    } else {
      ReportRestoreSELinuxContextResultForShadowDir(false);
      LOG(ERROR) << "RestoreSELinuxContexts(" << shadow_root << ") failed.";
    }
  }

  if (!GetSystemSalt(platform, salt)) {
    LOG(ERROR) << "Failed to create system salt.";
    return false;
  }
  return true;
}

}  // namespace cryptohome
