OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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. | |
4 | |
5 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ | |
6 #define CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/compiler_specific.h" | |
12 #include "base/gtest_prod_util.h" | |
13 #include "base/memory/scoped_ptr.h" | |
14 #include "base/synchronization/lock.h" | |
15 #include "chrome/browser/chromeos/login/auth_attempt_state.h" | |
16 #include "chrome/browser/chromeos/login/auth_attempt_state_resolver.h" | |
17 #include "chrome/browser/chromeos/login/authenticator.h" | |
18 #include "chrome/browser/chromeos/login/test_attempt_state.h" | |
19 #include "chrome/browser/chromeos/settings/device_settings_service.h" | |
20 #include "google_apis/gaia/gaia_auth_consumer.h" | |
21 | |
22 class LoginFailure; | |
23 class Profile; | |
24 | |
25 namespace chromeos { | |
26 | |
27 class LoginStatusConsumer; | |
28 | |
29 // Authenticates a Chromium OS user against cryptohome. | |
30 // Relies on the fact that online authentications has been already performed | |
31 // (i.e. using_oauth_ is true). | |
32 // | |
33 // At a high, level, here's what happens: | |
34 // AuthenticateToLogin() calls a Cryptohome's method to perform offline login. | |
35 // Resultes are stored in a AuthAttemptState owned by ParallelAuthenticator | |
36 // and then call Resolve(). Resolve() will attempt to | |
37 // determine which AuthState we're in, based on the info at hand. | |
38 // It then triggers further action based on the calculated AuthState; this | |
39 // further action might include calling back the passed-in LoginStatusConsumer | |
40 // to signal that login succeeded or failed, waiting for more outstanding | |
41 // operations to complete, or triggering some more Cryptohome method calls. | |
42 // | |
43 // Typical flows | |
44 // ------------- | |
45 // Add new user: CONTINUE > CONTINUE > CREATE_NEW > CONTINUE > ONLINE_LOGIN | |
46 // Login as existing user: CONTINUE > OFFLINE_LOGIN | |
47 // Login as existing user (failure): CONTINUE > FAILED_MOUNT | |
48 // Change password detected: | |
49 // GAIA online ok: CONTINUE > CONTINUE > NEED_OLD_PW | |
50 // Recreate: CREATE_NEW > CONTINUE > ONLINE_LOGIN | |
51 // Old password failure: NEED_OLD_PW | |
52 // Old password ok: RECOVER_MOUNT > CONTINUE > ONLINE_LOGIN | |
53 // | |
54 // TODO(nkostylev): Rename ParallelAuthenticator since it is not doing | |
55 // offline/online login operations in parallel anymore. | |
56 class ParallelAuthenticator : public Authenticator, | |
57 public AuthAttemptStateResolver { | |
58 public: | |
59 enum AuthState { | |
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 | |
72 // (GAIA auth is OK). | |
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 LOCALLY_MANAGED_USER_LOGIN = 19, // Logged in as a locally managed 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. | |
90 }; | |
91 | |
92 explicit ParallelAuthenticator(LoginStatusConsumer* consumer); | |
93 | |
94 // Authenticator overrides. | |
95 virtual void CompleteLogin(Profile* profile, | |
96 const UserContext& user_context) OVERRIDE; | |
97 | |
98 // Given |user_context|, this method attempts to authenticate to your | |
99 // Chrome OS device. As soon as we have successfully mounted the encrypted | |
100 // home directory for the user, we will call consumer_->OnLoginSuccess() | |
101 // with the username. | |
102 // Upon failure to login consumer_->OnLoginFailure() is called | |
103 // with an error message. | |
104 // | |
105 // Uses |profile| when doing URL fetches. | |
106 virtual void AuthenticateToLogin(Profile* profile, | |
107 const UserContext& user_context) OVERRIDE; | |
108 | |
109 // Given |user_context|, this method attempts to authenticate to the cached | |
110 // user_context. This will never contact the server even if it's online. | |
111 // The auth result is sent to LoginStatusConsumer in a same way as | |
112 // AuthenticateToLogin does. | |
113 virtual void AuthenticateToUnlock(const UserContext& user_context) OVERRIDE; | |
114 | |
115 // Initiates locally managed user login. | |
116 // Creates cryptohome if missing or mounts existing one and | |
117 // notifies consumer on the success/failure. | |
118 virtual void LoginAsLocallyManagedUser( | |
119 const UserContext& user_context) OVERRIDE; | |
120 | |
121 // Initiates retail mode login. | |
122 // Mounts tmpfs and notifies consumer on the success/failure. | |
123 virtual void LoginRetailMode() OVERRIDE; | |
124 | |
125 // Initiates incognito ("browse without signing in") login. | |
126 // Mounts tmpfs and notifies consumer on the success/failure. | |
127 virtual void LoginOffTheRecord() OVERRIDE; | |
128 | |
129 // Initiates login into the public account identified by |username|. | |
130 // Mounts an ephemeral cryptohome and notifies consumer on the | |
131 // success/failure. | |
132 virtual void LoginAsPublicAccount(const std::string& username) OVERRIDE; | |
133 | |
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 | |
138 // otherwise. | |
139 virtual void LoginAsKioskAccount(const std::string& app_user_id, | |
140 bool use_guest_mount) OVERRIDE; | |
141 | |
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 OnRetailModeLoginSuccess() OVERRIDE; | |
145 virtual void OnLoginSuccess() OVERRIDE; | |
146 virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE; | |
147 virtual void RecoverEncryptedData( | |
148 const std::string& old_password) OVERRIDE; | |
149 virtual void ResyncEncryptedData() OVERRIDE; | |
150 | |
151 // AuthAttemptStateResolver overrides. | |
152 // Attempts to make a decision and call back |consumer_| based on | |
153 // the state we have gathered at the time of call. If a decision | |
154 // can't be made, defers until the next time this is called. | |
155 // When a decision is made, will call back to |consumer_| on the UI thread. | |
156 // | |
157 // Must be called on the UI thread. | |
158 virtual void Resolve() OVERRIDE; | |
159 | |
160 // Returns hash of |password|, salted with the system salt. | |
161 static std::string HashPassword(const std::string& password, | |
162 const std::string& ascii_salt); | |
163 | |
164 void OnOffTheRecordLoginSuccess(); | |
165 void OnPasswordChangeDetected(); | |
166 | |
167 protected: | |
168 virtual ~ParallelAuthenticator(); | |
169 | |
170 private: | |
171 friend class ParallelAuthenticatorTest; | |
172 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, | |
173 ResolveOwnerNeededDirectFailedMount); | |
174 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, ResolveOwnerNeededMount); | |
175 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, | |
176 ResolveOwnerNeededFailedMount); | |
177 | |
178 // Removes the cryptohome of the user. | |
179 void RemoveEncryptedData(); | |
180 | |
181 // Returns the AuthState we're in, given the status info we have at | |
182 // the time of call. | |
183 // Must be called on the IO thread. | |
184 AuthState ResolveState(); | |
185 | |
186 // Helper for ResolveState(). | |
187 // Given that some cryptohome operation has failed, determine which of the | |
188 // possible failure states we're in. | |
189 // Must be called on the IO thread. | |
190 AuthState ResolveCryptohomeFailureState(); | |
191 | |
192 // Helper for ResolveState(). | |
193 // Given that some cryptohome operation has succeeded, determine which of | |
194 // the possible states we're in. | |
195 // Must be called on the IO thread. | |
196 AuthState ResolveCryptohomeSuccessState(); | |
197 | |
198 // Helper for ResolveState(). | |
199 // Given that some online auth operation has succeeded, determine which of | |
200 // the possible success states we're in. | |
201 // Must be called on the IO thread. | |
202 AuthState ResolveOnlineSuccessState(AuthState offline_state); | |
203 | |
204 // Used for testing. | |
205 void set_attempt_state(TestAttemptState* new_state) { // takes ownership. | |
206 current_state_.reset(new_state); | |
207 } | |
208 | |
209 // Used for testing to set the expected state of an owner check. | |
210 void SetOwnerState(bool owner_check_finished, bool check_result); | |
211 | |
212 // checks if the current mounted home contains the owner case and either | |
213 // continues or fails the log-in. Used for policy lost mitigation "safe-mode". | |
214 // Returns true if the owner check has been successful or if it is not needed. | |
215 bool VerifyOwner(); | |
216 | |
217 // Handles completion of the ownership check and continues login. | |
218 void OnOwnershipChecked(bool is_owner); | |
219 | |
220 // Signal login completion status for cases when a new user is added via | |
221 // an external authentication provider (i.e. GAIA extension). | |
222 void ResolveLoginCompletionStatus(); | |
223 | |
224 scoped_ptr<AuthAttemptState> current_state_; | |
225 bool migrate_attempted_; | |
226 bool remove_attempted_; | |
227 bool resync_attempted_; | |
228 bool ephemeral_mount_attempted_; | |
229 bool check_key_attempted_; | |
230 | |
231 // When the user has changed her password, but gives us the old one, we will | |
232 // be able to mount her cryptohome, but online authentication will fail. | |
233 // This allows us to present the same behavior to the caller, regardless | |
234 // of the order in which we receive these results. | |
235 bool already_reported_success_; | |
236 base::Lock success_lock_; // A lock around |already_reported_success_|. | |
237 | |
238 // Flags signaling whether the owner verification has been done and the result | |
239 // of it. | |
240 bool owner_is_verified_; | |
241 bool user_can_login_; | |
242 | |
243 // Flag indicating to delete the user's cryptohome the login fails. | |
244 bool remove_user_data_on_failure_; | |
245 | |
246 // When |remove_user_data_on_failure_| is set, we delay calling | |
247 // consumer_->OnLoginFailure() until we removed the user cryptohome. | |
248 const LoginFailure* delayed_login_failure_; | |
249 | |
250 DISALLOW_COPY_AND_ASSIGN(ParallelAuthenticator); | |
251 }; | |
252 | |
253 } // namespace chromeos | |
254 | |
255 #endif // CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ | |
OLD | NEW |