OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ | 5 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ |
6 #define CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ | 6 #define CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/gtest_prod_util.h" | 12 #include "base/gtest_prod_util.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/synchronization/lock.h" | 14 #include "base/synchronization/lock.h" |
15 #include "chrome/browser/chromeos/login/auth_attempt_state.h" | 15 #include "chrome/browser/chromeos/login/auth_attempt_state.h" |
16 #include "chrome/browser/chromeos/login/auth_attempt_state_resolver.h" | 16 #include "chrome/browser/chromeos/login/auth_attempt_state_resolver.h" |
17 #include "chrome/browser/chromeos/login/authenticator.h" | 17 #include "chrome/browser/chromeos/login/authenticator.h" |
18 #include "chrome/browser/chromeos/login/online_attempt.h" | 18 #include "chrome/browser/chromeos/login/online_attempt.h" |
19 #include "chrome/browser/chromeos/login/test_attempt_state.h" | 19 #include "chrome/browser/chromeos/login/test_attempt_state.h" |
20 #include "chrome/browser/chromeos/settings/device_settings_service.h" | 20 #include "chrome/browser/chromeos/settings/device_settings_service.h" |
21 #include "google_apis/gaia/gaia_auth_consumer.h" | 21 #include "google_apis/gaia/gaia_auth_consumer.h" |
22 | 22 |
23 class LoginFailure; | 23 class LoginFailure; |
24 class Profile; | 24 class Profile; |
25 | 25 |
26 namespace chromeos { | 26 namespace chromeos { |
27 | 27 |
28 class LoginStatusConsumer; | 28 class LoginStatusConsumer; |
29 | 29 |
30 // Authenticates a Chromium OS user against the Google Accounts ClientLogin API. | 30 // Authenticates a Chromium OS user against cryptohome. |
31 // | 31 // Relies on the fact that online authentications has been already performed |
32 // Simultaneously attempts authentication both offline and online. | 32 // (i.e. using_oauth_ is true). |
33 // | 33 // |
34 // At a high, level, here's what happens: | 34 // At a high, level, here's what happens: |
35 // AuthenticateToLogin() creates an OnlineAttempt and calls a Cryptohome's | 35 // AuthenticateToLogin() calls a Cryptohome's method to perform offline login. |
36 // method to perform online and offline login simultaneously. When one of | 36 // Resultes are stored in a AuthAttemptState owned by ParallelAuthenticator |
37 // these completes, it will store results in a AuthAttemptState owned by | 37 // and then call Resolve(). Resolve() will attempt to |
38 // ParallelAuthenticator and then call Resolve(). Resolve() will attempt to | |
39 // determine which AuthState we're in, based on the info at hand. | 38 // determine which AuthState we're in, based on the info at hand. |
40 // It then triggers further action based on the calculated AuthState; this | 39 // It then triggers further action based on the calculated AuthState; this |
41 // further action might include calling back the passed-in LoginStatusConsumer | 40 // further action might include calling back the passed-in LoginStatusConsumer |
42 // to signal that login succeeded or failed, waiting for more outstanding | 41 // to signal that login succeeded or failed, waiting for more outstanding |
43 // operations to complete, or triggering some more Cryptohome method calls. | 42 // operations to complete, or triggering some more Cryptohome method calls. |
| 43 // |
| 44 // Typical flows |
| 45 // ------------- |
| 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 |
| 54 // |
| 55 // TODO(nkostylev): Rename ParallelAuthenticator since it is not doing |
| 56 // offline/online login operations in parallel anymore. |
44 class ParallelAuthenticator : public Authenticator, | 57 class ParallelAuthenticator : public Authenticator, |
45 public AuthAttemptStateResolver { | 58 public AuthAttemptStateResolver { |
46 public: | 59 public: |
47 enum AuthState { | 60 enum AuthState { |
48 CONTINUE, // State indeterminate; try again when more info available. | 61 CONTINUE = 0, // State indeterminate; try again with more info. |
49 NO_MOUNT, // Cryptohome doesn't exist yet. | 62 NO_MOUNT = 1, // Cryptohome doesn't exist yet. |
50 FAILED_MOUNT, // Failed to mount existing cryptohome. | 63 FAILED_MOUNT = 2, // Failed to mount existing cryptohome. |
51 FAILED_REMOVE, // Failed to remove existing cryptohome. | 64 FAILED_REMOVE = 3, // Failed to remove existing cryptohome. |
52 FAILED_TMPFS, // Failed to mount tmpfs for guest user | 65 FAILED_TMPFS = 4, // Failed to mount tmpfs for guest user. |
53 FAILED_TPM, // Failed to mount/create cryptohome because of TPM error. | 66 FAILED_TPM = 5, // Failed to mount/create cryptohome, TPM error. |
54 CREATE_NEW, // Need to create cryptohome for a new user. | 67 CREATE_NEW = 6, // Need to create cryptohome for a new user. |
55 RECOVER_MOUNT, // After RecoverEncryptedData, mount cryptohome. | 68 RECOVER_MOUNT = 7, // After RecoverEncryptedData, mount cryptohome. |
56 POSSIBLE_PW_CHANGE, // Offline login failed, user may have changed pw. | 69 POSSIBLE_PW_CHANGE = 8, // Offline login failed, user may have changed pw. |
57 NEED_NEW_PW, // User changed pw, and we have the old one. | 70 NEED_NEW_PW = 9, // Obsolete (ClientLogin): user changed pw, |
58 NEED_OLD_PW, // User changed pw, and we have the new one. | 71 // we have the old one. |
59 HAVE_NEW_PW, // We have verified new pw, time to migrate key. | 72 NEED_OLD_PW = 10, // User changed pw, and we have the new one |
60 OFFLINE_LOGIN, // Login succeeded offline. | 73 // (GAIA auth is OK). |
61 DEMO_LOGIN, // Logged in as the demo user. | 74 HAVE_NEW_PW = 11, // Obsolete (ClientLogin): We have verified new pw, |
62 ONLINE_LOGIN, // Offline and online login succeeded. | 75 // time to migrate key. |
63 UNLOCK, // Screen unlock succeeded. | 76 OFFLINE_LOGIN = 12, // Login succeeded offline. |
64 ONLINE_FAILED, // Online login disallowed, but offline succeeded. | 77 DEMO_LOGIN = 13, // Logged in as the demo user. |
65 GUEST_LOGIN, // Logged in guest mode. | 78 ONLINE_LOGIN = 14, // Offline and online login succeeded. |
66 PUBLIC_ACCOUNT_LOGIN, // Logged into a public account. | 79 UNLOCK = 15, // Screen unlock succeeded. |
67 LOCALLY_MANAGED_USER_LOGIN, // Logged in as a locally managed user. | 80 ONLINE_FAILED = 16, // Obsolete (ClientLogin): Online login disallowed, |
68 LOGIN_FAILED, // Login denied. | 81 // but offline succeeded. |
69 OWNER_REQUIRED // Login is restricted to the owner only. | 82 GUEST_LOGIN = 17, // Logged in guest mode. |
| 83 PUBLIC_ACCOUNT_LOGIN = 18, // Logged into a public account. |
| 84 LOCALLY_MANAGED_USER_LOGIN = 19, // Logged in as a locally managed user. |
| 85 LOGIN_FAILED = 20, // Login denied. |
| 86 OWNER_REQUIRED = 21 // Login is restricted to the owner only. |
70 }; | 87 }; |
71 | 88 |
72 explicit ParallelAuthenticator(LoginStatusConsumer* consumer); | 89 explicit ParallelAuthenticator(LoginStatusConsumer* consumer); |
73 | 90 |
74 // Authenticator overrides. | 91 // Authenticator overrides. |
75 virtual void CompleteLogin(Profile* profile, | 92 virtual void CompleteLogin(Profile* profile, |
76 const UserContext& user_context) OVERRIDE; | 93 const UserContext& user_context) OVERRIDE; |
77 | 94 |
78 // Given a |username| and |password|, this method attempts to authenticate to | 95 // Given |user_context|, this method attempts to authenticate to your |
79 // the Google accounts servers and your Chrome OS device simultaneously. | 96 // Chrome OS device. As soon as we have successfully mounted the encrypted |
80 // As soon as we have successfully mounted the encrypted home directory for | 97 // home directory for the user, we will call consumer_->OnLoginSuccess() |
81 // |username|, we will call consumer_->OnLoginSuccess() with |username| and a | 98 // with the username. |
82 // vector of authentication cookies. If we're still waiting for an online | 99 // Upon failure to login consumer_->OnLoginFailure() is called |
83 // result at that time, we'll also pass back a flag indicating that more | |
84 // callbacks are on the way; if not, we pass back false. When the pending | |
85 // request completes, either consumer_->OnLoginSuccess() with an indication | |
86 // that no more requests are outstanding will be called, or | |
87 // consumer_->OnLoginFailure() if appropriate. | |
88 // | |
89 // Upon failure to login (online fails, then offline fails; | |
90 // offline fails, then online fails) consumer_->OnLoginFailure() is called | |
91 // with an error message. | 100 // with an error message. |
92 // | 101 // |
93 // In the event that we see an online success and then an offline failure, | |
94 // consumer_->OnPasswordChangeDetected() is called. | |
95 // | |
96 // Uses |profile| when doing URL fetches. | 102 // Uses |profile| when doing URL fetches. |
97 // Optionally could pass CAPTCHA challenge token - |login_token| and | |
98 // |login_captcha| string that user has entered. | |
99 // | |
100 // NOTE: We do not allow HOSTED accounts to log in. In the event that | |
101 // we are asked to authenticate valid HOSTED account creds, we will | |
102 // call OnLoginFailure() with HOSTED_NOT_ALLOWED. | |
103 virtual void AuthenticateToLogin(Profile* profile, | 103 virtual void AuthenticateToLogin(Profile* profile, |
104 const UserContext& user_context, | 104 const UserContext& user_context) OVERRIDE; |
105 const std::string& login_token, | |
106 const std::string& login_captcha) OVERRIDE; | |
107 | 105 |
108 // Given |user_context|, this method attempts to authenticate to the cached | 106 // Given |user_context|, this method attempts to authenticate to the cached |
109 // user_context. This will never contact the server even if it's online. | 107 // user_context. This will never contact the server even if it's online. |
110 // The auth result is sent to LoginStatusConsumer in a same way as | 108 // The auth result is sent to LoginStatusConsumer in a same way as |
111 // AuthenticateToLogin does. | 109 // AuthenticateToLogin does. |
112 virtual void AuthenticateToUnlock( | 110 virtual void AuthenticateToUnlock( |
113 const UserContext& user_context) OVERRIDE; | 111 const UserContext& user_context) OVERRIDE; |
114 | 112 |
115 // Initiates locally managed user login. | 113 // Initiates locally managed user login. |
116 // Creates cryptohome if missing or mounts existing one and | 114 // Creates cryptohome if missing or mounts existing one and |
(...skipping 15 matching lines...) Expand all Loading... |
132 virtual void LoginAsPublicAccount(const std::string& username) OVERRIDE; | 130 virtual void LoginAsPublicAccount(const std::string& username) OVERRIDE; |
133 | 131 |
134 // These methods must be called on the UI thread, as they make DBus calls | 132 // These methods must be called on the UI thread, as they make DBus calls |
135 // and also call back to the login UI. | 133 // and also call back to the login UI. |
136 virtual void OnRetailModeLoginSuccess() OVERRIDE; | 134 virtual void OnRetailModeLoginSuccess() OVERRIDE; |
137 virtual void OnLoginSuccess(bool request_pending) OVERRIDE; | 135 virtual void OnLoginSuccess(bool request_pending) OVERRIDE; |
138 virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE; | 136 virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE; |
139 virtual void RecoverEncryptedData( | 137 virtual void RecoverEncryptedData( |
140 const std::string& old_password) OVERRIDE; | 138 const std::string& old_password) OVERRIDE; |
141 virtual void ResyncEncryptedData() OVERRIDE; | 139 virtual void ResyncEncryptedData() OVERRIDE; |
142 virtual void RetryAuth(Profile* profile, | 140 |
143 const UserContext& user_context, | |
144 const std::string& login_token, | |
145 const std::string& login_captcha) OVERRIDE; | |
146 // AuthAttemptStateResolver overrides. | 141 // AuthAttemptStateResolver overrides. |
147 // Attempts to make a decision and call back |consumer_| based on | 142 // Attempts to make a decision and call back |consumer_| based on |
148 // the state we have gathered at the time of call. If a decision | 143 // the state we have gathered at the time of call. If a decision |
149 // can't be made, defers until the next time this is called. | 144 // can't be made, defers until the next time this is called. |
150 // When a decision is made, will call back to |consumer_| on the UI thread. | 145 // When a decision is made, will call back to |consumer_| on the UI thread. |
151 // | 146 // |
152 // Must be called on the UI thread. | 147 // Must be called on the UI thread. |
153 virtual void Resolve() OVERRIDE; | 148 virtual void Resolve() OVERRIDE; |
154 | 149 |
155 void OnOffTheRecordLoginSuccess(); | 150 void OnOffTheRecordLoginSuccess(); |
156 void OnPasswordChangeDetected(); | 151 void OnPasswordChangeDetected(); |
157 | 152 |
158 protected: | 153 protected: |
159 virtual ~ParallelAuthenticator(); | 154 virtual ~ParallelAuthenticator(); |
160 | 155 |
161 private: | 156 private: |
162 friend class ParallelAuthenticatorTest; | 157 friend class ParallelAuthenticatorTest; |
163 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, | 158 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, |
164 ResolveOwnerNeededDirectFailedMount); | 159 ResolveOwnerNeededDirectFailedMount); |
165 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, ResolveOwnerNeededMount); | 160 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, ResolveOwnerNeededMount); |
166 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, | 161 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, |
167 ResolveOwnerNeededFailedMount); | 162 ResolveOwnerNeededFailedMount); |
168 | 163 |
169 // Returns the AuthState we're in, given the status info we have at | 164 // Returns the AuthState we're in, given the status info we have at |
170 // the time of call. | 165 // the time of call. |
171 // Must be called on the IO thread. | 166 // Must be called on the IO thread. |
172 AuthState ResolveState(); | 167 AuthState ResolveState(); |
173 | 168 |
174 // Helper for ResolveState(). | 169 // Helper for ResolveState(). |
175 // Given that we're attempting to auth the user again, with a new password, | |
176 // determine which state we're in. Returns CONTINUE if no resolution. | |
177 // Must be called on the IO thread. | |
178 AuthState ResolveReauthState(); | |
179 | |
180 // Helper for ResolveState(). | |
181 // Given that some cryptohome operation has failed, determine which of the | 170 // Given that some cryptohome operation has failed, determine which of the |
182 // possible failure states we're in. | 171 // possible failure states we're in. |
183 // Must be called on the IO thread. | 172 // Must be called on the IO thread. |
184 AuthState ResolveCryptohomeFailureState(); | 173 AuthState ResolveCryptohomeFailureState(); |
185 | 174 |
186 // Helper for ResolveState(). | 175 // Helper for ResolveState(). |
187 // Given that some cryptohome operation has succeeded, determine which of | 176 // Given that some cryptohome operation has succeeded, determine which of |
188 // the possible states we're in. | 177 // the possible states we're in. |
189 // Must be called on the IO thread. | 178 // Must be called on the IO thread. |
190 AuthState ResolveCryptohomeSuccessState(); | 179 AuthState ResolveCryptohomeSuccessState(); |
191 | 180 |
192 // Helper for ResolveState(). | 181 // Helper for ResolveState(). |
193 // Given that some online auth operation has failed, determine which of the | |
194 // possible failure states we're in. Handles both failure to complete and | |
195 // actual failure responses from the server. | |
196 // Must be called on the IO thread. | |
197 AuthState ResolveOnlineFailureState(AuthState offline_state); | |
198 | |
199 // Helper for ResolveState(). | |
200 // Given that some online auth operation has succeeded, determine which of | 182 // Given that some online auth operation has succeeded, determine which of |
201 // the possible success states we're in. | 183 // the possible success states we're in. |
202 // Must be called on the IO thread. | 184 // Must be called on the IO thread. |
203 AuthState ResolveOnlineSuccessState(AuthState offline_state); | 185 AuthState ResolveOnlineSuccessState(AuthState offline_state); |
204 | 186 |
205 // Used to disable oauth, used for testing. | 187 // Used to disable oauth, used for testing. |
206 void set_using_oauth(bool value) { | 188 void set_using_oauth(bool value) { |
207 using_oauth_ = value; | 189 using_oauth_ = value; |
208 } | 190 } |
209 | 191 |
210 // Used for testing. | 192 // Used for testing. |
211 void set_attempt_state(TestAttemptState* new_state) { // takes ownership. | 193 void set_attempt_state(TestAttemptState* new_state) { // takes ownership. |
212 current_state_.reset(new_state); | 194 current_state_.reset(new_state); |
213 } | 195 } |
214 | 196 |
215 // Sets an online attemp for testing. | 197 // Sets an online attempt for testing. |
216 void set_online_attempt(OnlineAttempt* attempt) { | 198 void set_online_attempt(OnlineAttempt* attempt) { |
217 current_online_.reset(attempt); | 199 current_online_.reset(attempt); |
218 } | 200 } |
219 | 201 |
220 // Used for testing to set the expected state of an owner check. | 202 // Used for testing to set the expected state of an owner check. |
221 void SetOwnerState(bool owner_check_finished, bool check_result); | 203 void SetOwnerState(bool owner_check_finished, bool check_result); |
222 | 204 |
223 // checks if the current mounted home contains the owner case and either | 205 // checks if the current mounted home contains the owner case and either |
224 // continues or fails the log-in. Used for policy lost mitigation "safe-mode". | 206 // continues or fails the log-in. Used for policy lost mitigation "safe-mode". |
225 // Returns true if the owner check has been successful or if it is not needed. | 207 // Returns true if the owner check has been successful or if it is not needed. |
226 bool VerifyOwner(); | 208 bool VerifyOwner(); |
227 | 209 |
228 // Handles completion of the ownership check and continues login. | 210 // Handles completion of the ownership check and continues login. |
229 void OnOwnershipChecked(DeviceSettingsService::OwnershipStatus status, | 211 void OnOwnershipChecked(DeviceSettingsService::OwnershipStatus status, |
230 bool is_owner); | 212 bool is_owner); |
231 | 213 |
232 // Records OAuth1 access token verification failure for |user_account|. | |
233 void RecordOAuthCheckFailure(const std::string& user_account); | |
234 | |
235 // Signal login completion status for cases when a new user is added via | 214 // Signal login completion status for cases when a new user is added via |
236 // an external authentication provider (i.e. GAIA extension). | 215 // an external authentication provider (i.e. GAIA extension). |
237 void ResolveLoginCompletionStatus(); | 216 void ResolveLoginCompletionStatus(); |
238 | 217 |
239 // Used when we need to try online authentication again, after successful | |
240 // mount, but failed online login. | |
241 scoped_ptr<AuthAttemptState> reauth_state_; | |
242 | |
243 scoped_ptr<AuthAttemptState> current_state_; | 218 scoped_ptr<AuthAttemptState> current_state_; |
244 scoped_ptr<OnlineAttempt> current_online_; | 219 scoped_ptr<OnlineAttempt> current_online_; |
245 bool migrate_attempted_; | 220 bool migrate_attempted_; |
246 bool remove_attempted_; | 221 bool remove_attempted_; |
247 bool ephemeral_mount_attempted_; | 222 bool ephemeral_mount_attempted_; |
248 bool check_key_attempted_; | 223 bool check_key_attempted_; |
249 | 224 |
250 // When the user has changed her password, but gives us the old one, we will | 225 // When the user has changed her password, but gives us the old one, we will |
251 // be able to mount her cryptohome, but online authentication will fail. | 226 // be able to mount her cryptohome, but online authentication will fail. |
252 // This allows us to present the same behavior to the caller, regardless | 227 // This allows us to present the same behavior to the caller, regardless |
253 // of the order in which we receive these results. | 228 // of the order in which we receive these results. |
254 bool already_reported_success_; | 229 bool already_reported_success_; |
255 base::Lock success_lock_; // A lock around |already_reported_success_|. | 230 base::Lock success_lock_; // A lock around |already_reported_success_|. |
256 | 231 |
257 // Flags signaling whether the owner verification has been done and the result | 232 // Flags signaling whether the owner verification has been done and the result |
258 // of it. | 233 // of it. |
259 bool owner_is_verified_; | 234 bool owner_is_verified_; |
260 bool user_can_login_; | 235 bool user_can_login_; |
261 | 236 |
262 // True if we use OAuth-based authentication flow. | 237 // True if we use OAuth-based authentication flow. |
263 bool using_oauth_; | 238 bool using_oauth_; |
264 | 239 |
265 DISALLOW_COPY_AND_ASSIGN(ParallelAuthenticator); | 240 DISALLOW_COPY_AND_ASSIGN(ParallelAuthenticator); |
266 }; | 241 }; |
267 | 242 |
268 } // namespace chromeos | 243 } // namespace chromeos |
269 | 244 |
270 #endif // CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ | 245 #endif // CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ |
OLD | NEW |