// 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.

#ifndef CRYPTOHOME_SERVICE_H_
#define CRYPTOHOME_SERVICE_H_

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/atomic_sequence_num.h>
#include <base/files/file_path.h>
#include <base/gtest_prod_util.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/memory/ref_counted.h>
#include <base/task/task_observer.h>
#include <base/threading/thread.h>
#include <brillo/dbus/dbus_connection.h>
#include <brillo/glib/abstract_dbus_service.h>
#include <brillo/glib/dbus.h>
#include <brillo/glib/object.h>
#include <brillo/secure_blob.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/dbus-glib.h>

#include "cryptohome/challenge_credentials/challenge_credentials_helper.h"
#include "cryptohome/cryptohome_event_source.h"
#include "cryptohome/dbus_transition.h"
#include "cryptohome/fingerprint_manager.h"
#include "cryptohome/firmware_management_parameters.h"
#include "cryptohome/install_attributes.h"
#include "cryptohome/key_challenge_service_factory.h"
#include "cryptohome/key_challenge_service_factory_impl.h"
#include "cryptohome/keyset_management.h"
#include "cryptohome/migration_type.h"
#include "cryptohome/pkcs11_init.h"
#include "cryptohome/rpc.pb.h"
#include "cryptohome/storage/arc_disk_quota.h"
#include "cryptohome/storage/disk_cleanup.h"
#include "cryptohome/storage/mount.h"
#include "cryptohome/storage/mount_factory.h"
#include "cryptohome/storage/mount_task.h"
#include "cryptohome/tpm_init.h"
#include "cryptohome/user_session.h"

namespace chaps {
class TokenManagerClient;
}

namespace cryptohome {
namespace gobject {

struct Cryptohome;
}  // namespace gobject

class BootAttributes;
class BootLockbox;
class Credentials;
// Wrapper for all timers used by the cryptohome daemon.
class TimerCollection;

// MountThreadObserver
class MountThreadObserver : public base::TaskObserver {
 public:
  // This method is called when post a task
  void PostTask();

  // This method is called before processing a task.
  void WillProcessTask(const base::PendingTask& pending_task,
                       bool was_blocked_or_low_priority) override;

  // This method is called after processing a task.
  void DidProcessTask(const base::PendingTask& pending_task) override;

  int GetParallelTaskCount() const;

