Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chromeos / login / auth / cryptohome_authenticator.h
blobd767bd950aef0f8e33e858a942b4099043efcdcb
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROMEOS_LOGIN_AUTH_CRYPTOHOME_AUTHENTICATOR_H_
6 #define CHROMEOS_LOGIN_AUTH_CRYPTOHOME_AUTHENTICATOR_H_
8 #include <string>
10 #include "base/compiler_specific.h"
11 #include "base/gtest_prod_util.h"
12 #include "base/macros.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/synchronization/lock.h"
15 #include "base/task_runner.h"
16 #include "chromeos/chromeos_export.h"
17 #include "chromeos/login/auth/auth_attempt_state.h"
18 #include "chromeos/login/auth/auth_attempt_state_resolver.h"
19 #include "chromeos/login/auth/authenticator.h"
20 #include "chromeos/login/auth/test_attempt_state.h"
21 #include "google_apis/gaia/gaia_auth_consumer.h"
23 class AuthFailure;
25 namespace content {
26 class BrowserContext;
29 namespace chromeos {
31 class AuthStatusConsumer;
33 // Authenticates a Chromium OS user against cryptohome.
34 // Relies on the fact that online authentications has been already performed
35 // (i.e. using_oauth_ is true).
37 // At a high, level, here's what happens:
38 // AuthenticateToLogin() calls a Cryptohome's method to perform offline login.
39 // Resultes are stored in a AuthAttemptState owned by CryptohomeAuthenticator
40 // and then call Resolve(). Resolve() will attempt to
41 // determine which AuthState we're in, based on the info at hand.
42 // It then triggers further action based on the calculated AuthState; this
43 // further action might include calling back the passed-in AuthStatusConsumer
44 // to signal that login succeeded or failed, waiting for more outstanding
45 // operations to complete, or triggering some more Cryptohome method calls.
47 // Typical flows
48 // -------------
49 // Add new user: CONTINUE > CONTINUE > CREATE_NEW > CONTINUE > ONLINE_LOGIN
50 // Login as existing user: CONTINUE > OFFLINE_LOGIN
51 // Login as existing user (failure): CONTINUE > FAILED_MOUNT
52 // Change password detected:
53 // GAIA online ok: CONTINUE > CONTINUE > NEED_OLD_PW
54 // Recreate: CREATE_NEW > CONTINUE > ONLINE_LOGIN
55 // Old password failure: NEED_OLD_PW
56 // Old password ok: RECOVER_MOUNT > CONTINUE > ONLINE_LOGIN
58 class CHROMEOS_EXPORT CryptohomeAuthenticator
59 : public Authenticator,
60 public AuthAttemptStateResolver {
61 public:
62 enum AuthState {
63 CONTINUE = 0, // State indeterminate; try again with more info.
64 NO_MOUNT = 1, // Cryptohome doesn't exist yet.
65 FAILED_MOUNT = 2, // Failed to mount existing cryptohome.
66 FAILED_REMOVE = 3, // Failed to remove existing cryptohome.
67 FAILED_TMPFS = 4, // Failed to mount tmpfs for guest user.
68 FAILED_TPM = 5, // Failed to mount/create cryptohome, TPM error.
69 CREATE_NEW = 6, // Need to create cryptohome for a new user.
70 RECOVER_MOUNT = 7, // After RecoverEncryptedData, mount cryptohome.
71 POSSIBLE_PW_CHANGE = 8, // Offline login failed, user may have changed pw.
72 NEED_NEW_PW = 9, // Obsolete (ClientLogin): user changed pw,
73 // we have the old one.
74 NEED_OLD_PW = 10, // User changed pw, and we have the new one
75 // (GAIA auth is OK).
76 HAVE_NEW_PW = 11, // Obsolete (ClientLogin): We have verified new pw,
77 // time to migrate key.
78 OFFLINE_LOGIN = 12, // Login succeeded offline.
79 ONLINE_LOGIN = 13, // Offline and online login succeeded.
80 UNLOCK = 14, // Screen unlock succeeded.
81 ONLINE_FAILED = 15, // Obsolete (ClientLogin): Online login disallowed,
82 // but offline succeeded.
83 GUEST_LOGIN = 16, // Logged in guest mode.
84 PUBLIC_ACCOUNT_LOGIN = 17, // Logged into a public account.
85 SUPERVISED_USER_LOGIN = 18, // Logged in as a supervised user.
86 LOGIN_FAILED = 19, // Login denied.
87 OWNER_REQUIRED = 20, // Login is restricted to the owner only.
88 FAILED_USERNAME_HASH = 21, // Failed GetSanitizedUsername request.
89 KIOSK_ACCOUNT_LOGIN = 22, // Logged into a kiosk account.
90 REMOVED_DATA_AFTER_FAILURE = 23, // Successfully removed the user's
91 // cryptohome after a login failure.
94 CryptohomeAuthenticator(scoped_refptr<base::TaskRunner> task_runner,
95 AuthStatusConsumer* consumer);
97 // Authenticator overrides.
98 void CompleteLogin(content::BrowserContext* context,
99 const UserContext& user_context) override;
101 // Given |user_context|, this method attempts to authenticate to your
102 // Chrome OS device. As soon as we have successfully mounted the encrypted
103 // home directory for the user, we will call consumer_->OnAuthSuccess()
104 // with the username.
105 // Upon failure to login consumer_->OnAuthFailure() is called
106 // with an error message.
108 // Uses |context| when doing URL fetches.
109 void AuthenticateToLogin(content::BrowserContext* context,
110 const UserContext& user_context) override;
112 // Given |user_context|, this method attempts to authenticate to the cached
113 // user_context. This will never contact the server even if it's online.
114 // The auth result is sent to AuthStatusConsumer in a same way as
115 // AuthenticateToLogin does.
116 void AuthenticateToUnlock(const UserContext& user_context) override;
118 // Initiates supervised user login.
119 // Creates cryptohome if missing or mounts existing one and
120 // notifies consumer on the success/failure.
121 void LoginAsSupervisedUser(const UserContext& user_context) override;
123 // Initiates incognito ("browse without signing in") login.
124 // Mounts tmpfs and notifies consumer on the success/failure.
125 void LoginOffTheRecord() override;
127 // Initiates login into a public session.
128 // Mounts an ephemeral cryptohome and notifies consumer on the
129 // success/failure.
130 void LoginAsPublicSession(const UserContext& user_context) override;
132 // Initiates login into the kiosk mode account identified by |app_user_id|.
133 // Mounts an ephemeral guest cryptohome if |use_guest_mount| is |true|.
134 // Otherwise, mounts a public cryptohome, which will be ephemeral if the
135 // |DeviceEphemeralUsersEnabled| policy is enabled and non-ephemeral
136 // otherwise.
137 void LoginAsKioskAccount(const std::string& app_user_id,
138 bool use_guest_mount) override;
140 // These methods must be called on the UI thread, as they make DBus calls
141 // and also call back to the login UI.
142 void OnAuthSuccess() override;
143 void OnAuthFailure(const AuthFailure& error) override;
144 void RecoverEncryptedData(const std::string& old_password) override;
145 void ResyncEncryptedData() override;
147 // AuthAttemptStateResolver overrides.
148 // Attempts to make a decision and call back |consumer_| based on
149 // the state we have gathered at the time of call. If a decision
150 // can't be made, defers until the next time this is called.
151 // When a decision is made, will call back to |consumer_| on the UI thread.
153 // Must be called on the UI thread.
154 void Resolve() override;
156 void OnOffTheRecordAuthSuccess();
157 void OnPasswordChangeDetected();
159 protected:
160 ~CryptohomeAuthenticator() override;
162 typedef base::Callback<void(bool is_owner)> IsOwnerCallback;
164 // Method to be implemented in child. Return |true| if user specified in
165 // |context| exists on device.
166 virtual bool IsKnownUser(const UserContext& context) = 0;
168 // Method to be implemented in child. Return |true| if device is running
169 // in safe mode.
170 virtual bool IsSafeMode() = 0;
172 // Method to be implemented in child. Have to call |callback| with boolean
173 // parameter that indicates if user in |context| can act as an owner in
174 // safe mode.
175 virtual void CheckSafeModeOwnership(const UserContext& context,
176 const IsOwnerCallback& callback) = 0;
178 private:
179 friend class CryptohomeAuthenticatorTest;
180 FRIEND_TEST_ALL_PREFIXES(CryptohomeAuthenticatorTest,
181 ResolveOwnerNeededDirectFailedMount);
182 FRIEND_TEST_ALL_PREFIXES(CryptohomeAuthenticatorTest,
183 ResolveOwnerNeededMount);
184 FRIEND_TEST_ALL_PREFIXES(CryptohomeAuthenticatorTest,
185 ResolveOwnerNeededFailedMount);
187 // Removes the cryptohome of the user.
188 void RemoveEncryptedData();
190 // Returns the AuthState we're in, given the status info we have at
191 // the time of call.
192 // Must be called on the IO thread.
193 AuthState ResolveState();
195 // Helper for ResolveState().
196 // Given that some cryptohome operation has failed, determine which of the
197 // possible failure states we're in.
198 // Must be called on the IO thread.
199 AuthState ResolveCryptohomeFailureState();
201 // Helper for ResolveState().
202 // Given that some cryptohome operation has succeeded, determine which of
203 // the possible states we're in.
204 // Must be called on the IO thread.
205 AuthState ResolveCryptohomeSuccessState();
207 // Helper for ResolveState().
208 // Given that some online auth operation has succeeded, determine which of
209 // the possible success states we're in.
210 // Must be called on the IO thread.
211 AuthState ResolveOnlineSuccessState(AuthState offline_state);
213 // Used for testing.
214 void set_attempt_state(TestAttemptState* new_state) { // takes ownership.
215 current_state_.reset(new_state);
218 // Used for testing to set the expected state of an owner check.
219 void SetOwnerState(bool owner_check_finished, bool check_result);
221 // checks if the current mounted home contains the owner case and either
222 // continues or fails the log-in. Used for policy lost mitigation "safe-mode".
223 // Returns true if the owner check has been successful or if it is not needed.
224 bool VerifyOwner();
226 // Handles completion of the ownership check and continues login.
227 void OnOwnershipChecked(bool is_owner);
229 // Signal login completion status for cases when a new user is added via
230 // an external authentication provider (i.e. GAIA extension).
231 void ResolveLoginCompletionStatus();
233 scoped_refptr<base::TaskRunner> task_runner_;
235 scoped_ptr<AuthAttemptState> current_state_;
236 bool migrate_attempted_;
237 bool remove_attempted_;
238 bool resync_attempted_;
239 bool ephemeral_mount_attempted_;
240 bool check_key_attempted_;
242 // When the user has changed her password, but gives us the old one, we will
243 // be able to mount her cryptohome, but online authentication will fail.
244 // This allows us to present the same behavior to the caller, regardless
245 // of the order in which we receive these results.
246 bool already_reported_success_;
247 base::Lock success_lock_; // A lock around |already_reported_success_|.
249 // Flags signaling whether the owner verification has been done and the result
250 // of it.
251 bool owner_is_verified_;
252 bool user_can_login_;
254 // Flag indicating to delete the user's cryptohome the login fails.
255 bool remove_user_data_on_failure_;
257 // When |remove_user_data_on_failure_| is set, we delay calling
258 // consumer_->OnAuthFailure() until we removed the user cryptohome.
259 const AuthFailure* delayed_login_failure_;
261 DISALLOW_COPY_AND_ASSIGN(CryptohomeAuthenticator);
264 } // namespace chromeos
266 #endif // CHROMEOS_LOGIN_AUTH_CRYPTOHOME_AUTHENTICATOR_H_