[go: nahoru, domu]

blob: b930b4311be88c500dbe96a06905ad8e63fd5c97 [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"
Aga Wronska16abb432018-01-11 23:49:5911#include "ash/root_window_controller.h"
Sarah Hu069eea12017-09-08 01:28:4012#include "ash/session/session_controller.h"
13#include "ash/shell.h"
Aga Wronska16abb432018-01-11 23:49:5914#include "ash/system/status_area_widget.h"
Sarah Hu069eea12017-09-08 01:28:4015#include "base/strings/string_number_conversions.h"
Jialiu Linf99b788b2018-01-17 23:01:2116#include "base/strings/utf_string_conversions.h"
xiaoyinh2bbdd102017-05-18 23:29:4217#include "chromeos/cryptohome/system_salt_getter.h"
Roman Sorokinc5590012017-09-28 00:48:2918#include "chromeos/login/auth/authpolicy_login_helper.h"
xiaoyinh2bbdd102017-05-18 23:29:4219#include "chromeos/login/auth/user_context.h"
Jialiu Linf99b788b2018-01-17 23:01:2120#include "components/password_manager/core/browser/hash_password_manager.h"
Sarah Hu069eea12017-09-08 01:28:4021#include "components/prefs/pref_registry_simple.h"
22#include "components/prefs/pref_service.h"
Jacob Dufault957e0922017-12-06 19:16:0923#include "components/session_manager/session_manager_types.h"
xiaoyinh2bbdd102017-05-18 23:29:4224
25namespace ash {
26
Sarah Hu069eea12017-09-08 01:28:4027namespace {
xiaoyinh2bbdd102017-05-18 23:29:4228
Sarah Hu069eea12017-09-08 01:28:4029std::string CalculateHash(const std::string& password,
30 const std::string& salt,
31 chromeos::Key::KeyType key_type) {
32 chromeos::Key key(password);
33 key.Transform(key_type, salt);
34 return key.GetSecret();
35}
36
Aga Wronskaa844cdcd12018-01-29 16:06:4437enum class SystemTrayVisibility {
38 kNone, // Tray not visible anywhere.
39 kPrimary, // Tray visible only on primary display.
40 kAll, // Tray visible on all displays.
41};
42
43void SetSystemTrayVisibility(SystemTrayVisibility visibility) {
44 RootWindowController* primary_window_controller =
45 Shell::GetPrimaryRootWindowController();
46 for (RootWindowController* window_controller :
47 Shell::GetAllRootWindowControllers()) {
48 StatusAreaWidget* status_area = window_controller->GetStatusAreaWidget();
49 if (!status_area)
50 continue;
51 if (window_controller == primary_window_controller) {
52 status_area->SetSystemTrayVisibility(
53 visibility == SystemTrayVisibility::kPrimary ||
54 visibility == SystemTrayVisibility::kAll);
55 } else {
56 status_area->SetSystemTrayVisibility(visibility ==
57 SystemTrayVisibility::kAll);
58 }
59 }
Aga Wronska16abb432018-01-11 23:49:5960}
61
Sarah Hu069eea12017-09-08 01:28:4062} // namespace
63
James Cookede316a2017-12-14 22:38:4364LoginScreenController::LoginScreenController() : weak_factory_(this) {}
James Cook8f1e6062017-11-13 23:40:5965
Jacob Dufaultffd9b0d2017-11-15 23:07:1666LoginScreenController::~LoginScreenController() = default;
xiaoyinh2bbdd102017-05-18 23:29:4267
Sarah Hu069eea12017-09-08 01:28:4068// static
Jacob Dufaultffd9b0d2017-11-15 23:07:1669void LoginScreenController::RegisterProfilePrefs(PrefRegistrySimple* registry,
70 bool for_test) {
Sarah Hu069eea12017-09-08 01:28:4071 if (for_test) {
72 // There is no remote pref service, so pretend that ash owns the pref.
73 registry->RegisterStringPref(prefs::kQuickUnlockPinSalt, "");
74 return;
75 }
76
77 // Pref is owned by chrome and flagged as PUBLIC.
78 registry->RegisterForeignPref(prefs::kQuickUnlockPinSalt);
79}
80
Jacob Dufaultffd9b0d2017-11-15 23:07:1681void LoginScreenController::BindRequest(mojom::LoginScreenRequest request) {
James Cookede316a2017-12-14 22:38:4382 bindings_.AddBinding(this, std::move(request));
xiaoyinh2bbdd102017-05-18 23:29:4283}
84
Jacob Dufaultffd9b0d2017-11-15 23:07:1685void LoginScreenController::SetClient(mojom::LoginScreenClientPtr client) {
86 login_screen_client_ = std::move(client);
xiaoyinh2bbdd102017-05-18 23:29:4287}
88
Jacob Dufaultffd9b0d2017-11-15 23:07:1689void LoginScreenController::ShowLockScreen(ShowLockScreenCallback on_shown) {
Jacob Dufault957e0922017-12-06 19:16:0990 ash::LockScreen::Show(ash::LockScreen::ScreenType::kLock);
91 std::move(on_shown).Run(true);
Aga Wronskaa844cdcd12018-01-29 16:06:4492 SetSystemTrayVisibility(SystemTrayVisibility::kPrimary);
Jacob Dufault957e0922017-12-06 19:16:0993}
94
95void LoginScreenController::ShowLoginScreen(ShowLoginScreenCallback on_shown) {
96 // Login screen can only be used during login.
97 if (Shell::Get()->session_controller()->GetSessionState() !=
98 session_manager::SessionState::LOGIN_PRIMARY) {
99 std::move(on_shown).Run(false);
100 return;
101 }
102
103 // TODO(jdufault): rename ash::LockScreen to ash::LoginScreen.
104 ash::LockScreen::Show(ash::LockScreen::ScreenType::kLogin);
jdufaulteb4c9f1e2017-06-08 23:08:30105 std::move(on_shown).Run(true);
Aga Wronskaa844cdcd12018-01-29 16:06:44106 SetSystemTrayVisibility(SystemTrayVisibility::kPrimary);
jdufaulteb4c9f1e2017-06-08 23:08:30107}
108
Jacob Dufaultffd9b0d2017-11-15 23:07:16109void LoginScreenController::ShowErrorMessage(int32_t login_attempts,
110 const std::string& error_text,
111 const std::string& help_link_text,
112 int32_t help_topic_id) {
xiaoyinh2bbdd102017-05-18 23:29:42113 NOTIMPLEMENTED();
114}
115
Jacob Dufaultffd9b0d2017-11-15 23:07:16116void LoginScreenController::ClearErrors() {
xiaoyinh2bbdd102017-05-18 23:29:42117 NOTIMPLEMENTED();
118}
119
Jacob Dufaultffd9b0d2017-11-15 23:07:16120void LoginScreenController::ShowUserPodCustomIcon(
xiaoyinh9f6fa0e2017-06-07 19:22:32121 const AccountId& account_id,
Jacob Dufaultc5738ca2017-10-16 23:18:16122 mojom::EasyUnlockIconOptionsPtr icon) {
Jacob Dufaulta0225592017-10-17 21:53:38123 DataDispatcher()->ShowEasyUnlockIcon(account_id, icon);
xiaoyinh9f6fa0e2017-06-07 19:22:32124}
125
Jacob Dufaultffd9b0d2017-11-15 23:07:16126void LoginScreenController::HideUserPodCustomIcon(const AccountId& account_id) {
Jacob Dufaulta0225592017-10-17 21:53:38127 auto icon_options = mojom::EasyUnlockIconOptions::New();
128 icon_options->icon = mojom::EasyUnlockIconId::NONE;
129 DataDispatcher()->ShowEasyUnlockIcon(account_id, icon_options);
xiaoyinh9f6fa0e2017-06-07 19:22:32130}
131
Jacob Dufaultffd9b0d2017-11-15 23:07:16132void LoginScreenController::SetAuthType(
xiaoyinh820778c52017-06-21 01:42:51133 const AccountId& account_id,
134 proximity_auth::mojom::AuthType auth_type,
135 const base::string16& initial_value) {
Jacob Dufaulta0225592017-10-17 21:53:38136 if (auth_type == proximity_auth::mojom::AuthType::USER_CLICK) {
137 DataDispatcher()->SetClickToUnlockEnabledForUser(account_id,
138 true /*enabled*/);
139 } else {
140 NOTIMPLEMENTED();
141 }
xiaoyinh9f6fa0e2017-06-07 19:22:32142}
143
Jacob Dufaultffd9b0d2017-11-15 23:07:16144void LoginScreenController::LoadUsers(
145 std::vector<mojom::LoginUserInfoPtr> users,
146 bool show_guest) {
Jacob Dufault40623d52017-09-15 17:22:53147 DCHECK(DataDispatcher());
148
Sarah Huf3a99dd02017-10-03 22:04:11149 DataDispatcher()->NotifyUsers(users);
xiaoyinh9f6fa0e2017-06-07 19:22:32150}
151
Jacob Dufaultffd9b0d2017-11-15 23:07:16152void LoginScreenController::SetPinEnabledForUser(const AccountId& account_id,
153 bool is_enabled) {
Sarah Hu069eea12017-09-08 01:28:40154 // Chrome will update pin pod state every time user tries to authenticate.
155 // LockScreen is destroyed in the case of authentication success.
Jacob Dufault40623d52017-09-15 17:22:53156 if (DataDispatcher())
157 DataDispatcher()->SetPinEnabledForUser(account_id, is_enabled);
xiaoyinhf534c4f2017-06-13 20:50:27158}
159
Wenzhao Zanga05dcefc2017-11-30 05:50:03160void LoginScreenController::SetDevChannelInfo(
161 const std::string& os_version_label_text,
162 const std::string& enterprise_info_text,
163 const std::string& bluetooth_name) {
164 if (DataDispatcher()) {
165 DataDispatcher()->SetDevChannelInfo(os_version_label_text,
166 enterprise_info_text, bluetooth_name);
167 }
168}
169
Sarah Hu0bfd1872017-12-12 18:00:05170void LoginScreenController::IsReadyForPassword(
171 IsReadyForPasswordCallback callback) {
172 std::move(callback).Run(LockScreen::IsShown() && !is_authenticating_);
173}
174
Jacob Dufaultb7a2d842017-12-01 23:21:15175void LoginScreenController::AuthenticateUser(const AccountId& account_id,
176 const std::string& password,
177 bool authenticated_by_pin,
178 OnAuthenticateCallback callback) {
179 // Ignore concurrent auth attempts. This can happen if the user quickly enters
180 // two separate passwords and hits enter.
181 if (!login_screen_client_ || is_authenticating_) {
182 LOG_IF(ERROR, is_authenticating_) << "Ignoring concurrent auth attempt";
183 std::move(callback).Run(base::nullopt);
xiaoyinh9f6fa0e2017-06-07 19:22:32184 return;
Jacob Dufaultb7a2d842017-12-01 23:21:15185 }
186 is_authenticating_ = true;
xiaoyinh9f6fa0e2017-06-07 19:22:32187
Jacob Dufaulteafc6fe2017-10-11 21:16:52188 // If auth is disabled by the debug overlay bypass the mojo call entirely, as
189 // it will dismiss the lock screen if the password is correct.
Jacob Dufault0fbed9c02017-11-14 19:22:24190 switch (force_fail_auth_for_debug_overlay_) {
191 case ForceFailAuth::kOff:
192 break;
193 case ForceFailAuth::kImmediate:
Jacob Dufaultb7a2d842017-12-01 23:21:15194 OnAuthenticateComplete(std::move(callback), false /*success*/);
Jacob Dufault0fbed9c02017-11-14 19:22:24195 return;
196 case ForceFailAuth::kDelayed:
197 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Jacob Dufaultb7a2d842017-12-01 23:21:15198 FROM_HERE,
199 base::BindOnce(&LoginScreenController::OnAuthenticateComplete,
200 weak_factory_.GetWeakPtr(), base::Passed(&callback),
201 false),
Jacob Dufault0fbed9c02017-11-14 19:22:24202 base::TimeDelta::FromSeconds(1));
203 return;
Jacob Dufaulteafc6fe2017-10-11 21:16:52204 }
205
Jacob Dufaultb7a2d842017-12-01 23:21:15206 // |DoAuthenticateUser| requires the system salt, so we fetch it first, and
207 // then run |DoAuthenticateUser| as a continuation.
208 auto do_authenticate = base::BindOnce(
209 &LoginScreenController::DoAuthenticateUser, weak_factory_.GetWeakPtr(),
jdufaulteb4c9f1e2017-06-08 23:08:30210 account_id, password, authenticated_by_pin, std::move(callback));
Jacob Dufaultb7a2d842017-12-01 23:21:15211 chromeos::SystemSaltGetter::Get()->GetSystemSalt(base::BindRepeating(
212 &LoginScreenController::OnGetSystemSalt, weak_factory_.GetWeakPtr(),
213 base::Passed(&do_authenticate)));
xiaoyinh9f6fa0e2017-06-07 19:22:32214}
215
Jacob Dufaultffd9b0d2017-11-15 23:07:16216void LoginScreenController::HandleFocusLeavingLockScreenApps(bool reverse) {
Toni Barzicf61c4452017-10-05 03:57:48217 for (auto& observer : lock_screen_apps_focus_observers_)
218 observer.OnFocusLeavingLockScreenApps(reverse);
219}
220
Jacob Dufaultffd9b0d2017-11-15 23:07:16221void LoginScreenController::AttemptUnlock(const AccountId& account_id) {
222 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32223 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16224 login_screen_client_->AttemptUnlock(account_id);
Sarah Hue0e01a52017-10-25 20:29:30225
226 Shell::Get()->metrics()->login_metrics_recorder()->SetAuthMethod(
227 LoginMetricsRecorder::AuthMethod::kSmartlock);
xiaoyinh9f6fa0e2017-06-07 19:22:32228}
229
Jacob Dufaultffd9b0d2017-11-15 23:07:16230void LoginScreenController::HardlockPod(const AccountId& account_id) {
231 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32232 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16233 login_screen_client_->HardlockPod(account_id);
xiaoyinh9f6fa0e2017-06-07 19:22:32234}
235
Jacob Dufaultffd9b0d2017-11-15 23:07:16236void LoginScreenController::RecordClickOnLockIcon(const AccountId& account_id) {
237 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32238 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16239 login_screen_client_->RecordClickOnLockIcon(account_id);
xiaoyinh9f6fa0e2017-06-07 19:22:32240}
241
Jacob Dufaultffd9b0d2017-11-15 23:07:16242void LoginScreenController::OnFocusPod(const AccountId& account_id) {
243 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27244 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16245 login_screen_client_->OnFocusPod(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27246}
247
Jacob Dufaultffd9b0d2017-11-15 23:07:16248void LoginScreenController::OnNoPodFocused() {
249 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27250 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16251 login_screen_client_->OnNoPodFocused();
xiaoyinhf534c4f2017-06-13 20:50:27252}
253
Jacob Dufaultffd9b0d2017-11-15 23:07:16254void LoginScreenController::LoadWallpaper(const AccountId& account_id) {
255 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27256 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16257 login_screen_client_->LoadWallpaper(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27258}
259
Jacob Dufaultffd9b0d2017-11-15 23:07:16260void LoginScreenController::SignOutUser() {
261 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27262 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16263 login_screen_client_->SignOutUser();
xiaoyinhf534c4f2017-06-13 20:50:27264}
265
Jacob Dufaultffd9b0d2017-11-15 23:07:16266void LoginScreenController::CancelAddUser() {
267 if (!login_screen_client_)
Wenzhao Zang16e7ea722017-09-16 01:27:30268 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16269 login_screen_client_->CancelAddUser();
Wenzhao Zang16e7ea722017-09-16 01:27:30270}
271
Aga Wronska6a32f9872018-01-06 00:16:10272void LoginScreenController::LoginAsGuest() {
273 if (!login_screen_client_)
274 return;
275 login_screen_client_->LoginAsGuest();
276}
277
Jacob Dufaultffd9b0d2017-11-15 23:07:16278void LoginScreenController::OnMaxIncorrectPasswordAttempted(
xiaoyinhf534c4f2017-06-13 20:50:27279 const AccountId& account_id) {
Jacob Dufaultffd9b0d2017-11-15 23:07:16280 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27281 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16282 login_screen_client_->OnMaxIncorrectPasswordAttempted(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27283}
284
Jacob Dufaultffd9b0d2017-11-15 23:07:16285void LoginScreenController::FocusLockScreenApps(bool reverse) {
286 if (!login_screen_client_)
Toni Barzicf61c4452017-10-05 03:57:48287 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16288 login_screen_client_->FocusLockScreenApps(reverse);
Toni Barzicf61c4452017-10-05 03:57:48289}
290
Sarah Hu9fba0e752018-02-07 01:41:09291void LoginScreenController::ShowGaiaSignin() {
292 if (!login_screen_client_)
293 return;
294 login_screen_client_->ShowGaiaSignin();
295}
296
Jacob Dufaultffd9b0d2017-11-15 23:07:16297void LoginScreenController::AddLockScreenAppsFocusObserver(
Toni Barzicf61c4452017-10-05 03:57:48298 LockScreenAppsFocusObserver* observer) {
299 lock_screen_apps_focus_observers_.AddObserver(observer);
300}
301
Jacob Dufaultffd9b0d2017-11-15 23:07:16302void LoginScreenController::RemoveLockScreenAppsFocusObserver(
Toni Barzicf61c4452017-10-05 03:57:48303 LockScreenAppsFocusObserver* observer) {
304 lock_screen_apps_focus_observers_.RemoveObserver(observer);
305}
306
Jacob Dufaultffd9b0d2017-11-15 23:07:16307void LoginScreenController::FlushForTesting() {
308 login_screen_client_.FlushForTesting();
Toni Barzicf61c4452017-10-05 03:57:48309}
310
Jacob Dufaultb7a2d842017-12-01 23:21:15311void LoginScreenController::DoAuthenticateUser(const AccountId& account_id,
312 const std::string& password,
313 bool authenticated_by_pin,
314 OnAuthenticateCallback callback,
315 const std::string& system_salt) {
Sarah Hu069eea12017-09-08 01:28:40316 int dummy_value;
317 bool is_pin =
318 authenticated_by_pin && base::StringToInt(password, &dummy_value);
319 std::string hashed_password = CalculateHash(
320 password, system_salt, chromeos::Key::KEY_TYPE_SALTED_SHA256_TOP_HALF);
321
Jialiu Linf99b788b2018-01-17 23:01:21322 // Used for GAIA password reuse detection.
323 password_manager::SyncPasswordData sync_password_data(
324 base::UTF8ToUTF16(password), /*force_update=*/false);
325
Sarah Hu069eea12017-09-08 01:28:40326 PrefService* prefs =
327 Shell::Get()->session_controller()->GetLastActiveUserPrefService();
328 if (is_pin && prefs) {
329 hashed_password =
330 CalculateHash(password, prefs->GetString(prefs::kQuickUnlockPinSalt),
331 chromeos::Key::KEY_TYPE_SALTED_PBKDF2_AES256_1234);
332 }
333
Roman Sorokinc5590012017-09-28 00:48:29334 if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY && !is_pin) {
335 // Try to get kerberos TGT while we have user's password typed on the lock
336 // screen. Using invalid/bad password is fine. Failure to get TGT here is OK
337 // - that could mean e.g. Active Directory server is not reachable.
338 // AuthPolicyCredentialsManager regularly checks TGT status inside the user
339 // session.
340 chromeos::AuthPolicyLoginHelper::TryAuthenticateUser(
341 account_id.GetUserEmail(), account_id.GetObjGuid(), password);
342 }
343
Sarah Hue0e01a52017-10-25 20:29:30344 Shell::Get()->metrics()->login_metrics_recorder()->SetAuthMethod(
345 is_pin ? LoginMetricsRecorder::AuthMethod::kPin
346 : LoginMetricsRecorder::AuthMethod::kPassword);
Jacob Dufaultb7a2d842017-12-01 23:21:15347 login_screen_client_->AuthenticateUser(
Jialiu Linf99b788b2018-01-17 23:01:21348 account_id, hashed_password, sync_password_data, is_pin,
Jacob Dufaultb7a2d842017-12-01 23:21:15349 base::BindOnce(&LoginScreenController::OnAuthenticateComplete,
350 weak_factory_.GetWeakPtr(), base::Passed(&callback)));
jdufaulteb4c9f1e2017-06-08 23:08:30351}
352
Jacob Dufaultb7a2d842017-12-01 23:21:15353void LoginScreenController::OnAuthenticateComplete(
354 OnAuthenticateCallback callback,
355 bool success) {
356 is_authenticating_ = false;
357 std::move(callback).Run(success);
358}
359
360void LoginScreenController::OnGetSystemSalt(PendingDoAuthenticateUser then,
361 const std::string& system_salt) {
362 std::move(then).Run(system_salt);
xiaoyinh2bbdd102017-05-18 23:29:42363}
364
Jacob Dufaultffd9b0d2017-11-15 23:07:16365LoginDataDispatcher* LoginScreenController::DataDispatcher() const {
Jacob Dufault40623d52017-09-15 17:22:53366 if (!ash::LockScreen::IsShown())
367 return nullptr;
368 return ash::LockScreen::Get()->data_dispatcher();
369}
370
xiaoyinh2bbdd102017-05-18 23:29:42371} // namespace ash