 private:
  std::atomic<int> parallel_task_count_{0};
};

// Service
// Provides a wrapper for exporting CryptohomeInterface to
// D-Bus and entering the glib run loop.
class Service : public brillo::dbus::AbstractDbusService,
                public CryptohomeEventSourceSink {
 public:
  Service();
  Service(const Service&) = delete;
  Service& operator=(const Service&) = delete;

  virtual ~Service();

  // Create the right Service based on command-line flags and TPM version.
  static Service* CreateDefault();

  // From brillo::dbus::AbstractDbusService
  // Setup the wrapped GObject and the GMainLoop
  virtual bool Initialize();
  virtual bool SeedUrandom();
  virtual void InitializeInstallAttributes();
  virtual void InitializePkcs11(UserSession* session);
  virtual void DoInitializePkcs11(UserSession* session);
  virtual bool Reset();

  // Used internally during registration to set the
  // proper service information.
  virtual const char* service_name() const { return kCryptohomeServiceName; }
  virtual const char* service_path() const { return kCryptohomeServicePath; }
  virtual const char* service_interface() const { return kCryptohomeInterface; }
  virtual GObject* service_object() const { return G_OBJECT(cryptohome_); }
  virtual void set_tpm(Tpm* tpm) { tpm_ = tpm; }
  virtual void set_tpm_init(TpmInit* tpm_init) { tpm_init_ = tpm_init; }
  virtual void set_initialize_tpm(bool value) { initialize_tpm_ = value; }
  virtual void set_install_attrs(InstallAttributes* install_attrs) {
    install_attrs_ = install_attrs;
  }
  virtual void set_session_for_user(const std::string& username,
                                    UserSession* s) {
    sessions_[username] = s;
  }
  virtual void set_crypto(Crypto* crypto) { crypto_ = crypto; }
  virtual void set_mount_factory(cryptohome::MountFactory* mf) {
    mount_factory_ = mf;
  }

  // Overrides the Platform implementation for Service.
  virtual void set_platform(cryptohome::Platform* platform) {
    platform_ = platform;
  }

  virtual void set_arc_disk_quota(cryptohome::ArcDiskQuota* arc_disk_quota) {
    arc_disk_quota_ = arc_disk_quota;
  }

  virtual cryptohome::Crypto* crypto() { return crypto_; }

  virtual void set_keyset_management(KeysetManagement* value) {
    keyset_management_ = value;
  }

  virtual KeysetManagement* keyset_management() { return keyset_management_; }

  virtual void set_homedirs(cryptohome::HomeDirs* value) { homedirs_ = value; }

  virtual cryptohome::HomeDirs* homedirs() { return homedirs_; }

  virtual void set_chaps_client(chaps::TokenManagerClient* chaps_client) {
    chaps_client_ = chaps_client;
  }

  virtual void set_event_source_sink(CryptohomeEventSourceSink* sink) {
    event_source_sink_ = sink;
  }

  void set_challenge_credentials_helper(
      ChallengeCredentialsHelper* challenge_credentials_helper) {
    challenge_credentials_helper_ = challenge_credentials_helper;
  }

  void set_key_challenge_service_factory(
      KeyChallengeServiceFactory* key_challenge_service_factory) {
    key_challenge_service_factory_ = key_challenge_service_factory;
  }

  void set_disk_cleanup(DiskCleanup* disk_cleanup) {
    disk_cleanup_ = disk_cleanup;
  }

  // Checks if the given user is the system owner.
  virtual bool IsOwner(const std::string& userid);

  // Returns the base directory of the eCryptfs destination, containing
  // the "user" and "root" directories.
  virtual bool GetMountPointForUser(const std::string& username,
                                    base::FilePath* path);

  // CryptohomeEventSourceSink
  virtual void NotifyEvent(CryptohomeEventBase* event);

  // Performs the work of resetting the TPM context.
  virtual void DoResetTPMContext(UserSession* session);

  // TpmInit::OwnershipCallback
  virtual void OwnershipCallback(bool status, bool took_ownership);

  // Finalize TPM initialization after taking ownership:
  // - initialize & finalize install attributes
  // - send TpmInitStatus event
  // - prepare for enrollment
  // Posted on mount_thread_ by OwnershipCallback.
  virtual void ConfigureOwnedTpm(bool status, bool took_ownership);

  // Called during initialization (and on mount events) to ensure old mounts
  // are marked for unmount when possible by the kernel.  Returns true if any
  // mounts were stale and not cleaned up (because of open files).
  //
  // Parameters
  // - force: if true, unmounts all existing shadow mounts.
  //          if false, unmounts shadows mounts with no open files.
  virtual bool CleanUpStaleMounts(bool force);

  // Called during mount requests to ensure old hidden mounts are unmount.
  // Note that this only cleans up |mounts_| entries which were mounted with
  // the hidden_mount=true parameter, as these are supposed to be temporary.
  // Old mounts from another cryptohomed run (e.g. after a crash) are cleaned up
  // in CleanUpStaleMounts.
  virtual bool CleanUpHiddenMounts();

  void set_legacy_mount(bool legacy) { legacy_mount_ = legacy; }
  void set_bind_mount_downloads(bool bind) { bind_mount_downloads_ = bind; }
  void set_force_ecryptfs(bool force_ecryptfs) {
    force_ecryptfs_ = force_ecryptfs;
  }

  void set_cleanup_threshold(uint64_t cleanup_threshold);
  void set_aggressive_cleanup_threshold(uint64_t aggressive_cleanup_threshold);
  void set_target_free_space(uint64_t target_free_space);

  virtual void set_boot_lockbox(BootLockbox* boot_lockbox) {
    boot_lockbox_ = boot_lockbox;
  }

  virtual void set_boot_attributes(BootAttributes* boot_attributes) {
    boot_attributes_ = boot_attributes;
  }

  virtual void set_firmware_management_parameters(
      FirmwareManagementParameters* fwmp) {
    firmware_management_parameters_ = fwmp;
  }

  virtual void set_low_disk_notification_period_ms(int value) {
    low_disk_notification_period_ms_ = value;
  }

  virtual void set_upload_alerts_period_ms(int value) {
    upload_alerts_period_ms_ = value;
  }

  // Service implementation functions as wrapped in interface.cc
  // and defined in cryptohome.xml.
  virtual void DoMigrateKeyEx(AccountIdentifier* account,
                              AuthorizationRequest* auth_request,
                              MigrateKeyRequest* migrate_request,
                              DBusGMethodInvocation* context);
  virtual gboolean MigrateKeyEx(GArray* account,
                                GArray* auth_request,
                                GArray* migrate_request,
                                DBusGMethodInvocation* context);
  virtual void DoAddKeyEx(AccountIdentifier* account_id,
                          AuthorizationRequest* authorization_request,
                          AddKeyRequest* add_key_request,
                          DBusGMethodInvocation* context);
  virtual gboolean AddKeyEx(GArray* account_id,
                            GArray* authorization_request,
                            GArray* add_key_request,
                            DBusGMethodInvocation* context);
  virtual void DoAddDataRestoreKey(AccountIdentifier* account_id,
                                   AuthorizationRequest* authorization_request,
                                   DBusGMethodInvocation* context);
  virtual gboolean AddDataRestoreKey(GArray* account_id,
                                     GArray* authorization_request,
                                     DBusGMethodInvocation* context);
  virtual void DoCheckKeyEx(
      std::unique_ptr<AccountIdentifier> account_id,
      std::unique_ptr<AuthorizationRequest> authorization_request,
      std::unique_ptr<CheckKeyRequest> check_key_request,
      DBusGMethodInvocation* context);
  virtual gboolean CheckKeyEx(GArray* account_id,
                              GArray* authorization_request,
                              GArray* check_key_request,
                              DBusGMethodInvocation* context);
  virtual void DoRemoveKeyEx(AccountIdentifier* account_id,
                             AuthorizationRequest* authorization_request,
                             RemoveKeyRequest* remove_key_request,
                             DBusGMethodInvocation* context);
  virtual gboolean RemoveKeyEx(GArray* account_id,
                               GArray* authorization_request,
                               GArray* remove_key_request,
                               DBusGMethodInvocation* context);
  virtual void DoMassRemoveKeys(AccountIdentifier* account_id,
                                AuthorizationRequest* authorization_request,
                                MassRemoveKeysRequest* mass_remove_keys_request,
                                DBusGMethodInvocation* context);
  virtual gboolean MassRemoveKeys(GArray* account_id,
                                  GArray* authorization_request,
                                  GArray* mass_remove_keys_request,
                                  DBusGMethodInvocation* context);
  virtual void DoGetKeyDataEx(AccountIdentifier* account_id,
                              AuthorizationRequest* authorization_request,
                              GetKeyDataRequest* get_key_data_request,
                              DBusGMethodInvocation* context);
  virtual gboolean GetKeyDataEx(GArray* account_id,
                                GArray* authorization_request,
                                GArray* get_key_data_request,
                                DBusGMethodInvocation* context);
  virtual void DoListKeysEx(AccountIdentifier* account_id,
                            AuthorizationRequest* authorization_request,
                            ListKeysRequest* list_keys_request,
                            DBusGMethodInvocation* context);
  virtual gboolean ListKeysEx(GArray* account_id,
                              GArray* authorization_request,
                              GArray* list_keys_request,
                              DBusGMethodInvocation* context);
  virtual void DoRemoveEx(AccountIdentifier* account_id,
                          DBusGMethodInvocation* context);
  virtual gboolean RemoveEx(GArray* account, DBusGMethodInvocation* context);
  virtual gboolean RenameCryptohome(const GArray* account_id_from,
                                    const GArray* account_id_to,
                                    DBusGMethodInvocation* response);
  virtual gboolean GetAccountDiskUsage(const GArray* account_id,
                                       DBusGMethodInvocation* response);
  virtual gboolean GetSystemSalt(GArray** OUT_salt, GError** error);
  virtual gboolean GetSanitizedUsername(gchar* username,
                                        gchar** OUT_sanitized,
                                        GError** error);
  virtual gboolean IsMountedForUser(gchar* user,
                                    gboolean* OUT_is_mounted,
                                    gboolean* OUT_is_ephemeral_mount,
                                    GError** error);
  virtual gboolean IsMounted(gboolean* OUT_is_mounted, GError** error);

  void DoUpdateTimestamp(scoped_refptr<UserSession> session);
  void DoMount(scoped_refptr<UserSession> session,
               const Credentials& credentials,
               const Mount::MountArgs& mount_args,
               base::WaitableEvent* event,
               MountError* return_code,
               bool* return_status);
  virtual gboolean Mount(const gchar* user,
                         const gchar* key,
                         gboolean create_if_missing,
                         gboolean ensure_ephemeral,
                         gint* OUT_error_code,
                         gboolean* OUT_result,
                         GError** error);

  virtual void DoMountEx(std::unique_ptr<AccountIdentifier> identifier,
                         std::unique_ptr<AuthorizationRequest> authorization,
                         std::unique_ptr<MountRequest> request,
                         DBusGMethodInvocation* response);
  virtual void DoRenameCryptohome(AccountIdentifier* id_from,
                                  AccountIdentifier* id_to,
                                  DBusGMethodInvocation* context);
  virtual void DoGetAccountDiskUsage(AccountIdentifier* id,
                                     DBusGMethodInvocation* context);
  virtual gboolean MountEx(const GArray* account_id,
                           const GArray* authorization_request,
                           const GArray* mount_request,
                           DBusGMethodInvocation* response);
  virtual void DoMountGuestEx(scoped_refptr<UserSession> guest_session,
                              std::unique_ptr<MountGuestRequest> request_pb,
                              DBusGMethodInvocation* context);
  virtual gboolean MountGuestEx(GArray* request,
                                DBusGMethodInvocation* context);
  virtual gboolean Unmount(gboolean* OUT_result, GError** error);
  virtual void DoUnmountEx(std::unique_ptr<UnmountRequest> request_pb,
                           DBusGMethodInvocation* context);
  virtual gboolean UnmountEx(GArray* request, DBusGMethodInvocation* context);
  virtual gboolean UpdateCurrentUserActivityTimestamp(gint time_shift_sec,
                                                      GError** error);

  virtual gboolean TpmIsReady(gboolean* OUT_ready, GError** error);
  virtual gboolean TpmIsEnabled(gboolean* OUT_enabled, GError** error);
  virtual gboolean TpmGetPassword(gchar** OUT_password, GError** error);
  virtual gboolean TpmIsOwned(gboolean* OUT_owned, GError** error);
  virtual gboolean TpmIsBeingOwned(gboolean* OUT_owning, GError** error);
  virtual gboolean TpmCanAttemptOwnership(GError** error);
  virtual gboolean TpmClearStoredPassword(GError** error);

  virtual gboolean MigrateToDircrypto(const GArray* account_id,
                                      const GArray* migrate_request,
                                      GError** error);
  // Runs on the mount thread.
  virtual void DoMigrateToDircrypto(AccountIdentifier* identifier,
                                    MigrationType migration_type);

  virtual gboolean NeedsDircryptoMigration(const GArray* account_id,
                                           gboolean* OUT_needs_migration,
                                           GError** error);

  virtual gboolean GetSupportedKeyPolicies(const GArray* request,
                                           DBusGMethodInvocation* context);
  virtual void DoGetSupportedKeyPolicies(const std::string& request,
                                         DBusGMethodInvocation* context);

  // Remote Server Unlock related methods
  virtual void DoGetRsuDeviceId(DBusGMethodInvocation* context);
  virtual gboolean GetRsuDeviceId(const GArray* request,
                                  DBusGMethodInvocation* context);

  // Attestation functionality is implemented in descendant classes

  // Attestation-related hooks.
  // Called from Service::Initialize() before any other attestation calls.
  virtual void AttestationInitialize() = 0;
  // Called from Service::Initialize() if initialize_tpm_ is true.
  virtual void AttestationInitializeTpm() = 0;
  // Called from Service::OwnershipCallback().
  virtual void AttestationInitializeTpmComplete() = 0;
  // Called to fill attestation preparations. Returns |true| in case of
  // success, |false| otherwise.
  virtual bool AttestationGetEnrollmentPreparations(
      const AttestationGetEnrollmentPreparationsRequest& request,
      AttestationGetEnrollmentPreparationsReply* reply) = 0;
  // Called from Service::DoGetTpmStatus to fill attestation-related fields.
  virtual void AttestationGetTpmStatus(GetTpmStatusReply* reply) = 0;
  // Called from Service::ResetDictionaryAttackMitigation()
  // Provides the owner delegate credentials normally used for AIK activation.
  // Returns true on success.
  virtual bool AttestationGetDelegateCredentials(
      brillo::Blob* blob,
      brillo::Blob* secret,
      bool* has_reset_lock_permissions) = 0;

  // Attestation-related DBus calls.
  virtual gboolean TpmIsAttestationPrepared(gboolean* OUT_prepared,
                                            GError** error) = 0;
  virtual gboolean TpmVerifyAttestationData(gboolean is_cros_core,
                                            gboolean* OUT_verified,
                                            GError** error) = 0;
  virtual gboolean TpmVerifyEK(gboolean is_cros_core,
                               gboolean* OUT_verified,
                               GError** error) = 0;
  virtual gboolean TpmAttestationCreateEnrollRequest(gint pca_type,
                                                     GArray** OUT_pca_request,
                                                     GError** error) = 0;
  virtual gboolean AsyncTpmAttestationCreateEnrollRequest(gint pca_type,
                                                          gint* OUT_async_id,
                                                          GError** error) = 0;
  virtual gboolean TpmAttestationEnroll(gint pca_type,
                                        GArray* pca_response,
                                        gboolean* OUT_success,
                                        GError** error) = 0;
  virtual gboolean AsyncTpmAttestationEnroll(gint pca_type,
                                             GArray* pca_response,
                                             gint* OUT_async_id,
                                             GError** error) = 0;
  virtual gboolean TpmAttestationEnrollEx(gint pca_type,
                                          gboolean forced,
                                          gboolean* OUT_success,
                                          GError** error) = 0;
  virtual gboolean AsyncTpmAttestationEnrollEx(gint pca_type,
                                               gboolean forced,
                                               gint* OUT_async_id,
                                               GError** error) = 0;
  virtual gboolean TpmAttestationCreateCertRequest(gint pca_type,
                                                   gint certificate_profile,
                                                   gchar* username,
                                                   gchar* request_origin,
                                                   GArray** OUT_pca_request,
                                                   GError** error) = 0;
  virtual gboolean AsyncTpmAttestationCreateCertRequest(
      gint pca_type,
      gint certificate_profile,
      gchar* username,
      gchar* request_origin,
      gint* OUT_async_id,
      GError** error) = 0;
  virtual gboolean TpmAttestationFinishCertRequest(GArray* pca_response,
                                                   gboolean is_user_specific,
                                                   gchar* username,
                                                   gchar* key_name,
                                                   GArray** OUT_cert,
                                                   gboolean* OUT_success,
                                                   GError** error) = 0;
  virtual gboolean AsyncTpmAttestationFinishCertRequest(
      GArray* pca_response,
      gboolean is_user_specific,
      gchar* username,
      gchar* key_name,
      gint* OUT_async_id,
      GError** error) = 0;
  virtual gboolean TpmAttestationGetCertificateEx(
      gint certificate_profile,
      gchar* username,
      gchar* request_origin,
      gint pca_type,
      gint key_type,
      gchar* key_name,
      gboolean forced,
      gboolean shall_trigger_enrollment,
      GArray** OUT_certificate,
      gboolean* OUT_success,
      GError** error) = 0;
  virtual gboolean AsyncTpmAttestationGetCertificateEx(
      gint certificate_profile,
      gchar* username,
      gchar* request_origin,
      gint pca_type,
      gint key_type,
      gchar* key_name,
      gboolean forced,
      gboolean shall_trigger_enrollment,
      gint* OUT_async_id,
      GError** error) = 0;
  virtual gboolean TpmIsAttestationEnrolled(gboolean* OUT_is_enrolled,
                                            GError** error) = 0;
  virtual gboolean TpmAttestationDoesKeyExist(gboolean is_user_specific,
                                              gchar* username,
                                              gchar* key_name,
                                              gboolean* OUT_exists,
                                              GError** error) = 0;
  virtual gboolean TpmAttestationGetCertificate(gboolean is_user_specific,
                                                gchar* username,
                                                gchar* key_name,
                                                GArray** OUT_certificate,
                                                gboolean* OUT_success,
                                                GError** error) = 0;
  virtual gboolean TpmAttestationGetPublicKey(gboolean is_user_specific,
                                              gchar* username,
                                              gchar* key_name,
                                              GArray** OUT_public_key,
                                              gboolean* OUT_success,
                                              GError** error) = 0;
  virtual gboolean TpmAttestationRegisterKey(gboolean is_user_specific,
                                             gchar* username,
                                             gchar* key_name,
                                             gint* OUT_async_id,
                                             GError** error) = 0;
  virtual gboolean TpmAttestationSignEnterpriseChallenge(
      gboolean is_user_specific,
      gchar* username,
      gchar* key_name,
      gchar* domain,
      GArray* device_id,
      gboolean include_signed_public_key,
      GArray* challenge,
      gint* OUT_async_id,
      GError** error) = 0;
  virtual gboolean TpmAttestationSignEnterpriseVaChallenge(
      gint va_type,
      gboolean is_user_specific,
      gchar* username,
      gchar* key_name,
      gchar* domain,
      GArray* device_id,
      gboolean include_signed_public_key,
      GArray* challenge,
      gchar* key_name_for_spkac,
      gint* OUT_async_id,
      GError** error) = 0;
  virtual gboolean TpmAttestationSignSimpleChallenge(gboolean is_user_specific,
                                                     gchar* username,
                                                     gchar* key_name,
                                                     GArray* challenge,
                                                     gint* OUT_async_id,
                                                     GError** error) = 0;
  virtual gboolean TpmAttestationGetKeyPayload(gboolean is_user_specific,
                                               gchar* username,
                                               gchar* key_name,
                                               GArray** OUT_payload,
                                               gboolean* OUT_success,
                                               GError** error) = 0;
  virtual gboolean TpmAttestationSetKeyPayload(gboolean is_user_specific,
                                               gchar* username,
                                               gchar* key_name,
                                               GArray* payload,
                                               gboolean* OUT_success,
                                               GError** error) = 0;
  virtual gboolean TpmAttestationDeleteKeys(gboolean is_user_specific,
                                            gchar* username,
                                            gchar* key_prefix,
                                            gboolean* OUT_success,
                                            GError** error) = 0;
  virtual gboolean TpmAttestationDeleteKey(gboolean is_user_specific,
                                           gchar* username,
                                           gchar* key_name,
                                           gboolean* OUT_success,
                                           GError** error) = 0;
  virtual gboolean TpmAttestationGetEK(gchar** ek_info,
                                       gboolean* OUT_success,
                                       GError** error) = 0;
  virtual gboolean TpmAttestationResetIdentity(gchar* reset_token,
                                               GArray** OUT_reset_request,
                                               gboolean* OUT_success,
                                               GError** error) = 0;
  virtual gboolean TpmGetVersionStructured(guint32* OUT_family,
                                           guint64* OUT_spec_level,
                                           guint32* OUT_manufacturer,
                                           guint32* OUT_tpm_model,
                                           guint64* OUT_firmware_version,
                                           gchar** OUT_vendor_specific,
                                           GError** error);
  virtual gboolean GetEndorsementInfo(const GArray* request,
                                      DBusGMethodInvocation* context) = 0;
  virtual gboolean InitializeCastKey(const GArray* request,
                                     DBusGMethodInvocation* context) = 0;

  // Returns the label of the TPM token along with its user PIN.
  virtual gboolean Pkcs11GetTpmTokenInfo(gchar** OUT_label,
                                         gchar** OUT_user_pin,
                                         gint* OUT_slot,
                                         GError** error);
  // Returns the label of the TPM token along with its user PIN.
  virtual gboolean Pkcs11GetTpmTokenInfoForUser(gchar* username,
                                                gchar** OUT_label,
                                                gchar** OUT_user_pin,
                                                gint* OUT_slot,
                                                GError** error);

  // Returns in |OUT_ready| whether the TPM token is ready for use.
  virtual gboolean Pkcs11IsTpmTokenReady(gboolean* OUT_ready, GError** error);
  virtual gboolean Pkcs11Terminate(gchar* username, GError** error);
  virtual gboolean GetStatusString(gchar** OUT_status, GError** error);

  // Runs on the mount thread.
  virtual void CreateFingerprintManager();

  // InstallAttributes methods
  virtual gboolean InstallAttributesGet(gchar* name,
                                        GArray** OUT_value,
                                        gboolean* OUT_successful,
                                        GError** error);
  virtual gboolean InstallAttributesSet(gchar* name,
                                        GArray* value,
                                        gboolean* OUT_successful,
                                        GError** error);
  virtual gboolean InstallAttributesFinalize(gboolean* OUT_finalized,
                                             GError** error);
  virtual gboolean InstallAttributesCount(gint* OUT_count, GError** error);
  virtual gboolean InstallAttributesIsReady(gboolean* OUT_ready,
                                            GError** error);
  virtual gboolean InstallAttributesIsSecure(gboolean* OUT_secure,
                                             GError** error);
  virtual gboolean InstallAttributesIsInvalid(gboolean* OUT_invalid,
                                              GError** error);
  virtual gboolean InstallAttributesIsFirstInstall(gboolean* OUT_first_install,
                                                   GError** error);

  // Runs on the mount thread.
  virtual void DoSignBootLockbox(const brillo::Blob& request,
                                 DBusGMethodInvocation* context);
  virtual gboolean SignBootLockbox(const GArray* request,
                                   DBusGMethodInvocation* context);
  // Runs on the mount thread.
  virtual void DoVerifyBootLockbox(const brillo::Blob& request,
                                   DBusGMethodInvocation* context);
  virtual gboolean VerifyBootLockbox(const GArray* request,
                                     DBusGMethodInvocation* context);
  // Runs on the mount thread.
  virtual void DoFinalizeBootLockbox(const brillo::Blob& request,
                                     DBusGMethodInvocation* context);
  virtual gboolean FinalizeBootLockbox(const GArray* request,
                                       DBusGMethodInvocation* context);

  // Runs on the mount thread.
  virtual void DoGetBootAttribute(const brillo::Blob& request,
                                  DBusGMethodInvocation* context);
  virtual gboolean GetBootAttribute(const GArray* request,
                                    DBusGMethodInvocation* context);
  // Runs on the mount thread.
  virtual void DoSetBootAttribute(const brillo::Blob& request,
                                  DBusGMethodInvocation* context);
  virtual gboolean SetBootAttribute(const GArray* request,
                                    DBusGMethodInvocation* context);
  // Runs on the mount thread.
  virtual void DoFlushAndSignBootAttributes(const brillo::Blob& request,
                                            DBusGMethodInvocation* context);
  virtual gboolean FlushAndSignBootAttributes(const GArray* request,
                                              DBusGMethodInvocation* context);
  // Runs on the mount thread.
  virtual void DoGetLoginStatus(const brillo::SecureBlob& request,
                                DBusGMethodInvocation* context);
  virtual gboolean GetLoginStatus(const GArray* request,
                                  DBusGMethodInvocation* context);
  // Runs on the mount thread.
  virtual void DoTpmAttestationGetEnrollmentPreparationsEx(
      const brillo::Blob& request, DBusGMethodInvocation* context);
  virtual gboolean TpmAttestationGetEnrollmentPreparationsEx(
      const GArray* request, DBusGMethodInvocation* context);
  // Runs on the mount thread.
  virtual void DoGetTpmStatus(const brillo::SecureBlob& request,
                              DBusGMethodInvocation* context);
  virtual gboolean GetTpmStatus(const GArray* request,
                                DBusGMethodInvocation* context);
  // Runs on the mount thread.
  virtual void DoStartFingerprintAuthSession(
      std::unique_ptr<AccountIdentifier> account_id,
      std::unique_ptr<StartFingerprintAuthSessionRequest> request,
      DBusGMethodInvocation* context);
  virtual gboolean StartFingerprintAuthSession(const GArray* account_id,
                                               const GArray* request,
                                               DBusGMethodInvocation* context);
  // Runs on the mount thread.
  virtual void DoEndFingerprintAuthSession(
      std::unique_ptr<EndFingerprintAuthSessionRequest> request,
      DBusGMethodInvocation* context);
  virtual gboolean EndFingerprintAuthSession(const GArray* request,
                                             DBusGMethodInvocation* context);

  // Runs on the mount thread.
  virtual gboolean GetWebAuthnSecret(const GArray* account_id,
                                     const GArray* request,
                                     DBusGMethodInvocation* context);

  // Runs on the mount thread.
  virtual void DoGetFirmwareManagementParameters(
      const brillo::SecureBlob& request, DBusGMethodInvocation* context);
  virtual gboolean GetFirmwareManagementParameters(
      const GArray* request, DBusGMethodInvocation* context);

  // Runs on the mount thread.
  virtual void DoSetFirmwareManagementParameters(
      const brillo::SecureBlob& request, DBusGMethodInvocation* context);
  virtual gboolean SetFirmwareManagementParameters(
      const GArray* request, DBusGMethodInvocation* context);

  // Runs on the mount thread.
  virtual void DoRemoveFirmwareManagementParameters(
      const brillo::SecureBlob& request, DBusGMethodInvocation* context);
  virtual gboolean RemoveFirmwareManagementParameters(
      const GArray* request, DBusGMethodInvocation* context);

  virtual gboolean TpmAttestationGetEnrollmentId(gboolean ignore_cache,
                                                 GArray** OUT_enrollment_id,
                                                 gboolean* OUT_success,
                                                 GError** error) = 0;

  // Runs the event loop once. Only for testing.
  virtual void DispatchEventsForTesting();

  // Return the next sequence number.
  int NextSequence();

  // Whether or not quota-based disk usage stats is supported.
  virtual gboolean IsQuotaSupported(gboolean* OUT_quota_supported,
                                    GError** error);

  // Get the current disk space usage for the given uid.
  virtual gboolean GetCurrentSpaceForUid(guint32 uid,
                                         gint64* OUT_cur_space,
                                         GError** error);

  // Get the current disk space usage for the given gid.
  virtual gboolean GetCurrentSpaceForGid(guint gid,
                                         gint64* OUT_cur_space,
                                         GError** error);

  // Get the current disk space usage for the given project ID.
  virtual gboolean GetCurrentSpaceForProjectId(guint project_id,
                                               gint64* OUT_cur_space,
                                               GError** error);

  // Sets the project ID to the file/directory pointed by path.
  virtual gboolean SetProjectId(guint project_id,
                                gint parent_path,
                                gchar* child_path,
                                GArray* account_id,
                                gboolean* OUT_success,
                                GError** error);

  virtual gboolean LockToSingleUserMountUntilReboot(
      const GArray* request, DBusGMethodInvocation* context);

  virtual void DoLockToSingleUserMountUntilReboot(
      const std::string& obfuscated_username, DBusGMethodInvocation* context);

  virtual gboolean CheckHealth(const GArray* request,
                               DBusGMethodInvocation* context);

  void PostTaskToEventLoop(base::OnceClosure task);

  virtual gboolean StartAuthSession(const GArray* account_id,
                                    const GArray* request,
                                    DBusGMethodInvocation* context);

 protected:
  FRIEND_TEST(ServiceTest, NoDeadlocksInInitializeTpmComplete);

  // Meta data for each imcoming dbus requests
  struct RequestTrackedInfo {
    std::string name;
    base::Time start_time;
  };

  GMainLoop* loop_;
  // Can't use unique_ptr for cryptohome_ because memory is allocated by glib.
  gobject::Cryptohome* cryptohome_;
  brillo::SecureBlob system_salt_;
  std::unique_ptr<cryptohome::Platform> default_platform_;
  cryptohome::Platform* platform_;
  std::unique_ptr<cryptohome::Crypto> default_crypto_;
  cryptohome::Crypto* crypto_;
  // TPM doesn't use the unique_ptr for default pattern, since the tpm is a
  // singleton - we don't want it getting destroyed when we are.
  Tpm* tpm_;
  std::unique_ptr<TpmInit> default_tpm_init_;
  TpmInit* tpm_init_;
  std::unique_ptr<FingerprintManager> fingerprint_manager_;
  std::unique_ptr<Pkcs11Init> default_pkcs11_init_;
  Pkcs11Init* pkcs11_init_;
  bool initialize_tpm_;
  MountThreadObserver mount_thread_observer_;
  base::Thread mount_thread_;
  guint async_complete_signal_;
  // A completion signal for async calls that return data.
  guint async_data_complete_signal_;
  guint tpm_init_signal_;
  guint low_disk_space_signal_;
  guint dircrypto_migration_progress_signal_;
  bool low_disk_space_signal_was_emitted_;
  CryptohomeEventSource event_source_;
  CryptohomeEventSourceSink* event_source_sink_;
  base::Time last_auto_cleanup_time_;
  base::Time last_user_activity_timestamp_time_;
  std::unique_ptr<cryptohome::InstallAttributes> default_install_attrs_;
  cryptohome::InstallAttributes* install_attrs_;
  // Keeps track of whether a failure on PKCS#11 initialization was reported
  // during this user login. We use this not to report a same failure multiple
  // times.
  bool reported_pkcs11_init_fail_;
  // Keeps track of whether the device is enterprise-owned.
  bool enterprise_owned_;
  // Track the metadata of incoming dbus request, used for reporting UMA.
  std::map<int, RequestTrackedInfo> async_id_tracked_info_;

  // Should we skip the ownership taken signal connection. This value shouldn't
  // be true unless it's for testing purposes.
  //
  // TODO(garryxiao): remove this after we migrate to the new dbus librabry.
  bool skip_ownership_taken_signal_connection_;

  virtual GMainLoop* main_loop() { return loop_; }

  // Called periodically from LowDiskCallback to initiate automatic disk
  // cleanup if needed.
  virtual void DoAutoCleanup();
  // Called periodically from LowDiskCallback.
  // Update current user's activity timestamp every day.
  virtual void UpdateCurrentUserActivityTimestamp();
  // Called periodically on Mount thread to detect low disk space and emit a
  // signal if detected.
  virtual void LowDiskCallback();
  // Called periodically to fetch alerts data from TPM and upload it to UMA.
  virtual void UploadAlertsDataCallback();
  // Filters out active mounts from |mounts|, populating |active_mounts| set.
  // If |force| is false, it ignores stale mounts that that have open files
  // and mount points connected to children of the mount source.
  // Returns true if any stale mount filtered out because of open files.
  virtual bool FilterActiveMounts(
      std::multimap<const base::FilePath, const base::FilePath>* mounts,
      std::multimap<const base::FilePath, const base::FilePath>* active_mounts,
      bool force);
  // Populates |mounts| with ephemeral cryptohome mount points.
  virtual void GetEphemeralLoopDevicesMounts(
      std::multimap<const base::FilePath, const base::FilePath>* mounts);

  // Checks if the machine is enterprise owned and report to mount_ then.
  virtual void DetectEnterpriseOwnership();

  // Creates and initialized MountObject for user
  scoped_refptr<cryptohome::Mount> CreateMount(const std::string& username);

  // Returns session associated with mount.
  // TODO(dlunev): This function is required for single place and I am pretty
  // certain that code path is dead. However, the leads to the place are
  // extremely hard to track because they are intertwined with seamingly
  // alive code. Thus just have this function for now and let it die with the
  // Service itself.
  scoped_refptr<UserSession> GetUserSessionForMount(cryptohome::Mount* mount);

  // Returns the UserSession object associated with the given username
  scoped_refptr<UserSession> GetUserSession(const std::string& username);

  // Returns either and existing or a newly created UserSession, if not present.
  scoped_refptr<UserSession> GetOrCreateUserSession(
      const std::string& username);

  // Safely removes the reference to the UserSession from. This method returns
  // true if as a result of the operation there is no reference to a session of
  // the given user (including if it was absent in the first place).
  bool RemoveUserSession(const std::string& username);
  // Removes session by the pointer.
  bool RemoveUserSession(UserSession* session);

  // Safely empties the MountMap and may request unmounting. If |unmount| is
  // true, the return value will reflect if all mounts unmounted cleanly or not.
  virtual bool RemoveAllMounts(bool unmount);

  // Unload any pkcs11 tokens _not_ belonging to one of the mounts in |exclude|.
  // This is used to clean up any stale loaded tokens after a cryptohome crash.
  virtual bool UnloadPkcs11Tokens(const std::vector<base::FilePath>& exclude);

  // A wrapper for PostTask to mount_thread_ which also count some metrics
  virtual void PostTask(const base::Location& from_here,
                        base::OnceClosure task);

  // Posts a message back from the mount_thread_ to the main thread to
  // reply to a DBus message.  Only call from mount_thread_-based
  // functions!
  virtual void SendReply(DBusGMethodInvocation* context,
                         const BaseReply& reply);

  // Helper methods that post a message back to the main thread where
  // a DBus InvalidArgs GError is returned to the caller.
  // Only call from mount_thread_-based functions!
  virtual void SendDBusErrorReply(DBusGMethodInvocation* context,
                                  GQuark domain,
                                  gint code,
                                  const gchar* message);
  virtual void SendInvalidArgsReply(DBusGMethodInvocation* context,
                                    const char* message) {
    SendDBusErrorReply(context, DBUS_GERROR, DBUS_GERROR_INVALID_ARGS, message);
  }
  virtual void SendFailureReply(DBusGMethodInvocation* context,
                                const char* message) {
    SendDBusErrorReply(context, DBUS_GERROR, DBUS_GERROR_FAILED, message);
  }
  virtual void SendNotSupportedReply(DBusGMethodInvocation* context,
                                     const char* message) {
    SendDBusErrorReply(context, DBUS_GERROR, DBUS_GERROR_NOT_SUPPORTED,
                       message);
  }

  // Returns a CryptohomeErrorCode for an internal Mount::MountError code.
  virtual CryptohomeErrorCode MountErrorToCryptohomeError(
      const MountError code) const;

  // Sends a signal for notifying the migration progress.
  // Runs on the mount thread.
  virtual void SendDircryptoMigrationProgressSignal(
      DircryptoMigrationStatus status,
      uint64_t current_bytes,
      uint64_t total_bytes);

  // This is a simple conversion that takes the protobuf version of the progress
  // callback and forward it to SendDircryptoMigrationProgressSignal() above.
  virtual void SendDircryptoMigrationProgressSignalProto(
      const user_data_auth::DircryptoMigrationProgress& progress);

  // Listens to the ownership taken signal sent from tpm manager.
  virtual void ConnectOwnershipTakenSignal() = 0;

  // Stop processing tasks on dbus and mount threads.
  // Must be called from derived destructors. Otherwise, after derived
  // destructor, all pure virtual functions from Service overloaded there and
  // all members defined for that class will be gone, while mount_thread_
  // will continue running tasks until stopped in ~Service.
  void StopTasks();

  // Store the information for |async_id| which is unique of dbus requests.
  // |name| and |start_time| will store and report to UMA when this |async_id|
  // is replied.
  void LogAsyncIdInfo(int async_id, std::string name, base::Time start_time);
  // Report the UMA of the running time of |async_id| and cleanup the stored
  // information.
  void SendAsyncIdInfoToUma(int async_id, base::Time finished_time);

  // Called on Mount thread. This method calls ReportDictionaryAttackResetStatus
  // exactly once (i.e. records one sample) with the status of the operation.
  void ResetDictionaryAttackMitigation();

 private:
  FRIEND_TEST(ServiceTest, GetPublicMountPassKey);

  std::unique_ptr<brillo::SecureBlob> GetAttestationBasedEnrollmentData();

  bool CreatePublicMountSaltIfNeeded();

  // Gets passkey for |public_mount_id|. Returns true if a passkey is generated
  // successfully. Otherwise, returns false.
  bool GetPublicMountPassKey(const std::string& public_mount_id,
                             std::string* public_mount_passkey);

  // Performs the lazy part of the initialization that is required for
  // performing operations with challenge-response keys. Returns whether
  // succeeded.
  bool InitForChallengeResponseAuth(CryptohomeErrorCode* error_code);

  // Called on Mount thread. This triggers the credentials verification steps
  // that are specific to challenge-response keys, going through
  // {TryLightweightChallengeResponseCheckKeyEx(),
  // OnLightweightChallengeResponseCheckKeyExDone()} and/or
  // {DoFullChallengeResponseCheckKeyEx(),
  // OnFullChallengeResponseCheckKeyExDone()}.
  void DoChallengeResponseCheckKeyEx(
      std::unique_ptr<AccountIdentifier> identifier,
      std::unique_ptr<AuthorizationRequest> authorization,
      DBusGMethodInvocation* context);
  void TryLightweightChallengeResponseCheckKeyEx(
      std::unique_ptr<AccountIdentifier> identifier,
      std::unique_ptr<AuthorizationRequest> authorization,
      DBusGMethodInvocation* context);
  void OnLightweightChallengeResponseCheckKeyExDone(
      std::unique_ptr<AccountIdentifier> identifier,
      std::unique_ptr<AuthorizationRequest> authorization,
      DBusGMethodInvocation* context,
      bool is_key_valid);
  void DoFullChallengeResponseCheckKeyEx(
      std::unique_ptr<AccountIdentifier> identifier,
      std::unique_ptr<AuthorizationRequest> authorization,
      DBusGMethodInvocation* context);
  void OnFullChallengeResponseCheckKeyExDone(
      DBusGMethodInvocation* context, std::unique_ptr<Credentials> credentials);

  // Called on Mount thread. This triggers the credentials generation steps that
  // are specific to challenge-response keys, before scheduling
  // ContinueMountExWithCredentials().
  void DoChallengeResponseMountEx(
      std::unique_ptr<AccountIdentifier> identifier,
      std::unique_ptr<AuthorizationRequest> authorization,
      std::unique_ptr<MountRequest> request,
      const Mount::MountArgs& mount_args,
      DBusGMethodInvocation* context);
  // Called on Mount thread when the challenge-response credentials are
  // obtained.
  void OnChallengeResponseMountCredentialsObtained(
      std::unique_ptr<AccountIdentifier> identifier,
      std::unique_ptr<AuthorizationRequest> authorization,
      std::unique_ptr<MountRequest> request,
      const Mount::MountArgs& mount_args,
      DBusGMethodInvocation* context,
      std::unique_ptr<Credentials> credentials);

  // Called on Mount thread. This method completes the MountEx request, given
  // the built Credentials object. It assumes that the input parameters went
  // through format validity checks.
  void ContinueMountExWithCredentials(
      std::unique_ptr<AccountIdentifier> identifier,
      std::unique_ptr<AuthorizationRequest> authorization,
      std::unique_ptr<MountRequest> request,
      std::unique_ptr<Credentials> credentials,
      const Mount::MountArgs& mount_args,
      DBusGMethodInvocation* context);

  // Builds the PCR restrictions to be applied to the challenge-protected vault
  // keyset.
  void GetChallengeCredentialsPcrRestrictions(
      const std::string& obfuscated_username,
      std::vector<std::map<uint32_t, brillo::Blob>>* pcr_restrictions);

  // Determines whether the mount request should be ephemeral. On error, returns
  // false and sets the error code in |error|. Otherwise, returns true and fills
  // the result in |is_ephemeral|.
  bool GetShouldMountAsEphemeral(const std::string& account_id,
                                 bool is_ephemeral_mount_requested,
                                 bool has_create_request,
                                 bool* is_ephemeral,
                                 MountError* error) const;
  // Called on Mount thread when starting fingerprint auth session succeeds or
  // fails.
  void OnStartFingerprintAuthSessionDone(DBusGMethodInvocation* context,
                                         bool success);

  // Called on Mount thread. Scheduled by DoCheckKeyEx(). Callback for one
  // fingerprint scan. Completes fingerprint CheckKeyEx by replying to the
  // CheckKeyEx call in |context|. Sets the error if the scan has an error.
  void CompleteFingerprintCheckKeyEx(DBusGMethodInvocation* context,
                                     FingerprintScanStatus status);

  // This is a utility function for stateful recovery functionality to call when
  // it wants to mount a user's home directory. The user specified by
  // |username|'s home is mounted with |passkey|, and if successfully mounted,
  // returns true and set out_home_path to the mounted home. Otherwise, returns
  // false. Note that this function must log any error itself, no logging will
  // be done by the caller.
  bool StatefulRecoveryMount(const std::string& username,
                             const std::string& passkey,
                             FilePath* out_home_path);

  // This is a utility function for stateful recovery to unmount all user's home
  // directories. It'll return true if all the user's home directories are
  // successfully unmounted. Otherwise, it'll return false. Note that this
  // function must log any error itself, no logging will be done by the caller.
  bool StatefulRecoveryUnmount();

  // Ensures BootLockbox is finalized;
  void EnsureBootLockboxFinalized();

  brillo::DBusConnection system_dbus_connection_;

  // Tracks UserSession objects for each user by username.
  typedef std::map<const std::string, scoped_refptr<UserSession>>
      UserSessionMap;
  UserSessionMap sessions_;
  base::Lock sessions_lock_;  // Protects against parallel insertions only.
  std::unique_ptr<UserOldestActivityTimestampCache> user_timestamp_cache_;
  std::unique_ptr<cryptohome::MountFactory> default_mount_factory_;
  cryptohome::MountFactory* mount_factory_;

  std::unique_ptr<KeysetManagement> default_keyset_management_;
  KeysetManagement* keyset_management_;
  std::unique_ptr<HomeDirs> default_homedirs_;
  HomeDirs* homedirs_;
  std::unique_ptr<ArcDiskQuota> default_arc_disk_quota_;
  ArcDiskQuota* arc_disk_quota_;
  std::unique_ptr<DiskCleanup> default_disk_cleanup_;
  DiskCleanup* disk_cleanup_;
  std::string guest_user_;
  bool force_ecryptfs_;
  bool legacy_mount_;
  bool bind_mount_downloads_;
  brillo::SecureBlob public_mount_salt_;
  std::unique_ptr<chaps::TokenManagerClient> default_chaps_client_;
  chaps::TokenManagerClient* chaps_client_;
  std::unique_ptr<BootLockbox> default_boot_lockbox_;
  // After construction, this should only be used on the mount thread.
  BootLockbox* boot_lockbox_;
  std::unique_ptr<BootAttributes> default_boot_attributes_;
  // After construction, this should only be used on the mount thread.
  BootAttributes* boot_attributes_;
  KeyChallengeServiceFactoryImpl default_key_challenge_service_factory_;
  KeyChallengeServiceFactory* key_challenge_service_factory_ =
      &default_key_challenge_service_factory_;
  std::unique_ptr<FirmwareManagementParameters>
      default_firmware_management_params_;
  FirmwareManagementParameters* firmware_management_parameters_;
  int low_disk_notification_period_ms_;
  int upload_alerts_period_ms_;
  std::unique_ptr<ChallengeCredentialsHelper>
      default_challenge_credentials_helper_;
  ChallengeCredentialsHelper* challenge_credentials_helper_ = nullptr;

  // An atomic incrementing sequence for setting asynchronous call ids.
  base::AtomicSequenceNumber sequence_holder_;

  // The signal callback to make GMainLoop quit gracefully.
  static gboolean ShutdownService(gpointer user_data);

  // This is set to true iff OwnershipCallback has run.
  bool ownership_callback_has_run_;
};

}  // namespace cryptohome

#endif  // CRYPTOHOME_SERVICE_H_
