OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/login_performer.h" | 5 #include "chrome/browser/chromeos/login/login_performer.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | |
9 #include "base/command_line.h" | 10 #include "base/command_line.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
12 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
13 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
14 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
15 #include "chrome/browser/chromeos/boot_times_loader.h" | 16 #include "chrome/browser/chromeos/boot_times_loader.h" |
16 #include "chrome/browser/chromeos/cros/cros_library.h" | 17 #include "chrome/browser/chromeos/cros/cros_library.h" |
17 #include "chrome/browser/chromeos/cros/screen_lock_library.h" | 18 #include "chrome/browser/chromeos/cros/screen_lock_library.h" |
19 #include "chrome/browser/chromeos/cros_settings.h" | |
18 #include "chrome/browser/chromeos/cros_settings_names.h" | 20 #include "chrome/browser/chromeos/cros_settings_names.h" |
19 #include "chrome/browser/chromeos/login/login_utils.h" | 21 #include "chrome/browser/chromeos/login/login_utils.h" |
20 #include "chrome/browser/chromeos/login/screen_locker.h" | 22 #include "chrome/browser/chromeos/login/screen_locker.h" |
21 #include "chrome/browser/chromeos/user_cros_settings_provider.h" | |
22 #include "chrome/browser/prefs/pref_service.h" | 23 #include "chrome/browser/prefs/pref_service.h" |
23 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
24 #include "chrome/browser/profiles/profile_manager.h" | 25 #include "chrome/browser/profiles/profile_manager.h" |
25 #include "chrome/common/chrome_notification_types.h" | 26 #include "chrome/common/chrome_notification_types.h" |
26 #include "chrome/common/chrome_switches.h" | 27 #include "chrome/common/chrome_switches.h" |
27 #include "chrome/common/pref_names.h" | 28 #include "chrome/common/pref_names.h" |
28 #include "content/browser/browser_thread.h" | 29 #include "content/browser/browser_thread.h" |
29 #include "content/browser/user_metrics.h" | 30 #include "content/browser/user_metrics.h" |
30 #include "content/common/content_notification_types.h" | 31 #include "content/common/content_notification_types.h" |
31 #include "content/common/notification_service.h" | 32 #include "content/common/notification_service.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
48 delegate_(delegate), | 49 delegate_(delegate), |
49 password_changed_(false), | 50 password_changed_(false), |
50 screen_lock_requested_(false), | 51 screen_lock_requested_(false), |
51 initial_online_auth_pending_(false), | 52 initial_online_auth_pending_(false), |
52 auth_mode_(AUTH_MODE_INTERNAL), | 53 auth_mode_(AUTH_MODE_INTERNAL), |
53 using_oauth_( | 54 using_oauth_( |
54 CommandLine::ForCurrentProcess()->HasSwitch( | 55 CommandLine::ForCurrentProcess()->HasSwitch( |
55 switches::kWebUILogin) && | 56 switches::kWebUILogin) && |
56 !CommandLine::ForCurrentProcess()->HasSwitch( | 57 !CommandLine::ForCurrentProcess()->HasSwitch( |
57 switches::kSkipOAuthLogin)), | 58 switches::kSkipOAuthLogin)), |
58 method_factory_(this) { | 59 pointer_factory_(this) { |
59 DCHECK(default_performer_ == NULL) | 60 DCHECK(default_performer_ == NULL) |
60 << "LoginPerformer should have only one instance."; | 61 << "LoginPerformer should have only one instance."; |
61 default_performer_ = this; | 62 default_performer_ = this; |
62 } | 63 } |
63 | 64 |
64 LoginPerformer::~LoginPerformer() { | 65 LoginPerformer::~LoginPerformer() { |
65 DVLOG(1) << "Deleting LoginPerformer"; | 66 DVLOG(1) << "Deleting LoginPerformer"; |
66 DCHECK(default_performer_ != NULL) << "Default instance should exist."; | 67 DCHECK(default_performer_ != NULL) << "Default instance should exist."; |
67 default_performer_ = NULL; | 68 default_performer_ = NULL; |
68 } | 69 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 last_login_failure_ = | 220 last_login_failure_ = |
220 LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError( | 221 LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError( |
221 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); | 222 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); |
222 password_changed_ = true; | 223 password_changed_ = true; |
223 DVLOG(1) << "Password change detected - locking screen."; | 224 DVLOG(1) << "Password change detected - locking screen."; |
224 RequestScreenLock(); | 225 RequestScreenLock(); |
225 } | 226 } |
226 } | 227 } |
227 | 228 |
228 //////////////////////////////////////////////////////////////////////////////// | 229 //////////////////////////////////////////////////////////////////////////////// |
229 // LoginPerformer, SignedSettingsHelper::Callback implementation: | |
230 | |
231 void LoginPerformer::OnCheckWhitelistCompleted(SignedSettings::ReturnCode code, | |
232 const std::string& email) { | |
233 if (code == SignedSettings::SUCCESS) { | |
234 // Whitelist check passed, continue with authentication. | |
235 if (auth_mode_ == AUTH_MODE_EXTENSION) { | |
236 StartLoginCompletion(); | |
237 } else { | |
238 StartAuthentication(); | |
239 } | |
240 } else { | |
241 if (delegate_) | |
242 delegate_->WhiteListCheckFailed(email); | |
243 else | |
244 NOTREACHED(); | |
245 } | |
246 } | |
247 | |
248 //////////////////////////////////////////////////////////////////////////////// | |
249 // LoginPerformer, NotificationObserver implementation: | 230 // LoginPerformer, NotificationObserver implementation: |
250 // | 231 // |
251 | 232 |
252 void LoginPerformer::Observe(int type, | 233 void LoginPerformer::Observe(int type, |
253 const NotificationSource& source, | 234 const NotificationSource& source, |
254 const NotificationDetails& details) { | 235 const NotificationDetails& details) { |
255 if (type != chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED) | 236 if (type != chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED) |
256 return; | 237 return; |
257 | 238 |
258 bool is_screen_locked = *Details<bool>(details).ptr(); | 239 bool is_screen_locked = *Details<bool>(details).ptr(); |
259 if (is_screen_locked) { | 240 if (is_screen_locked) { |
260 if (screen_lock_requested_) { | 241 if (screen_lock_requested_) { |
261 screen_lock_requested_ = false; | 242 screen_lock_requested_ = false; |
262 ResolveScreenLocked(); | 243 ResolveScreenLocked(); |
263 } | 244 } |
264 } else { | 245 } else { |
265 ResolveScreenUnlocked(); | 246 ResolveScreenUnlocked(); |
266 } | 247 } |
267 } | 248 } |
268 | 249 |
269 //////////////////////////////////////////////////////////////////////////////// | 250 //////////////////////////////////////////////////////////////////////////////// |
270 // LoginPerformer, public: | 251 // LoginPerformer, public: |
271 void LoginPerformer::CompleteLogin(const std::string& username, | 252 void LoginPerformer::CompleteLogin(const std::string& username, |
272 const std::string& password) { | 253 const std::string& password) { |
273 auth_mode_ = AUTH_MODE_EXTENSION; | 254 auth_mode_ = AUTH_MODE_EXTENSION; |
274 username_ = username; | 255 username_ = username; |
275 password_ = password; | 256 password_ = password; |
257 | |
258 CrosSettings* cros_settings = CrosSettings::Get(); | |
259 | |
276 // Whitelist check is always performed during initial login and | 260 // Whitelist check is always performed during initial login and |
277 // should not be performed when ScreenLock is active (pending online auth). | 261 // should not be performed when ScreenLock is active (pending online auth). |
278 if (!ScreenLocker::default_screen_locker()) { | 262 if (!ScreenLocker::default_screen_locker()) { |
279 // Must not proceed without signature verification. | 263 // Must not proceed without signature verification or valid user list. |
280 UserCrosSettingsProvider user_settings; | 264 bool trusted_settings_available = |
281 bool trusted_setting_available = user_settings.RequestTrustedAllowNewUser( | 265 cros_settings->GetTrusted( |
282 method_factory_.NewRunnableMethod(&LoginPerformer::CompleteLogin, | 266 kAccountsPrefAllowNewUser, |
283 username, | 267 base::Bind(&LoginPerformer::CompleteLogin, |
284 password)); | 268 pointer_factory_.GetWeakPtr(), |
285 if (!trusted_setting_available) { | 269 username, password)) || |
270 cros_settings->GetTrusted( | |
271 kAccountsPrefAllowNewUser, | |
272 base::Bind(&LoginPerformer::CompleteLogin, | |
273 pointer_factory_.GetWeakPtr(), | |
274 username, password)); | |
Mattias Nissler (ping if slow)
2011/09/21 11:12:59
Doing the same thing twice to be extra-sure?
pastarmovj
2011/09/23 15:19:32
Done.
| |
275 if (!trusted_settings_available) { | |
286 // Value of AllowNewUser setting is still not verified. | 276 // Value of AllowNewUser setting is still not verified. |
287 // Another attempt will be invoked after verification completion. | 277 // Another attempt will be invoked after verification completion. |
288 return; | 278 return; |
289 } | 279 } |
290 } | 280 } |
291 | 281 |
292 if (ScreenLocker::default_screen_locker() || | 282 bool allow_new_user = false; |
293 UserCrosSettingsProvider::cached_allow_new_user()) { | 283 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); |
Mattias Nissler (ping if slow)
2011/09/21 11:12:59
no guarantee that you have trusted values here if
pastarmovj
2011/09/23 15:19:32
I must admit I didn't really try to verify the log
| |
284 if (ScreenLocker::default_screen_locker() || allow_new_user) { | |
294 // Starts authentication if guest login is allowed or online auth pending. | 285 // Starts authentication if guest login is allowed or online auth pending. |
295 StartLoginCompletion(); | 286 StartLoginCompletion(); |
296 } else { | 287 } else { |
297 // Otherwise, do whitelist check first. | 288 const ListValue *user_list; |
298 PrefService* local_state = g_browser_process->local_state(); | 289 if (cros_settings->GetList(kAccountsPrefUsers, &user_list) && |
299 CHECK(local_state); | 290 user_list->Find(StringValue(username)) != user_list->end()) { |
300 if (local_state->IsManagedPreference(kAccountsPrefUsers)) { | 291 StartLoginCompletion(); |
301 if (UserCrosSettingsProvider::IsEmailInCachedWhitelist(username)) { | |
302 StartLoginCompletion(); | |
303 } else { | |
304 if (delegate_) | |
305 delegate_->WhiteListCheckFailed(username); | |
306 else | |
307 NOTREACHED(); | |
308 } | |
309 } else { | 292 } else { |
310 // In case of signed settings: with current implementation we do not | 293 if (delegate_) |
311 // trust whitelist returned by PrefService. So make separate check. | 294 delegate_->WhiteListCheckFailed(username); |
312 SignedSettingsHelper::Get()->StartCheckWhitelistOp( | 295 else |
313 username, this); | 296 NOTREACHED(); |
314 } | 297 } |
315 } | 298 } |
316 } | 299 } |
317 | 300 |
318 void LoginPerformer::Login(const std::string& username, | 301 void LoginPerformer::Login(const std::string& username, |
319 const std::string& password) { | 302 const std::string& password) { |
320 auth_mode_ = AUTH_MODE_INTERNAL; | 303 auth_mode_ = AUTH_MODE_INTERNAL; |
321 username_ = username; | 304 username_ = username; |
322 password_ = password; | 305 password_ = password; |
323 | 306 |
307 CrosSettings* cros_settings = CrosSettings::Get(); | |
308 | |
324 // Whitelist check is always performed during initial login and | 309 // Whitelist check is always performed during initial login and |
325 // should not be performed when ScreenLock is active (pending online auth). | 310 // should not be performed when ScreenLock is active (pending online auth). |
326 if (!ScreenLocker::default_screen_locker()) { | 311 if (!ScreenLocker::default_screen_locker()) { |
327 // Must not proceed without signature verification. | 312 // Must not proceed without signature verification. |
328 UserCrosSettingsProvider user_settings; | 313 bool trusted_settings_available = |
329 bool trusted_setting_available = user_settings.RequestTrustedAllowNewUser( | 314 cros_settings->GetTrusted( |
330 method_factory_.NewRunnableMethod(&LoginPerformer::Login, | 315 kAccountsPrefAllowNewUser, |
331 username, | 316 base::Bind(&LoginPerformer::CompleteLogin, |
332 password)); | 317 pointer_factory_.GetWeakPtr(), |
333 if (!trusted_setting_available) { | 318 username, password)) || |
319 cros_settings->GetTrusted( | |
320 kAccountsPrefAllowNewUser, | |
321 base::Bind(&LoginPerformer::CompleteLogin, | |
322 pointer_factory_.GetWeakPtr(), | |
323 username, password)); | |
Mattias Nissler (ping if slow)
2011/09/21 11:12:59
Same two identical things again. Also, this is pre
pastarmovj
2011/09/23 15:19:32
Done.
| |
324 if (!trusted_settings_available) { | |
334 // Value of AllowNewUser setting is still not verified. | 325 // Value of AllowNewUser setting is still not verified. |
335 // Another attempt will be invoked after verification completion. | 326 // Another attempt will be invoked after verification completion. |
336 return; | 327 return; |
337 } | 328 } |
338 } | 329 } |
339 | 330 |
340 if (ScreenLocker::default_screen_locker() || | 331 bool allow_new_user = false; |
341 UserCrosSettingsProvider::cached_allow_new_user()) { | 332 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); |
Mattias Nissler (ping if slow)
2011/09/21 11:12:59
same comment regarding trustedness as above.
pastarmovj
2011/09/23 15:19:32
Same answer as above too :)
| |
333 if (ScreenLocker::default_screen_locker() || allow_new_user) { | |
342 // Starts authentication if guest login is allowed or online auth pending. | 334 // Starts authentication if guest login is allowed or online auth pending. |
343 StartAuthentication(); | 335 StartAuthentication(); |
344 } else { | 336 } else { |
345 // Otherwise, do whitelist check first. | 337 const ListValue *user_list; |
346 PrefService* local_state = g_browser_process->local_state(); | 338 if (cros_settings->GetList(kAccountsPrefUsers, &user_list) && |
347 CHECK(local_state); | 339 user_list->Find(StringValue(username)) != user_list->end()) { |
348 if (local_state->IsManagedPreference(kAccountsPrefUsers)) { | 340 StartAuthentication(); |
349 if (UserCrosSettingsProvider::IsEmailInCachedWhitelist(username)) { | |
350 StartAuthentication(); | |
351 } else { | |
352 if (delegate_) | |
353 delegate_->WhiteListCheckFailed(username); | |
354 else | |
355 NOTREACHED(); | |
356 } | |
357 } else { | 341 } else { |
358 // In case of signed settings: with current implementation we do not | 342 if (delegate_) |
359 // trust whitelist returned by PrefService. So make separate check. | 343 delegate_->WhiteListCheckFailed(username); |
360 SignedSettingsHelper::Get()->StartCheckWhitelistOp( | 344 else |
361 username, this); | 345 NOTREACHED(); |
362 } | 346 } |
363 } | 347 } |
364 } | 348 } |
365 | 349 |
366 void LoginPerformer::LoginOffTheRecord() { | 350 void LoginPerformer::LoginOffTheRecord() { |
367 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); | 351 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); |
368 BrowserThread::PostTask( | 352 BrowserThread::PostTask( |
369 BrowserThread::UI, FROM_HERE, | 353 BrowserThread::UI, FROM_HERE, |
370 NewRunnableMethod(authenticator_.get(), | 354 base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get())); |
371 &Authenticator::LoginOffTheRecord)); | |
372 } | 355 } |
373 | 356 |
374 void LoginPerformer::RecoverEncryptedData(const std::string& old_password) { | 357 void LoginPerformer::RecoverEncryptedData(const std::string& old_password) { |
375 BrowserThread::PostTask( | 358 BrowserThread::PostTask( |
376 BrowserThread::UI, FROM_HERE, | 359 BrowserThread::UI, FROM_HERE, |
377 NewRunnableMethod(authenticator_.get(), | 360 base::Bind(&Authenticator::RecoverEncryptedData, authenticator_.get(), |
378 &Authenticator::RecoverEncryptedData, | 361 old_password, |
379 old_password, | 362 cached_credentials_)); |
380 cached_credentials_)); | |
381 cached_credentials_ = GaiaAuthConsumer::ClientLoginResult(); | 363 cached_credentials_ = GaiaAuthConsumer::ClientLoginResult(); |
382 } | 364 } |
383 | 365 |
384 void LoginPerformer::ResyncEncryptedData() { | 366 void LoginPerformer::ResyncEncryptedData() { |
385 BrowserThread::PostTask( | 367 BrowserThread::PostTask( |
386 BrowserThread::UI, FROM_HERE, | 368 BrowserThread::UI, FROM_HERE, |
387 NewRunnableMethod(authenticator_.get(), | 369 base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get(), |
388 &Authenticator::ResyncEncryptedData, | 370 cached_credentials_)); |
389 cached_credentials_)); | |
390 cached_credentials_ = GaiaAuthConsumer::ClientLoginResult(); | 371 cached_credentials_ = GaiaAuthConsumer::ClientLoginResult(); |
391 } | 372 } |
392 | 373 |
393 //////////////////////////////////////////////////////////////////////////////// | 374 //////////////////////////////////////////////////////////////////////////////// |
394 // LoginPerformer, private: | 375 // LoginPerformer, private: |
395 | 376 |
396 void LoginPerformer::RequestScreenLock() { | 377 void LoginPerformer::RequestScreenLock() { |
397 DVLOG(1) << "Screen lock requested"; | 378 DVLOG(1) << "Screen lock requested"; |
398 // Will receive notifications on screen unlock and delete itself. | 379 // Will receive notifications on screen unlock and delete itself. |
399 registrar_.Add(this, | 380 registrar_.Add(this, |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
544 } | 525 } |
545 | 526 |
546 void LoginPerformer::StartLoginCompletion() { | 527 void LoginPerformer::StartLoginCompletion() { |
547 DVLOG(1) << "Login completion started"; | 528 DVLOG(1) << "Login completion started"; |
548 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); | 529 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); |
549 Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); | 530 Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); |
550 | 531 |
551 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); | 532 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); |
552 BrowserThread::PostTask( | 533 BrowserThread::PostTask( |
553 BrowserThread::UI, FROM_HERE, | 534 BrowserThread::UI, FROM_HERE, |
554 NewRunnableMethod(authenticator_.get(), | 535 base::Bind(&Authenticator::CompleteLogin, authenticator_.get(), |
555 &Authenticator::CompleteLogin, | 536 profile, |
556 profile, | 537 username_, |
557 username_, | 538 password_)); |
558 password_)); | |
559 | 539 |
560 password_.clear(); | 540 password_.clear(); |
561 } | 541 } |
562 | 542 |
563 void LoginPerformer::StartAuthentication() { | 543 void LoginPerformer::StartAuthentication() { |
564 DVLOG(1) << "Auth started"; | 544 DVLOG(1) << "Auth started"; |
565 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); | 545 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); |
566 Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); | 546 Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); |
567 if (delegate_) { | 547 if (delegate_) { |
568 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); | 548 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); |
569 BrowserThread::PostTask( | 549 BrowserThread::PostTask( |
570 BrowserThread::UI, FROM_HERE, | 550 BrowserThread::UI, FROM_HERE, |
571 NewRunnableMethod(authenticator_.get(), | 551 base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(), |
572 &Authenticator::AuthenticateToLogin, | 552 profile, |
573 profile, | 553 username_, |
574 username_, | 554 password_, |
575 password_, | 555 captcha_token_, |
576 captcha_token_, | 556 captcha_)); |
577 captcha_)); | |
578 } else { | 557 } else { |
579 DCHECK(authenticator_.get()) | 558 DCHECK(authenticator_.get()) |
580 << "Authenticator instance doesn't exist for login attempt retry."; | 559 << "Authenticator instance doesn't exist for login attempt retry."; |
581 // At this point offline auth has been successful, | 560 // At this point offline auth has been successful, |
582 // retry online auth, using existing Authenticator instance. | 561 // retry online auth, using existing Authenticator instance. |
583 BrowserThread::PostTask( | 562 BrowserThread::PostTask( |
584 BrowserThread::UI, FROM_HERE, | 563 BrowserThread::UI, FROM_HERE, |
585 NewRunnableMethod(authenticator_.get(), | 564 base::Bind(&Authenticator::RetryAuth, authenticator_.get(), |
586 &Authenticator::RetryAuth, | 565 profile, |
587 profile, | 566 username_, |
588 username_, | 567 password_, |
589 password_, | 568 captcha_token_, |
590 captcha_token_, | 569 captcha_)); |
591 captcha_)); | |
592 } | 570 } |
593 password_.clear(); | 571 password_.clear(); |
594 } | 572 } |
595 | 573 |
596 } // namespace chromeos | 574 } // namespace chromeos |
OLD | NEW |