1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 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)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/auth/login_performer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/boot_times_loader.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_utils.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_constants.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h"
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.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"
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/user_names.h"
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h"
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_store.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoginPerformer::LoginPerformer(Delegate* delegate)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : online_attempt_host_(this),
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      last_login_failure_(AuthFailure::AuthFailureNone()),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      password_changed_(false),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      password_changed_callback_count_(0),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_mode_(AUTH_MODE_INTERNAL),
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoginPerformer::~LoginPerformer() {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Deleting LoginPerformer";
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (authenticator_.get())
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_->SetConsumer(NULL);
6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (extended_authenticator_.get())
6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    extended_authenticator_->SetConsumer(NULL);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// LoginPerformer, AuthStatusConsumer implementation:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid LoginPerformer::OnAuthFailure(const AuthFailure& failure) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Login_Failure"));
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UMA_HISTOGRAM_ENUMERATION("Login.FailureReason",
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            failure.reason(),
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            AuthFailure::NUM_FAILURE_REASONS);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "failure.reason " << failure.reason();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "failure.error.state " << failure.error().state();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_login_failure_ = failure;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnAuthFailure(failure);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // happens during offline auth only.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid LoginPerformer::OnRetailModeAuthSuccess(const UserContext& user_context) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UserMetricsAction("Login_DemoUserLoginSuccess"));
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AuthStatusConsumer::OnRetailModeAuthSuccess(user_context);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid LoginPerformer::OnAuthSuccess(const UserContext& user_context) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Login_Success"));
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  VLOG(1) << "LoginSuccess hash: " << user_context.GetUserIDHash();
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(delegate_);
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // After delegate_->OnAuthSuccess(...) is called, delegate_ releases
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // LoginPerformer ownership. LP now manages it's lifetime on its own.
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  delegate_->OnAuthSuccess(user_context);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid LoginPerformer::OnOffTheRecordAuthSuccess() {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UserMetricsAction("Login_GuestLoginSuccess"));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnOffTheRecordAuthSuccess();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnPasswordChangeDetected() {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  password_changed_ = true;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  password_changed_callback_count_++;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnPasswordChangeDetected();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NOTREACHED();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnChecked(const std::string& username, bool success) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate_) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Delegate is reset in case of successful offline login.
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // See ExistingUserConstoller::OnAuthSuccess().
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Case when user has changed password and enters old password
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // does not block user from sign in yet.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->OnOnlineChecked(username, success);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoginPerformer, public:
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void LoginPerformer::PerformLogin(const UserContext& user_context,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  AuthorizationMode auth_mode) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_mode_ = auth_mode;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_ = user_context;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettings* cros_settings = CrosSettings::Get();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Whitelist check is always performed during initial login.
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CrosSettingsProvider::TrustedStatus status =
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_settings->PrepareTrustedValues(
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          base::Bind(&LoginPerformer::PerformLogin,
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     weak_factory_.GetWeakPtr(),
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     user_context_, auth_mode));
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Must not proceed without signature verification.
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (delegate_)
1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      delegate_->PolicyLoadFailed();
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    else
1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NOTREACHED();
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else if (status != CrosSettingsProvider::TRUSTED) {
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Value of AllowNewUser setting is still not verified.
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Another attempt will be invoked after verification completion.
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool wildcard_match = false;
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string email = gaia::CanonicalizeEmail(user_context.GetUserID());
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool is_whitelisted = LoginUtils::IsWhitelisted(email, &wildcard_match);
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (is_whitelisted) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (auth_mode_) {
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case AUTH_MODE_EXTENSION: {
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // On enterprise devices, reconfirm login permission with the server.
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        policy::BrowserPolicyConnectorChromeOS* connector =
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            g_browser_process->platform_part()
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                ->browser_policy_connector_chromeos();
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (connector->IsEnterpriseManaged() && wildcard_match &&
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            !connector->IsNonEnterpriseUser(email)) {
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          wildcard_login_checker_.reset(new policy::WildcardLoginChecker());
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          wildcard_login_checker_->Start(
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  ProfileHelper::GetSigninProfile()->GetRequestContext(),
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  base::Bind(&LoginPerformer::OnlineWildcardLoginCheckCompleted,
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             weak_factory_.GetWeakPtr()));
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        } else {
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          StartLoginCompletion();
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case AUTH_MODE_INTERNAL:
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        StartAuthentication();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate_)
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      delegate_->WhiteListCheckFailed(user_context.GetUserID());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LoginPerformer::LoginAsSupervisedUser(
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UserContext& user_context) {
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(chromeos::login::kSupervisedUserDomain,
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            gaia::ExtractDomainName(user_context.GetUserID()));
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CrosSettings* cros_settings = CrosSettings::Get();
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CrosSettingsProvider::TrustedStatus status =
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        cros_settings->PrepareTrustedValues(
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            base::Bind(&LoginPerformer::LoginAsSupervisedUser,
2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       weak_factory_.GetWeakPtr(),
2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       user_context_));
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Must not proceed without signature verification.
2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (delegate_)
2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      delegate_->PolicyLoadFailed();
2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    else
2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NOTREACHED();
2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (status != CrosSettingsProvider::TRUSTED) {
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Value of kAccountsPrefSupervisedUsersEnabled setting is still not
2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // verified. Another attempt will be invoked after verification completion.
2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!user_manager::UserManager::Get()->AreSupervisedUsersAllowed()) {
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(ERROR) << "Login attempt of supervised user detected.";
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    delegate_->WhiteListCheckFailed(user_context.GetUserID());
2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SupervisedUserLoginFlow* new_flow =
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new SupervisedUserLoginFlow(user_context.GetUserID());
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  new_flow->set_host(
2326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ChromeUserManager::Get()->GetUserFlow(user_context.GetUserID())->host());
2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ChromeUserManager::Get()->SetUserFlow(user_context.GetUserID(), new_flow);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SupervisedUserAuthentication* authentication =
2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ChromeUserManager::Get()->GetSupervisedUserManager()->GetAuthentication();
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UserContext user_context_copy = authentication->TransformKey(user_context);
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (authentication->GetPasswordSchema(user_context.GetUserID()) ==
24123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      SupervisedUserAuthentication::SCHEMA_SALT_HASHED) {
24223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (extended_authenticator_.get()) {
24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      extended_authenticator_->SetConsumer(NULL);
24423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
24529b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch    extended_authenticator_ = ExtendedAuthenticator::Create(this);
24623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // TODO(antrim) : Replace empty callback with explicit method.
24723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // http://crbug.com/351268
24823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    BrowserThread::PostTask(
24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        BrowserThread::UI,
25023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        FROM_HERE,
25123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        base::Bind(&ExtendedAuthenticator::AuthenticateToMount,
25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                   extended_authenticator_.get(),
25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                   user_context_copy,
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   ExtendedAuthenticator::ResultCallback()));
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
25623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else {
25723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    BrowserThread::PostTask(
25923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        BrowserThread::UI,
26023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        FROM_HERE,
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&Authenticator::LoginAsSupervisedUser,
26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                   authenticator_.get(),
26323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                   user_context_copy));
26423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginPerformer::LoginRetailMode() {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&Authenticator::LoginRetailMode, authenticator_.get()));
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::LoginOffTheRecord() {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get()));
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LoginPerformer::LoginAsPublicSession(const UserContext& user_context) {
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Login is not allowed if policy could not be loaded for the account.
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy::BrowserPolicyConnectorChromeOS* connector =
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy::DeviceLocalAccountPolicyService* policy_service =
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      connector->GetDeviceLocalAccountPolicyService();
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!policy_service ||
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !policy_service->IsPolicyAvailableForUser(user_context.GetUserID())) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(delegate_);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (delegate_)
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate_->PolicyLoadFailed();
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&Authenticator::LoginAsPublicSession,
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 authenticator_.get(),
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 user_context));
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
303effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid LoginPerformer::LoginAsKioskAccount(const std::string& app_user_id,
304effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                         bool use_guest_mount) {
305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  BrowserThread::PostTask(
307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&Authenticator::LoginAsKioskAccount, authenticator_.get(),
309effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 app_user_id, use_guest_mount));
310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::RecoverEncryptedData, authenticator_.get(),
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 old_password));
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::ResyncEncryptedData() {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get()));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoginPerformer, private:
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::StartLoginCompletion() {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Login completion started";
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Profile* profile = ProfileHelper::GetSigninProfile();
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::CompleteLogin, authenticator_.get(),
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 profile,
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 user_context_));
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  user_context_.ClearSecrets();
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::StartAuthentication() {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Auth started";
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Profile* profile = ProfileHelper::GetSigninProfile();
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::UI, FROM_HERE,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(),
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   profile,
3527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   user_context_));
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make unobtrusive online check. It helps to determine password change
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // state in the case when offline login fails.
35503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    online_attempt_host_.Check(profile->GetRequestContext(), user_context_);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NOTREACHED();
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  user_context_.ClearSecrets();
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void LoginPerformer::OnlineWildcardLoginCheckCompleted(
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    policy::WildcardLoginChecker::Result result) {
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (result == policy::WildcardLoginChecker::RESULT_ALLOWED) {
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    StartLoginCompletion();
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (delegate_)
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      delegate_->WhiteListCheckFailed(user_context_.GetUserID());
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
373