[go: nahoru, domu]

blob: 6351847913509a57085640944b9a8f326e108af8 [file] [log] [blame]
xiaoyinh2bbdd102017-05-18 23:29:421// Copyright 2017 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
Jacob Dufaultffd9b0d2017-11-15 23:07:165#include "ash/login/login_screen_controller.h"
xiaoyinh2bbdd102017-05-18 23:29:426
Toni Barzicf61c4452017-10-05 03:57:487#include "ash/login/lock_screen_apps_focus_observer.h"
jdufaulteb4c9f1e2017-06-08 23:08:308#include "ash/login/ui/lock_screen.h"
Jacob Dufault40623d52017-09-15 17:22:539#include "ash/login/ui/login_data_dispatcher.h"
Sarah Hu069eea12017-09-08 01:28:4010#include "ash/public/cpp/ash_pref_names.h"
11#include "ash/session/session_controller.h"
12#include "ash/shell.h"
13#include "base/strings/string_number_conversions.h"
xiaoyinh2bbdd102017-05-18 23:29:4214#include "chromeos/cryptohome/system_salt_getter.h"
Roman Sorokinc5590012017-09-28 00:48:2915#include "chromeos/login/auth/authpolicy_login_helper.h"
xiaoyinh2bbdd102017-05-18 23:29:4216#include "chromeos/login/auth/user_context.h"
Sarah Hu069eea12017-09-08 01:28:4017#include "components/prefs/pref_registry_simple.h"
18#include "components/prefs/pref_service.h"
xiaoyinh2bbdd102017-05-18 23:29:4219
20namespace ash {
21
Sarah Hu069eea12017-09-08 01:28:4022namespace {
xiaoyinh2bbdd102017-05-18 23:29:4223
Sarah Hu069eea12017-09-08 01:28:4024std::string CalculateHash(const std::string& password,
25 const std::string& salt,
26 chromeos::Key::KeyType key_type) {
27 chromeos::Key key(password);
28 key.Transform(key_type, salt);
29 return key.GetSecret();
30}
31
32} // namespace
33
Jacob Dufaultffd9b0d2017-11-15 23:07:1634LoginScreenController::LoginScreenController() : binding_(this) {}
James Cook8f1e6062017-11-13 23:40:5935
Jacob Dufaultffd9b0d2017-11-15 23:07:1636LoginScreenController::~LoginScreenController() = default;
xiaoyinh2bbdd102017-05-18 23:29:4237
Sarah Hu069eea12017-09-08 01:28:4038// static
Jacob Dufaultffd9b0d2017-11-15 23:07:1639void LoginScreenController::RegisterProfilePrefs(PrefRegistrySimple* registry,
40 bool for_test) {
Sarah Hu069eea12017-09-08 01:28:4041 if (for_test) {
42 // There is no remote pref service, so pretend that ash owns the pref.
43 registry->RegisterStringPref(prefs::kQuickUnlockPinSalt, "");
44 return;
45 }
46
47 // Pref is owned by chrome and flagged as PUBLIC.
48 registry->RegisterForeignPref(prefs::kQuickUnlockPinSalt);
49}
50
Jacob Dufaultffd9b0d2017-11-15 23:07:1651void LoginScreenController::BindRequest(mojom::LoginScreenRequest request) {
James Cook8f1e6062017-11-13 23:40:5952 binding_.Bind(std::move(request));
xiaoyinh2bbdd102017-05-18 23:29:4253}
54
Jacob Dufaultffd9b0d2017-11-15 23:07:1655void LoginScreenController::SetClient(mojom::LoginScreenClientPtr client) {
56 login_screen_client_ = std::move(client);
xiaoyinh2bbdd102017-05-18 23:29:4257}
58
Jacob Dufaultffd9b0d2017-11-15 23:07:1659void LoginScreenController::ShowLockScreen(ShowLockScreenCallback on_shown) {
Jacob Dufaultdb20a4e2017-06-21 19:00:5460 ash::LockScreen::Show();
jdufaulteb4c9f1e2017-06-08 23:08:3061 std::move(on_shown).Run(true);
62}
63
Jacob Dufaultffd9b0d2017-11-15 23:07:1664void LoginScreenController::ShowErrorMessage(int32_t login_attempts,
65 const std::string& error_text,
66 const std::string& help_link_text,
67 int32_t help_topic_id) {
xiaoyinh2bbdd102017-05-18 23:29:4268 NOTIMPLEMENTED();
69}
70
Jacob Dufaultffd9b0d2017-11-15 23:07:1671void LoginScreenController::ClearErrors() {
xiaoyinh2bbdd102017-05-18 23:29:4272 NOTIMPLEMENTED();
73}
74
Jacob Dufaultffd9b0d2017-11-15 23:07:1675void LoginScreenController::ShowUserPodCustomIcon(
xiaoyinh9f6fa0e2017-06-07 19:22:3276 const AccountId& account_id,
Jacob Dufaultc5738ca2017-10-16 23:18:1677 mojom::EasyUnlockIconOptionsPtr icon) {
Jacob Dufaulta0225592017-10-17 21:53:3878 DataDispatcher()->ShowEasyUnlockIcon(account_id, icon);
xiaoyinh9f6fa0e2017-06-07 19:22:3279}
80
Jacob Dufaultffd9b0d2017-11-15 23:07:1681void LoginScreenController::HideUserPodCustomIcon(const AccountId& account_id) {
Jacob Dufaulta0225592017-10-17 21:53:3882 auto icon_options = mojom::EasyUnlockIconOptions::New();
83 icon_options->icon = mojom::EasyUnlockIconId::NONE;
84 DataDispatcher()->ShowEasyUnlockIcon(account_id, icon_options);
xiaoyinh9f6fa0e2017-06-07 19:22:3285}
86
Jacob Dufaultffd9b0d2017-11-15 23:07:1687void LoginScreenController::SetAuthType(
xiaoyinh820778c52017-06-21 01:42:5188 const AccountId& account_id,
89 proximity_auth::mojom::AuthType auth_type,
90 const base::string16& initial_value) {
Jacob Dufaulta0225592017-10-17 21:53:3891 if (auth_type == proximity_auth::mojom::AuthType::USER_CLICK) {
92 DataDispatcher()->SetClickToUnlockEnabledForUser(account_id,
93 true /*enabled*/);
94 } else {
95 NOTIMPLEMENTED();
96 }
xiaoyinh9f6fa0e2017-06-07 19:22:3297}
98
Jacob Dufaultffd9b0d2017-11-15 23:07:1699void LoginScreenController::LoadUsers(
100 std::vector<mojom::LoginUserInfoPtr> users,
101 bool show_guest) {
Jacob Dufault40623d52017-09-15 17:22:53102 DCHECK(DataDispatcher());
103
Sarah Huf3a99dd02017-10-03 22:04:11104 DataDispatcher()->NotifyUsers(users);
xiaoyinh9f6fa0e2017-06-07 19:22:32105}
106
Jacob Dufaultffd9b0d2017-11-15 23:07:16107void LoginScreenController::SetPinEnabledForUser(const AccountId& account_id,
108 bool is_enabled) {
Sarah Hu069eea12017-09-08 01:28:40109 // Chrome will update pin pod state every time user tries to authenticate.
110 // LockScreen is destroyed in the case of authentication success.
Jacob Dufault40623d52017-09-15 17:22:53111 if (DataDispatcher())
112 DataDispatcher()->SetPinEnabledForUser(account_id, is_enabled);
xiaoyinhf534c4f2017-06-13 20:50:27113}
114
Jacob Dufaultffd9b0d2017-11-15 23:07:16115void LoginScreenController::AuthenticateUser(
jdufaulteb4c9f1e2017-06-08 23:08:30116 const AccountId& account_id,
117 const std::string& password,
118 bool authenticated_by_pin,
Jacob Dufaultffd9b0d2017-11-15 23:07:16119 mojom::LoginScreenClient::AuthenticateUserCallback callback) {
120 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32121 return;
122
Jacob Dufaulteafc6fe2017-10-11 21:16:52123 // If auth is disabled by the debug overlay bypass the mojo call entirely, as
124 // it will dismiss the lock screen if the password is correct.
Jacob Dufault0fbed9c02017-11-14 19:22:24125 switch (force_fail_auth_for_debug_overlay_) {
126 case ForceFailAuth::kOff:
127 break;
128 case ForceFailAuth::kImmediate:
129 std::move(callback).Run(false);
130 return;
131 case ForceFailAuth::kDelayed:
132 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
133 FROM_HERE, base::BindOnce(std::move(callback), false),
134 base::TimeDelta::FromSeconds(1));
135 return;
Jacob Dufaulteafc6fe2017-10-11 21:16:52136 }
137
jdufaulteb4c9f1e2017-06-08 23:08:30138 // We cannot execute auth requests directly via GetSystemSalt because it
139 // expects a base::Callback instance, but |callback| is a base::OnceCallback.
140 // Instead, we store |callback| on this object and invoke it locally once we
141 // have the system salt.
142 DCHECK(!pending_user_auth_) << "More than one concurrent auth attempt";
143 pending_user_auth_ = base::BindOnce(
Jacob Dufaultffd9b0d2017-11-15 23:07:16144 &LoginScreenController::DoAuthenticateUser, base::Unretained(this),
jdufaulteb4c9f1e2017-06-08 23:08:30145 account_id, password, authenticated_by_pin, std::move(callback));
146 chromeos::SystemSaltGetter::Get()->GetSystemSalt(base::Bind(
Jacob Dufaultffd9b0d2017-11-15 23:07:16147 &LoginScreenController::OnGetSystemSalt, base::Unretained(this)));
xiaoyinh9f6fa0e2017-06-07 19:22:32148}
149
Jacob Dufaultffd9b0d2017-11-15 23:07:16150void LoginScreenController::HandleFocusLeavingLockScreenApps(bool reverse) {
Toni Barzicf61c4452017-10-05 03:57:48151 for (auto& observer : lock_screen_apps_focus_observers_)
152 observer.OnFocusLeavingLockScreenApps(reverse);
153}
154
Jacob Dufaultffd9b0d2017-11-15 23:07:16155void LoginScreenController::AttemptUnlock(const AccountId& account_id) {
156 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32157 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16158 login_screen_client_->AttemptUnlock(account_id);
Sarah Hue0e01a52017-10-25 20:29:30159
160 Shell::Get()->metrics()->login_metrics_recorder()->SetAuthMethod(
161 LoginMetricsRecorder::AuthMethod::kSmartlock);
xiaoyinh9f6fa0e2017-06-07 19:22:32162}
163
Jacob Dufaultffd9b0d2017-11-15 23:07:16164void LoginScreenController::HardlockPod(const AccountId& account_id) {
165 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32166 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16167 login_screen_client_->HardlockPod(account_id);
xiaoyinh9f6fa0e2017-06-07 19:22:32168}
169
Jacob Dufaultffd9b0d2017-11-15 23:07:16170void LoginScreenController::RecordClickOnLockIcon(const AccountId& account_id) {
171 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32172 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16173 login_screen_client_->RecordClickOnLockIcon(account_id);
xiaoyinh9f6fa0e2017-06-07 19:22:32174}
175
Jacob Dufaultffd9b0d2017-11-15 23:07:16176void LoginScreenController::OnFocusPod(const AccountId& account_id) {
177 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27178 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16179 login_screen_client_->OnFocusPod(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27180}
181
Jacob Dufaultffd9b0d2017-11-15 23:07:16182void LoginScreenController::OnNoPodFocused() {
183 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27184 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16185 login_screen_client_->OnNoPodFocused();
xiaoyinhf534c4f2017-06-13 20:50:27186}
187
Jacob Dufaultffd9b0d2017-11-15 23:07:16188void LoginScreenController::LoadWallpaper(const AccountId& account_id) {
189 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27190 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16191 login_screen_client_->LoadWallpaper(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27192}
193
Jacob Dufaultffd9b0d2017-11-15 23:07:16194void LoginScreenController::SignOutUser() {
195 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27196 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16197 login_screen_client_->SignOutUser();
xiaoyinhf534c4f2017-06-13 20:50:27198}
199
Jacob Dufaultffd9b0d2017-11-15 23:07:16200void LoginScreenController::CancelAddUser() {
201 if (!login_screen_client_)
Wenzhao Zang16e7ea722017-09-16 01:27:30202 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16203 login_screen_client_->CancelAddUser();
Wenzhao Zang16e7ea722017-09-16 01:27:30204}
205
Jacob Dufaultffd9b0d2017-11-15 23:07:16206void LoginScreenController::OnMaxIncorrectPasswordAttempted(
xiaoyinhf534c4f2017-06-13 20:50:27207 const AccountId& account_id) {
Jacob Dufaultffd9b0d2017-11-15 23:07:16208 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27209 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16210 login_screen_client_->OnMaxIncorrectPasswordAttempted(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27211}
212
Jacob Dufaultffd9b0d2017-11-15 23:07:16213void LoginScreenController::FocusLockScreenApps(bool reverse) {
214 if (!login_screen_client_)
Toni Barzicf61c4452017-10-05 03:57:48215 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16216 login_screen_client_->FocusLockScreenApps(reverse);
Toni Barzicf61c4452017-10-05 03:57:48217}
218
Jacob Dufaultffd9b0d2017-11-15 23:07:16219void LoginScreenController::AddLockScreenAppsFocusObserver(
Toni Barzicf61c4452017-10-05 03:57:48220 LockScreenAppsFocusObserver* observer) {
221 lock_screen_apps_focus_observers_.AddObserver(observer);
222}
223
Jacob Dufaultffd9b0d2017-11-15 23:07:16224void LoginScreenController::RemoveLockScreenAppsFocusObserver(
Toni Barzicf61c4452017-10-05 03:57:48225 LockScreenAppsFocusObserver* observer) {
226 lock_screen_apps_focus_observers_.RemoveObserver(observer);
227}
228
Jacob Dufaultffd9b0d2017-11-15 23:07:16229void LoginScreenController::FlushForTesting() {
230 login_screen_client_.FlushForTesting();
Toni Barzicf61c4452017-10-05 03:57:48231}
232
Jacob Dufaultffd9b0d2017-11-15 23:07:16233void LoginScreenController::DoAuthenticateUser(
jdufaulteb4c9f1e2017-06-08 23:08:30234 const AccountId& account_id,
235 const std::string& password,
236 bool authenticated_by_pin,
Jacob Dufaultffd9b0d2017-11-15 23:07:16237 mojom::LoginScreenClient::AuthenticateUserCallback callback,
jdufaulteb4c9f1e2017-06-08 23:08:30238 const std::string& system_salt) {
Sarah Hu069eea12017-09-08 01:28:40239 int dummy_value;
240 bool is_pin =
241 authenticated_by_pin && base::StringToInt(password, &dummy_value);
242 std::string hashed_password = CalculateHash(
243 password, system_salt, chromeos::Key::KEY_TYPE_SALTED_SHA256_TOP_HALF);
244
245 PrefService* prefs =
246 Shell::Get()->session_controller()->GetLastActiveUserPrefService();
247 if (is_pin && prefs) {
248 hashed_password =
249 CalculateHash(password, prefs->GetString(prefs::kQuickUnlockPinSalt),
250 chromeos::Key::KEY_TYPE_SALTED_PBKDF2_AES256_1234);
251 }
252
Roman Sorokinc5590012017-09-28 00:48:29253 if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY && !is_pin) {
254 // Try to get kerberos TGT while we have user's password typed on the lock
255 // screen. Using invalid/bad password is fine. Failure to get TGT here is OK
256 // - that could mean e.g. Active Directory server is not reachable.
257 // AuthPolicyCredentialsManager regularly checks TGT status inside the user
258 // session.
259 chromeos::AuthPolicyLoginHelper::TryAuthenticateUser(
260 account_id.GetUserEmail(), account_id.GetObjGuid(), password);
261 }
262
Sarah Hue0e01a52017-10-25 20:29:30263 Shell::Get()->metrics()->login_metrics_recorder()->SetAuthMethod(
264 is_pin ? LoginMetricsRecorder::AuthMethod::kPin
265 : LoginMetricsRecorder::AuthMethod::kPassword);
Jacob Dufaultffd9b0d2017-11-15 23:07:16266 login_screen_client_->AuthenticateUser(account_id, hashed_password, is_pin,
267 std::move(callback));
jdufaulteb4c9f1e2017-06-08 23:08:30268}
269
Jacob Dufaultffd9b0d2017-11-15 23:07:16270void LoginScreenController::OnGetSystemSalt(const std::string& system_salt) {
jdufaulteb4c9f1e2017-06-08 23:08:30271 std::move(pending_user_auth_).Run(system_salt);
xiaoyinh2bbdd102017-05-18 23:29:42272}
273
Jacob Dufaultffd9b0d2017-11-15 23:07:16274LoginDataDispatcher* LoginScreenController::DataDispatcher() const {
Jacob Dufault40623d52017-09-15 17:22:53275 if (!ash::LockScreen::IsShown())
276 return nullptr;
277 return ash::LockScreen::Get()->data_dispatcher();
278}
279
xiaoyinh2bbdd102017-05-18 23:29:42280} // namespace ash