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

// Homedirs - manages the collection of user home directories on disk. When a
// homedir is actually mounted, it becomes a Mount.

#ifndef CRYPTOHOME_HOMEDIRS_H_
#define CRYPTOHOME_HOMEDIRS_H_

#include <stdint.h>

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

#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/time/time.h>
#include <brillo/secure_blob.h>
#include <chaps/token_manager_client.h>
#include <dbus/cryptohome/dbus-constants.h>
#include <gtest/gtest_prod.h>
#include <policy/device_policy.h>
#include <policy/libpolicy.h>

#include "cryptohome/mount_factory.h"
#include "cryptohome/vault_keyset.h"
#include "cryptohome/vault_keyset_factory.h"

#include "rpc.pb.h"  // NOLINT(build/include)
#include "vault_keyset.pb.h"  // NOLINT(build/include)

namespace cryptohome {

// The uid shift of ARC++ container.
const uid_t kArcContainerShiftUid = 655360;
// The gid shift of ARC++ container.
const gid_t kArcContainerShiftGid = 655360;
const int64_t kFreeSpaceThresholdToTriggerCleanup = 1LL << 30;
const int64_t kTargetFreeSpaceAfterCleanup = 2LL << 30;
extern const char kAndroidCacheFilesAttribute[];
extern const char kAndroidCacheInodeAttribute[];
extern const char kAndroidCodeCacheInodeAttribute[];
extern const char kTrackedDirectoryNameAttribute[];
extern const char kRemovableFileAttribute[];
extern const char kEcryptfsVaultDir[];
extern const char kMountDir[];

class Credentials;
class Crypto;
class Platform;
class UserOldestActivityTimestampCache;
class VaultKeyset;

class HomeDirs {
 public:
  HomeDirs();
  virtual ~HomeDirs();

  // Initializes this HomeDirs object. Returns true for success.
  virtual bool Init(Platform* platform, Crypto* crypto,
                    UserOldestActivityTimestampCache *cache);

  // Frees disk space for unused cryptohomes. If the available disk space is
  // below |kFreeSpaceThresholdToTriggerCleanup|, attempts to free space until
  // it goes up to |kTargetFreeSpaceAfterCleanup|.
  virtual void FreeDiskSpace();

  // Return the available disk space in bytes for home directories, or -1 on
  // failure.
  virtual int64_t AmountOfFreeDiskSpace() const;

  // Removes all cryptohomes owned by anyone other than the owner user (if set),
  // regardless of free disk space.
  virtual void RemoveNonOwnerCryptohomes();

  // Returns the system salt, creating a new one if necessary. If loading the
  // system salt fails, returns false, and blob is unchanged.
  virtual bool GetSystemSalt(brillo::SecureBlob *blob);

  // Returns the owner's obfuscated username.
  virtual bool GetOwner(std::string* owner);
  virtual bool GetPlainOwner(std::string* owner);

  // Returns whether the given user is a non-enterprise owner, or if it will
  // become such in case it signs in now.
  bool IsOrWillBeOwner(const std::string& account_id);

  // Returns whether the ephemeral users policy is enabled.
  virtual bool AreEphemeralUsersEnabled();

  // Returns a list of present keyset indices for an obfuscated username.
  // There is no guarantee the keysets are valid.
  virtual bool GetVaultKeysets(const std::string& obfuscated,
                               std::vector<int>* keysets) const;

  // Outputs a list of present keysets by label for a given obfuscated username.
  // There is no guarantee the keysets are valid nor is the ordering guaranteed.
  // Returns true on success, false if no keysets are found.
  virtual bool GetVaultKeysetLabels(const std::string& obfuscated_username,
                                    std::vector<std::string>* labels) const;

  // Returns a VaultKeyset that matches the given obfuscated username and the
  // key label. If the label is empty or if no matching keyset is found, NULL
  // will be returned.
  //
  // The caller DOES take ownership of the returned VaultKeyset pointer.
  // There is no guarantee the keyset is valid.
  virtual VaultKeyset* GetVaultKeyset(const std::string& obfuscated_username,
                                      const std::string& key_label) const;

  // Removes the cryptohome for the named user.
  virtual bool Remove(const std::string& username);

