| // Copyright 2020 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_FINGERPRINT_MANAGER_H_ |
| #define CRYPTOHOME_FINGERPRINT_MANAGER_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include <biod/biod_proxy/biometrics_manager_proxy_base.h> |
| |
| namespace cryptohome { |
| |
| const char kCrosFpBiometricsManagerRelativePath[] = "/CrosFpBiometricsManager"; |
| const int kMaxFingerprintRetries = 5; |
| |
| enum class FingerprintScanStatus { |
| SUCCESS = 0, |
| FAILED_RETRY_ALLOWED = 1, |
| FAILED_RETRY_NOT_ALLOWED = 2, |
| }; |
| |
| // FingerprintManager talks to Biometrics Daemon for starting/stopping |
| // fingerprint auth sessions, and receiving fingerprint auth results. |
| // |
| // This class is intended to be used only on a single thread / task runner only. |
| // Response callbacks will also be run on the same thread / task runner. |
| class FingerprintManager { |
| public: |
| using StartSessionCallback = base::Callback<void(bool success)>; |
| using ResultCallback = base::Callback<void(FingerprintScanStatus status)>; |
| |
| // Factory method. Returns nullptr if Biometrics Daemon is not in a good |
| // state or if the device does not have fingerprint support. |
| static std::unique_ptr<FingerprintManager> Create( |
| const scoped_refptr<dbus::Bus>& bus, const dbus::ObjectPath& path); |
| |
| FingerprintManager(); |
| virtual ~FingerprintManager(); |
| |
| const std::string& GetCurrentUser(); |
| |
| // Returns a weak pointer to this instance. Used when creating callbacks. |
| base::WeakPtr<FingerprintManager> GetWeakPtr(); |
| |
| // Starts fingerprint auth session asynchronously, and sets the user if auth |
| // session started successfully. |
| // |auth_session_start_client_callback| will be called with true if auth |
| // session started successfully, or called with false otherwise. |
| // |
| // One auth session may serve multiple fingerprint-related calls, e.g. |
| // multiple CheckKey() calls with KEY_TYPE_FINGERPRINT, until one of the |
| // following occurs: |
| // 1. One fingerprint scan succeeds, or a non-recoverable error occurs. |
| // |state_| will be set to AUTH_SESSION_LOCKED. |
| // 2. Max retry count reached for the current auth session. |state_| will be |
| // set to AUTH_SESSION_LOCKED. |
| // 3. EndAuthSession() is called, e.g. user decides to cancel operation |
| // through UI. |
| virtual void StartAuthSessionAsyncForUser( |
| const std::string& user, |
| StartSessionCallback auth_session_start_client_callback); |
| |
| // Tells Biometrics Daemon to end fingerprint auth session and resets all |
| // states. |
| virtual void EndAuthSession(); |
| |
| virtual bool HasAuthSessionForUser(const std::string& user); |
| |
| // Sets the callback for a fingerprint scan. Must be called after |
| // StartAuthSessionAsyncForUser. |auth_scan_done_callback| will be |
| // called with the status of a fingerprint match, once biod sends it. |
| virtual void SetAuthScanDoneCallback(ResultCallback auth_scan_done_callback); |
| |
| // For testing. |
| void SetProxy(biod::BiometricsManagerProxyBase* proxy); |
| |
| private: |
| friend class FingerprintManagerPeer; |
| |
| enum class State { |
| NO_AUTH_SESSION = 0, |
| AUTH_SESSION_OPEN = 1, |
| // A fatal error occurred, or max retry count reached, but auth |
| // session is not cancelled yet. |
| AUTH_SESSION_LOCKED = 2, |
| }; |
| |
| // Class for properly finish processing an AuthScanDone signal. |
| class AuthScanDoneResourceManager { |
| public: |
| explicit AuthScanDoneResourceManager( |
| FingerprintManager* fingerprint_manager) |
| : fingerprint_manager_(fingerprint_manager) {} |
| |
| ~AuthScanDoneResourceManager() { |
| fingerprint_manager_->auth_scan_done_callback_.Reset(); |
| // If auth session is still open, then we are waiting for retry, so keep |
| // |current_user_|. |
| if (fingerprint_manager_->state_ != State::AUTH_SESSION_OPEN) |
| fingerprint_manager_->current_user_.clear(); |
| } |
| |
| private: |
| FingerprintManager* fingerprint_manager_; |
| }; |
| |
| // Initializes the underlying dbus object proxy for BiometricsDaemon, and |
| // connects to relevant dbus signals. Returns false if failing to get the |
| // dbus object proxy (e.g. if biod is not in a good state or the device does |
| // not have fingerprint support). |
| bool Initialize(const scoped_refptr<dbus::Bus>& bus, |
| const dbus::ObjectPath& path); |
| |
| // Callback for connecting to biod's AuthScanDoneSignal. |
| void OnAuthScanDoneSignalConnected(const std::string& interface, |
| const std::string& signal, |
| bool success); |
| |
| // Signal handler biod::kBiometricsManagerAuthScanDoneSignal. |
| // Parses the auth scan result from biod, compares the matched user to |
| // |current_user_|, and calls |auth_scan_done_callback_|. |
| void OnAuthScanDone(dbus::Signal* signal); |
| |
| // Internal wrapper around the client's callback for starting auth session |
| // asynchronously. If auth session starts successfully, set |current_user_| |
| // before running the client's callback. |
| void SetUserAndRunClientCallback( |
| StartSessionCallback auth_session_start_client_callback, |
| const std::string& user, |
| bool success); |
| |
| // Calculates the retry count left in the current auth session, and run |
| // |auth_scan_done_callback_|. |
| void ProcessRetry(); |
| |
| void Reset(); |
| |
| // The default BiometricsManagerProxyBase object. |
| std::unique_ptr<biod::BiometricsManagerProxyBase> default_proxy_; |
| // The actual BiometricsManagerProxyBase object used in this class. |
| // Can be overridden for testing. |
| biod::BiometricsManagerProxyBase* proxy_; |
| bool connected_to_auth_scan_done_signal_; |
| ResultCallback auth_scan_done_callback_; |
| State state_ = State::NO_AUTH_SESSION; |
| // The obfuscated username tied to the current auth session. |
| std::string current_user_; |
| // The number of retries left in the current auth session. |
| int retry_left_ = 0; |
| base::WeakPtrFactory<FingerprintManager> weak_factory_; |
| base::PlatformThreadId mount_thread_id_; |
| }; |
| |
| } // namespace cryptohome |
| |
| #endif // CRYPTOHOME_FINGERPRINT_MANAGER_H_ |