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 |