  // Renames account identified by |account_id_from| to |account_id_to|.
  // This is called when user e-mail is replaced with GaiaId as account
  // identifier.
  virtual bool Rename(const std::string& account_id_from,
                      const std::string& account_id_to);

  // Computes the size of cryptohome for the named user.
  virtual int64_t ComputeSize(const std::string& account_id);

  // Returns true if the supplied Credentials are a valid (username, passkey)
  // pair.
  virtual bool AreCredentialsValid(const Credentials& credentials);

  // Returns true if a path exists for the given obfuscated username.
  virtual bool Exists(const std::string& obfuscated_username) const;

  // Checks if a cryptohome vault exists for the given obfuscated username.
  virtual bool CryptohomeExists(const std::string& obfuscated_username) const;

  // Checks if a eCryptfs cryptohome vault exists for the given obfuscated
  // username.
  virtual bool EcryptfsCryptohomeExists(
      const std::string& obfuscated_username) const;

  // Checks if a dircrypto cryptohome vault exists for the given obfuscated
  // username.
  virtual bool DircryptoCryptohomeExists(
      const std::string& obfuscated_username) const;

  // Gets the user's eCryptfs vault directory for the given obfuscated username.
  base::FilePath GetEcryptfsUserVaultPath(
      const std::string& obfuscated_username) const;

  // Gets the directory to mount the user's cryptohome at. The user is specified
  // by its obfuscated username.
  base::FilePath GetUserMountDirectory(
      const std::string& obfuscated_username) const;

  // Returns true if a valid keyset can be decrypted with |creds|.  If true,
  // |vk| will contain the decrypted value, and |key_index|, if non-null, will
  // contain the key index. If false, |vk| will contain the last failed keyset
  // attempt, and |error|, if non-null, will contain the error details.
  // NOTE: The LE Credential Keysets are only considered when the key label
  // provided via |creds| is non-empty.
  virtual bool GetValidKeyset(const Credentials& creds,
                              VaultKeyset* vk,
                              int* key_index,
                              MountError* error);

  // Returns the vault keyset path for the supplied obfuscated username.
  virtual base::FilePath GetVaultKeysetPath(const std::string& obfuscated,
                                            int index) const;

  // Adds a new vault keyset for the user using the |existing_credentials| to
  // unwrap the homedir key and the |new_credentials| to rewrap and persist to
  // disk.  The key index is return in the |index| pointer if the function
  // returns true.  |index| is not modified if the function returns false.
  // |new_data|, when provided, is copied to the key_data of the new keyset.
  // If |new_data| is provided, a best-effort attempt will be made at ensuring
  // key_data().label() is unique.
  // If |clobber| is true and there are no matching, labeled keys, then it does
  // nothing.  If there is an identically labeled key, it will overwrite it.
  virtual CryptohomeErrorCode AddKeyset(
                         const Credentials& existing_credentials,
                         const brillo::SecureBlob& new_passkey,
                         const KeyData* new_data,
                         bool clobber,
                         int* index);


  // Removes the keyset identified by |key_data| if |credentials|
  // has the remove() KeyPrivilege.  The VaultKeyset backing
  // |credentials| may be the same that |key_data| identifies.
  virtual CryptohomeErrorCode RemoveKeyset(const Credentials& credentials,
                                           const KeyData& key_data);

  // Finds and updates the keyset authenticated by |credentials| and
  // applies |changed_data| to the keyset conditionally on if
  // |authorization_signature| is needed and is valid.
  virtual CryptohomeErrorCode UpdateKeyset(
                         const Credentials& credentials,
                         const Key* changed_data,
                         const std::string& authorization_signature);

  // Returns true if the |signature| is valid over the |new_key| given
  // the AuthorizationData specification from |existing_key_data|.
  virtual bool CheckAuthorizationSignature(const KeyData& existing_key_data,
                                           const Key& new_key,
                                           const std::string& signature);

  // Removes the keyset specified by |index| from the list for the user
  // vault identified by its |obfuscated| username.
  // The caller should check credentials if the call is user-sourced.
  // TODO(wad,ellyjones) Determine a better keyset priotization and management
  //                     scheme than just integer indices, like fingerprints.
  virtual bool ForceRemoveKeyset(const std::string& obfuscated, int index);

