15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_performer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/boot_times_loader.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_utils.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
2381d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch#include "chrome/browser/chromeos/policy/wildcard_login_checker.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/policy/browser_policy_connector.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/session_manager_client.h"
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_store.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UserMetricsAction;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoginPerformer::LoginPerformer(Delegate* delegate)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : online_attempt_host_(this),
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      last_login_failure_(LoginFailure::LoginFailureNone()),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      password_changed_(false),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      password_changed_callback_count_(0),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_mode_(AUTH_MODE_INTERNAL),
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoginPerformer::~LoginPerformer() {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Deleting LoginPerformer";
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (authenticator_.get())
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_->SetConsumer(NULL);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoginPerformer, LoginStatusConsumer implementation:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnLoginFailure(const LoginFailure& failure) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Login_Failure"));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Login.FailureReason", failure.reason(),
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LoginFailure::NUM_FAILURE_REASONS);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "failure.reason " << failure.reason();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "failure.error.state " << failure.error().state();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_login_failure_ = failure;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnLoginFailure(failure);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // happens during offline auth only.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void LoginPerformer::OnRetailModeLoginSuccess(
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UserContext& user_context) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UserMetricsAction("Login_DemoUserLoginSuccess"));
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LoginStatusConsumer::OnRetailModeLoginSuccess(user_context);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void LoginPerformer::OnLoginSuccess(const UserContext& user_context) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Login_Success"));
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  VLOG(1) << "LoginSuccess hash: " << user_context.username_hash;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(delegate_);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After delegate_->OnLoginSuccess(...) is called, delegate_ releases
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // LoginPerformer ownership. LP now manages it's lifetime on its own.
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  delegate_->OnLoginSuccess(user_context);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnOffTheRecordLoginSuccess() {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UserMetricsAction("Login_GuestLoginSuccess"));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnOffTheRecordLoginSuccess();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnPasswordChangeDetected() {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  password_changed_ = true;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  password_changed_callback_count_++;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnPasswordChangeDetected();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NOTREACHED();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnChecked(const std::string& username, bool success) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate_) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Delegate is reset in case of successful offline login.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See ExistingUserConstoller::OnLoginSuccess().
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Case when user has changed password and enters old password
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // does not block user from sign in yet.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->OnOnlineChecked(username, success);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoginPerformer, public:
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void LoginPerformer::PerformLogin(const UserContext& user_context,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  AuthorizationMode auth_mode) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_mode_ = auth_mode;
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_ = user_context;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettings* cros_settings = CrosSettings::Get();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Whitelist check is always performed during initial login.
1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CrosSettingsProvider::TrustedStatus status =
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_settings->PrepareTrustedValues(
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          base::Bind(&LoginPerformer::PerformLogin,
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     weak_factory_.GetWeakPtr(),
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     user_context_, auth_mode));
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Must not proceed without signature verification.
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (delegate_)
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      delegate_->PolicyLoadFailed();
1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    else
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NOTREACHED();
1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else if (status != CrosSettingsProvider::TRUSTED) {
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Value of AllowNewUser setting is still not verified.
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Another attempt will be invoked after verification completion.
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16481d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  bool wildcard_match = false;
16581d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  std::string email = gaia::CanonicalizeEmail(user_context.username);
16681d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  bool is_whitelisted = LoginUtils::IsWhitelisted(email, &wildcard_match);
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (is_whitelisted) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (auth_mode_) {
16981d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch      case AUTH_MODE_EXTENSION: {
17081d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch        // On enterprise devices, reconfirm login permission with the server.
17181d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch        policy::BrowserPolicyConnector* connector =
17281d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch            g_browser_process->browser_policy_connector();
17381d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch        if (connector->IsEnterpriseManaged() && wildcard_match &&
17481d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch            !connector->IsNonEnterpriseUser(email)) {
17581d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch          wildcard_login_checker_.reset(new policy::WildcardLoginChecker());
17681d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch          wildcard_login_checker_->Start(
17781d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch                  ProfileHelper::GetSigninProfile()->GetRequestContext(),
17881d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch                  base::Bind(&LoginPerformer::OnlineWildcardLoginCheckCompleted,
17981d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch                             weak_factory_.GetWeakPtr()));
18081d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch        } else {
18181d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch          StartLoginCompletion();
18281d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch        }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
18481d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch      }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case AUTH_MODE_INTERNAL:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        StartAuthentication();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate_)
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      delegate_->WhiteListCheckFailed(user_context.username);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginPerformer::LoginAsLocallyManagedUser(
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UserContext& user_context) {
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(UserManager::kLocallyManagedUserDomain,
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            gaia::ExtractDomainName(user_context.username));
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CrosSettings* cros_settings = CrosSettings::Get();
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CrosSettingsProvider::TrustedStatus status =
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        cros_settings->PrepareTrustedValues(
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            base::Bind(&LoginPerformer::LoginAsLocallyManagedUser,
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       weak_factory_.GetWeakPtr(),
2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       user_context_));
2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Must not proceed without signature verification.
2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (delegate_)
2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      delegate_->PolicyLoadFailed();
2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    else
2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NOTREACHED();
2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (status != CrosSettingsProvider::TRUSTED) {
2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Value of kAccountsPrefSupervisedUsersEnabled setting is still not
2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // verified. Another attempt will be invoked after verification completion.
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!UserManager::Get()->AreLocallyManagedUsersAllowed()) {
2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    LOG(ERROR) << "Login attempt of locally managed user detected.";
2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    delegate_->WhiteListCheckFailed(user_context.username);
2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UserFlow* new_flow = new LocallyManagedUserLoginFlow(user_context.username);
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  new_flow->set_host(
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UserManager::Get()->GetUserFlow(user_context.username)->host());
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UserManager::Get()->SetUserFlow(user_context.username, new_flow);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&Authenticator::LoginAsLocallyManagedUser,
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 authenticator_.get(),
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 user_context));
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginPerformer::LoginRetailMode() {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&Authenticator::LoginRetailMode, authenticator_.get()));
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::LoginOffTheRecord() {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get()));
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginPerformer::LoginAsPublicAccount(const std::string& username) {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Login is not allowed if policy could not be loaded for the account.
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy::DeviceLocalAccountPolicyService* policy_service =
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      g_browser_process->browser_policy_connector()->
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetDeviceLocalAccountPolicyService();
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!policy_service || !policy_service->IsPolicyAvailableForUser(username)) {
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(delegate_);
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (delegate_)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate_->PolicyLoadFailed();
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&Authenticator::LoginAsPublicAccount, authenticator_.get(),
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 username));
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void LoginPerformer::LoginAsKioskAccount(const std::string& app_user_id) {
274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  BrowserThread::PostTask(
276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&Authenticator::LoginAsKioskAccount, authenticator_.get(),
278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 app_user_id));
279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::RecoverEncryptedData, authenticator_.get(),
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 old_password));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::ResyncEncryptedData() {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get()));
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoginPerformer, private:
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::StartLoginCompletion() {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Login completion started";
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Profile* profile = ProfileHelper::GetSigninProfile();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::CompleteLogin, authenticator_.get(),
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 profile,
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 user_context_));
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.password.clear();
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.auth_code.clear();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::StartAuthentication() {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Auth started";
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Profile* profile = ProfileHelper::GetSigninProfile();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::UI, FROM_HERE,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(),
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   profile,
3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   user_context_));
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make unobtrusive online check. It helps to determine password change
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // state in the case when offline login fails.
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    online_attempt_host_.Check(profile, user_context_);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NOTREACHED();
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.password.clear();
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.auth_code.clear();
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33481d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdochvoid LoginPerformer::OnlineWildcardLoginCheckCompleted(bool result) {
33581d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  if (result) {
33681d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch    StartLoginCompletion();
33781d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  } else {
33881d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch    if (delegate_)
33981d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch      delegate_->WhiteListCheckFailed(user_context_.username);
34081d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch  }
34181d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch}
34281d04fa4ca6b8e7c49e7a3401149aa77d5b4f381Ben Murdoch
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
344