login_performer.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
121e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman// Copyright (c) 2012 The Chromium Authors. All rights reserved. 27c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner// Use of this source code is governed by a BSD-style license that can be 37c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner// found in the LICENSE file. 47c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner 57c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "chrome/browser/chromeos/login/login_performer.h" 67c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner 77c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include <string> 87c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner 97c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "base/bind.h" 107c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "base/logging.h" 117c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "base/message_loop.h" 127c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "base/metrics/histogram.h" 137c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "base/prefs/pref_service.h" 147c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "base/threading/thread_restrictions.h" 157c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "base/utf_string_conversions.h" 167c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "chrome/browser/browser_process.h" 177c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "chrome/browser/chromeos/boot_times_loader.h" 187c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "chrome/browser/chromeos/login/login_utils.h" 190bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner#include "chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.h" 202668959b8879097db368aec7d76c455260abc75bChris Lattner#include "chrome/browser/chromeos/login/screen_locker.h" 217c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "chrome/browser/chromeos/login/user_manager.h" 227c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" 230bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner#include "chrome/browser/chromeos/profiles/profile_helper.h" 240bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner#include "chrome/browser/chromeos/settings/cros_settings.h" 250bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner#include "chrome/browser/chromeos/settings/cros_settings_names.h" 260bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner#include "chrome/browser/policy/browser_policy_connector.h" 270bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner#include "chrome/common/chrome_notification_types.h" 280bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner#include "chrome/common/pref_names.h" 290bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner#include "chromeos/dbus/dbus_thread_manager.h" 300bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner#include "chromeos/dbus/session_manager_client.h" 31f76053269ecc6c7bd3d0b1e90ebdd0cef1bb2bdcChris Lattner#include "content/public/browser/browser_thread.h" 32c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#include "content/public/browser/notification_service.h" 33c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#include "content/public/browser/notification_types.h" 34c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#include "content/public/browser/user_metrics.h" 35c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#include "google_apis/gaia/gaia_auth_util.h" 36c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#include "grit/generated_resources.h" 37c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#include "net/cookies/cookie_monster.h" 38c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#include "net/cookies/cookie_store.h" 39c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#include "net/url_request/url_request_context.h" 40c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#include "net/url_request/url_request_context_getter.h" 41860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner#include "ui/base/l10n/l10n_util.h" 425126984b1da4bda0e93961da07e883699f1f2d57Chris Lattner#include "ui/base/resource/resource_bundle.h" 435126984b1da4bda0e93961da07e883699f1f2d57Chris Lattner 445126984b1da4bda0e93961da07e883699f1f2d57Chris Lattnerusing content::BrowserThread; 455126984b1da4bda0e93961da07e883699f1f2d57Chris Lattnerusing content::UserMetricsAction; 465126984b1da4bda0e93961da07e883699f1f2d57Chris Lattner 47993aeb2ed93f99faf1438f1b67cd922989306828Nate Begemannamespace chromeos { 48993aeb2ed93f99faf1438f1b67cd922989306828Nate Begeman 49993aeb2ed93f99faf1438f1b67cd922989306828Nate Begeman// Initialize default LoginPerformer. 50993aeb2ed93f99faf1438f1b67cd922989306828Nate Begeman// static 51f1d0b2bedaa065972a5ba17259055c1176cd1497Chris LattnerLoginPerformer* LoginPerformer::default_performer_ = NULL; 52f1d0b2bedaa065972a5ba17259055c1176cd1497Chris Lattner 53f1d0b2bedaa065972a5ba17259055c1176cd1497Chris LattnerLoginPerformer::LoginPerformer(Delegate* delegate) 54f1d0b2bedaa065972a5ba17259055c1176cd1497Chris Lattner : online_attempt_host_(this), 55860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner last_login_failure_(LoginFailure::LoginFailureNone()), 56860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner delegate_(delegate), 57860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner password_changed_(false), 58860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner password_changed_callback_count_(0), 59860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner screen_lock_requested_(false), 60860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner initial_online_auth_pending_(false), 61860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner auth_mode_(AUTH_MODE_INTERNAL), 62860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner weak_factory_(this) { 63860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner DCHECK(default_performer_ == NULL) 64860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner << "LoginPerformer should have only one instance."; 654172b10ca1adfc1026428e5f522aaab98bd939adChris Lattner default_performer_ = this; 664172b10ca1adfc1026428e5f522aaab98bd939adChris Lattner} 674172b10ca1adfc1026428e5f522aaab98bd939adChris Lattner 684172b10ca1adfc1026428e5f522aaab98bd939adChris LattnerLoginPerformer::~LoginPerformer() { 694172b10ca1adfc1026428e5f522aaab98bd939adChris Lattner DVLOG(1) << "Deleting LoginPerformer"; 70ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner DCHECK(default_performer_ != NULL) << "Default instance should exist."; 71ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner default_performer_ = NULL; 72ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner if (authenticator_) 73ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner authenticator_->SetConsumer(NULL); 749e4dd9dfc97f3930f58ca6e47bebbd8eb5cdd8a1Nate Begeman} 75ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner 76ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner//////////////////////////////////////////////////////////////////////////////// 77ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner// LoginPerformer, LoginStatusConsumer implementation: 78281b55ebeccd3f0d723888c1bb9ec6e476f708f1Chris Lattner 79281b55ebeccd3f0d723888c1bb9ec6e476f708f1Chris Lattnervoid LoginPerformer::OnLoginFailure(const LoginFailure& failure) { 80281b55ebeccd3f0d723888c1bb9ec6e476f708f1Chris Lattner content::RecordAction(UserMetricsAction("Login_Failure")); 819e4dd9dfc97f3930f58ca6e47bebbd8eb5cdd8a1Nate Begeman UMA_HISTOGRAM_ENUMERATION("Login.FailureReason", failure.reason(), 829e4dd9dfc97f3930f58ca6e47bebbd8eb5cdd8a1Nate Begeman LoginFailure::NUM_FAILURE_REASONS); 836d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner 846d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner DVLOG(1) << "failure.reason " << failure.reason(); 856d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner DVLOG(1) << "failure.error.state " << failure.error().state(); 866d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner 876d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner last_login_failure_ = failure; 88a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner if (delegate_) { 89a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner delegate_->OnLoginFailure(failure); 90a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner return; 91a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner } 92a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner 93a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner // Consequent online login failure with blocking UI on. 946d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner // No difference between cases whether screen was locked by the user or 956d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner // by LoginPerformer except for the very first screen lock while waiting 966d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner // for online auth. Otherwise it will be SL active > timeout > screen unlock. 976d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner // Display recoverable error message using ScreenLocker, 986d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner // force sign out otherwise. 9990564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner if (ScreenLocker::default_screen_locker() && !initial_online_auth_pending_) { 10090564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner ResolveLockLoginFailure(); 10190564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner return; 10290564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner } 10390564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner initial_online_auth_pending_ = false; 10490564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner 10590564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner // Offline auth - OK, online auth - failed. 10690564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner if (failure.reason() == LoginFailure::NETWORK_AUTH_FAILED) { 107281b55ebeccd3f0d723888c1bb9ec6e476f708f1Chris Lattner ResolveInitialNetworkAuthFailure(); 1083c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner } else if (failure.reason() == LoginFailure::LOGIN_TIMED_OUT) { 1093c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner VLOG(1) << "Online login timed out. " 1103c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner << "Granting user access based on offline auth only."; 1113c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner // ScreenLock is not active, it's ok to delete itself. 112ddb739e5ea6ccf6fa4f4e2a23e3da550868efaa1Chris Lattner base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 113ddb739e5ea6ccf6fa4f4e2a23e3da550868efaa1Chris Lattner } else { 114f24380e78ecc8a2db1b2116867d878b1e7c6f6edChris Lattner // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS: 115ddb739e5ea6ccf6fa4f4e2a23e3da550868efaa1Chris Lattner // happens during offline auth only. 116ddb739e5ea6ccf6fa4f4e2a23e3da550868efaa1Chris Lattner // UNLOCK_FAILED is used during normal screen lock case. 117ddb739e5ea6ccf6fa4f4e2a23e3da550868efaa1Chris Lattner // TODO(nkostylev) DATA_REMOVAL_FAILED - ? 118f24380e78ecc8a2db1b2116867d878b1e7c6f6edChris Lattner NOTREACHED(); 119116cc48e30b9c307bf3eec29c890b4ba25cd18dbChris Lattner } 120116cc48e30b9c307bf3eec29c890b4ba25cd18dbChris Lattner} 121116cc48e30b9c307bf3eec29c890b4ba25cd18dbChris Lattner 122caad163496a3ad207a75009f4ad16bae1b1527aeChris Lattnervoid LoginPerformer::OnRetailModeLoginSuccess( 123116cc48e30b9c307bf3eec29c890b4ba25cd18dbChris Lattner const UserContext& user_context) { 124116cc48e30b9c307bf3eec29c890b4ba25cd18dbChris Lattner content::RecordAction( 125116cc48e30b9c307bf3eec29c890b4ba25cd18dbChris Lattner UserMetricsAction("Login_DemoUserLoginSuccess")); 126caad163496a3ad207a75009f4ad16bae1b1527aeChris Lattner LoginStatusConsumer::OnRetailModeLoginSuccess(user_context); 127ddb739e5ea6ccf6fa4f4e2a23e3da550868efaa1Chris Lattner} 128d0608e191ff9c00af68985f246410c219d1bec57Chris Lattner 129d0608e191ff9c00af68985f246410c219d1bec57Chris Lattnervoid LoginPerformer::OnLoginSuccess( 130f24380e78ecc8a2db1b2116867d878b1e7c6f6edChris Lattner const UserContext& user_context, 131d0608e191ff9c00af68985f246410c219d1bec57Chris Lattner bool pending_requests, 1323c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner bool using_oauth) { 1333c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner content::RecordAction(UserMetricsAction("Login_Success")); 1343c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner // The value of |pending_requests| indicates: 1357ff7e674580adad7a5bccdbd74cf9c9f05e46d0fChris Lattner // 0 - New regular user, login success offline and online. 1363c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner // - or - 1373c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner // Existing regular user, login success offline and online, offline 1383c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner // authentication took longer than online authentication. 1397ff7e674580adad7a5bccdbd74cf9c9f05e46d0fChris Lattner // - or - 14064b3a08bc696b2ef8733d72ce81e49be175cbbffChris Lattner // Public account user, login successful. 141e87192a854ff0f2f1904dd9ea282eb36059bb5afChris Lattner // 1 - Existing regular user, login success offline only. 142140a58f9dfda30dbb80edd3da1b5632c178f7efcChris Lattner UMA_HISTOGRAM_ENUMERATION("Login.SuccessReason", pending_requests, 2); 143140a58f9dfda30dbb80edd3da1b5632c178f7efcChris Lattner 144140a58f9dfda30dbb80edd3da1b5632c178f7efcChris Lattner VLOG(1) << "LoginSuccess hash: " << user_context.username_hash 145e87192a854ff0f2f1904dd9ea282eb36059bb5afChris Lattner << ", pending_requests " << pending_requests; 1463c0f9cc90cdcb70caf0dc517b9f9206d731aeb70Chris Lattner DCHECK(delegate_); 1470bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner // After delegate_->OnLoginSuccess(...) is called, delegate_ releases 14821e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman // LoginPerformer ownership. LP now manages it's lifetime on its own. 1497c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner // 2 things could make it exist longer: 1507c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner // 1. ScreenLock active (pending correct new password input) 1517c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner // 2. Pending online auth request. 15221e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman if (!pending_requests) 1537c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 154da6d20f0c15205923cb2c3ef4bf9b5d77de88881Chris Lattner else 155da6d20f0c15205923cb2c3ef4bf9b5d77de88881Chris Lattner initial_online_auth_pending_ = true; 156da6d20f0c15205923cb2c3ef4bf9b5d77de88881Chris Lattner 157da6d20f0c15205923cb2c3ef4bf9b5d77de88881Chris Lattner delegate_->OnLoginSuccess(user_context, 158e4bc9ea0a560d8a0ba42f5a2da617e1f1f834710Chris Lattner pending_requests, 159e4bc9ea0a560d8a0ba42f5a2da617e1f1f834710Chris Lattner using_oauth); 160e4bc9ea0a560d8a0ba42f5a2da617e1f1f834710Chris Lattner} 161e4bc9ea0a560d8a0ba42f5a2da617e1f1f834710Chris Lattner 1628c13d0a5734a2f9d2b1c3870732cafffb20e3a55Chris Lattnervoid LoginPerformer::OnOffTheRecordLoginSuccess() { 1638c13d0a5734a2f9d2b1c3870732cafffb20e3a55Chris Lattner content::RecordAction( 164bbe77de450ef36b4f83cc3b57705a9758adbd925Chris Lattner UserMetricsAction("Login_GuestLoginSuccess")); 165bbe77de450ef36b4f83cc3b57705a9758adbd925Chris Lattner 166bbe77de450ef36b4f83cc3b57705a9758adbd925Chris Lattner if (delegate_) 167bbe77de450ef36b4f83cc3b57705a9758adbd925Chris Lattner delegate_->OnOffTheRecordLoginSuccess(); 168bbe77de450ef36b4f83cc3b57705a9758adbd925Chris Lattner else 1697c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner NOTREACHED(); 1707c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner} 1717c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner 1727c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattnervoid LoginPerformer::OnPasswordChangeDetected() { 1737c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner password_changed_ = true; 1747c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner password_changed_callback_count_++; 1757c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner if (delegate_) { 1767c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner delegate_->OnPasswordChangeDetected(); 1777c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner } else { 1787c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner last_login_failure_ = 1797c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError( 1807c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); 1814a95945fa5aa431110f50092f4a45d24772a553bNate Begeman DVLOG(1) << "Password change detected - locking screen."; 1828a2d3ca7dff8f37ee0f1fc0042f47c194045183dChris Lattner RequestScreenLock(); 1838a2d3ca7dff8f37ee0f1fc0042f47c194045183dChris Lattner } 184ddc787dfdc75fb2d78eb3e5793ca0f417ad74fd3Chris Lattner} 185ad3bc8d8add8204195aeb5106036eb7992541bdbChris Lattner 186ddc787dfdc75fb2d78eb3e5793ca0f417ad74fd3Chris Lattnervoid LoginPerformer::OnChecked(const std::string& username, bool success) { 1871efa40f6a4b561cf8f80fe018684236010645cd0Chris Lattner if (!delegate_) { 1881efa40f6a4b561cf8f80fe018684236010645cd0Chris Lattner // Delegate is reset in case of successful offline login. 189763317de1bda41581b12915b31ba06c2e16450feChris Lattner // See ExistingUserConstoller::OnLoginSuccess(). 190c4c6257c1a154279bf10e9498d46d6c1793dbaa7Evan Cheng // Case when user has changed password and enters old password 191c4c6257c1a154279bf10e9498d46d6c1793dbaa7Evan Cheng // does not block user from sign in yet. 192c4c6257c1a154279bf10e9498d46d6c1793dbaa7Evan Cheng return; 193c4c6257c1a154279bf10e9498d46d6c1793dbaa7Evan Cheng } 1947c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner delegate_->OnOnlineChecked(username, success); 1957c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner} 1967c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner 1977c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner//////////////////////////////////////////////////////////////////////////////// 198// LoginPerformer, content::NotificationObserver implementation: 199// 200 201void LoginPerformer::Observe(int type, 202 const content::NotificationSource& source, 203 const content::NotificationDetails& details) { 204 if (type != chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED) 205 return; 206 207 bool is_screen_locked = *content::Details<bool>(details).ptr(); 208 if (is_screen_locked) { 209 if (screen_lock_requested_) { 210 screen_lock_requested_ = false; 211 ResolveScreenLocked(); 212 } 213 } else { 214 ResolveScreenUnlocked(); 215 } 216} 217 218//////////////////////////////////////////////////////////////////////////////// 219// LoginPerformer, public: 220 221void LoginPerformer::PerformLogin(const UserContext& user_context, 222 AuthorizationMode auth_mode) { 223 auth_mode_ = auth_mode; 224 user_context_ = user_context; 225 226 CrosSettings* cros_settings = CrosSettings::Get(); 227 228 // Whitelist check is always performed during initial login and 229 // should not be performed when ScreenLock is active (pending online auth). 230 if (!ScreenLocker::default_screen_locker()) { 231 CrosSettingsProvider::TrustedStatus status = 232 cros_settings->PrepareTrustedValues( 233 base::Bind(&LoginPerformer::PerformLogin, 234 weak_factory_.GetWeakPtr(), 235 user_context_, auth_mode)); 236 // Must not proceed without signature verification. 237 if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) { 238 if (delegate_) 239 delegate_->PolicyLoadFailed(); 240 else 241 NOTREACHED(); 242 return; 243 } else if (status != CrosSettingsProvider::TRUSTED) { 244 // Value of AllowNewUser setting is still not verified. 245 // Another attempt will be invoked after verification completion. 246 return; 247 } 248 } 249 250 bool is_whitelisted = LoginUtils::IsWhitelisted( 251 gaia::CanonicalizeEmail(user_context.username)); 252 if (ScreenLocker::default_screen_locker() || is_whitelisted) { 253 switch (auth_mode_) { 254 case AUTH_MODE_EXTENSION: 255 StartLoginCompletion(); 256 break; 257 case AUTH_MODE_INTERNAL: 258 StartAuthentication(); 259 break; 260 } 261 } else { 262 if (delegate_) 263 delegate_->WhiteListCheckFailed(user_context.username); 264 else 265 NOTREACHED(); 266 } 267} 268 269void LoginPerformer::LoginAsLocallyManagedUser( 270 const UserContext& user_context) { 271 DCHECK_EQ(UserManager::kLocallyManagedUserDomain, 272 gaia::ExtractDomainName(user_context.username)); 273 // TODO(nkostylev): Check that policy allows locally managed user login. 274 UserFlow* new_flow = new LocallyManagedUserLoginFlow(user_context.username); 275 new_flow->set_host( 276 UserManager::Get()->GetUserFlow(user_context.username)->host()); 277 UserManager::Get()->SetUserFlow(user_context.username, new_flow); 278 279 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 280 BrowserThread::PostTask( 281 BrowserThread::UI, FROM_HERE, 282 base::Bind(&Authenticator::LoginAsLocallyManagedUser, 283 authenticator_.get(), 284 user_context)); 285} 286 287void LoginPerformer::LoginRetailMode() { 288 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 289 BrowserThread::PostTask( 290 BrowserThread::UI, FROM_HERE, 291 base::Bind(&Authenticator::LoginRetailMode, authenticator_.get())); 292} 293 294void LoginPerformer::LoginOffTheRecord() { 295 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 296 BrowserThread::PostTask( 297 BrowserThread::UI, FROM_HERE, 298 base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get())); 299} 300 301void LoginPerformer::LoginAsPublicAccount(const std::string& username) { 302 // Login is not allowed if policy could not be loaded for the account. 303 policy::DeviceLocalAccountPolicyService* policy_service = 304 g_browser_process->browser_policy_connector()-> 305 GetDeviceLocalAccountPolicyService(); 306 if (!policy_service || !policy_service->IsPolicyAvailableForUser(username)) { 307 DCHECK(delegate_); 308 if (delegate_) 309 delegate_->PolicyLoadFailed(); 310 return; 311 } 312 313 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 314 BrowserThread::PostTask( 315 BrowserThread::UI, FROM_HERE, 316 base::Bind(&Authenticator::LoginAsPublicAccount, authenticator_.get(), 317 username)); 318} 319 320void LoginPerformer::RecoverEncryptedData(const std::string& old_password) { 321 BrowserThread::PostTask( 322 BrowserThread::UI, FROM_HERE, 323 base::Bind(&Authenticator::RecoverEncryptedData, authenticator_.get(), 324 old_password)); 325} 326 327void LoginPerformer::ResyncEncryptedData() { 328 BrowserThread::PostTask( 329 BrowserThread::UI, FROM_HERE, 330 base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get())); 331} 332 333//////////////////////////////////////////////////////////////////////////////// 334// LoginPerformer, private: 335 336void LoginPerformer::RequestScreenLock() { 337 DVLOG(1) << "Screen lock requested"; 338 // Will receive notifications on screen unlock and delete itself. 339 registrar_.Add(this, 340 chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, 341 content::NotificationService::AllSources()); 342 if (ScreenLocker::default_screen_locker()) { 343 DVLOG(1) << "Screen already locked"; 344 ResolveScreenLocked(); 345 } else { 346 screen_lock_requested_ = true; 347 // TODO(antrim) : additional logging for crbug/173178 348 LOG(WARNING) << "Requesting screen lock from LoginPerformer"; 349 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen(); 350 } 351} 352 353void LoginPerformer::RequestScreenUnlock() { 354 DVLOG(1) << "Screen unlock requested"; 355 if (ScreenLocker::default_screen_locker()) { 356 DBusThreadManager::Get()->GetSessionManagerClient()->RequestUnlockScreen(); 357 // Will unsubscribe from notifications once unlock is successful. 358 } else { 359 LOG(ERROR) << "Screen is not locked"; 360 NOTREACHED(); 361 } 362} 363 364void LoginPerformer::ResolveInitialNetworkAuthFailure() { 365 DVLOG(1) << "auth_error: " << last_login_failure_.error().state(); 366 367 switch (last_login_failure_.error().state()) { 368 case GoogleServiceAuthError::CONNECTION_FAILED: 369 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: 370 case GoogleServiceAuthError::TWO_FACTOR: 371 case GoogleServiceAuthError::REQUEST_CANCELED: 372 // Offline auth already done. Online auth will be done next time 373 // or once user accesses web property. 374 VLOG(1) << "Granting user access based on offline auth only. " 375 << "Online login failed with " 376 << last_login_failure_.error().state(); 377 // Resolving initial online auth failure, no ScreenLock is active. 378 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 379 return; 380 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: 381 // Offline auth OK, so it might be the case of changed password. 382 password_changed_ = true; 383 case GoogleServiceAuthError::USER_NOT_SIGNED_UP: 384 case GoogleServiceAuthError::ACCOUNT_DELETED: 385 case GoogleServiceAuthError::ACCOUNT_DISABLED: 386 // Access not granted. User has to sign out. 387 // Request screen lock & show error message there. 388 case GoogleServiceAuthError::CAPTCHA_REQUIRED: 389 default: 390 // Unless there's new GoogleServiceAuthErrors state has been added. 391 NOTREACHED(); 392 return; 393 } 394} 395 396void LoginPerformer::ResolveLockLoginFailure() { 397 if (last_login_failure_.reason() == LoginFailure::LOGIN_TIMED_OUT) { 398 LOG(WARNING) << "Online login timed out - unlocking screen. " 399 << "Granting user access based on offline auth only."; 400 RequestScreenUnlock(); 401 return; 402 } else if (last_login_failure_.reason() == 403 LoginFailure::NETWORK_AUTH_FAILED) { 404 ResolveLockNetworkAuthFailure(); 405 return; 406 } else if (last_login_failure_.reason() == 407 LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME || 408 last_login_failure_.reason() == 409 LoginFailure::DATA_REMOVAL_FAILED) { 410 LOG(ERROR) << "Cryptohome error, forcing sign out."; 411 } else { 412 // COULD_NOT_MOUNT_TMPFS, UNLOCK_FAILED should not happen here. 413 NOTREACHED(); 414 } 415 ScreenLocker::default_screen_locker()->Signout(); 416} 417 418void LoginPerformer::ResolveLockNetworkAuthFailure() { 419 DCHECK(ScreenLocker::default_screen_locker()) 420 << "ScreenLocker instance doesn't exist."; 421 DCHECK(last_login_failure_.reason() == LoginFailure::NETWORK_AUTH_FAILED); 422 423 int msg_id = IDS_LOGIN_ERROR_AUTHENTICATING; 424 HelpAppLauncher::HelpTopic help_topic = 425 HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT; 426 bool sign_out_only = false; 427 428 DVLOG(1) << "auth_error: " << last_login_failure_.error().state(); 429 430 switch (last_login_failure_.error().state()) { 431 case GoogleServiceAuthError::CONNECTION_FAILED: 432 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: 433 case GoogleServiceAuthError::TWO_FACTOR: 434 case GoogleServiceAuthError::REQUEST_CANCELED: 435 // Offline auth already done. Online auth will be done next time 436 // or once user accesses web property. 437 LOG(WARNING) << "Granting user access based on offline auth only. " 438 << "Online login failed with " 439 << last_login_failure_.error().state(); 440 RequestScreenUnlock(); 441 return; 442 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: 443 // Password change detected. 444 msg_id = IDS_LOGIN_ERROR_PASSWORD_CHANGED; 445 break; 446 case GoogleServiceAuthError::USER_NOT_SIGNED_UP: 447 case GoogleServiceAuthError::ACCOUNT_DELETED: 448 case GoogleServiceAuthError::ACCOUNT_DISABLED: 449 // Access not granted. User has to sign out. 450 // Show error message using existing screen lock. 451 msg_id = IDS_LOGIN_ERROR_RESTRICTED; 452 help_topic = HelpAppLauncher::HELP_ACCOUNT_DISABLED; 453 sign_out_only = true; 454 break; 455 case GoogleServiceAuthError::CAPTCHA_REQUIRED: 456 default: 457 // Unless there's new GoogleServiceAuthError state has been added. 458 NOTREACHED(); 459 break; 460 } 461 462 ScreenLocker::default_screen_locker()->ShowErrorMessage(msg_id, 463 help_topic, 464 sign_out_only); 465} 466 467void LoginPerformer::ResolveScreenLocked() { 468 DVLOG(1) << "Screen locked"; 469 ResolveLockNetworkAuthFailure(); 470} 471 472void LoginPerformer::ResolveScreenUnlocked() { 473 DVLOG(1) << "Screen unlocked"; 474 registrar_.RemoveAll(); 475 // If screen was unlocked that was for a reason, should delete itself now. 476 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 477} 478 479void LoginPerformer::StartLoginCompletion() { 480 DVLOG(1) << "Login completion started"; 481 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); 482 Profile* profile = ProfileHelper::GetSigninProfile(); 483 484 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 485 BrowserThread::PostTask( 486 BrowserThread::UI, FROM_HERE, 487 base::Bind(&Authenticator::CompleteLogin, authenticator_.get(), 488 profile, 489 user_context_)); 490 491 user_context_.password.clear(); 492 user_context_.auth_code.clear(); 493} 494 495void LoginPerformer::StartAuthentication() { 496 DVLOG(1) << "Auth started"; 497 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); 498 Profile* profile = ProfileHelper::GetSigninProfile(); 499 if (delegate_) { 500 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 501 BrowserThread::PostTask( 502 BrowserThread::UI, FROM_HERE, 503 base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(), 504 profile, 505 user_context_, 506 std::string(), 507 std::string())); 508 // Make unobtrusive online check. It helps to determine password change 509 // state in the case when offline login fails. 510 online_attempt_host_.Check(profile, user_context_); 511 } else { 512 DCHECK(authenticator_.get()) 513 << "Authenticator instance doesn't exist for login attempt retry."; 514 // At this point offline auth has been successful, 515 // retry online auth, using existing Authenticator instance. 516 BrowserThread::PostTask( 517 BrowserThread::UI, FROM_HERE, 518 base::Bind(&Authenticator::RetryAuth, authenticator_.get(), 519 profile, 520 user_context_, 521 std::string(), 522 std::string())); 523 } 524 user_context_.password.clear(); 525 user_context_.auth_code.clear(); 526} 527 528} // namespace chromeos 529