  // Allows a keyset to be moved to a different index assuming the index can be
  // claimed for a given |obfuscated| username.
  virtual bool MoveKeyset(const std::string& obfuscated, int src, int dst);

  // Migrates the cryptohome for the supplied obfuscated username from the
  // supplied old key to the supplied new key. Reuses |user_mount| if it's not
  // null.
  virtual bool Migrate(const Credentials& newcreds,
                       const brillo::SecureBlob& oldkey,
                       scoped_refptr<Mount> user_mount);

  // Returns the path to the user's chaps token directory.
  virtual base::FilePath GetChapsTokenDir(const std::string& username) const;

  // Returns the path to the user's legacy chaps token directory.
  virtual base::FilePath GetLegacyChapsTokenDir(
      const std::string& username) const;

  // Returns the path to the user's token salt.
  virtual base::FilePath GetChapsTokenSaltPath(
      const std::string& username) const;

  // Returns true if the cryptohome for the given obfuscated username should
  // migrate to dircrypto.
  virtual bool NeedsDircryptoMigration(
      const std::string& obfuscated_username) const;

  // Attempts to reset all LE credentials associated with a username, given
  // a credential |cred|.
  virtual void ResetLECredentials(const Credentials& creds);

  // Removes all LE credentials for a user with |obfuscated_username|.
  virtual void RemoveLECredentials(const std::string& obfuscated_username);

  // Get the number of unmounted android-data directory. Each android users
  // that is not currently logged in should have exactly one android-data
  // directory.
  virtual int32_t GetUnmountedAndroidDataCount();

  // Marks that the device got locked to be able to use only data of a single
  // user until reboot. Internally touches a file in temporary storage marking
  // that PCR was extended.
  virtual bool SetLockedToSingleUser() const;

  // Accessors. Mostly used for unit testing. These do not take ownership of
  // passed-in pointers.
  // TODO(wad) Should this update default_crypto_.set_platform()?
  void set_platform(Platform *value) { platform_ = value; }
  Platform* platform() { return platform_; }
  void set_shadow_root(const base::FilePath& value) { shadow_root_ = value; }
  const base::FilePath& shadow_root() const { return shadow_root_; }
  void set_enterprise_owned(bool value) { enterprise_owned_ = value; }
  bool enterprise_owned() const { return enterprise_owned_; }
  void set_policy_provider(policy::PolicyProvider* value) {
    policy_provider_ = value;
  }
  policy::PolicyProvider* policy_provider() { return policy_provider_; }
  void set_crypto(Crypto* value) { crypto_ = value; }
  Crypto* crypto() const { return crypto_; }
  void set_mount_factory(MountFactory* value) { mount_factory_ = value; }
  MountFactory* mount_factory() const { return mount_factory_; }
  void set_vault_keyset_factory(VaultKeysetFactory* value) {
    vault_keyset_factory_ = value;
  }
  VaultKeysetFactory* vault_keyset_factory() const {
    return vault_keyset_factory_;
  }

  // Returns true if there is now at least |kTargetFreeSpaceAfterCleanup|
  // amount of free disk space or false otherwise.
  bool HasTargetFreeSpace() const;

