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/session/user_session_manager.h" 6 7 #include <string> 8 9 #include "base/base_paths.h" 10 #include "base/bind.h" 11 #include "base/command_line.h" 12 #include "base/logging.h" 13 #include "base/path_service.h" 14 #include "base/prefs/pref_member.h" 15 #include "base/prefs/pref_registry_simple.h" 16 #include "base/prefs/pref_service.h" 17 #include "base/strings/string16.h" 18 #include "base/sys_info.h" 19 #include "base/task_runner_util.h" 20 #include "base/threading/worker_pool.h" 21 #include "chrome/browser/app_mode/app_mode_utils.h" 22 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/browser_process_platform_part_chromeos.h" 24 #include "chrome/browser/chrome_notification_types.h" 25 #include "chrome/browser/chromeos/base/locale_util.h" 26 #include "chrome/browser/chromeos/boot_times_loader.h" 27 #include "chrome/browser/chromeos/input_method/input_method_util.h" 28 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" 29 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h" 30 #include "chrome/browser/chromeos/login/profile_auth_data.h" 31 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h" 32 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory.h" 33 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h" 34 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h" 35 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" 36 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 37 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 38 #include "chrome/browser/chromeos/profiles/profile_helper.h" 39 #include "chrome/browser/chromeos/settings/cros_settings.h" 40 #include "chrome/browser/first_run/first_run.h" 41 #include "chrome/browser/google/google_brand_chromeos.h" 42 #include "chrome/browser/lifetime/application_lifetime.h" 43 #include "chrome/browser/net/crl_set_fetcher.h" 44 #include "chrome/browser/net/nss_context.h" 45 #include "chrome/browser/profiles/profile.h" 46 #include "chrome/browser/profiles/profile_manager.h" 47 #include "chrome/browser/rlz/rlz.h" 48 #include "chrome/browser/signin/easy_unlock_service.h" 49 #include "chrome/browser/signin/signin_manager_factory.h" 50 #include "chrome/common/chrome_switches.h" 51 #include "chrome/common/logging_chrome.h" 52 #include "chrome/common/pref_names.h" 53 #include "chromeos/cert_loader.h" 54 #include "chromeos/chromeos_switches.h" 55 #include "chromeos/cryptohome/cryptohome_util.h" 56 #include "chromeos/dbus/cryptohome_client.h" 57 #include "chromeos/dbus/dbus_thread_manager.h" 58 #include "chromeos/dbus/session_manager_client.h" 59 #include "chromeos/ime/input_method_manager.h" 60 #include "chromeos/network/portal_detector/network_portal_detector.h" 61 #include "chromeos/network/portal_detector/network_portal_detector_strategy.h" 62 #include "chromeos/settings/cros_settings_names.h" 63 #include "components/component_updater/component_updater_service.h" 64 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 65 #include "components/session_manager/core/session_manager.h" 66 #include "components/signin/core/browser/signin_manager_base.h" 67 #include "components/user_manager/user.h" 68 #include "components/user_manager/user_manager.h" 69 #include "components/user_manager/user_type.h" 70 #include "content/public/browser/browser_thread.h" 71 #include "content/public/browser/notification_service.h" 72 73 namespace chromeos { 74 75 namespace { 76 77 void InitLocaleAndInputMethodsForNewUser( 78 UserSessionManager* session_manager, 79 Profile* profile, 80 const std::string& public_session_locale, 81 const std::string& public_session_input_method) { 82 PrefService* prefs = profile->GetPrefs(); 83 std::string locale; 84 if (!public_session_locale.empty()) { 85 // If this is a public session and the user chose a |public_session_locale|, 86 // write it to |prefs| so that the UI switches to it. 87 locale = public_session_locale; 88 prefs->SetString(prefs::kApplicationLocale, locale); 89 90 // Suppress the locale change dialog. 91 prefs->SetString(prefs::kApplicationLocaleAccepted, locale); 92 } else { 93 // Otherwise, assume that the session will use the current UI locale. 94 locale = g_browser_process->GetApplicationLocale(); 95 } 96 97 // First, we'll set kLanguagePreloadEngines. 98 input_method::InputMethodManager* manager = 99 input_method::InputMethodManager::Get(); 100 std::vector<std::string> input_method_ids; 101 102 if (!public_session_input_method.empty()) { 103 // If this is a public session and the user chose a 104 // |public_session_input_method|, set kLanguagePreloadEngines to this input 105 // method only. 106 input_method_ids.push_back(public_session_input_method); 107 } else { 108 // Otherwise, set kLanguagePreloadEngines to a list of input methods derived 109 // from the |locale| and the currently active input method. 110 manager->GetInputMethodUtil()->GetFirstLoginInputMethodIds( 111 locale, 112 session_manager->GetDefaultIMEState(profile)->GetCurrentInputMethod(), 113 &input_method_ids); 114 } 115 116 // Save the input methods in the user's preferences. 117 StringPrefMember language_preload_engines; 118 language_preload_engines.Init(prefs::kLanguagePreloadEngines, prefs); 119 language_preload_engines.SetValue(JoinString(input_method_ids, ',')); 120 BootTimesLoader::Get()->AddLoginTimeMarker("IMEStarted", false); 121 122 // Second, we'll set kLanguagePreferredLanguages. 123 std::vector<std::string> language_codes; 124 125 // The current locale should be on the top. 126 language_codes.push_back(locale); 127 128 // Add input method IDs based on the input methods, as there may be 129 // input methods that are unrelated to the current locale. Example: the 130 // hardware keyboard layout xkb:us::eng is used for logging in, but the 131 // UI language is set to French. In this case, we should set "fr,en" 132 // to the preferred languages preference. 133 std::vector<std::string> candidates; 134 manager->GetInputMethodUtil()->GetLanguageCodesFromInputMethodIds( 135 input_method_ids, &candidates); 136 for (size_t i = 0; i < candidates.size(); ++i) { 137 const std::string& candidate = candidates[i]; 138 // Skip if it's already in language_codes. 139 if (std::count(language_codes.begin(), language_codes.end(), 140 candidate) == 0) { 141 language_codes.push_back(candidate); 142 } 143 } 144 145 // Save the preferred languages in the user's preferences. 146 StringPrefMember language_preferred_languages; 147 language_preferred_languages.Init(prefs::kLanguagePreferredLanguages, prefs); 148 language_preferred_languages.SetValue(JoinString(language_codes, ',')); 149 } 150 151 #if defined(ENABLE_RLZ) 152 // Flag file that disables RLZ tracking, when present. 153 const base::FilePath::CharType kRLZDisabledFlagName[] = 154 FILE_PATH_LITERAL(".rlz_disabled"); 155 156 base::FilePath GetRlzDisabledFlagPath() { 157 base::FilePath homedir; 158 PathService::Get(base::DIR_HOME, &homedir); 159 return homedir.Append(kRLZDisabledFlagName); 160 } 161 #endif 162 163 // Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the 164 // provided NSS database. It must be called for primary user only. 165 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) { 166 if (!CertLoader::IsInitialized()) 167 return; 168 169 CertLoader::Get()->StartWithNSSDB(database); 170 } 171 172 } // namespace 173 174 #if defined(ENABLE_RLZ) 175 void UserSessionManagerDelegate::OnRlzInitialized() { 176 } 177 #endif 178 179 UserSessionManagerDelegate::~UserSessionManagerDelegate() { 180 } 181 182 void UserSessionStateObserver::PendingUserSessionsRestoreFinished() { 183 } 184 185 UserSessionStateObserver::~UserSessionStateObserver() { 186 } 187 188 // static 189 UserSessionManager* UserSessionManager::GetInstance() { 190 return Singleton<UserSessionManager, 191 DefaultSingletonTraits<UserSessionManager> >::get(); 192 } 193 194 // static 195 void UserSessionManager::OverrideHomedir() { 196 // Override user homedir, check for ProfileManager being initialized as 197 // it may not exist in unit tests. 198 if (g_browser_process->profile_manager()) { 199 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 200 if (user_manager->GetLoggedInUsers().size() == 1) { 201 base::FilePath homedir = ProfileHelper::GetProfilePathByUserIdHash( 202 user_manager->GetPrimaryUser()->username_hash()); 203 // This path has been either created by cryptohome (on real Chrome OS 204 // device) or by ProfileManager (on chromeos=1 desktop builds). 205 PathService::OverrideAndCreateIfNeeded(base::DIR_HOME, 206 homedir, 207 true /* path is absolute */, 208 false /* don't create */); 209 } 210 } 211 } 212 213 // static 214 void UserSessionManager::RegisterPrefs(PrefRegistrySimple* registry) { 215 registry->RegisterStringPref(prefs::kRLZBrand, std::string()); 216 registry->RegisterBooleanPref(prefs::kRLZDisabled, false); 217 } 218 219 UserSessionManager::UserSessionManager() 220 : delegate_(NULL), 221 has_auth_cookies_(false), 222 user_sessions_restored_(false), 223 user_sessions_restore_in_progress_(false), 224 exit_after_session_restore_(false), 225 session_restore_strategy_( 226 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN), 227 running_easy_unlock_key_ops_(false) { 228 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 229 user_manager::UserManager::Get()->AddSessionStateObserver(this); 230 } 231 232 UserSessionManager::~UserSessionManager() { 233 // UserManager is destroyed before singletons, so we need to check if it 234 // still exists. 235 // TODO(nkostylev): fix order of destruction of UserManager 236 // / UserSessionManager objects. 237 if (user_manager::UserManager::IsInitialized()) 238 user_manager::UserManager::Get()->RemoveSessionStateObserver(this); 239 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 240 } 241 242 void UserSessionManager::StartSession( 243 const UserContext& user_context, 244 scoped_refptr<Authenticator> authenticator, 245 bool has_auth_cookies, 246 bool has_active_session, 247 UserSessionManagerDelegate* delegate) { 248 authenticator_ = authenticator; 249 delegate_ = delegate; 250 251 VLOG(1) << "Starting session for " << user_context.GetUserID(); 252 253 PreStartSession(); 254 CreateUserSession(user_context, has_auth_cookies); 255 256 if (!has_active_session) 257 StartCrosSession(); 258 259 // TODO(nkostylev): Notify UserLoggedIn() after profile is actually 260 // ready to be used (http://crbug.com/361528). 261 NotifyUserLoggedIn(); 262 PrepareProfile(); 263 } 264 265 void UserSessionManager::PerformPostUserLoggedInActions() { 266 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 267 if (user_manager->GetLoggedInUsers().size() == 1) { 268 if (NetworkPortalDetector::IsInitialized()) { 269 NetworkPortalDetector::Get()->SetStrategy( 270 PortalDetectorStrategy::STRATEGY_ID_SESSION); 271 } 272 } 273 } 274 275 void UserSessionManager::RestoreAuthenticationSession(Profile* user_profile) { 276 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 277 // We need to restore session only for logged in regular (GAIA) users. 278 // Note: stub user is a special case that is used for tests, running 279 // linux_chromeos build on dev workstations w/o user_id parameters. 280 // Stub user is considered to be a regular GAIA user but it has special 281 // user_id (kStubUser) and certain services like restoring OAuth session are 282 // explicitly disabled for it. 283 if (!user_manager->IsUserLoggedIn() || 284 !user_manager->IsLoggedInAsRegularUser() || 285 user_manager->IsLoggedInAsStub()) { 286 return; 287 } 288 289 user_manager::User* user = 290 ProfileHelper::Get()->GetUserByProfile(user_profile); 291 DCHECK(user); 292 if (!net::NetworkChangeNotifier::IsOffline()) { 293 pending_signin_restore_sessions_.erase(user->email()); 294 RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */); 295 } else { 296 // Even if we're online we should wait till initial 297 // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may 298 // end up canceling all request when initial network connection type is 299 // processed. See http://crbug.com/121643. 300 pending_signin_restore_sessions_.insert(user->email()); 301 } 302 } 303 304 void UserSessionManager::RestoreActiveSessions() { 305 user_sessions_restore_in_progress_ = true; 306 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions( 307 base::Bind(&UserSessionManager::OnRestoreActiveSessions, 308 base::Unretained(this))); 309 } 310 311 bool UserSessionManager::UserSessionsRestored() const { 312 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 313 return user_sessions_restored_; 314 } 315 316 bool UserSessionManager::UserSessionsRestoreInProgress() const { 317 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 318 return user_sessions_restore_in_progress_; 319 } 320 321 void UserSessionManager::InitRlz(Profile* profile) { 322 #if defined(ENABLE_RLZ) 323 if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) { 324 // Read brand code asynchronously from an OEM data and repost ourselves. 325 google_brand::chromeos::InitBrand( 326 base::Bind(&UserSessionManager::InitRlz, AsWeakPtr(), profile)); 327 return; 328 } 329 base::PostTaskAndReplyWithResult( 330 base::WorkerPool::GetTaskRunner(false).get(), 331 FROM_HERE, 332 base::Bind(&base::PathExists, GetRlzDisabledFlagPath()), 333 base::Bind(&UserSessionManager::InitRlzImpl, AsWeakPtr(), profile)); 334 #endif 335 } 336 337 OAuth2LoginManager::SessionRestoreStrategy 338 UserSessionManager::GetSigninSessionRestoreStrategy() { 339 return session_restore_strategy_; 340 } 341 342 void UserSessionManager::SetFirstLoginPrefs( 343 Profile* profile, 344 const std::string& public_session_locale, 345 const std::string& public_session_input_method) { 346 VLOG(1) << "Setting first login prefs"; 347 InitLocaleAndInputMethodsForNewUser( 348 this, profile, public_session_locale, public_session_input_method); 349 } 350 351 bool UserSessionManager::GetAppModeChromeClientOAuthInfo( 352 std::string* chrome_client_id, std::string* chrome_client_secret) { 353 if (!chrome::IsRunningInForcedAppMode() || 354 chrome_client_id_.empty() || 355 chrome_client_secret_.empty()) { 356 return false; 357 } 358 359 *chrome_client_id = chrome_client_id_; 360 *chrome_client_secret = chrome_client_secret_; 361 return true; 362 } 363 364 void UserSessionManager::SetAppModeChromeClientOAuthInfo( 365 const std::string& chrome_client_id, 366 const std::string& chrome_client_secret) { 367 if (!chrome::IsRunningInForcedAppMode()) 368 return; 369 370 chrome_client_id_ = chrome_client_id; 371 chrome_client_secret_ = chrome_client_secret; 372 } 373 374 bool UserSessionManager::RespectLocalePreference( 375 Profile* profile, 376 const user_manager::User* user, 377 scoped_ptr<locale_util::SwitchLanguageCallback> callback) const { 378 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in 379 // the Google user profile. 380 if (g_browser_process == NULL) 381 return false; 382 383 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 384 if (!user || (user_manager->IsUserLoggedIn() && 385 user != user_manager->GetPrimaryUser())) { 386 return false; 387 } 388 389 // In case of multi-profiles session we don't apply profile locale 390 // because it is unsafe. 391 if (user_manager->GetLoggedInUsers().size() != 1) 392 return false; 393 394 const PrefService* prefs = profile->GetPrefs(); 395 if (prefs == NULL) 396 return false; 397 398 std::string pref_locale; 399 const std::string pref_app_locale = 400 prefs->GetString(prefs::kApplicationLocale); 401 const std::string pref_bkup_locale = 402 prefs->GetString(prefs::kApplicationLocaleBackup); 403 404 pref_locale = pref_app_locale; 405 if (pref_locale.empty()) 406 pref_locale = pref_bkup_locale; 407 408 const std::string* account_locale = NULL; 409 if (pref_locale.empty() && user->has_gaia_account()) { 410 if (user->GetAccountLocale() == NULL) 411 return false; // wait until Account profile is loaded. 412 account_locale = user->GetAccountLocale(); 413 pref_locale = *account_locale; 414 } 415 const std::string global_app_locale = 416 g_browser_process->GetApplicationLocale(); 417 if (pref_locale.empty()) 418 pref_locale = global_app_locale; 419 DCHECK(!pref_locale.empty()); 420 VLOG(1) << "RespectLocalePreference: " 421 << "app_locale='" << pref_app_locale << "', " 422 << "bkup_locale='" << pref_bkup_locale << "', " 423 << (account_locale != NULL 424 ? (std::string("account_locale='") + (*account_locale) + 425 "'. ") 426 : (std::string("account_locale - unused. "))) 427 << " Selected '" << pref_locale << "'"; 428 profile->ChangeAppLocale( 429 pref_locale, 430 user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT ? 431 Profile::APP_LOCALE_CHANGED_VIA_PUBLIC_SESSION_LOGIN : 432 Profile::APP_LOCALE_CHANGED_VIA_LOGIN); 433 434 // Here we don't enable keyboard layouts for normal users. Input methods 435 // are set up when the user first logs in. Then the user may customize the 436 // input methods. Hence changing input methods here, just because the user's 437 // UI language is different from the login screen UI language, is not 438 // desirable. Note that input method preferences are synced, so users can use 439 // their farovite input methods as soon as the preferences are synced. 440 // 441 // For Guest mode, user locale preferences will never get initialized. 442 // So input methods should be enabled somewhere. 443 const bool enable_layouts = 444 user_manager::UserManager::Get()->IsLoggedInAsGuest(); 445 locale_util::SwitchLanguage(pref_locale, 446 enable_layouts, 447 false /* login_layouts_only */, 448 callback.Pass()); 449 450 return true; 451 } 452 453 bool UserSessionManager::NeedsToUpdateEasyUnlockKeys() const { 454 return EasyUnlockService::IsSignInEnabled() && 455 !user_context_.GetUserID().empty() && 456 user_context_.GetUserType() == user_manager::USER_TYPE_REGULAR && 457 user_context_.GetKey() && !user_context_.GetKey()->GetSecret().empty(); 458 } 459 460 bool UserSessionManager::CheckEasyUnlockKeyOps(const base::Closure& callback) { 461 if (!running_easy_unlock_key_ops_) 462 return false; 463 464 // Assumes only one deferred callback is needed. 465 DCHECK(easy_unlock_key_ops_finished_callback_.is_null()); 466 467 easy_unlock_key_ops_finished_callback_ = callback; 468 return true; 469 } 470 471 void UserSessionManager::AddSessionStateObserver( 472 chromeos::UserSessionStateObserver* observer) { 473 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 474 session_state_observer_list_.AddObserver(observer); 475 } 476 477 void UserSessionManager::RemoveSessionStateObserver( 478 chromeos::UserSessionStateObserver* observer) { 479 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 480 session_state_observer_list_.RemoveObserver(observer); 481 } 482 483 void UserSessionManager::OnSessionRestoreStateChanged( 484 Profile* user_profile, 485 OAuth2LoginManager::SessionRestoreState state) { 486 user_manager::User::OAuthTokenStatus user_status = 487 user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN; 488 OAuth2LoginManager* login_manager = 489 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); 490 491 bool connection_error = false; 492 switch (state) { 493 case OAuth2LoginManager::SESSION_RESTORE_DONE: 494 user_status = user_manager::User::OAUTH2_TOKEN_STATUS_VALID; 495 break; 496 case OAuth2LoginManager::SESSION_RESTORE_FAILED: 497 user_status = user_manager::User::OAUTH2_TOKEN_STATUS_INVALID; 498 break; 499 case OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED: 500 connection_error = true; 501 break; 502 case OAuth2LoginManager::SESSION_RESTORE_NOT_STARTED: 503 case OAuth2LoginManager::SESSION_RESTORE_PREPARING: 504 case OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS: 505 return; 506 } 507 508 // We should not be clearing existing token state if that was a connection 509 // error. http://crbug.com/295245 510 if (!connection_error) { 511 // We are in one of "done" states here. 512 user_manager::UserManager::Get()->SaveUserOAuthStatus( 513 user_manager::UserManager::Get()->GetLoggedInUser()->email(), 514 user_status); 515 } 516 517 login_manager->RemoveObserver(this); 518 } 519 520 void UserSessionManager::OnNewRefreshTokenAvaiable(Profile* user_profile) { 521 // Check if we were waiting to restart chrome. 522 if (!exit_after_session_restore_) 523 return; 524 525 OAuth2LoginManager* login_manager = 526 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); 527 login_manager->RemoveObserver(this); 528 529 // Mark user auth token status as valid. 530 user_manager::UserManager::Get()->SaveUserOAuthStatus( 531 user_manager::UserManager::Get()->GetLoggedInUser()->email(), 532 user_manager::User::OAUTH2_TOKEN_STATUS_VALID); 533 534 VLOG(1) << "Exiting after new refresh token fetched"; 535 536 // We need to restart cleanly in this case to make sure OAuth2 RT is actually 537 // saved. 538 chrome::AttemptRestart(); 539 } 540 541 void UserSessionManager::OnConnectionTypeChanged( 542 net::NetworkChangeNotifier::ConnectionType type) { 543 bool is_running_test = 544 base::CommandLine::ForCurrentProcess()->HasSwitch( 545 ::switches::kTestName) || 546 base::CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType); 547 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 548 if (type == net::NetworkChangeNotifier::CONNECTION_NONE || 549 !user_manager->IsUserLoggedIn() || 550 !user_manager->IsLoggedInAsRegularUser() || 551 user_manager->IsLoggedInAsStub() || is_running_test) { 552 return; 553 } 554 555 // Need to iterate over all users and their OAuth2 session state. 556 const user_manager::UserList& users = user_manager->GetLoggedInUsers(); 557 for (user_manager::UserList::const_iterator it = users.begin(); 558 it != users.end(); 559 ++it) { 560 if (!(*it)->is_profile_created()) 561 continue; 562 563 Profile* user_profile = ProfileHelper::Get()->GetProfileByUserUnsafe(*it); 564 bool should_restore_session = 565 pending_signin_restore_sessions_.find((*it)->email()) != 566 pending_signin_restore_sessions_.end(); 567 OAuth2LoginManager* login_manager = 568 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); 569 if (login_manager->state() == 570 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) { 571 // If we come online for the first time after successful offline login, 572 // we need to kick off OAuth token verification process again. 573 login_manager->ContinueSessionRestore(); 574 } else if (should_restore_session) { 575 pending_signin_restore_sessions_.erase((*it)->email()); 576 RestoreAuthSessionImpl(user_profile, false /* has_auth_cookies */); 577 } 578 } 579 } 580 581 void UserSessionManager::OnProfilePrepared(Profile* profile) { 582 LoginUtils::Get()->DoBrowserLaunch(profile, NULL); // host_, not needed here 583 584 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) { 585 // Did not log in (we crashed or are debugging), need to restore Sync. 586 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all 587 // users once it is fully multi-profile aware. http://crbug.com/238987 588 // For now if we have other user pending sessions they'll override OAuth 589 // session restore for previous users. 590 UserSessionManager::GetInstance()->RestoreAuthenticationSession(profile); 591 } 592 593 // Restore other user sessions if any. 594 RestorePendingUserSessions(); 595 } 596 597 void UserSessionManager::CreateUserSession(const UserContext& user_context, 598 bool has_auth_cookies) { 599 user_context_ = user_context; 600 has_auth_cookies_ = has_auth_cookies; 601 InitSessionRestoreStrategy(); 602 } 603 604 void UserSessionManager::PreStartSession() { 605 // Switch log file as soon as possible. 606 if (base::SysInfo::IsRunningOnChromeOS()) 607 logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess())); 608 } 609 610 void UserSessionManager::StartCrosSession() { 611 BootTimesLoader* btl = BootTimesLoader::Get(); 612 btl->AddLoginTimeMarker("StartSession-Start", false); 613 DBusThreadManager::Get()->GetSessionManagerClient()-> 614 StartSession(user_context_.GetUserID()); 615 btl->AddLoginTimeMarker("StartSession-End", false); 616 } 617 618 void UserSessionManager::NotifyUserLoggedIn() { 619 BootTimesLoader* btl = BootTimesLoader::Get(); 620 btl->AddLoginTimeMarker("UserLoggedIn-Start", false); 621 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 622 user_manager->UserLoggedIn(user_context_.GetUserID(), 623 user_context_.GetUserIDHash(), 624 false); 625 btl->AddLoginTimeMarker("UserLoggedIn-End", false); 626 } 627 628 void UserSessionManager::PrepareProfile() { 629 bool is_demo_session = 630 DemoAppLauncher::IsDemoAppSession(user_context_.GetUserID()); 631 632 // TODO(nkostylev): Figure out whether demo session is using the right profile 633 // path or not. See https://codereview.chromium.org/171423009 634 g_browser_process->profile_manager()->CreateProfileAsync( 635 ProfileHelper::GetProfilePathByUserIdHash(user_context_.GetUserIDHash()), 636 base::Bind(&UserSessionManager::OnProfileCreated, 637 AsWeakPtr(), 638 user_context_, 639 is_demo_session), 640 base::string16(), 641 base::string16(), 642 std::string()); 643 } 644 645 void UserSessionManager::OnProfileCreated(const UserContext& user_context, 646 bool is_incognito_profile, 647 Profile* profile, 648 Profile::CreateStatus status) { 649 CHECK(profile); 650 651 switch (status) { 652 case Profile::CREATE_STATUS_CREATED: 653 // Profile created but before initializing extensions and promo resources. 654 InitProfilePreferences(profile, user_context); 655 break; 656 case Profile::CREATE_STATUS_INITIALIZED: 657 // Profile is created, extensions and promo resources are initialized. 658 // At this point all other Chrome OS services will be notified that it is 659 // safe to use this profile. 660 UserProfileInitialized(profile, 661 is_incognito_profile, 662 user_context.GetUserID()); 663 break; 664 case Profile::CREATE_STATUS_LOCAL_FAIL: 665 case Profile::CREATE_STATUS_REMOTE_FAIL: 666 case Profile::CREATE_STATUS_CANCELED: 667 case Profile::MAX_CREATE_STATUS: 668 NOTREACHED(); 669 break; 670 } 671 } 672 673 void UserSessionManager::InitProfilePreferences( 674 Profile* profile, 675 const UserContext& user_context) { 676 user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile); 677 if (user->is_active()) { 678 input_method::InputMethodManager* manager = 679 input_method::InputMethodManager::Get(); 680 manager->SetState(GetDefaultIMEState(profile)); 681 } 682 if (user_manager::UserManager::Get()->IsCurrentUserNew()) { 683 SetFirstLoginPrefs(profile, 684 user_context.GetPublicSessionLocale(), 685 user_context.GetPublicSessionInputMethod()); 686 } 687 688 if (user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser()) { 689 user_manager::User* active_user = 690 user_manager::UserManager::Get()->GetActiveUser(); 691 std::string supervised_user_sync_id = 692 ChromeUserManager::Get()->GetSupervisedUserManager()->GetUserSyncId( 693 active_user->email()); 694 profile->GetPrefs()->SetString(prefs::kSupervisedUserId, 695 supervised_user_sync_id); 696 } else if (user_manager::UserManager::Get()->IsLoggedInAsRegularUser()) { 697 // Make sure that the google service username is properly set (we do this 698 // on every sign in, not just the first login, to deal with existing 699 // profiles that might not have it set yet). 700 SigninManagerBase* signin_manager = 701 SigninManagerFactory::GetForProfile(profile); 702 signin_manager->SetAuthenticatedUsername(user_context.GetUserID()); 703 } 704 } 705 706 void UserSessionManager::UserProfileInitialized(Profile* profile, 707 bool is_incognito_profile, 708 const std::string& user_id) { 709 if (is_incognito_profile) { 710 profile->OnLogin(); 711 // Send the notification before creating the browser so additional objects 712 // that need the profile (e.g. the launcher) can be created first. 713 content::NotificationService::current()->Notify( 714 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, 715 content::NotificationService::AllSources(), 716 content::Details<Profile>(profile)); 717 718 if (delegate_) 719 delegate_->OnProfilePrepared(profile); 720 721 return; 722 } 723 724 BootTimesLoader* btl = BootTimesLoader::Get(); 725 btl->AddLoginTimeMarker("UserProfileGotten", false); 726 727 if (user_context_.IsUsingOAuth()) { 728 // Retrieve the policy that indicates whether to continue copying 729 // authentication cookies set by a SAML IdP on subsequent logins after the 730 // first. 731 bool transfer_saml_auth_cookies_on_subsequent_login = false; 732 if (has_auth_cookies_ && 733 g_browser_process->platform_part()-> 734 browser_policy_connector_chromeos()->GetUserAffiliation(user_id) == 735 policy::USER_AFFILIATION_MANAGED) { 736 CrosSettings::Get()->GetBoolean( 737 kAccountsPrefTransferSAMLCookies, 738 &transfer_saml_auth_cookies_on_subsequent_login); 739 } 740 741 // Transfers authentication-related data from the profile that was used for 742 // authentication to the user's profile. The proxy authentication state is 743 // transferred unconditionally. If the user authenticated via an auth 744 // extension, authentication cookies and channel IDs will be transferred as 745 // well when the user's cookie jar is empty. If the cookie jar is not empty, 746 // the authentication states in the login profile and the user's profile 747 // must be merged using /MergeSession instead. Authentication cookies set by 748 // a SAML IdP will also be transferred when the user's cookie jar is not 749 // empty if |transfer_saml_auth_cookies_on_subsequent_login| is true. 750 const bool transfer_auth_cookies_and_channel_ids_on_first_login = 751 has_auth_cookies_; 752 ProfileAuthData::Transfer( 753 authenticator_->authentication_profile(), 754 profile, 755 transfer_auth_cookies_and_channel_ids_on_first_login, 756 transfer_saml_auth_cookies_on_subsequent_login, 757 base::Bind(&UserSessionManager::CompleteProfileCreateAfterAuthTransfer, 758 AsWeakPtr(), 759 profile)); 760 return; 761 } 762 763 FinalizePrepareProfile(profile); 764 } 765 766 void UserSessionManager::CompleteProfileCreateAfterAuthTransfer( 767 Profile* profile) { 768 RestoreAuthSessionImpl(profile, has_auth_cookies_); 769 FinalizePrepareProfile(profile); 770 } 771 772 void UserSessionManager::FinalizePrepareProfile(Profile* profile) { 773 BootTimesLoader* btl = BootTimesLoader::Get(); 774 775 // Own TPM device if, for any reason, it has not been done in EULA screen. 776 CryptohomeClient* client = DBusThreadManager::Get()->GetCryptohomeClient(); 777 btl->AddLoginTimeMarker("TPMOwn-Start", false); 778 if (cryptohome_util::TpmIsEnabled() && !cryptohome_util::TpmIsBeingOwned()) { 779 if (cryptohome_util::TpmIsOwned()) 780 client->CallTpmClearStoredPasswordAndBlock(); 781 else 782 client->TpmCanAttemptOwnership(EmptyVoidDBusMethodCallback()); 783 } 784 btl->AddLoginTimeMarker("TPMOwn-End", false); 785 786 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 787 if (user_manager->IsLoggedInAsRegularUser()) { 788 SAMLOfflineSigninLimiter* saml_offline_signin_limiter = 789 SAMLOfflineSigninLimiterFactory::GetForProfile(profile); 790 if (saml_offline_signin_limiter) 791 saml_offline_signin_limiter->SignedIn(user_context_.GetAuthFlow()); 792 } 793 794 profile->OnLogin(); 795 796 g_browser_process->platform_part()->SessionManager()->SetSessionState( 797 session_manager::SESSION_STATE_LOGGED_IN_NOT_ACTIVE); 798 799 // Send the notification before creating the browser so additional objects 800 // that need the profile (e.g. the launcher) can be created first. 801 content::NotificationService::current()->Notify( 802 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, 803 content::NotificationService::AllSources(), 804 content::Details<Profile>(profile)); 805 806 // Initialize various services only for primary user. 807 const user_manager::User* user = 808 ProfileHelper::Get()->GetUserByProfile(profile); 809 if (user_manager->GetPrimaryUser() == user) { 810 InitRlz(profile); 811 InitializeCerts(profile); 812 InitializeCRLSetFetcher(user); 813 } 814 815 UpdateEasyUnlockKeys(user_context_); 816 user_context_.ClearSecrets(); 817 818 // TODO(nkostylev): This pointer should probably never be NULL, but it looks 819 // like LoginUtilsImpl::OnProfileCreated() may be getting called before 820 // UserSessionManager::PrepareProfile() has set |delegate_| when Chrome is 821 // killed during shutdown in tests -- see http://crosbug.com/18269. Replace 822 // this 'if' statement with a CHECK(delegate_) once the underlying issue is 823 // resolved. 824 if (delegate_) 825 delegate_->OnProfilePrepared(profile); 826 } 827 828 void UserSessionManager::InitSessionRestoreStrategy() { 829 CommandLine* command_line = CommandLine::ForCurrentProcess(); 830 bool in_app_mode = chrome::IsRunningInForcedAppMode(); 831 832 // Are we in kiosk app mode? 833 if (in_app_mode) { 834 if (command_line->HasSwitch(::switches::kAppModeOAuth2Token)) { 835 oauth2_refresh_token_ = command_line->GetSwitchValueASCII( 836 ::switches::kAppModeOAuth2Token); 837 } 838 839 if (command_line->HasSwitch(::switches::kAppModeAuthCode)) { 840 user_context_.SetAuthCode(command_line->GetSwitchValueASCII( 841 ::switches::kAppModeAuthCode)); 842 } 843 844 DCHECK(!has_auth_cookies_); 845 if (!user_context_.GetAuthCode().empty()) { 846 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE; 847 } else if (!oauth2_refresh_token_.empty()) { 848 session_restore_strategy_ = 849 OAuth2LoginManager::RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN; 850 } else { 851 session_restore_strategy_ = 852 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; 853 } 854 return; 855 } 856 857 if (has_auth_cookies_) { 858 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR; 859 } else if (!user_context_.GetAuthCode().empty()) { 860 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE; 861 } else { 862 session_restore_strategy_ = 863 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; 864 } 865 } 866 867 void UserSessionManager::RestoreAuthSessionImpl(Profile* profile, 868 bool restore_from_auth_cookies) { 869 CHECK((authenticator_.get() && authenticator_->authentication_profile()) || 870 !restore_from_auth_cookies); 871 872 if (chrome::IsRunningInForcedAppMode() || 873 CommandLine::ForCurrentProcess()->HasSwitch( 874 chromeos::switches::kDisableGaiaServices)) { 875 return; 876 } 877 878 exit_after_session_restore_ = false; 879 880 // Remove legacy OAuth1 token if we have one. If it's valid, we should already 881 // have OAuth2 refresh token in OAuth2TokenService that could be used to 882 // retrieve all other tokens and user_context. 883 OAuth2LoginManager* login_manager = 884 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile); 885 login_manager->AddObserver(this); 886 login_manager->RestoreSession( 887 authenticator_.get() && authenticator_->authentication_profile() 888 ? authenticator_->authentication_profile()->GetRequestContext() 889 : NULL, 890 session_restore_strategy_, 891 oauth2_refresh_token_, 892 user_context_.GetAuthCode()); 893 } 894 895 void UserSessionManager::InitRlzImpl(Profile* profile, bool disabled) { 896 #if defined(ENABLE_RLZ) 897 PrefService* local_state = g_browser_process->local_state(); 898 if (disabled) { 899 // Empty brand code means an organic install (no RLZ pings are sent). 900 google_brand::chromeos::ClearBrandForCurrentSession(); 901 } 902 if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) { 903 // When switching to RLZ enabled/disabled state, clear all recorded events. 904 RLZTracker::ClearRlzState(); 905 local_state->SetBoolean(prefs::kRLZDisabled, disabled); 906 } 907 // Init the RLZ library. 908 int ping_delay = profile->GetPrefs()->GetInteger( 909 first_run::GetPingDelayPrefName().c_str()); 910 // Negative ping delay means to send ping immediately after a first search is 911 // recorded. 912 RLZTracker::InitRlzFromProfileDelayed( 913 profile, 914 user_manager::UserManager::Get()->IsCurrentUserNew(), 915 ping_delay < 0, 916 base::TimeDelta::FromMilliseconds(abs(ping_delay))); 917 if (delegate_) 918 delegate_->OnRlzInitialized(); 919 #endif 920 } 921 922 void UserSessionManager::InitializeCerts(Profile* profile) { 923 // Now that the user profile has been initialized 924 // |GetNSSCertDatabaseForProfile| is safe to be used. 925 if (CertLoader::IsInitialized() && base::SysInfo::IsRunningOnChromeOS()) { 926 GetNSSCertDatabaseForProfile(profile, 927 base::Bind(&OnGetNSSCertDatabaseForUser)); 928 } 929 } 930 931 void UserSessionManager::InitializeCRLSetFetcher( 932 const user_manager::User* user) { 933 const std::string username_hash = user->username_hash(); 934 if (!username_hash.empty()) { 935 base::FilePath path; 936 path = ProfileHelper::GetProfilePathByUserIdHash(username_hash); 937 component_updater::ComponentUpdateService* cus = 938 g_browser_process->component_updater(); 939 CRLSetFetcher* crl_set = g_browser_process->crl_set_fetcher(); 940 if (crl_set && cus) 941 crl_set->StartInitialLoad(cus, path); 942 } 943 } 944 945 void UserSessionManager::OnRestoreActiveSessions( 946 const SessionManagerClient::ActiveSessionsMap& sessions, 947 bool success) { 948 if (!success) { 949 LOG(ERROR) << "Could not get list of active user sessions after crash."; 950 // If we could not get list of active user sessions it is safer to just 951 // sign out so that we don't get in the inconsistent state. 952 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession(); 953 return; 954 } 955 956 // One profile has been already loaded on browser start. 957 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 958 DCHECK(user_manager->GetLoggedInUsers().size() == 1); 959 DCHECK(user_manager->GetActiveUser()); 960 std::string active_user_id = user_manager->GetActiveUser()->email(); 961 962 SessionManagerClient::ActiveSessionsMap::const_iterator it; 963 for (it = sessions.begin(); it != sessions.end(); ++it) { 964 if (active_user_id == it->first) 965 continue; 966 pending_user_sessions_[it->first] = it->second; 967 } 968 RestorePendingUserSessions(); 969 } 970 971 void UserSessionManager::RestorePendingUserSessions() { 972 if (pending_user_sessions_.empty()) { 973 user_manager::UserManager::Get()->SwitchToLastActiveUser(); 974 NotifyPendingUserSessionsRestoreFinished(); 975 return; 976 } 977 978 // Get next user to restore sessions and delete it from list. 979 SessionManagerClient::ActiveSessionsMap::const_iterator it = 980 pending_user_sessions_.begin(); 981 std::string user_id = it->first; 982 std::string user_id_hash = it->second; 983 DCHECK(!user_id.empty()); 984 DCHECK(!user_id_hash.empty()); 985 pending_user_sessions_.erase(user_id); 986 987 // Check that this user is not logged in yet. 988 user_manager::UserList logged_in_users = 989 user_manager::UserManager::Get()->GetLoggedInUsers(); 990 bool user_already_logged_in = false; 991 for (user_manager::UserList::const_iterator it = logged_in_users.begin(); 992 it != logged_in_users.end(); 993 ++it) { 994 const user_manager::User* user = (*it); 995 if (user->email() == user_id) { 996 user_already_logged_in = true; 997 break; 998 } 999 } 1000 DCHECK(!user_already_logged_in); 1001 1002 if (!user_already_logged_in) { 1003 UserContext user_context(user_id); 1004 user_context.SetUserIDHash(user_id_hash); 1005 user_context.SetIsUsingOAuth(false); 1006 1007 // Will call OnProfilePrepared() once profile has been loaded. 1008 StartSession(user_context, 1009 NULL, // authenticator 1010 false, // has_auth_cookies 1011 true, // has_active_session 1012 this); 1013 } else { 1014 RestorePendingUserSessions(); 1015 } 1016 } 1017 1018 void UserSessionManager::NotifyPendingUserSessionsRestoreFinished() { 1019 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1020 user_sessions_restored_ = true; 1021 user_sessions_restore_in_progress_ = false; 1022 FOR_EACH_OBSERVER(chromeos::UserSessionStateObserver, 1023 session_state_observer_list_, 1024 PendingUserSessionsRestoreFinished()); 1025 } 1026 1027 void UserSessionManager::UpdateEasyUnlockKeys(const UserContext& user_context) { 1028 // Skip key update because FakeCryptohomeClient always return success 1029 // and RemoveKey op expects a failure to stop. As a result, some tests would 1030 // timeout. 1031 // TODO(xiyuan): Revisit this when adding tests. 1032 if (!base::SysInfo::IsRunningOnChromeOS()) 1033 return; 1034 1035 // Only update Easy unlock keys for regular user. 1036 // TODO(xiyuan): Fix inconsistency user type of |user_context| introduced in 1037 // authenticator. 1038 const user_manager::User* user = 1039 user_manager::UserManager::Get()->FindUser(user_context.GetUserID()); 1040 if (!user || user->GetType() != user_manager::USER_TYPE_REGULAR) 1041 return; 1042 1043 // Bail if |user_context| does not have secret. 1044 if (user_context.GetKey()->GetSecret().empty()) 1045 return; 1046 1047 const base::ListValue* device_list = NULL; 1048 EasyUnlockService* easy_unlock_service = EasyUnlockService::GetForUser(*user); 1049 if (easy_unlock_service) { 1050 device_list = easy_unlock_service->GetRemoteDevices(); 1051 easy_unlock_service->SetHardlockState( 1052 EasyUnlockScreenlockStateHandler::NO_HARDLOCK); 1053 } 1054 1055 EasyUnlockKeyManager* key_manager = GetEasyUnlockKeyManager(); 1056 running_easy_unlock_key_ops_ = true; 1057 if (device_list) { 1058 key_manager->RefreshKeys( 1059 user_context, 1060 *device_list, 1061 base::Bind(&UserSessionManager::OnEasyUnlockKeyOpsFinished, 1062 AsWeakPtr(), 1063 user_context.GetUserID())); 1064 } else { 1065 key_manager->RemoveKeys( 1066 user_context, 1067 0, 1068 base::Bind(&UserSessionManager::OnEasyUnlockKeyOpsFinished, 1069 AsWeakPtr(), 1070 user_context.GetUserID())); 1071 } 1072 } 1073 1074 void UserSessionManager::OnEasyUnlockKeyOpsFinished( 1075 const std::string& user_id, 1076 bool success) { 1077 running_easy_unlock_key_ops_ = false; 1078 if (!easy_unlock_key_ops_finished_callback_.is_null()) 1079 easy_unlock_key_ops_finished_callback_.Run(); 1080 1081 const user_manager::User* user = 1082 user_manager::UserManager::Get()->FindUser(user_id); 1083 EasyUnlockService* easy_unlock_service = 1084 EasyUnlockService::GetForUser(*user); 1085 easy_unlock_service->CheckCryptohomeKeysAndMaybeHardlock(); 1086 } 1087 1088 void UserSessionManager::ActiveUserChanged( 1089 const user_manager::User* active_user) { 1090 Profile* profile = ProfileHelper::Get()->GetProfileByUser(active_user); 1091 // If profile has not yet been initialized, delay initialization of IME. 1092 if (!profile) 1093 return; 1094 1095 input_method::InputMethodManager* manager = 1096 input_method::InputMethodManager::Get(); 1097 manager->SetState( 1098 GetDefaultIMEState(ProfileHelper::Get()->GetProfileByUser(active_user))); 1099 } 1100 1101 scoped_refptr<input_method::InputMethodManager::State> 1102 UserSessionManager::GetDefaultIMEState(Profile* profile) { 1103 scoped_refptr<input_method::InputMethodManager::State> state = 1104 default_ime_states_[profile]; 1105 if (!state.get()) { 1106 // Profile can be NULL in tests. 1107 state = input_method::InputMethodManager::Get()->CreateNewState(profile); 1108 default_ime_states_[profile] = state; 1109 } 1110 return state; 1111 } 1112 1113 EasyUnlockKeyManager* UserSessionManager::GetEasyUnlockKeyManager() { 1114 if (!easy_unlock_key_manager_) 1115 easy_unlock_key_manager_.reset(new EasyUnlockKeyManager); 1116 1117 return easy_unlock_key_manager_.get(); 1118 } 1119 1120 } // namespace chromeos 1121