[go: nahoru, domu]

blob: ae141477eb1e6dbff92643dc6043e26e102f84c6 [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
jdufaulteb4c9f1e2017-06-08 23:08:307#include "ash/login/ui/lock_screen.h"
Jacob Dufault40623d52017-09-15 17:22:538#include "ash/login/ui/login_data_dispatcher.h"
Sarah Hu069eea12017-09-08 01:28:409#include "ash/public/cpp/ash_pref_names.h"
Aga Wronska16abb432018-01-11 23:49:5910#include "ash/root_window_controller.h"
Sarah Hu069eea12017-09-08 01:28:4011#include "ash/session/session_controller.h"
12#include "ash/shell.h"
Aga Wronska16abb432018-01-11 23:49:5913#include "ash/system/status_area_widget.h"
Sarah Hu069eea12017-09-08 01:28:4014#include "base/strings/string_number_conversions.h"
Jialiu Linf99b788b2018-01-17 23:01:2115#include "base/strings/utf_string_conversions.h"
xiaoyinh2bbdd102017-05-18 23:29:4216#include "chromeos/cryptohome/system_salt_getter.h"
Roman Sorokinc5590012017-09-28 00:48:2917#include "chromeos/login/auth/authpolicy_login_helper.h"
xiaoyinh2bbdd102017-05-18 23:29:4218#include "chromeos/login/auth/user_context.h"
Jialiu Linf99b788b2018-01-17 23:01:2119#include "components/password_manager/core/browser/hash_password_manager.h"
Sarah Hu069eea12017-09-08 01:28:4020#include "components/prefs/pref_registry_simple.h"
21#include "components/prefs/pref_service.h"
Jacob Dufault957e0922017-12-06 19:16:0922#include "components/session_manager/session_manager_types.h"
xiaoyinh2bbdd102017-05-18 23:29:4223
24namespace ash {
25
Sarah Hu069eea12017-09-08 01:28:4026namespace {
xiaoyinh2bbdd102017-05-18 23:29:4227
Sarah Hu069eea12017-09-08 01:28:4028std::string CalculateHash(const std::string& password,
29 const std::string& salt,
30 chromeos::Key::KeyType key_type) {
31 chromeos::Key key(password);
32 key.Transform(key_type, salt);
33 return key.GetSecret();
34}
35
Aga Wronskaa844cdcd12018-01-29 16:06:4436enum class SystemTrayVisibility {
37 kNone, // Tray not visible anywhere.
38 kPrimary, // Tray visible only on primary display.
39 kAll, // Tray visible on all displays.
40};
41
42void SetSystemTrayVisibility(SystemTrayVisibility visibility) {
43 RootWindowController* primary_window_controller =
44 Shell::GetPrimaryRootWindowController();
45 for (RootWindowController* window_controller :
46 Shell::GetAllRootWindowControllers()) {
47 StatusAreaWidget* status_area = window_controller->GetStatusAreaWidget();
48 if (!status_area)
49 continue;
50 if (window_controller == primary_window_controller) {
51 status_area->SetSystemTrayVisibility(
52 visibility == SystemTrayVisibility::kPrimary ||
53 visibility == SystemTrayVisibility::kAll);
54 } else {
55 status_area->SetSystemTrayVisibility(visibility ==
56 SystemTrayVisibility::kAll);
57 }
58 }
Aga Wronska16abb432018-01-11 23:49:5959}
60
Sarah Hu069eea12017-09-08 01:28:4061} // namespace
62
James Cookede316a2017-12-14 22:38:4363LoginScreenController::LoginScreenController() : weak_factory_(this) {}
James Cook8f1e6062017-11-13 23:40:5964
Jacob Dufaultffd9b0d2017-11-15 23:07:1665LoginScreenController::~LoginScreenController() = default;
xiaoyinh2bbdd102017-05-18 23:29:4266
Sarah Hu069eea12017-09-08 01:28:4067// static
Jacob Dufaultffd9b0d2017-11-15 23:07:1668void LoginScreenController::RegisterProfilePrefs(PrefRegistrySimple* registry,
69 bool for_test) {
Sarah Hu069eea12017-09-08 01:28:4070 if (for_test) {
71 // There is no remote pref service, so pretend that ash owns the pref.
72 registry->RegisterStringPref(prefs::kQuickUnlockPinSalt, "");
73 return;
74 }
75
76 // Pref is owned by chrome and flagged as PUBLIC.
77 registry->RegisterForeignPref(prefs::kQuickUnlockPinSalt);
78}
79
Jacob Dufaultffd9b0d2017-11-15 23:07:1680void LoginScreenController::BindRequest(mojom::LoginScreenRequest request) {
James Cookede316a2017-12-14 22:38:4381 bindings_.AddBinding(this, std::move(request));
xiaoyinh2bbdd102017-05-18 23:29:4282}
83
Jacob Dufaultb7a2d842017-12-01 23:21:1584void LoginScreenController::AuthenticateUser(const AccountId& account_id,
85 const std::string& password,
86 bool authenticated_by_pin,
87 OnAuthenticateCallback callback) {
88 // Ignore concurrent auth attempts. This can happen if the user quickly enters
89 // two separate passwords and hits enter.
90 if (!login_screen_client_ || is_authenticating_) {
91 LOG_IF(ERROR, is_authenticating_) << "Ignoring concurrent auth attempt";
92 std::move(callback).Run(base::nullopt);
xiaoyinh9f6fa0e2017-06-07 19:22:3293 return;
Jacob Dufaultb7a2d842017-12-01 23:21:1594 }
95 is_authenticating_ = true;
xiaoyinh9f6fa0e2017-06-07 19:22:3296
Jacob Dufaulteafc6fe2017-10-11 21:16:5297 // If auth is disabled by the debug overlay bypass the mojo call entirely, as
98 // it will dismiss the lock screen if the password is correct.
Jacob Dufault0fbed9c02017-11-14 19:22:2499 switch (force_fail_auth_for_debug_overlay_) {
100 case ForceFailAuth::kOff:
101 break;
102 case ForceFailAuth::kImmediate:
Jacob Dufaultb7a2d842017-12-01 23:21:15103 OnAuthenticateComplete(std::move(callback), false /*success*/);
Jacob Dufault0fbed9c02017-11-14 19:22:24104 return;
105 case ForceFailAuth::kDelayed:
106 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Jacob Dufaultb7a2d842017-12-01 23:21:15107 FROM_HERE,
108 base::BindOnce(&LoginScreenController::OnAuthenticateComplete,
109 weak_factory_.GetWeakPtr(), base::Passed(&callback),
110 false),
Jacob Dufault0fbed9c02017-11-14 19:22:24111 base::TimeDelta::FromSeconds(1));
112 return;
Jacob Dufaulteafc6fe2017-10-11 21:16:52113 }
114
Jacob Dufaultb7a2d842017-12-01 23:21:15115 // |DoAuthenticateUser| requires the system salt, so we fetch it first, and
116 // then run |DoAuthenticateUser| as a continuation.
117 auto do_authenticate = base::BindOnce(
118 &LoginScreenController::DoAuthenticateUser, weak_factory_.GetWeakPtr(),
jdufaulteb4c9f1e2017-06-08 23:08:30119 account_id, password, authenticated_by_pin, std::move(callback));
Jacob Dufaultb7a2d842017-12-01 23:21:15120 chromeos::SystemSaltGetter::Get()->GetSystemSalt(base::BindRepeating(
121 &LoginScreenController::OnGetSystemSalt, weak_factory_.GetWeakPtr(),
122 base::Passed(&do_authenticate)));
xiaoyinh9f6fa0e2017-06-07 19:22:32123}
124
Jacob Dufaultffd9b0d2017-11-15 23:07:16125void LoginScreenController::AttemptUnlock(const AccountId& account_id) {
126 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32127 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16128 login_screen_client_->AttemptUnlock(account_id);
Sarah Hue0e01a52017-10-25 20:29:30129
130 Shell::Get()->metrics()->login_metrics_recorder()->SetAuthMethod(
131 LoginMetricsRecorder::AuthMethod::kSmartlock);
xiaoyinh9f6fa0e2017-06-07 19:22:32132}
133
Jacob Dufaultffd9b0d2017-11-15 23:07:16134void LoginScreenController::HardlockPod(const AccountId& account_id) {
135 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32136 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16137 login_screen_client_->HardlockPod(account_id);
xiaoyinh9f6fa0e2017-06-07 19:22:32138}
139
Jacob Dufaultffd9b0d2017-11-15 23:07:16140void LoginScreenController::RecordClickOnLockIcon(const AccountId& account_id) {
141 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32142 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16143 login_screen_client_->RecordClickOnLockIcon(account_id);
xiaoyinh9f6fa0e2017-06-07 19:22:32144}
145
Jacob Dufaultffd9b0d2017-11-15 23:07:16146void LoginScreenController::OnFocusPod(const AccountId& account_id) {
147 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27148 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16149 login_screen_client_->OnFocusPod(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27150}
151
Jacob Dufaultffd9b0d2017-11-15 23:07:16152void LoginScreenController::OnNoPodFocused() {
153 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27154 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16155 login_screen_client_->OnNoPodFocused();
xiaoyinhf534c4f2017-06-13 20:50:27156}
157
Jacob Dufaultffd9b0d2017-11-15 23:07:16158void LoginScreenController::LoadWallpaper(const AccountId& account_id) {
159 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27160 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16161 login_screen_client_->LoadWallpaper(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27162}
163
Jacob Dufaultffd9b0d2017-11-15 23:07:16164void LoginScreenController::SignOutUser() {
165 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27166 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16167 login_screen_client_->SignOutUser();
xiaoyinhf534c4f2017-06-13 20:50:27168}
169
Jacob Dufaultffd9b0d2017-11-15 23:07:16170void LoginScreenController::CancelAddUser() {
171 if (!login_screen_client_)
Wenzhao Zang16e7ea722017-09-16 01:27:30172 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16173 login_screen_client_->CancelAddUser();
Wenzhao Zang16e7ea722017-09-16 01:27:30174}
175
Aga Wronska6a32f9872018-01-06 00:16:10176void LoginScreenController::LoginAsGuest() {
177 if (!login_screen_client_)
178 return;
179 login_screen_client_->LoginAsGuest();
180}
181
Jacob Dufaultffd9b0d2017-11-15 23:07:16182void LoginScreenController::OnMaxIncorrectPasswordAttempted(
xiaoyinhf534c4f2017-06-13 20:50:27183 const AccountId& account_id) {
Jacob Dufaultffd9b0d2017-11-15 23:07:16184 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27185 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16186 login_screen_client_->OnMaxIncorrectPasswordAttempted(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27187}
188
Jacob Dufaultffd9b0d2017-11-15 23:07:16189void LoginScreenController::FocusLockScreenApps(bool reverse) {
190 if (!login_screen_client_)
Toni Barzicf61c4452017-10-05 03:57:48191 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16192 login_screen_client_->FocusLockScreenApps(reverse);
Toni Barzicf61c4452017-10-05 03:57:48193}
194
Sarah Hu9fba0e752018-02-07 01:41:09195void LoginScreenController::ShowGaiaSignin() {
196 if (!login_screen_client_)
197 return;
198 login_screen_client_->ShowGaiaSignin();
199}
200
Jacob Dufaultfc31c742018-03-20 17:32:19201void LoginScreenController::OnRemoveUserWarningShown() {
202 if (!login_screen_client_)
203 return;
204 login_screen_client_->OnRemoveUserWarningShown();
205}
206
207void LoginScreenController::RemoveUser(const AccountId& account_id) {
208 if (!login_screen_client_)
209 return;
210 login_screen_client_->RemoveUser(account_id);
211}
212
Sarah Hu3fcf9f82018-03-22 20:32:54213void LoginScreenController::LaunchPublicSession(
214 const AccountId& account_id,
215 const std::string& locale,
216 const std::string& input_method) {
217 if (!login_screen_client_)
218 return;
219 login_screen_client_->LaunchPublicSession(account_id, locale, input_method);
220}
221
Jacob Dufault589d9942018-03-27 20:28:47222void LoginScreenController::AddObserver(
223 LoginScreenControllerObserver* observer) {
224 observers_.AddObserver(observer);
Toni Barzicf61c4452017-10-05 03:57:48225}
226
Jacob Dufault589d9942018-03-27 20:28:47227void LoginScreenController::RemoveObserver(
228 LoginScreenControllerObserver* observer) {
229 observers_.RemoveObserver(observer);
Toni Barzicf61c4452017-10-05 03:57:48230}
231
Jacob Dufaultffd9b0d2017-11-15 23:07:16232void LoginScreenController::FlushForTesting() {
233 login_screen_client_.FlushForTesting();
Toni Barzicf61c4452017-10-05 03:57:48234}
235
Jacob Dufault589d9942018-03-27 20:28:47236void LoginScreenController::SetClient(mojom::LoginScreenClientPtr client) {
237 login_screen_client_ = std::move(client);
238}
239
240void LoginScreenController::ShowLockScreen(ShowLockScreenCallback on_shown) {
241 OnShow();
242 ash::LockScreen::Show(ash::LockScreen::ScreenType::kLock);
243 std::move(on_shown).Run(true);
244}
245
246void LoginScreenController::ShowLoginScreen(ShowLoginScreenCallback on_shown) {
247 // Login screen can only be used during login.
248 if (Shell::Get()->session_controller()->GetSessionState() !=
249 session_manager::SessionState::LOGIN_PRIMARY) {
250 LOG(ERROR) << "Not showing login screen since session state is "
251 << static_cast<int>(
252 Shell::Get()->session_controller()->GetSessionState());
253 std::move(on_shown).Run(false);
254 return;
255 }
256
257 OnShow();
258 // TODO(jdufault): rename ash::LockScreen to ash::LoginScreen.
259 ash::LockScreen::Show(ash::LockScreen::ScreenType::kLogin);
260 std::move(on_shown).Run(true);
261}
262
263void LoginScreenController::ShowErrorMessage(int32_t login_attempts,
264 const std::string& error_text,
265 const std::string& help_link_text,
266 int32_t help_topic_id) {
267 NOTIMPLEMENTED();
268}
269
270void LoginScreenController::ClearErrors() {
271 NOTIMPLEMENTED();
272}
273
274void LoginScreenController::ShowUserPodCustomIcon(
275 const AccountId& account_id,
276 mojom::EasyUnlockIconOptionsPtr icon) {
277 DataDispatcher()->ShowEasyUnlockIcon(account_id, icon);
278}
279
280void LoginScreenController::HideUserPodCustomIcon(const AccountId& account_id) {
281 auto icon_options = mojom::EasyUnlockIconOptions::New();
282 icon_options->icon = mojom::EasyUnlockIconId::NONE;
283 DataDispatcher()->ShowEasyUnlockIcon(account_id, icon_options);
284}
285
286void LoginScreenController::SetAuthType(
287 const AccountId& account_id,
288 proximity_auth::mojom::AuthType auth_type,
289 const base::string16& initial_value) {
290 if (auth_type == proximity_auth::mojom::AuthType::USER_CLICK) {
291 DataDispatcher()->SetClickToUnlockEnabledForUser(account_id,
292 true /*enabled*/);
293 } else {
294 NOTIMPLEMENTED();
295 }
296}
297
298void LoginScreenController::LoadUsers(
299 std::vector<mojom::LoginUserInfoPtr> users,
300 bool show_guest) {
301 DCHECK(DataDispatcher());
302
303 DataDispatcher()->NotifyUsers(users);
304}
305
306void LoginScreenController::SetPinEnabledForUser(const AccountId& account_id,
307 bool is_enabled) {
308 // Chrome will update pin pod state every time user tries to authenticate.
309 // LockScreen is destroyed in the case of authentication success.
310 if (DataDispatcher())
311 DataDispatcher()->SetPinEnabledForUser(account_id, is_enabled);
312}
313
314void LoginScreenController::HandleFocusLeavingLockScreenApps(bool reverse) {
315 for (auto& observer : observers_)
316 observer.OnFocusLeavingLockScreenApps(reverse);
317}
318
319void LoginScreenController::SetDevChannelInfo(
320 const std::string& os_version_label_text,
321 const std::string& enterprise_info_text,
322 const std::string& bluetooth_name) {
323 if (DataDispatcher()) {
324 DataDispatcher()->SetDevChannelInfo(os_version_label_text,
325 enterprise_info_text, bluetooth_name);
326 }
327}
328
329void LoginScreenController::IsReadyForPassword(
330 IsReadyForPasswordCallback callback) {
331 std::move(callback).Run(LockScreen::IsShown() && !is_authenticating_);
332}
333
334void LoginScreenController::SetPublicSessionDisplayName(
335 const AccountId& account_id,
336 const std::string& display_name) {
337 if (DataDispatcher())
338 DataDispatcher()->SetPublicSessionDisplayName(account_id, display_name);
339}
340
341void LoginScreenController::SetPublicSessionLocales(
342 const AccountId& account_id,
343 std::unique_ptr<base::ListValue> locales,
344 const std::string& default_locale,
345 bool show_advanced_view) {
346 if (DataDispatcher()) {
347 DataDispatcher()->SetPublicSessionLocales(
348 account_id, std::move(locales), default_locale, show_advanced_view);
349 }
350}
351
Jacob Dufaultb7a2d842017-12-01 23:21:15352void LoginScreenController::DoAuthenticateUser(const AccountId& account_id,
353 const std::string& password,
354 bool authenticated_by_pin,
355 OnAuthenticateCallback callback,
356 const std::string& system_salt) {
Sarah Hu069eea12017-09-08 01:28:40357 int dummy_value;
358 bool is_pin =
359 authenticated_by_pin && base::StringToInt(password, &dummy_value);
360 std::string hashed_password = CalculateHash(
361 password, system_salt, chromeos::Key::KEY_TYPE_SALTED_SHA256_TOP_HALF);
362
Jialiu Linf99b788b2018-01-17 23:01:21363 // Used for GAIA password reuse detection.
364 password_manager::SyncPasswordData sync_password_data(
365 base::UTF8ToUTF16(password), /*force_update=*/false);
366
Sarah Hu069eea12017-09-08 01:28:40367 PrefService* prefs =
368 Shell::Get()->session_controller()->GetLastActiveUserPrefService();
369 if (is_pin && prefs) {
370 hashed_password =
371 CalculateHash(password, prefs->GetString(prefs::kQuickUnlockPinSalt),
372 chromeos::Key::KEY_TYPE_SALTED_PBKDF2_AES256_1234);
373 }
374
Roman Sorokinc5590012017-09-28 00:48:29375 if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY && !is_pin) {
376 // Try to get kerberos TGT while we have user's password typed on the lock
377 // screen. Using invalid/bad password is fine. Failure to get TGT here is OK
378 // - that could mean e.g. Active Directory server is not reachable.
379 // AuthPolicyCredentialsManager regularly checks TGT status inside the user
380 // session.
381 chromeos::AuthPolicyLoginHelper::TryAuthenticateUser(
382 account_id.GetUserEmail(), account_id.GetObjGuid(), password);
383 }
384
Sarah Hue0e01a52017-10-25 20:29:30385 Shell::Get()->metrics()->login_metrics_recorder()->SetAuthMethod(
386 is_pin ? LoginMetricsRecorder::AuthMethod::kPin
387 : LoginMetricsRecorder::AuthMethod::kPassword);
Jacob Dufaultb7a2d842017-12-01 23:21:15388 login_screen_client_->AuthenticateUser(
Jialiu Linf99b788b2018-01-17 23:01:21389 account_id, hashed_password, sync_password_data, is_pin,
Jacob Dufaultb7a2d842017-12-01 23:21:15390 base::BindOnce(&LoginScreenController::OnAuthenticateComplete,
391 weak_factory_.GetWeakPtr(), base::Passed(&callback)));
jdufaulteb4c9f1e2017-06-08 23:08:30392}
393
Jacob Dufaultb7a2d842017-12-01 23:21:15394void LoginScreenController::OnAuthenticateComplete(
395 OnAuthenticateCallback callback,
396 bool success) {
397 is_authenticating_ = false;
398 std::move(callback).Run(success);
399}
400
401void LoginScreenController::OnGetSystemSalt(PendingDoAuthenticateUser then,
402 const std::string& system_salt) {
403 std::move(then).Run(system_salt);
xiaoyinh2bbdd102017-05-18 23:29:42404}
405
Jacob Dufaultffd9b0d2017-11-15 23:07:16406LoginDataDispatcher* LoginScreenController::DataDispatcher() const {
Jacob Dufault40623d52017-09-15 17:22:53407 if (!ash::LockScreen::IsShown())
408 return nullptr;
409 return ash::LockScreen::Get()->data_dispatcher();
410}
411
Jacob Dufaultcbc1ee02018-02-28 18:38:54412void LoginScreenController::OnShow() {
413 SetSystemTrayVisibility(SystemTrayVisibility::kPrimary);
414 is_authenticating_ = false;
415}
416
xiaoyinh2bbdd102017-05-18 23:29:42417} // namespace ash