| 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 <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "base/stringprintf.h" | 16 #include "base/stringprintf.h" |
| 17 #include "base/test/thread_test_helper.h" | 17 #include "base/test/thread_test_helper.h" |
| 18 #include "chrome/browser/chromeos/cros/cros_library.h" | 18 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 19 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" | 19 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" |
| 20 #include "chrome/browser/chromeos/cros/mock_library_loader.h" | 20 #include "chrome/browser/chromeos/cros/mock_library_loader.h" |
| 21 #include "chrome/browser/chromeos/cros_settings.h" |
| 21 #include "chrome/browser/chromeos/cryptohome/mock_async_method_caller.h" | 22 #include "chrome/browser/chromeos/cryptohome/mock_async_method_caller.h" |
| 23 #include "chrome/browser/chromeos/dbus/mock_dbus_thread_manager.h" |
| 24 #include "chrome/browser/chromeos/dbus/mock_cryptohome_client.h" |
| 22 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h" | 25 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h" |
| 23 #include "chrome/browser/chromeos/login/mock_url_fetchers.h" | 26 #include "chrome/browser/chromeos/login/mock_url_fetchers.h" |
| 27 #include "chrome/browser/chromeos/login/mock_user_manager.h" |
| 24 #include "chrome/browser/chromeos/login/test_attempt_state.h" | 28 #include "chrome/browser/chromeos/login/test_attempt_state.h" |
| 29 #include "chrome/browser/chromeos/stub_cros_settings_provider.h" |
| 25 #include "chrome/common/chrome_paths.h" | 30 #include "chrome/common/chrome_paths.h" |
| 26 #include "chrome/common/net/gaia/mock_url_fetcher_factory.h" | 31 #include "chrome/common/net/gaia/mock_url_fetcher_factory.h" |
| 27 #include "chrome/test/base/testing_profile.h" | 32 #include "chrome/test/base/testing_profile.h" |
| 28 #include "content/test/test_browser_thread.h" | 33 #include "content/test/test_browser_thread.h" |
| 29 #include "googleurl/src/gurl.h" | 34 #include "googleurl/src/gurl.h" |
| 30 #include "net/base/net_errors.h" | 35 #include "net/base/net_errors.h" |
| 31 #include "net/url_request/url_request_status.h" | 36 #include "net/url_request/url_request_status.h" |
| 32 #include "testing/gmock/include/gmock/gmock.h" | 37 #include "testing/gmock/include/gmock/gmock.h" |
| 33 #include "testing/gtest/include/gtest/gtest.h" | 38 #include "testing/gtest/include/gtest/gtest.h" |
| 34 #include "third_party/cros_system_api/dbus/service_constants.h" | 39 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 35 | 40 |
| 36 using content::BrowserThread; | 41 using content::BrowserThread; |
| 37 using file_util::CloseFile; | 42 using file_util::CloseFile; |
| 38 using file_util::CreateAndOpenTemporaryFile; | 43 using file_util::CreateAndOpenTemporaryFile; |
| 39 using file_util::CreateAndOpenTemporaryFileInDir; | 44 using file_util::CreateAndOpenTemporaryFileInDir; |
| 40 using file_util::Delete; | 45 using file_util::Delete; |
| 41 using file_util::WriteFile; | 46 using file_util::WriteFile; |
| 42 using ::testing::AnyNumber; | 47 using ::testing::AnyNumber; |
| 43 using ::testing::DoAll; | 48 using ::testing::DoAll; |
| 44 using ::testing::Invoke; | 49 using ::testing::Invoke; |
| 45 using ::testing::Return; | 50 using ::testing::Return; |
| 46 using ::testing::SetArgumentPointee; | 51 using ::testing::SetArgPointee; |
| 47 using ::testing::_; | 52 using ::testing::_; |
| 48 | 53 |
| 49 namespace chromeos { | 54 namespace chromeos { |
| 50 | 55 |
| 51 class ResolveChecker : public base::ThreadTestHelper { | 56 class ResolveChecker : public base::ThreadTestHelper { |
| 52 public: | 57 public: |
| 53 ResolveChecker(TestAttemptState* state, | 58 ResolveChecker(TestAttemptState* state, |
| 54 ParallelAuthenticator* auth, | 59 ParallelAuthenticator* auth, |
| 55 ParallelAuthenticator::AuthState expected) | 60 ParallelAuthenticator::AuthState expected) |
| 56 : base::ThreadTestHelper( | 61 : base::ThreadTestHelper( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 78 AuthAttemptStateResolver* resolver) | 83 AuthAttemptStateResolver* resolver) |
| 79 : OnlineAttempt(false, state, resolver) { | 84 : OnlineAttempt(false, state, resolver) { |
| 80 } | 85 } |
| 81 }; | 86 }; |
| 82 | 87 |
| 83 class ParallelAuthenticatorTest : public testing::Test { | 88 class ParallelAuthenticatorTest : public testing::Test { |
| 84 public: | 89 public: |
| 85 ParallelAuthenticatorTest() | 90 ParallelAuthenticatorTest() |
| 86 : message_loop_(MessageLoop::TYPE_UI), | 91 : message_loop_(MessageLoop::TYPE_UI), |
| 87 ui_thread_(BrowserThread::UI, &message_loop_), | 92 ui_thread_(BrowserThread::UI, &message_loop_), |
| 93 file_thread_(BrowserThread::FILE, &message_loop_), |
| 88 io_thread_(BrowserThread::IO), | 94 io_thread_(BrowserThread::IO), |
| 89 username_("me@nowhere.org"), | 95 username_("me@nowhere.org"), |
| 90 password_("fakepass") { | 96 password_("fakepass") { |
| 91 hash_ascii_.assign("0a010000000000a0"); | 97 hash_ascii_.assign("0a010000000000a0"); |
| 92 hash_ascii_.append(std::string(16, '0')); | 98 hash_ascii_.append(std::string(16, '0')); |
| 93 } | 99 } |
| 94 | 100 |
| 95 ~ParallelAuthenticatorTest() { | 101 ~ParallelAuthenticatorTest() { |
| 96 DCHECK(!mock_caller_); | 102 DCHECK(!mock_caller_); |
| 97 } | 103 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 108 .WillByDefault(Return(true)); | 114 .WillByDefault(Return(true)); |
| 109 EXPECT_CALL(*loader_, Load(_)) | 115 EXPECT_CALL(*loader_, Load(_)) |
| 110 .Times(AnyNumber()); | 116 .Times(AnyNumber()); |
| 111 | 117 |
| 112 test_api->SetLibraryLoader(loader_, true); | 118 test_api->SetLibraryLoader(loader_, true); |
| 113 | 119 |
| 114 mock_library_ = new MockCryptohomeLibrary(); | 120 mock_library_ = new MockCryptohomeLibrary(); |
| 115 test_api->SetCryptohomeLibrary(mock_library_, true); | 121 test_api->SetCryptohomeLibrary(mock_library_, true); |
| 116 io_thread_.Start(); | 122 io_thread_.Start(); |
| 117 | 123 |
| 124 mock_user_manager_ = new MockUserManager(); |
| 125 UserManager::Set(mock_user_manager_); |
| 126 EXPECT_CALL(*mock_user_manager_, LoadKeyStore()) |
| 127 .Times(AnyNumber()); |
| 128 |
| 118 auth_ = new ParallelAuthenticator(&consumer_); | 129 auth_ = new ParallelAuthenticator(&consumer_); |
| 119 auth_->set_using_oauth(false); | 130 auth_->set_using_oauth(false); |
| 120 state_.reset(new TestAttemptState(username_, | 131 state_.reset(new TestAttemptState(username_, |
| 121 password_, | 132 password_, |
| 122 hash_ascii_, | 133 hash_ascii_, |
| 123 "", | 134 "", |
| 124 "", | 135 "", |
| 125 false)); | 136 false)); |
| 126 } | 137 } |
| 127 | 138 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 BrowserThread::PostTask( | 222 BrowserThread::PostTask( |
| 212 BrowserThread::IO, FROM_HERE, | 223 BrowserThread::IO, FROM_HERE, |
| 213 base::Bind(&ParallelAuthenticator::Resolve, auth)); | 224 base::Bind(&ParallelAuthenticator::Resolve, auth)); |
| 214 loop->Run(); | 225 loop->Run(); |
| 215 } | 226 } |
| 216 | 227 |
| 217 void SetAttemptState(ParallelAuthenticator* auth, TestAttemptState* state) { | 228 void SetAttemptState(ParallelAuthenticator* auth, TestAttemptState* state) { |
| 218 auth->set_attempt_state(state); | 229 auth->set_attempt_state(state); |
| 219 } | 230 } |
| 220 | 231 |
| 232 void SetOwnerState(bool owner_check_finished, bool check_result) { |
| 233 auth_->SetOwnerState(owner_check_finished, check_result); |
| 234 } |
| 235 |
| 221 void FakeOnlineAttempt() { | 236 void FakeOnlineAttempt() { |
| 222 auth_->set_online_attempt(new TestOnlineAttempt(state_.get(), auth_.get())); | 237 auth_->set_online_attempt(new TestOnlineAttempt(state_.get(), auth_.get())); |
| 223 } | 238 } |
| 224 | 239 |
| 225 MessageLoop message_loop_; | 240 MessageLoop message_loop_; |
| 226 content::TestBrowserThread ui_thread_; | 241 content::TestBrowserThread ui_thread_; |
| 242 content::TestBrowserThread file_thread_; |
| 227 content::TestBrowserThread io_thread_; | 243 content::TestBrowserThread io_thread_; |
| 228 | 244 |
| 229 std::string username_; | 245 std::string username_; |
| 230 std::string password_; | 246 std::string password_; |
| 231 std::string hash_ascii_; | 247 std::string hash_ascii_; |
| 232 | 248 |
| 233 // Initializes / shuts down a stub CrosLibrary. | 249 // Initializes / shuts down a stub CrosLibrary. |
| 234 chromeos::ScopedStubCrosEnabler stub_cros_enabler_; | 250 chromeos::ScopedStubCrosEnabler stub_cros_enabler_; |
| 235 | 251 |
| 236 // Mocks, destroyed by CrosLibrary class. | 252 // Mocks, destroyed by CrosLibrary class. |
| 237 MockCryptohomeLibrary* mock_library_; | 253 MockCryptohomeLibrary* mock_library_; |
| 238 MockLibraryLoader* loader_; | 254 MockLibraryLoader* loader_; |
| 255 MockUserManager* mock_user_manager_; |
| 239 | 256 |
| 240 cryptohome::MockAsyncMethodCaller* mock_caller_; | 257 cryptohome::MockAsyncMethodCaller* mock_caller_; |
| 241 | 258 |
| 242 MockConsumer consumer_; | 259 MockConsumer consumer_; |
| 243 scoped_refptr<ParallelAuthenticator> auth_; | 260 scoped_refptr<ParallelAuthenticator> auth_; |
| 244 scoped_ptr<TestAttemptState> state_; | 261 scoped_ptr<TestAttemptState> state_; |
| 245 }; | 262 }; |
| 246 | 263 |
| 247 TEST_F(ParallelAuthenticatorTest, OnLoginSuccess) { | 264 TEST_F(ParallelAuthenticatorTest, OnLoginSuccess) { |
| 248 EXPECT_CALL(consumer_, OnLoginSuccess(username_, password_, false, false)) | 265 EXPECT_CALL(consumer_, OnLoginSuccess(username_, password_, false, false)) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 // an online auth attempt has completed successfully. | 320 // an online auth attempt has completed successfully. |
| 304 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_KEY_FAILURE); | 321 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_KEY_FAILURE); |
| 305 state_->PresetOnlineLoginStatus(LoginFailure::None()); | 322 state_->PresetOnlineLoginStatus(LoginFailure::None()); |
| 306 scoped_refptr<ResolveChecker> checker( | 323 scoped_refptr<ResolveChecker> checker( |
| 307 new ResolveChecker(state_.release(), | 324 new ResolveChecker(state_.release(), |
| 308 auth_.get(), | 325 auth_.get(), |
| 309 ParallelAuthenticator::NEED_OLD_PW)); | 326 ParallelAuthenticator::NEED_OLD_PW)); |
| 310 EXPECT_TRUE(checker->Run()); | 327 EXPECT_TRUE(checker->Run()); |
| 311 } | 328 } |
| 312 | 329 |
| 330 TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededDirectFailedMount) { |
| 331 // Set up state as though a cryptohome mount attempt has occurred |
| 332 // and succeeded but we are in safe mode and the current user is not owner. |
| 333 // This is a high level test to verify the proper transitioning in this mode |
| 334 // only. It is not testing that we properly verify that the user is an owner |
| 335 // or that we really are in "safe-mode". |
| 336 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE); |
| 337 SetOwnerState(true, false); |
| 338 |
| 339 scoped_refptr<ResolveChecker> checker( |
| 340 new ResolveChecker(state_.release(), |
| 341 auth_.get(), |
| 342 ParallelAuthenticator::OWNER_REQUIRED)); |
| 343 EXPECT_TRUE(checker->Run()); |
| 344 } |
| 345 |
| 346 TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededMount) { |
| 347 // Set up state as though a cryptohome mount attempt has occurred |
| 348 // and succeeded but we are in safe mode and the current user is not owner. |
| 349 // This test will check that the "safe-mode" policy is not set and will let |
| 350 // the mount finish successfully. |
| 351 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE); |
| 352 SetOwnerState(false, false); |
| 353 |
| 354 scoped_refptr<ResolveChecker> checker( |
| 355 new ResolveChecker(state_.release(), |
| 356 auth_.get(), |
| 357 ParallelAuthenticator::CONTINUE)); |
| 358 EXPECT_TRUE(checker->Run()); |
| 359 // Let the owner verification run on the FILE thread... |
| 360 message_loop_.RunAllPending(); |
| 361 // and test that the mount has succeeded. |
| 362 state_.reset(new TestAttemptState(username_, |
| 363 password_, |
| 364 hash_ascii_, |
| 365 "", |
| 366 "", |
| 367 false)); |
| 368 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE); |
| 369 checker = new ResolveChecker(state_.release(), |
| 370 auth_.get(), |
| 371 ParallelAuthenticator::OFFLINE_LOGIN); |
| 372 EXPECT_TRUE(checker->Run()); |
| 373 } |
| 374 |
| 375 TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) { |
| 376 scoped_ptr<MockDBusThreadManager> mock_dbus_thread_manager( |
| 377 new MockDBusThreadManager); |
| 378 DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager.get()); |
| 379 EXPECT_CALL(*mock_dbus_thread_manager->mock_cryptohome_client(), Unmount(_)) |
| 380 .WillOnce(DoAll(SetArgPointee<0>(true), Return(true))); |
| 381 |
| 382 CrosSettingsProvider* device_settings_provider; |
| 383 StubCrosSettingsProvider stub_settings_provider; |
| 384 // Set up state as though a cryptohome mount attempt has occurred |
| 385 // and succeeded but we are in safe mode and the current user is not owner. |
| 386 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE); |
| 387 SetOwnerState(false, false); |
| 388 // Remove the real DeviceSettingsProvider and replace it with a stub. |
| 389 device_settings_provider = |
| 390 CrosSettings::Get()->GetProvider(chromeos::kReportDeviceVersionInfo); |
| 391 EXPECT_TRUE(device_settings_provider != NULL); |
| 392 EXPECT_TRUE( |
| 393 CrosSettings::Get()->RemoveSettingsProvider(device_settings_provider)); |
| 394 CrosSettings::Get()->AddSettingsProvider(&stub_settings_provider); |
| 395 CrosSettings::Get()->SetBoolean(kPolicyMissingMitigationMode, true); |
| 396 |
| 397 scoped_refptr<ResolveChecker> checker( |
| 398 new ResolveChecker(state_.release(), |
| 399 auth_.get(), |
| 400 ParallelAuthenticator::CONTINUE)); |
| 401 EXPECT_TRUE(checker->Run()); |
| 402 // Let the owner verification run on the FILE thread... |
| 403 message_loop_.RunAllPending(); |
| 404 // and test that the mount has succeeded. |
| 405 state_.reset(new TestAttemptState(username_, |
| 406 password_, |
| 407 hash_ascii_, |
| 408 "", |
| 409 "", |
| 410 false)); |
| 411 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE); |
| 412 checker = new ResolveChecker(state_.release(), |
| 413 auth_.get(), |
| 414 ParallelAuthenticator::OWNER_REQUIRED); |
| 415 EXPECT_TRUE(checker->Run()); |
| 416 |
| 417 EXPECT_TRUE( |
| 418 CrosSettings::Get()->RemoveSettingsProvider(&stub_settings_provider)); |
| 419 CrosSettings::Get()->AddSettingsProvider(device_settings_provider); |
| 420 } |
| 421 |
| 313 TEST_F(ParallelAuthenticatorTest, DriveFailedMount) { | 422 TEST_F(ParallelAuthenticatorTest, DriveFailedMount) { |
| 314 FailOnLoginSuccess(); | 423 FailOnLoginSuccess(); |
| 315 ExpectLoginFailure(LoginFailure(LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME)); | 424 ExpectLoginFailure(LoginFailure(LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME)); |
| 316 | 425 |
| 317 // Set up state as though a cryptohome mount attempt has occurred | 426 // Set up state as though a cryptohome mount attempt has occurred |
| 318 // and failed. | 427 // and failed. |
| 319 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_NONE); | 428 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_NONE); |
| 320 SetAttemptState(auth_, state_.release()); | 429 SetAttemptState(auth_, state_.release()); |
| 321 | 430 |
| 322 RunResolve(auth_.get(), &message_loop_); | 431 RunResolve(auth_.get(), &message_loop_); |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 .RetiresOnSaturation(); | 817 .RetiresOnSaturation(); |
| 709 EXPECT_CALL(*mock_library_, HashPassword(_)) | 818 EXPECT_CALL(*mock_library_, HashPassword(_)) |
| 710 .WillOnce(Return(std::string())) | 819 .WillOnce(Return(std::string())) |
| 711 .RetiresOnSaturation(); | 820 .RetiresOnSaturation(); |
| 712 | 821 |
| 713 auth_->AuthenticateToUnlock(username_, ""); | 822 auth_->AuthenticateToUnlock(username_, ""); |
| 714 message_loop_.Run(); | 823 message_loop_.Run(); |
| 715 } | 824 } |
| 716 | 825 |
| 717 } // namespace chromeos | 826 } // namespace chromeos |
| OLD | NEW |