| // 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/arc_disk_quota.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/migration_type.h" |
| #include "cryptohome/mount.h" |
| #include "cryptohome/mount_factory.h" |
| #include "cryptohome/mount_task.h" |
| #include "cryptohome/pkcs11_init.h" |
| #include "cryptohome/rpc.pb.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(); |
| 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; |
| } |
| virtual void set_use_tpm(bool value) { use_tpm_ = value; } |
| |
| // 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_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; |
| } |
| |
| // 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_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 DoUpdateKeyEx(AccountIdentifier* account_id, |
| AuthorizationRequest* authorization_request, |
| UpdateKeyRequest* update_key_request, |
| DBusGMethodInvocation* context); |
| virtual gboolean UpdateKeyEx(GArray* account_id, |
| GArray* authorization_request, |
| GArray* update_key_request, |
| DBusGMethodInvocation* response); |
| 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); |
| |
| 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); |
| |
| protected: |
| FRIEND_TEST(ServiceTest, NoDeadlocksInInitializeTpmComplete); |
| |
| // Meta data for each imcoming dbus requests |
| struct RequestTrackedInfo { |
| std::string name; |
| base::Time start_time; |
| }; |
| |
| bool use_tpm_; |
| |
| 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<HomeDirs> default_homedirs_; |
| HomeDirs* homedirs_; |
| std::unique_ptr<ArcDiskQuota> default_arc_disk_quota_; |
| ArcDiskQuota* arc_disk_quota_; |
| std::string guest_user_; |
| bool force_ecryptfs_; |
| bool legacy_mount_; |
| 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_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Service); |
| }; |
| |
| } // namespace cryptohome |
| |
| #endif // CRYPTOHOME_SERVICE_H_ |