 private:
  base::TimeDelta GetUserInactivityThresholdForRemoval();
  // Loads the device policy, either by initializing it or reloading the
  // existing one.
  void LoadDevicePolicy();
  // Returns the path of the specified tracked directory (i.e. a directory which
  // we can locate even when without the key).
  bool GetTrackedDirectory(const base::FilePath& user_dir,
                           const base::FilePath& tracked_dir_name,
                           base::FilePath* out);
  // GetTrackedDirectory() implementation for dircrypto.
  bool GetTrackedDirectoryForDirCrypto(
      const base::FilePath& mount_dir,
      const base::FilePath& tracked_dir_name,
      base::FilePath* out);
  typedef base::Callback<void(const base::FilePath&)> CryptohomeCallback;
  // Runs the supplied callback for every unmounted cryptohome with the user dir
  // path.
  void DoForEveryUnmountedCryptohome(const CryptohomeCallback& cryptohome_cb);
  // Returns the number of currently-mounted cryptohomes.
  int CountMountedCryptohomes() const;
  // Callback used during RemoveNonOwnerCryptohomes()
  void RemoveNonOwnerCryptohomesCallback(const base::FilePath& user_dir);
  // Callback used during FreeDiskSpace().
  void DeleteCacheCallback(const base::FilePath& user_dir);
  // Callback used during FreeDiskSpace().
  void DeleteGCacheTmpCallback(const base::FilePath& user_dir);
  // Callback used during FreeDiskSpace().
  void DeleteAndroidCacheCallback(const base::FilePath& user_dir);
  // Recursively deletes all contents of a directory while leaving the directory
  // itself intact.
  void DeleteDirectoryContents(const base::FilePath& dir);
  // Deletes all directories under the supplied directory whose basename is not
  // the same as the obfuscated owner name.
  void RemoveNonOwnerDirectories(const base::FilePath& prefix);
  // Callback used during FreeDiskSpace() if the timestamp cache is not yet
  // initialized. Loads the last activity timestamp from the vault keyset.
  void AddUserTimestampToCacheCallback(const base::FilePath& user_dir);
  // Loads the serialized vault keyset for the supplied obfuscated username.
  // Returns true for success, false for failure.
  bool LoadVaultKeysetForUser(const std::string& obfuscated_user,
                              int index,
                              VaultKeyset* keyset) const;
  // Deletes old user profiles, the oldest first.
  // Returns a number, how many profiles were deleted.
  int DeleteUserProfiles();
  // An implementation function for public FreeDiskSpace interface.
  void FreeDiskSpaceInternal();

  // Increase the out parameter count if the give user_dir contains
  // android-data directory.
  void IncreaseCountIfAndroidUser(int32_t* count,
                                  const base::FilePath& uesr_dir);

  // Helper function to check if the directory contains subdirectory that looks
  // like encrypted android-data (see definition of looks-like-android-data in
  // the LooksLikeAndroidData function). Each file names under mounted_user_dir
  // filesystem tree has encrypted name, but unencrypted metadata.
  // False positive is possible, but practically should never happen. Even if
  // false positive happens, installd in ARC++ will use non-quota path and the
  // system will keep running properly (though a bit slower) so it is still
  // safe.
  bool MayContainAndroidData(const base::FilePath& mounted_user_dir) const;

  // Helper function to check if the directory looks like android-data. A
  // directory is said to look like android-data if it has subdirectory owned by
  // Android system. It is possible for a directory that looks like android-data
  // to not actually be android-data, but the other way around is not possible.
  // But practically in current home directory structure, directory that looks
  // like android-data is always android-data. So normally, this function
  // accurately predicts if the directory in the parameter is actually
  // android-data.
  bool LooksLikeAndroidData(const base::FilePath& directory) const;

  // Helper function to check if the directory is owned by android system
  // UID.
  bool IsOwnedByAndroidSystem(const base::FilePath& directory) const;

  // Takes ownership of the supplied PolicyProvider. Used to avoid leaking mocks
  // in unit tests.
  void own_policy_provider(policy::PolicyProvider* value) {
    default_policy_provider_.reset(value);
    policy_provider_ = value;
  }

  std::unique_ptr<Platform> default_platform_;
  Platform* platform_;
  base::FilePath shadow_root_;
  UserOldestActivityTimestampCache* timestamp_cache_;
  bool enterprise_owned_;
  std::unique_ptr<policy::PolicyProvider> default_policy_provider_;
  policy::PolicyProvider* policy_provider_;
  Crypto* crypto_;
  std::unique_ptr<MountFactory> default_mount_factory_;
  MountFactory* mount_factory_;
  // TODO(wad) Collapse all factories into a single manufacturing plant to save
  //           some pointers.
  std::unique_ptr<VaultKeysetFactory> default_vault_keyset_factory_;
  VaultKeysetFactory* vault_keyset_factory_;
  brillo::SecureBlob system_salt_;
  chaps::TokenManagerClient chaps_client_;

  // The container a not-shifted system UID in ARC++ container (AID_SYSTEM).
  static constexpr uid_t kAndroidSystemUid = 1000;

  friend class HomeDirsTest;
  FRIEND_TEST(HomeDirsTest, GetTrackedDirectoryForDirCrypto);

  DISALLOW_COPY_AND_ASSIGN(HomeDirs);
};

}  // namespace cryptohome

#endif  // CRYPTOHOME_HOMEDIRS_H_
