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 #include "chrome/browser/chromeos/login/parallel_authenticator.h" | 5 #include "chrome/browser/chromeos/login/parallel_authenticator.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/string_number_conversions.h" |
12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
13 #include "chrome/browser/chromeos/boot_times_loader.h" | 14 #include "chrome/browser/chromeos/boot_times_loader.h" |
14 #include "chrome/browser/chromeos/cros/cert_library.h" | 15 #include "chrome/browser/chromeos/cros/cert_library.h" |
15 #include "chrome/browser/chromeos/cros/cros_library.h" | 16 #include "chrome/browser/chromeos/cros/cros_library.h" |
16 #include "chrome/browser/chromeos/cros/cryptohome_library.h" | 17 #include "chrome/browser/chromeos/cros/cryptohome_library.h" |
17 #include "chrome/browser/chromeos/cros_settings.h" | 18 #include "chrome/browser/chromeos/cros_settings.h" |
18 #include "chrome/browser/chromeos/cryptohome/async_method_caller.h" | 19 #include "chrome/browser/chromeos/cryptohome/async_method_caller.h" |
19 #include "chrome/browser/chromeos/login/authentication_notification_details.h" | 20 #include "chrome/browser/chromeos/login/authentication_notification_details.h" |
20 #include "chrome/browser/chromeos/login/login_status_consumer.h" | 21 #include "chrome/browser/chromeos/login/login_status_consumer.h" |
21 #include "chrome/browser/chromeos/login/ownership_service.h" | 22 #include "chrome/browser/chromeos/login/ownership_service.h" |
22 #include "chrome/browser/chromeos/login/user_manager.h" | 23 #include "chrome/browser/chromeos/login/user_manager.h" |
23 #include "chrome/common/chrome_notification_types.h" | 24 #include "chrome/common/chrome_notification_types.h" |
24 #include "chrome/common/chrome_switches.h" | 25 #include "chrome/common/chrome_switches.h" |
25 #include "chrome/common/net/gaia/gaia_auth_util.h" | 26 #include "chrome/common/net/gaia/gaia_auth_util.h" |
26 #include "chromeos/dbus/cryptohome_client.h" | 27 #include "chromeos/dbus/cryptohome_client.h" |
27 #include "chromeos/dbus/dbus_thread_manager.h" | 28 #include "chromeos/dbus/dbus_thread_manager.h" |
28 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/notification_service.h" | 30 #include "content/public/browser/notification_service.h" |
| 31 #include "crypto/sha2.h" |
30 #include "third_party/cros_system_api/dbus/service_constants.h" | 32 #include "third_party/cros_system_api/dbus/service_constants.h" |
31 | 33 |
32 using content::BrowserThread; | 34 using content::BrowserThread; |
33 | 35 |
34 namespace chromeos { | 36 namespace chromeos { |
35 | 37 |
36 namespace { | 38 namespace { |
37 | 39 |
38 // Milliseconds until we timeout our attempt to hit ClientLogin. | 40 // Milliseconds until we timeout our attempt to hit ClientLogin. |
39 const int kClientLoginTimeoutMs = 10000; | 41 const int kClientLoginTimeoutMs = 10000; |
40 | 42 |
| 43 // Length of password hashed with SHA-256. |
| 44 const int kPasswordHashLength = 32; |
| 45 |
41 // Records status and calls resolver->Resolve(). | 46 // Records status and calls resolver->Resolve(). |
42 void TriggerResolve(AuthAttemptState* attempt, | 47 void TriggerResolve(AuthAttemptState* attempt, |
43 AuthAttemptStateResolver* resolver, | 48 AuthAttemptStateResolver* resolver, |
44 bool success, | 49 bool success, |
45 cryptohome::MountError return_code) { | 50 cryptohome::MountError return_code) { |
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
47 attempt->RecordCryptohomeStatus(success, return_code); | 52 attempt->RecordCryptohomeStatus(success, return_code); |
48 resolver->Resolve(); | 53 resolver->Resolve(); |
49 } | 54 } |
50 | 55 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 160 |
156 // Returns whether the login failure was connection issue. | 161 // Returns whether the login failure was connection issue. |
157 bool WasConnectionIssue(const LoginFailure& online_outcome) { | 162 bool WasConnectionIssue(const LoginFailure& online_outcome) { |
158 return ((online_outcome.reason() == LoginFailure::LOGIN_TIMED_OUT) || | 163 return ((online_outcome.reason() == LoginFailure::LOGIN_TIMED_OUT) || |
159 (online_outcome.error().state() == | 164 (online_outcome.error().state() == |
160 GoogleServiceAuthError::CONNECTION_FAILED) || | 165 GoogleServiceAuthError::CONNECTION_FAILED) || |
161 (online_outcome.error().state() == | 166 (online_outcome.error().state() == |
162 GoogleServiceAuthError::REQUEST_CANCELED)); | 167 GoogleServiceAuthError::REQUEST_CANCELED)); |
163 } | 168 } |
164 | 169 |
| 170 // Returns hash of |password|, salted with the system salt. |
| 171 std::string HashPassword(const std::string& password) { |
| 172 // Get salt, ascii encode, update sha with that, then update with ascii |
| 173 // of password, then end. |
| 174 std::string ascii_salt = |
| 175 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(); |
| 176 char passhash_buf[kPasswordHashLength]; |
| 177 |
| 178 // Hash salt and password |
| 179 crypto::SHA256HashString(ascii_salt + password, |
| 180 &passhash_buf, sizeof(passhash_buf)); |
| 181 |
| 182 // Only want the top half for 'weak' hashing so that the passphrase is not |
| 183 // immediately exposed even if the output is reversed. |
| 184 const int encoded_length = sizeof(passhash_buf) / 2; |
| 185 |
| 186 return StringToLowerASCII(base::HexEncode( |
| 187 reinterpret_cast<const void*>(passhash_buf), encoded_length)); |
| 188 } |
| 189 |
165 } // namespace | 190 } // namespace |
166 | 191 |
167 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer) | 192 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer) |
168 : Authenticator(consumer), | 193 : Authenticator(consumer), |
169 migrate_attempted_(false), | 194 migrate_attempted_(false), |
170 remove_attempted_(false), | 195 remove_attempted_(false), |
171 mount_guest_attempted_(false), | 196 mount_guest_attempted_(false), |
172 check_key_attempted_(false), | 197 check_key_attempted_(false), |
173 already_reported_success_(false), | 198 already_reported_success_(false), |
174 owner_is_verified_(false), | 199 owner_is_verified_(false), |
(...skipping 11 matching lines...) Expand all Loading... |
186 const std::string& username, | 211 const std::string& username, |
187 const std::string& password, | 212 const std::string& password, |
188 const std::string& login_token, | 213 const std::string& login_token, |
189 const std::string& login_captcha) { | 214 const std::string& login_captcha) { |
190 std::string canonicalized = gaia::CanonicalizeEmail(username); | 215 std::string canonicalized = gaia::CanonicalizeEmail(username); |
191 authentication_profile_ = profile; | 216 authentication_profile_ = profile; |
192 current_state_.reset( | 217 current_state_.reset( |
193 new AuthAttemptState( | 218 new AuthAttemptState( |
194 canonicalized, | 219 canonicalized, |
195 password, | 220 password, |
196 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), | 221 HashPassword(password), |
197 login_token, | 222 login_token, |
198 login_captcha, | 223 login_captcha, |
199 !UserManager::Get()->IsKnownUser(canonicalized))); | 224 !UserManager::Get()->IsKnownUser(canonicalized))); |
200 { | 225 { |
201 // Reset the verified flag. | 226 // Reset the verified flag. |
202 base::AutoLock for_this_block(owner_verified_lock_); | 227 base::AutoLock for_this_block(owner_verified_lock_); |
203 owner_is_verified_ = false; | 228 owner_is_verified_ = false; |
204 } | 229 } |
205 | 230 |
206 const bool create_if_missing = false; | 231 const bool create_if_missing = false; |
(...skipping 16 matching lines...) Expand all Loading... |
223 | 248 |
224 void ParallelAuthenticator::CompleteLogin(Profile* profile, | 249 void ParallelAuthenticator::CompleteLogin(Profile* profile, |
225 const std::string& username, | 250 const std::string& username, |
226 const std::string& password) { | 251 const std::string& password) { |
227 std::string canonicalized = gaia::CanonicalizeEmail(username); | 252 std::string canonicalized = gaia::CanonicalizeEmail(username); |
228 authentication_profile_ = profile; | 253 authentication_profile_ = profile; |
229 current_state_.reset( | 254 current_state_.reset( |
230 new AuthAttemptState( | 255 new AuthAttemptState( |
231 canonicalized, | 256 canonicalized, |
232 password, | 257 password, |
233 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), | 258 HashPassword(password), |
234 !UserManager::Get()->IsKnownUser(canonicalized))); | 259 !UserManager::Get()->IsKnownUser(canonicalized))); |
235 { | 260 { |
236 // Reset the verified flag. | 261 // Reset the verified flag. |
237 base::AutoLock for_this_block(owner_verified_lock_); | 262 base::AutoLock for_this_block(owner_verified_lock_); |
238 owner_is_verified_ = false; | 263 owner_is_verified_ = false; |
239 } | 264 } |
240 | 265 |
241 const bool create_if_missing = false; | 266 const bool create_if_missing = false; |
242 BrowserThread::PostTask( | 267 BrowserThread::PostTask( |
243 BrowserThread::UI, FROM_HERE, | 268 BrowserThread::UI, FROM_HERE, |
(...skipping 19 matching lines...) Expand all Loading... |
263 BrowserThread::UI, FROM_HERE, | 288 BrowserThread::UI, FROM_HERE, |
264 base::Bind(&ParallelAuthenticator::ResolveLoginCompletionStatus, this)); | 289 base::Bind(&ParallelAuthenticator::ResolveLoginCompletionStatus, this)); |
265 } | 290 } |
266 } | 291 } |
267 | 292 |
268 void ParallelAuthenticator::AuthenticateToUnlock(const std::string& username, | 293 void ParallelAuthenticator::AuthenticateToUnlock(const std::string& username, |
269 const std::string& password) { | 294 const std::string& password) { |
270 current_state_.reset( | 295 current_state_.reset( |
271 new AuthAttemptState( | 296 new AuthAttemptState( |
272 gaia::CanonicalizeEmail(username), | 297 gaia::CanonicalizeEmail(username), |
273 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password))); | 298 HashPassword(password))); |
274 check_key_attempted_ = true; | 299 check_key_attempted_ = true; |
275 BrowserThread::PostTask( | 300 BrowserThread::PostTask( |
276 BrowserThread::UI, FROM_HERE, | 301 BrowserThread::UI, FROM_HERE, |
277 base::Bind(&CheckKey, | 302 base::Bind(&CheckKey, |
278 current_state_.get(), | 303 current_state_.get(), |
279 static_cast<AuthAttemptStateResolver*>(this))); | 304 static_cast<AuthAttemptStateResolver*>(this))); |
280 } | 305 } |
281 | 306 |
282 void ParallelAuthenticator::LoginDemoUser() { | 307 void ParallelAuthenticator::LoginDemoUser() { |
283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 const std::string& user_name) { | 385 const std::string& user_name) { |
361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
362 DCHECK(using_oauth_); | 387 DCHECK(using_oauth_); |
363 // Mark this account's OAuth token state as invalid in the local state. | 388 // Mark this account's OAuth token state as invalid in the local state. |
364 UserManager::Get()->SaveUserOAuthStatus(user_name, | 389 UserManager::Get()->SaveUserOAuthStatus(user_name, |
365 User::OAUTH_TOKEN_STATUS_INVALID); | 390 User::OAUTH_TOKEN_STATUS_INVALID); |
366 } | 391 } |
367 | 392 |
368 void ParallelAuthenticator::RecoverEncryptedData( | 393 void ParallelAuthenticator::RecoverEncryptedData( |
369 const std::string& old_password) { | 394 const std::string& old_password) { |
370 std::string old_hash = | 395 std::string old_hash = HashPassword(old_password); |
371 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(old_password); | |
372 migrate_attempted_ = true; | 396 migrate_attempted_ = true; |
373 current_state_->ResetCryptohomeStatus(); | 397 current_state_->ResetCryptohomeStatus(); |
374 BrowserThread::PostTask( | 398 BrowserThread::PostTask( |
375 BrowserThread::UI, FROM_HERE, | 399 BrowserThread::UI, FROM_HERE, |
376 base::Bind(&Migrate, | 400 base::Bind(&Migrate, |
377 current_state_.get(), | 401 current_state_.get(), |
378 static_cast<AuthAttemptStateResolver*>(this), | 402 static_cast<AuthAttemptStateResolver*>(this), |
379 true, | 403 true, |
380 old_hash)); | 404 old_hash)); |
381 } | 405 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 | 449 |
426 void ParallelAuthenticator::RetryAuth(Profile* profile, | 450 void ParallelAuthenticator::RetryAuth(Profile* profile, |
427 const std::string& username, | 451 const std::string& username, |
428 const std::string& password, | 452 const std::string& password, |
429 const std::string& login_token, | 453 const std::string& login_token, |
430 const std::string& login_captcha) { | 454 const std::string& login_captcha) { |
431 reauth_state_.reset( | 455 reauth_state_.reset( |
432 new AuthAttemptState( | 456 new AuthAttemptState( |
433 gaia::CanonicalizeEmail(username), | 457 gaia::CanonicalizeEmail(username), |
434 password, | 458 password, |
435 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), | 459 HashPassword(password), |
436 login_token, | 460 login_token, |
437 login_captcha, | 461 login_captcha, |
438 false /* not a new user */)); | 462 false /* not a new user */)); |
439 // Always use ClientLogin regardless of using_oauth flag. This is because | 463 // Always use ClientLogin regardless of using_oauth flag. This is because |
440 // we are unable to renew oauth token on lock screen currently and will | 464 // we are unable to renew oauth token on lock screen currently and will |
441 // stuck with lock screen if we use OAuthLogin here. | 465 // stuck with lock screen if we use OAuthLogin here. |
442 // TODO(xiyuan): Revisit this after we support Gaia in lock screen. | 466 // TODO(xiyuan): Revisit this after we support Gaia in lock screen. |
443 current_online_.reset(new OnlineAttempt(false /* using_oauth */, | 467 current_online_.reset(new OnlineAttempt(false /* using_oauth */, |
444 reauth_state_.get(), | 468 reauth_state_.get(), |
445 this)); | 469 this)); |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 } | 802 } |
779 | 803 |
780 void ParallelAuthenticator::SetOwnerState(bool owner_check_finished, | 804 void ParallelAuthenticator::SetOwnerState(bool owner_check_finished, |
781 bool check_result) { | 805 bool check_result) { |
782 base::AutoLock for_this_block(owner_verified_lock_); | 806 base::AutoLock for_this_block(owner_verified_lock_); |
783 owner_is_verified_ = owner_check_finished; | 807 owner_is_verified_ = owner_check_finished; |
784 user_can_login_ = check_result; | 808 user_can_login_ = check_result; |
785 } | 809 } |
786 | 810 |
787 } // namespace chromeos | 811 } // namespace chromeos |
OLD | NEW |