Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: chrome/browser/chromeos/login/auth/parallel_authenticator_unittest.cc

Issue 495563003: Move ParallelAuthnticator to chromeos and rename it to CryptohomeAuthenticator (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 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 #include "chrome/browser/chromeos/login/auth/parallel_authenticator.h"
6
7 #include <string>
8
9 #include "base/command_line.h"
10 #include "base/file_util.h"
11 #include "base/files/file_path.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
17 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
18 #include "chrome/browser/chromeos/ownership/owner_settings_service.h"
19 #include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h"
20 #include "chrome/browser/chromeos/profiles/profile_helper.h"
21 #include "chrome/browser/chromeos/settings/cros_settings.h"
22 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
23 #include "chrome/browser/chromeos/settings/mock_owner_key_util.h"
24 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
25 #include "chrome/test/base/testing_browser_process.h"
26 #include "chrome/test/base/testing_profile.h"
27 #include "chrome/test/base/testing_profile_manager.h"
28 #include "chromeos/chromeos_switches.h"
29 #include "chromeos/cryptohome/mock_async_method_caller.h"
30 #include "chromeos/cryptohome/system_salt_getter.h"
31 #include "chromeos/dbus/fake_cryptohome_client.h"
32 #include "chromeos/dbus/fake_dbus_thread_manager.h"
33 #include "chromeos/login/auth/key.h"
34 #include "chromeos/login/auth/mock_auth_status_consumer.h"
35 #include "chromeos/login/auth/mock_url_fetchers.h"
36 #include "chromeos/login/auth/test_attempt_state.h"
37 #include "chromeos/login/auth/user_context.h"
38 #include "content/public/test/test_browser_thread_bundle.h"
39 #include "crypto/nss_util_internal.h"
40 #include "crypto/scoped_test_nss_chromeos_user.h"
41 #include "google_apis/gaia/mock_url_fetcher_factory.h"
42 #include "net/base/net_errors.h"
43 #include "net/url_request/url_request_status.h"
44 #include "testing/gmock/include/gmock/gmock.h"
45 #include "testing/gtest/include/gtest/gtest.h"
46 #include "third_party/cros_system_api/dbus/service_constants.h"
47 #include "url/gurl.h"
48
49 using ::testing::Invoke;
50 using ::testing::Return;
51 using ::testing::_;
52
53 namespace chromeos {
54
55 namespace {
56
57 // An owner key in PKCS#8 PrivateKeyInfo for testing owner checks.
58 const uint8 kOwnerPrivateKey[] = {
59 0x30, 0x82, 0x01, 0x53, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
60 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
61 0x01, 0x3d, 0x30, 0x82, 0x01, 0x39, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
62 0xb4, 0xf5, 0xab, 0xfe, 0xd8, 0xf1, 0xcb, 0x5f, 0x8f, 0x48, 0x3e, 0xdf,
63 0x40, 0x8e, 0x2b, 0x15, 0x43, 0x6c, 0x67, 0x74, 0xa2, 0xcb, 0xe4, 0xf3,
64 0xec, 0xab, 0x41, 0x57, 0x1d, 0x5f, 0xed, 0xcf, 0x09, 0xf4, 0xcc, 0xbb,
65 0x52, 0x52, 0xe8, 0x46, 0xf5, 0xc5, 0x01, 0xa3, 0xd8, 0x24, 0xc0, 0x15,
66 0xc5, 0x65, 0x50, 0x7d, 0xbd, 0x4e, 0x81, 0xb2, 0x28, 0x38, 0xf9, 0x3d,
67 0x3e, 0x2a, 0x68, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x40,
68 0xc7, 0xb5, 0xb3, 0xbc, 0xac, 0x0a, 0x77, 0x02, 0x0f, 0x05, 0xda, 0xdb,
69 0xfc, 0x48, 0xf6, 0x0a, 0xb5, 0xf2, 0xef, 0x31, 0x1c, 0x36, 0xb1, 0x0f,
70 0xa7, 0x5a, 0xf3, 0xb9, 0xa3, 0x4e, 0xb8, 0xf6, 0x10, 0xfe, 0x25, 0x7b,
71 0x36, 0xb4, 0x1b, 0x80, 0xe3, 0x92, 0x37, 0x83, 0xf0, 0x43, 0xb3, 0x00,
72 0xa6, 0x53, 0xc6, 0x1b, 0x7e, 0x4b, 0xb0, 0x33, 0xd4, 0xe1, 0x03, 0xc4,
73 0xaa, 0xbc, 0x89, 0x02, 0x21, 0x00, 0xde, 0xc8, 0x8d, 0x10, 0xbc, 0xf3,
74 0x43, 0x49, 0x1f, 0x07, 0xf7, 0x12, 0xeb, 0x0a, 0x90, 0xab, 0xb9, 0xaa,
75 0x81, 0xb5, 0x54, 0x71, 0xf4, 0x2e, 0xc4, 0x44, 0xec, 0xff, 0x7d, 0xff,
76 0xe8, 0xa5, 0x02, 0x21, 0x00, 0xcf, 0xf0, 0xbe, 0xa6, 0xde, 0x9c, 0x70,
77 0xed, 0xf0, 0xc3, 0x18, 0x9b, 0xca, 0xe5, 0x7c, 0x4b, 0x9b, 0xf5, 0x12,
78 0x5d, 0x86, 0xbe, 0x8d, 0xf1, 0xbc, 0x2c, 0x79, 0x59, 0xf5, 0xff, 0xbc,
79 0x6b, 0x02, 0x20, 0x7c, 0x09, 0x1c, 0xc1, 0x1c, 0xf2, 0x33, 0x9c, 0x1a,
80 0x72, 0xcc, 0xd4, 0xf3, 0x97, 0xc6, 0x44, 0x55, 0xf2, 0xe0, 0x94, 0x9c,
81 0x97, 0x75, 0x64, 0x34, 0x52, 0x4b, 0xc1, 0x53, 0xdd, 0x8f, 0x21, 0x02,
82 0x20, 0x0e, 0xef, 0x48, 0x92, 0x2d, 0x9c, 0xe8, 0xd3, 0x7e, 0x1e, 0x55,
83 0x0f, 0x23, 0x74, 0x76, 0x07, 0xec, 0x2c, 0x9e, 0xe4, 0x0e, 0xc0, 0x72,
84 0xeb, 0x70, 0xcb, 0x74, 0xef, 0xcc, 0x26, 0x50, 0xff, 0x02, 0x20, 0x29,
85 0x32, 0xd0, 0xbf, 0x11, 0xf2, 0xbf, 0x54, 0xfd, 0x6d, 0xf2, 0x1c, 0xbe,
86 0x50, 0x18, 0x62, 0x6d, 0x23, 0xe4, 0x26, 0x03, 0x8b, 0xb3, 0x42, 0x24,
87 0x7e, 0x68, 0x37, 0x26, 0xda, 0xb9, 0x87
88 };
89
90 // The public key alone matcing kOwnerPrivateKey.
91 const uint8 kOwnerPublicKey[] = {
92 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
93 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
94 0x00, 0xb4, 0xf5, 0xab, 0xfe, 0xd8, 0xf1, 0xcb, 0x5f, 0x8f, 0x48, 0x3e,
95 0xdf, 0x40, 0x8e, 0x2b, 0x15, 0x43, 0x6c, 0x67, 0x74, 0xa2, 0xcb, 0xe4,
96 0xf3, 0xec, 0xab, 0x41, 0x57, 0x1d, 0x5f, 0xed, 0xcf, 0x09, 0xf4, 0xcc,
97 0xbb, 0x52, 0x52, 0xe8, 0x46, 0xf5, 0xc5, 0x01, 0xa3, 0xd8, 0x24, 0xc0,
98 0x15, 0xc5, 0x65, 0x50, 0x7d, 0xbd, 0x4e, 0x81, 0xb2, 0x28, 0x38, 0xf9,
99 0x3d, 0x3e, 0x2a, 0x68, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01
100 };
101
102 std::vector<uint8> GetOwnerPublicKey() {
103 return std::vector<uint8>(kOwnerPublicKey,
104 kOwnerPublicKey + arraysize(kOwnerPublicKey));
105 }
106
107 scoped_ptr<crypto::RSAPrivateKey> CreateOwnerKeyInSlot(PK11SlotInfo* slot) {
108 const std::vector<uint8> key(kOwnerPrivateKey,
109 kOwnerPrivateKey + arraysize(kOwnerPrivateKey));
110 return make_scoped_ptr(
111 crypto::RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(slot, key));
112 }
113
114 } // namespace
115
116 class ParallelAuthenticatorTest : public testing::Test {
117 public:
118 ParallelAuthenticatorTest()
119 : user_context_("me@nowhere.org"),
120 user_manager_(new FakeUserManager()),
121 user_manager_enabler_(user_manager_),
122 mock_caller_(NULL),
123 owner_key_util_(new MockOwnerKeyUtil) {
124 user_context_.SetKey(Key("fakepass"));
125 user_context_.SetUserIDHash("me_nowhere_com_hash");
126 const user_manager::User* user =
127 user_manager_->AddUser(user_context_.GetUserID());
128 profile_.set_profile_name(user_context_.GetUserID());
129
130 ProfileHelper::Get()->SetUserToProfileMappingForTesting(user, &profile_);
131
132 transformed_key_ = *user_context_.GetKey();
133 transformed_key_.Transform(Key::KEY_TYPE_SALTED_SHA256_TOP_HALF,
134 SystemSaltGetter::ConvertRawSaltToHexString(
135 FakeCryptohomeClient::GetStubSystemSalt()));
136 }
137
138 virtual ~ParallelAuthenticatorTest() {}
139
140 virtual void SetUp() {
141 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kLoginManager);
142
143 mock_caller_ = new cryptohome::MockAsyncMethodCaller;
144 cryptohome::AsyncMethodCaller::InitializeForTesting(mock_caller_);
145
146 FakeDBusThreadManager* fake_dbus_thread_manager = new FakeDBusThreadManager;
147 fake_cryptohome_client_ = new FakeCryptohomeClient;
148 fake_dbus_thread_manager->SetCryptohomeClient(
149 scoped_ptr<CryptohomeClient>(fake_cryptohome_client_));
150 DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
151
152 SystemSaltGetter::Initialize();
153
154 OwnerSettingsService::SetOwnerKeyUtilForTesting(owner_key_util_);
155
156 auth_ = new ParallelAuthenticator(&consumer_);
157 state_.reset(new TestAttemptState(user_context_, false));
158 }
159
160 // Tears down the test fixture.
161 virtual void TearDown() {
162 OwnerSettingsService::SetOwnerKeyUtilForTesting(NULL);
163 SystemSaltGetter::Shutdown();
164 DBusThreadManager::Shutdown();
165
166 cryptohome::AsyncMethodCaller::Shutdown();
167 mock_caller_ = NULL;
168 }
169
170 base::FilePath PopulateTempFile(const char* data, int data_len) {
171 base::FilePath out;
172 FILE* tmp_file = base::CreateAndOpenTemporaryFile(&out);
173 EXPECT_NE(tmp_file, static_cast<FILE*>(NULL));
174 EXPECT_EQ(base::WriteFile(out, data, data_len), data_len);
175 EXPECT_TRUE(base::CloseFile(tmp_file));
176 return out;
177 }
178
179 // Allow test to fail and exit gracefully, even if OnAuthFailure()
180 // wasn't supposed to happen.
181 void FailOnLoginFailure() {
182 ON_CALL(consumer_, OnAuthFailure(_))
183 .WillByDefault(Invoke(MockAuthStatusConsumer::OnFailQuitAndFail));
184 }
185
186 // Allow test to fail and exit gracefully, even if
187 // OnRetailModeAuthSuccess() wasn't supposed to happen.
188 void FailOnRetailModeLoginSuccess() {
189 ON_CALL(consumer_, OnRetailModeAuthSuccess(_)).WillByDefault(
190 Invoke(MockAuthStatusConsumer::OnRetailModeSuccessQuitAndFail));
191 }
192
193 // Allow test to fail and exit gracefully, even if OnAuthSuccess()
194 // wasn't supposed to happen.
195 void FailOnLoginSuccess() {
196 ON_CALL(consumer_, OnAuthSuccess(_))
197 .WillByDefault(Invoke(MockAuthStatusConsumer::OnSuccessQuitAndFail));
198 }
199
200 // Allow test to fail and exit gracefully, even if
201 // OnOffTheRecordAuthSuccess() wasn't supposed to happen.
202 void FailOnGuestLoginSuccess() {
203 ON_CALL(consumer_, OnOffTheRecordAuthSuccess()).WillByDefault(
204 Invoke(MockAuthStatusConsumer::OnGuestSuccessQuitAndFail));
205 }
206
207 void ExpectLoginFailure(const AuthFailure& failure) {
208 EXPECT_CALL(consumer_, OnAuthFailure(failure))
209 .WillOnce(Invoke(MockAuthStatusConsumer::OnFailQuit))
210 .RetiresOnSaturation();
211 }
212
213 void ExpectRetailModeLoginSuccess() {
214 EXPECT_CALL(consumer_, OnRetailModeAuthSuccess(_))
215 .WillOnce(Invoke(MockAuthStatusConsumer::OnRetailModeSuccessQuit))
216 .RetiresOnSaturation();
217 }
218
219 void ExpectLoginSuccess(const UserContext& user_context) {
220 EXPECT_CALL(consumer_, OnAuthSuccess(user_context))
221 .WillOnce(Invoke(MockAuthStatusConsumer::OnSuccessQuit))
222 .RetiresOnSaturation();
223 }
224
225 void ExpectGuestLoginSuccess() {
226 EXPECT_CALL(consumer_, OnOffTheRecordAuthSuccess())
227 .WillOnce(Invoke(MockAuthStatusConsumer::OnGuestSuccessQuit))
228 .RetiresOnSaturation();
229 }
230
231 void ExpectPasswordChange() {
232 EXPECT_CALL(consumer_, OnPasswordChangeDetected())
233 .WillOnce(Invoke(MockAuthStatusConsumer::OnMigrateQuit))
234 .RetiresOnSaturation();
235 }
236
237 void RunResolve(ParallelAuthenticator* auth) {
238 auth->Resolve();
239 base::MessageLoop::current()->RunUntilIdle();
240 }
241
242 void SetAttemptState(ParallelAuthenticator* auth, TestAttemptState* state) {
243 auth->set_attempt_state(state);
244 }
245
246 ParallelAuthenticator::AuthState SetAndResolveState(
247 ParallelAuthenticator* auth, TestAttemptState* state) {
248 auth->set_attempt_state(state);
249 return auth->ResolveState();
250 }
251
252 void SetOwnerState(bool owner_check_finished, bool check_result) {
253 auth_->SetOwnerState(owner_check_finished, check_result);
254 }
255
256 content::TestBrowserThreadBundle thread_bundle_;
257
258 UserContext user_context_;
259 Key transformed_key_;
260
261 ScopedDeviceSettingsTestHelper device_settings_test_helper_;
262 ScopedTestCrosSettings test_cros_settings_;
263
264 TestingProfile profile_;
265 scoped_ptr<TestingProfileManager> profile_manager_;
266 FakeUserManager* user_manager_;
267 ScopedUserManagerEnabler user_manager_enabler_;
268
269 cryptohome::MockAsyncMethodCaller* mock_caller_;
270
271 MockAuthStatusConsumer consumer_;
272
273 scoped_refptr<ParallelAuthenticator> auth_;
274 scoped_ptr<TestAttemptState> state_;
275 FakeCryptohomeClient* fake_cryptohome_client_;
276
277 scoped_refptr<MockOwnerKeyUtil> owner_key_util_;
278 };
279
280 TEST_F(ParallelAuthenticatorTest, OnAuthSuccess) {
281 EXPECT_CALL(consumer_, OnAuthSuccess(user_context_))
282 .Times(1)
283 .RetiresOnSaturation();
284
285 SetAttemptState(auth_.get(), state_.release());
286 auth_->OnAuthSuccess();
287 }
288
289 TEST_F(ParallelAuthenticatorTest, OnPasswordChangeDetected) {
290 EXPECT_CALL(consumer_, OnPasswordChangeDetected())
291 .Times(1)
292 .RetiresOnSaturation();
293 SetAttemptState(auth_.get(), state_.release());
294 auth_->OnPasswordChangeDetected();
295 }
296
297 TEST_F(ParallelAuthenticatorTest, ResolveNothingDone) {
298 EXPECT_EQ(ParallelAuthenticator::CONTINUE,
299 SetAndResolveState(auth_.get(), state_.release()));
300 }
301
302
303 TEST_F(ParallelAuthenticatorTest, ResolvePossiblePwChangeToFailedMount) {
304 // Set up state as though a cryptohome mount attempt has occurred
305 // and been rejected.
306 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_KEY_FAILURE);
307
308 // When there is no online attempt and online results, POSSIBLE_PW_CHANGE
309 EXPECT_EQ(ParallelAuthenticator::FAILED_MOUNT,
310 SetAndResolveState(auth_.get(), state_.release()));
311 }
312
313 TEST_F(ParallelAuthenticatorTest, ResolveNeedOldPw) {
314 // Set up state as though a cryptohome mount attempt has occurred
315 // and been rejected because of unmatched key; additionally,
316 // an online auth attempt has completed successfully.
317 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_KEY_FAILURE);
318 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone());
319
320 EXPECT_EQ(ParallelAuthenticator::NEED_OLD_PW,
321 SetAndResolveState(auth_.get(), state_.release()));
322 }
323
324 TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededDirectFailedMount) {
325 // Set up state as though a cryptohome mount attempt has occurred
326 // and succeeded but we are in safe mode and the current user is not owner.
327 // This is a high level test to verify the proper transitioning in this mode
328 // only. It is not testing that we properly verify that the user is an owner
329 // or that we really are in "safe-mode".
330 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
331 SetOwnerState(true, false);
332
333 EXPECT_EQ(ParallelAuthenticator::OWNER_REQUIRED,
334 SetAndResolveState(auth_.get(), state_.release()));
335 }
336
337 TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededMount) {
338 // Set up state as though a cryptohome mount attempt has occurred
339 // and succeeded but we are in safe mode and the current user is not owner.
340 // This test will check that the "safe-mode" policy is not set and will let
341 // the mount finish successfully.
342 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
343 SetOwnerState(false, false);
344 EXPECT_EQ(ParallelAuthenticator::OFFLINE_LOGIN,
345 SetAndResolveState(auth_.get(), state_.release()));
346 }
347
348 // Test the case that login switches to SafeMode and a User that is not the
349 // owner tries to log in. The login should fail because of the missing owner
350 // private key.
351 TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) {
352 crypto::ScopedTestNSSChromeOSUser user_slot(user_context_.GetUserIDHash());
353 owner_key_util_->SetPublicKey(GetOwnerPublicKey());
354
355 profile_manager_.reset(
356 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
357 ASSERT_TRUE(profile_manager_->SetUp());
358
359 FailOnLoginSuccess(); // Set failing on success as the default...
360 AuthFailure failure = AuthFailure(AuthFailure::OWNER_REQUIRED);
361 ExpectLoginFailure(failure);
362
363 // Set up state as though a cryptohome mount attempt has occurred
364 // and succeeded but we are in safe mode and the current user is not owner.
365 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
366 SetOwnerState(false, false);
367 // Remove the real DeviceSettingsProvider and replace it with a stub.
368 CrosSettingsProvider* device_settings_provider =
369 CrosSettings::Get()->GetProvider(chromeos::kReportDeviceVersionInfo);
370 EXPECT_TRUE(device_settings_provider != NULL);
371 EXPECT_TRUE(
372 CrosSettings::Get()->RemoveSettingsProvider(device_settings_provider));
373 StubCrosSettingsProvider stub_settings_provider;
374 CrosSettings::Get()->AddSettingsProvider(&stub_settings_provider);
375 CrosSettings::Get()->SetBoolean(kPolicyMissingMitigationMode, true);
376
377 // Initialize login state for this test to verify the login state is changed
378 // to SAFE_MODE.
379 LoginState::Initialize();
380
381 EXPECT_EQ(ParallelAuthenticator::CONTINUE,
382 SetAndResolveState(auth_.get(), state_.release()));
383 EXPECT_TRUE(LoginState::Get()->IsInSafeMode());
384
385 // Flush all the pending operations. The operations should induce an owner
386 // verification.
387 device_settings_test_helper_.Flush();
388
389 state_.reset(new TestAttemptState(user_context_, false));
390 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
391
392 // The owner key util should not have found the owner key, so login should
393 // not be allowed.
394 EXPECT_EQ(ParallelAuthenticator::OWNER_REQUIRED,
395 SetAndResolveState(auth_.get(), state_.release()));
396 EXPECT_TRUE(LoginState::Get()->IsInSafeMode());
397
398 // Unset global objects used by this test.
399 fake_cryptohome_client_->set_unmount_result(true);
400 LoginState::Shutdown();
401 EXPECT_TRUE(
402 CrosSettings::Get()->RemoveSettingsProvider(&stub_settings_provider));
403 CrosSettings::Get()->AddSettingsProvider(device_settings_provider);
404 }
405
406 // Test the case that login switches to SafeMode and the Owner logs in, which
407 // should lead to a successful login.
408 TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededSuccess) {
409 crypto::ScopedTestNSSChromeOSUser test_user_db(user_context_.GetUserIDHash());
410 owner_key_util_->SetPublicKey(GetOwnerPublicKey());
411
412 crypto::ScopedPK11Slot user_slot(
413 crypto::GetPublicSlotForChromeOSUser(user_context_.GetUserIDHash()));
414 CreateOwnerKeyInSlot(user_slot.get());
415
416 profile_manager_.reset(
417 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
418 ASSERT_TRUE(profile_manager_->SetUp());
419
420 ExpectLoginSuccess(user_context_);
421
422 // Set up state as though a cryptohome mount attempt has occurred
423 // and succeeded but we are in safe mode and the current user is not owner.
424 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
425 SetOwnerState(false, false);
426 // Remove the real DeviceSettingsProvider and replace it with a stub.
427 CrosSettingsProvider* device_settings_provider =
428 CrosSettings::Get()->GetProvider(chromeos::kReportDeviceVersionInfo);
429 EXPECT_TRUE(device_settings_provider != NULL);
430 EXPECT_TRUE(
431 CrosSettings::Get()->RemoveSettingsProvider(device_settings_provider));
432 StubCrosSettingsProvider stub_settings_provider;
433 CrosSettings::Get()->AddSettingsProvider(&stub_settings_provider);
434 CrosSettings::Get()->SetBoolean(kPolicyMissingMitigationMode, true);
435
436 // Initialize login state for this test to verify the login state is changed
437 // to SAFE_MODE.
438 LoginState::Initialize();
439
440 EXPECT_EQ(ParallelAuthenticator::CONTINUE,
441 SetAndResolveState(auth_.get(), state_.release()));
442 EXPECT_TRUE(LoginState::Get()->IsInSafeMode());
443
444 // Flush all the pending operations. The operations should induce an owner
445 // verification.
446 device_settings_test_helper_.Flush();
447
448 state_.reset(new TestAttemptState(user_context_, false));
449 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
450
451 // The owner key util should find the owner key, so login should succeed.
452 EXPECT_EQ(ParallelAuthenticator::OFFLINE_LOGIN,
453 SetAndResolveState(auth_.get(), state_.release()));
454 EXPECT_TRUE(LoginState::Get()->IsInSafeMode());
455
456 // Unset global objects used by this test.
457 fake_cryptohome_client_->set_unmount_result(true);
458 LoginState::Shutdown();
459 EXPECT_TRUE(
460 CrosSettings::Get()->RemoveSettingsProvider(&stub_settings_provider));
461 CrosSettings::Get()->AddSettingsProvider(device_settings_provider);
462 }
463
464 TEST_F(ParallelAuthenticatorTest, DriveFailedMount) {
465 FailOnLoginSuccess();
466 ExpectLoginFailure(AuthFailure(AuthFailure::COULD_NOT_MOUNT_CRYPTOHOME));
467
468 // Set up state as though a cryptohome mount attempt has occurred
469 // and failed.
470 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_NONE);
471 SetAttemptState(auth_.get(), state_.release());
472
473 RunResolve(auth_.get());
474 }
475
476 TEST_F(ParallelAuthenticatorTest, DriveGuestLogin) {
477 ExpectGuestLoginSuccess();
478 FailOnLoginFailure();
479
480 // Set up mock async method caller to respond as though a tmpfs mount
481 // attempt has occurred and succeeded.
482 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
483 EXPECT_CALL(*mock_caller_, AsyncMountGuest(_))
484 .Times(1)
485 .RetiresOnSaturation();
486
487 auth_->LoginOffTheRecord();
488 base::MessageLoop::current()->Run();
489 }
490
491 TEST_F(ParallelAuthenticatorTest, DriveGuestLoginButFail) {
492 FailOnGuestLoginSuccess();
493 ExpectLoginFailure(AuthFailure(AuthFailure::COULD_NOT_MOUNT_TMPFS));
494
495 // Set up mock async method caller to respond as though a tmpfs mount
496 // attempt has occurred and failed.
497 mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_NONE);
498 EXPECT_CALL(*mock_caller_, AsyncMountGuest(_))
499 .Times(1)
500 .RetiresOnSaturation();
501
502 auth_->LoginOffTheRecord();
503 base::MessageLoop::current()->Run();
504 }
505
506 TEST_F(ParallelAuthenticatorTest, DriveRetailModeUserLogin) {
507 ExpectRetailModeLoginSuccess();
508 FailOnLoginFailure();
509
510 // Set up mock async method caller to respond as though a tmpfs mount
511 // attempt has occurred and succeeded.
512 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
513 EXPECT_CALL(*mock_caller_, AsyncMountGuest(_))
514 .Times(1)
515 .RetiresOnSaturation();
516
517 auth_->LoginRetailMode();
518 base::MessageLoop::current()->Run();
519 }
520
521 TEST_F(ParallelAuthenticatorTest, DriveRetailModeLoginButFail) {
522 FailOnRetailModeLoginSuccess();
523 ExpectLoginFailure(AuthFailure(AuthFailure::COULD_NOT_MOUNT_TMPFS));
524
525 // Set up mock async method caller to respond as though a tmpfs mount
526 // attempt has occurred and failed.
527 mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_NONE);
528 EXPECT_CALL(*mock_caller_, AsyncMountGuest(_))
529 .Times(1)
530 .RetiresOnSaturation();
531
532 auth_->LoginRetailMode();
533 base::MessageLoop::current()->Run();
534 }
535
536 TEST_F(ParallelAuthenticatorTest, DriveDataResync) {
537 UserContext expected_user_context(user_context_);
538 expected_user_context.SetUserIDHash(
539 cryptohome::MockAsyncMethodCaller::kFakeSanitizedUsername);
540 ExpectLoginSuccess(expected_user_context);
541 FailOnLoginFailure();
542
543 // Set up mock async method caller to respond successfully to a cryptohome
544 // remove attempt and a cryptohome create attempt (indicated by the
545 // |CREATE_IF_MISSING| flag to AsyncMount).
546 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
547 EXPECT_CALL(*mock_caller_, AsyncRemove(user_context_.GetUserID(), _))
548 .Times(1)
549 .RetiresOnSaturation();
550 EXPECT_CALL(*mock_caller_, AsyncMount(user_context_.GetUserID(),
551 transformed_key_.GetSecret(),
552 cryptohome::CREATE_IF_MISSING,
553 _))
554 .Times(1)
555 .RetiresOnSaturation();
556 EXPECT_CALL(*mock_caller_,
557 AsyncGetSanitizedUsername(user_context_.GetUserID(), _))
558 .Times(1)
559 .RetiresOnSaturation();
560
561 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone());
562 SetAttemptState(auth_.get(), state_.release());
563
564 auth_->ResyncEncryptedData();
565 base::MessageLoop::current()->Run();
566 }
567
568 TEST_F(ParallelAuthenticatorTest, DriveResyncFail) {
569 FailOnLoginSuccess();
570 ExpectLoginFailure(AuthFailure(AuthFailure::DATA_REMOVAL_FAILED));
571
572 // Set up mock async method caller to fail a cryptohome remove attempt.
573 mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_NONE);
574 EXPECT_CALL(*mock_caller_, AsyncRemove(user_context_.GetUserID(), _))
575 .Times(1)
576 .RetiresOnSaturation();
577
578 SetAttemptState(auth_.get(), state_.release());
579
580 auth_->ResyncEncryptedData();
581 base::MessageLoop::current()->Run();
582 }
583
584 TEST_F(ParallelAuthenticatorTest, DriveRequestOldPassword) {
585 FailOnLoginSuccess();
586 ExpectPasswordChange();
587
588 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_KEY_FAILURE);
589 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone());
590 SetAttemptState(auth_.get(), state_.release());
591
592 RunResolve(auth_.get());
593 }
594
595 TEST_F(ParallelAuthenticatorTest, DriveDataRecover) {
596 UserContext expected_user_context(user_context_);
597 expected_user_context.SetUserIDHash(
598 cryptohome::MockAsyncMethodCaller::kFakeSanitizedUsername);
599 ExpectLoginSuccess(expected_user_context);
600 FailOnLoginFailure();
601
602 // Set up mock async method caller to respond successfully to a key migration.
603 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
604 EXPECT_CALL(*mock_caller_, AsyncMigrateKey(user_context_.GetUserID(),
605 _,
606 transformed_key_.GetSecret(),
607 _))
608 .Times(1)
609 .RetiresOnSaturation();
610 EXPECT_CALL(*mock_caller_, AsyncMount(user_context_.GetUserID(),
611 transformed_key_.GetSecret(),
612 cryptohome::MOUNT_FLAGS_NONE,
613 _))
614 .Times(1)
615 .RetiresOnSaturation();
616 EXPECT_CALL(*mock_caller_,
617 AsyncGetSanitizedUsername(user_context_.GetUserID(), _))
618 .Times(1)
619 .RetiresOnSaturation();
620
621 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone());
622 SetAttemptState(auth_.get(), state_.release());
623
624 auth_->RecoverEncryptedData(std::string());
625 base::MessageLoop::current()->Run();
626 }
627
628 TEST_F(ParallelAuthenticatorTest, DriveDataRecoverButFail) {
629 FailOnLoginSuccess();
630 ExpectPasswordChange();
631
632 // Set up mock async method caller to fail a key migration attempt,
633 // asserting that the wrong password was used.
634 mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_KEY_FAILURE);
635 EXPECT_CALL(*mock_caller_, AsyncMigrateKey(user_context_.GetUserID(),
636 _,
637 transformed_key_.GetSecret(),
638 _))
639 .Times(1)
640 .RetiresOnSaturation();
641
642 SetAttemptState(auth_.get(), state_.release());
643
644 auth_->RecoverEncryptedData(std::string());
645 base::MessageLoop::current()->Run();
646 }
647
648 TEST_F(ParallelAuthenticatorTest, ResolveNoMountToFailedMount) {
649 // Set up state as though a cryptohome mount attempt has occurred
650 // and been rejected because the user doesn't exist.
651 state_->PresetCryptohomeStatus(false,
652 cryptohome::MOUNT_ERROR_USER_DOES_NOT_EXIST);
653
654 // When there is no online attempt and online results, NO_MOUNT will be
655 // resolved to FAILED_MOUNT.
656 EXPECT_EQ(ParallelAuthenticator::FAILED_MOUNT,
657 SetAndResolveState(auth_.get(), state_.release()));
658 }
659
660 TEST_F(ParallelAuthenticatorTest, ResolveCreateNew) {
661 // Set up state as though a cryptohome mount attempt has occurred
662 // and been rejected because the user doesn't exist; additionally,
663 // an online auth attempt has completed successfully.
664 state_->PresetCryptohomeStatus(false,
665 cryptohome::MOUNT_ERROR_USER_DOES_NOT_EXIST);
666 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone());
667
668 EXPECT_EQ(ParallelAuthenticator::CREATE_NEW,
669 SetAndResolveState(auth_.get(), state_.release()));
670 }
671
672 TEST_F(ParallelAuthenticatorTest, DriveCreateForNewUser) {
673 UserContext expected_user_context(user_context_);
674 expected_user_context.SetUserIDHash(
675 cryptohome::MockAsyncMethodCaller::kFakeSanitizedUsername);
676 ExpectLoginSuccess(expected_user_context);
677 FailOnLoginFailure();
678
679 // Set up mock async method caller to respond successfully to a cryptohome
680 // create attempt (indicated by the |CREATE_IF_MISSING| flag to AsyncMount).
681 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
682 EXPECT_CALL(*mock_caller_, AsyncMount(user_context_.GetUserID(),
683 transformed_key_.GetSecret(),
684 cryptohome::CREATE_IF_MISSING,
685 _))
686 .Times(1)
687 .RetiresOnSaturation();
688 EXPECT_CALL(*mock_caller_,
689 AsyncGetSanitizedUsername(user_context_.GetUserID(), _))
690 .Times(1)
691 .RetiresOnSaturation();
692
693 // Set up state as though a cryptohome mount attempt has occurred
694 // and been rejected because the user doesn't exist; additionally,
695 // an online auth attempt has completed successfully.
696 state_->PresetCryptohomeStatus(false,
697 cryptohome::MOUNT_ERROR_USER_DOES_NOT_EXIST);
698 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone());
699 SetAttemptState(auth_.get(), state_.release());
700
701 RunResolve(auth_.get());
702 }
703
704 TEST_F(ParallelAuthenticatorTest, DriveOfflineLogin) {
705 ExpectLoginSuccess(user_context_);
706 FailOnLoginFailure();
707
708 // Set up state as though a cryptohome mount attempt has occurred and
709 // succeeded.
710 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
711 SetAttemptState(auth_.get(), state_.release());
712
713 RunResolve(auth_.get());
714 }
715
716 TEST_F(ParallelAuthenticatorTest, DriveOnlineLogin) {
717 ExpectLoginSuccess(user_context_);
718 FailOnLoginFailure();
719
720 // Set up state as though a cryptohome mount attempt has occurred and
721 // succeeded.
722 state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
723 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone());
724 SetAttemptState(auth_.get(), state_.release());
725
726 RunResolve(auth_.get());
727 }
728
729 TEST_F(ParallelAuthenticatorTest, DriveUnlock) {
730 ExpectLoginSuccess(user_context_);
731 FailOnLoginFailure();
732
733 // Set up mock async method caller to respond successfully to a cryptohome
734 // key-check attempt.
735 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
736 EXPECT_CALL(*mock_caller_, AsyncCheckKey(user_context_.GetUserID(), _, _))
737 .Times(1)
738 .RetiresOnSaturation();
739
740 auth_->AuthenticateToUnlock(user_context_);
741 base::MessageLoop::current()->Run();
742 }
743
744 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698