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