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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/login/login_performer.h" 6 7 #include <string> 8 9 #include "base/bind.h" 10 #include "base/logging.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/metrics/histogram.h" 13 #include "base/prefs/pref_service.h" 14 #include "base/strings/utf_string_conversions.h" 15 #include "base/threading/thread_restrictions.h" 16 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/chrome_notification_types.h" 18 #include "chrome/browser/chromeos/boot_times_loader.h" 19 #include "chrome/browser/chromeos/login/login_utils.h" 20 #include "chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.h" 21 #include "chrome/browser/chromeos/login/user_manager.h" 22 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" 23 #include "chrome/browser/chromeos/profiles/profile_helper.h" 24 #include "chrome/browser/chromeos/settings/cros_settings.h" 25 #include "chrome/browser/chromeos/settings/cros_settings_names.h" 26 #include "chrome/browser/policy/browser_policy_connector.h" 27 #include "chrome/common/pref_names.h" 28 #include "chromeos/dbus/dbus_thread_manager.h" 29 #include "chromeos/dbus/session_manager_client.h" 30 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/notification_service.h" 32 #include "content/public/browser/notification_types.h" 33 #include "content/public/browser/user_metrics.h" 34 #include "google_apis/gaia/gaia_auth_util.h" 35 #include "grit/generated_resources.h" 36 #include "net/cookies/cookie_monster.h" 37 #include "net/cookies/cookie_store.h" 38 #include "net/url_request/url_request_context.h" 39 #include "net/url_request/url_request_context_getter.h" 40 #include "ui/base/l10n/l10n_util.h" 41 #include "ui/base/resource/resource_bundle.h" 42 43 using content::BrowserThread; 44 using content::UserMetricsAction; 45 46 namespace chromeos { 47 48 LoginPerformer::LoginPerformer(Delegate* delegate) 49 : online_attempt_host_(this), 50 last_login_failure_(LoginFailure::LoginFailureNone()), 51 delegate_(delegate), 52 password_changed_(false), 53 password_changed_callback_count_(0), 54 auth_mode_(AUTH_MODE_INTERNAL), 55 weak_factory_(this) { 56 } 57 58 LoginPerformer::~LoginPerformer() { 59 DVLOG(1) << "Deleting LoginPerformer"; 60 if (authenticator_.get()) 61 authenticator_->SetConsumer(NULL); 62 } 63 64 //////////////////////////////////////////////////////////////////////////////// 65 // LoginPerformer, LoginStatusConsumer implementation: 66 67 void LoginPerformer::OnLoginFailure(const LoginFailure& failure) { 68 content::RecordAction(UserMetricsAction("Login_Failure")); 69 UMA_HISTOGRAM_ENUMERATION("Login.FailureReason", failure.reason(), 70 LoginFailure::NUM_FAILURE_REASONS); 71 72 DVLOG(1) << "failure.reason " << failure.reason(); 73 DVLOG(1) << "failure.error.state " << failure.error().state(); 74 75 last_login_failure_ = failure; 76 if (delegate_) { 77 delegate_->OnLoginFailure(failure); 78 return; 79 } else { 80 // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS: 81 // happens during offline auth only. 82 NOTREACHED(); 83 } 84 } 85 86 void LoginPerformer::OnRetailModeLoginSuccess( 87 const UserContext& user_context) { 88 content::RecordAction( 89 UserMetricsAction("Login_DemoUserLoginSuccess")); 90 LoginStatusConsumer::OnRetailModeLoginSuccess(user_context); 91 } 92 93 void LoginPerformer::OnLoginSuccess( 94 const UserContext& user_context, 95 bool pending_requests, 96 bool using_oauth) { 97 content::RecordAction(UserMetricsAction("Login_Success")); 98 // The value of |pending_requests| indicates: 99 // 0 - New regular user, login success offline and online. 100 // - or - 101 // Existing regular user, login success offline and online, offline 102 // authentication took longer than online authentication. 103 // - or - 104 // Public account user, login successful. 105 // 1 - Existing regular user, login success offline only. 106 UMA_HISTOGRAM_ENUMERATION("Login.SuccessReason", pending_requests, 2); 107 108 VLOG(1) << "LoginSuccess hash: " << user_context.username_hash 109 << ", pending_requests " << pending_requests; 110 DCHECK(delegate_); 111 // After delegate_->OnLoginSuccess(...) is called, delegate_ releases 112 // LoginPerformer ownership. LP now manages it's lifetime on its own. 113 DCHECK(!pending_requests); 114 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 115 116 delegate_->OnLoginSuccess(user_context, 117 pending_requests, 118 using_oauth); 119 } 120 121 void LoginPerformer::OnOffTheRecordLoginSuccess() { 122 content::RecordAction( 123 UserMetricsAction("Login_GuestLoginSuccess")); 124 125 if (delegate_) 126 delegate_->OnOffTheRecordLoginSuccess(); 127 else 128 NOTREACHED(); 129 } 130 131 void LoginPerformer::OnPasswordChangeDetected() { 132 password_changed_ = true; 133 password_changed_callback_count_++; 134 if (delegate_) { 135 delegate_->OnPasswordChangeDetected(); 136 } else { 137 NOTREACHED(); 138 } 139 } 140 141 void LoginPerformer::OnChecked(const std::string& username, bool success) { 142 if (!delegate_) { 143 // Delegate is reset in case of successful offline login. 144 // See ExistingUserConstoller::OnLoginSuccess(). 145 // Case when user has changed password and enters old password 146 // does not block user from sign in yet. 147 return; 148 } 149 delegate_->OnOnlineChecked(username, success); 150 } 151 152 //////////////////////////////////////////////////////////////////////////////// 153 // LoginPerformer, public: 154 155 void LoginPerformer::PerformLogin(const UserContext& user_context, 156 AuthorizationMode auth_mode) { 157 auth_mode_ = auth_mode; 158 user_context_ = user_context; 159 160 CrosSettings* cros_settings = CrosSettings::Get(); 161 162 // Whitelist check is always performed during initial login. 163 CrosSettingsProvider::TrustedStatus status = 164 cros_settings->PrepareTrustedValues( 165 base::Bind(&LoginPerformer::PerformLogin, 166 weak_factory_.GetWeakPtr(), 167 user_context_, auth_mode)); 168 // Must not proceed without signature verification. 169 if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) { 170 if (delegate_) 171 delegate_->PolicyLoadFailed(); 172 else 173 NOTREACHED(); 174 return; 175 } else if (status != CrosSettingsProvider::TRUSTED) { 176 // Value of AllowNewUser setting is still not verified. 177 // Another attempt will be invoked after verification completion. 178 return; 179 } 180 181 bool is_whitelisted = LoginUtils::IsWhitelisted( 182 gaia::CanonicalizeEmail(user_context.username)); 183 if (is_whitelisted) { 184 switch (auth_mode_) { 185 case AUTH_MODE_EXTENSION: 186 StartLoginCompletion(); 187 break; 188 case AUTH_MODE_INTERNAL: 189 StartAuthentication(); 190 break; 191 } 192 } else { 193 if (delegate_) 194 delegate_->WhiteListCheckFailed(user_context.username); 195 else 196 NOTREACHED(); 197 } 198 } 199 200 void LoginPerformer::LoginAsLocallyManagedUser( 201 const UserContext& user_context) { 202 DCHECK_EQ(UserManager::kLocallyManagedUserDomain, 203 gaia::ExtractDomainName(user_context.username)); 204 // TODO(nkostylev): Check that policy allows locally managed user login. 205 UserFlow* new_flow = new LocallyManagedUserLoginFlow(user_context.username); 206 new_flow->set_host( 207 UserManager::Get()->GetUserFlow(user_context.username)->host()); 208 UserManager::Get()->SetUserFlow(user_context.username, new_flow); 209 210 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 211 BrowserThread::PostTask( 212 BrowserThread::UI, FROM_HERE, 213 base::Bind(&Authenticator::LoginAsLocallyManagedUser, 214 authenticator_.get(), 215 user_context)); 216 } 217 218 void LoginPerformer::LoginRetailMode() { 219 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 220 BrowserThread::PostTask( 221 BrowserThread::UI, FROM_HERE, 222 base::Bind(&Authenticator::LoginRetailMode, authenticator_.get())); 223 } 224 225 void LoginPerformer::LoginOffTheRecord() { 226 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 227 BrowserThread::PostTask( 228 BrowserThread::UI, FROM_HERE, 229 base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get())); 230 } 231 232 void LoginPerformer::LoginAsPublicAccount(const std::string& username) { 233 // Login is not allowed if policy could not be loaded for the account. 234 policy::DeviceLocalAccountPolicyService* policy_service = 235 g_browser_process->browser_policy_connector()-> 236 GetDeviceLocalAccountPolicyService(); 237 if (!policy_service || !policy_service->IsPolicyAvailableForUser(username)) { 238 DCHECK(delegate_); 239 if (delegate_) 240 delegate_->PolicyLoadFailed(); 241 return; 242 } 243 244 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 245 BrowserThread::PostTask( 246 BrowserThread::UI, FROM_HERE, 247 base::Bind(&Authenticator::LoginAsPublicAccount, authenticator_.get(), 248 username)); 249 } 250 251 void LoginPerformer::RecoverEncryptedData(const std::string& old_password) { 252 BrowserThread::PostTask( 253 BrowserThread::UI, FROM_HERE, 254 base::Bind(&Authenticator::RecoverEncryptedData, authenticator_.get(), 255 old_password)); 256 } 257 258 void LoginPerformer::ResyncEncryptedData() { 259 BrowserThread::PostTask( 260 BrowserThread::UI, FROM_HERE, 261 base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get())); 262 } 263 264 //////////////////////////////////////////////////////////////////////////////// 265 // LoginPerformer, private: 266 267 void LoginPerformer::StartLoginCompletion() { 268 DVLOG(1) << "Login completion started"; 269 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); 270 Profile* profile = ProfileHelper::GetSigninProfile(); 271 272 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 273 BrowserThread::PostTask( 274 BrowserThread::UI, FROM_HERE, 275 base::Bind(&Authenticator::CompleteLogin, authenticator_.get(), 276 profile, 277 user_context_)); 278 279 user_context_.password.clear(); 280 user_context_.auth_code.clear(); 281 } 282 283 void LoginPerformer::StartAuthentication() { 284 DVLOG(1) << "Auth started"; 285 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); 286 Profile* profile = ProfileHelper::GetSigninProfile(); 287 if (delegate_) { 288 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 289 BrowserThread::PostTask( 290 BrowserThread::UI, FROM_HERE, 291 base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(), 292 profile, 293 user_context_)); 294 // Make unobtrusive online check. It helps to determine password change 295 // state in the case when offline login fails. 296 online_attempt_host_.Check(profile, user_context_); 297 } else { 298 NOTREACHED(); 299 } 300 user_context_.password.clear(); 301 user_context_.auth_code.clear(); 302 } 303 304 } // namespace chromeos 305