• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 
5 #include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h"
6 
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/metrics/histogram.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/login/login_utils.h"
14 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
15 #include "chrome/browser/chromeos/login/startup_utils.h"
16 #include "chrome/browser/chromeos/login/wizard_controller.h"
17 #include "chrome/browser/chromeos/policy/auto_enrollment_client.h"
18 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
19 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
20 #include "chromeos/dbus/cryptohome_client.h"
21 #include "chromeos/dbus/dbus_method_call_status.h"
22 #include "chromeos/dbus/dbus_thread_manager.h"
23 #include "chromeos/dbus/session_manager_client.h"
24 #include "google_apis/gaia/gaia_auth_util.h"
25 #include "google_apis/gaia/google_service_auth_error.h"
26 
27 namespace chromeos {
28 
EnrollmentScreen(ScreenObserver * observer,EnrollmentScreenActor * actor)29 EnrollmentScreen::EnrollmentScreen(
30     ScreenObserver* observer,
31     EnrollmentScreenActor* actor)
32     : WizardScreen(observer),
33       actor_(actor),
34       enrollment_mode_(EnrollmentScreenActor::ENROLLMENT_MODE_MANUAL),
35       enrollment_failed_once_(false),
36       lockbox_init_duration_(0),
37       weak_ptr_factory_(this) {
38   // Init the TPM if it has not been done until now (in debug build we might
39   // have not done that yet).
40   DBusThreadManager::Get()->GetCryptohomeClient()->TpmCanAttemptOwnership(
41       EmptyVoidDBusMethodCallback());
42 }
43 
~EnrollmentScreen()44 EnrollmentScreen::~EnrollmentScreen() {}
45 
SetParameters(EnrollmentScreenActor::EnrollmentMode enrollment_mode,const std::string & management_domain,const std::string & user)46 void EnrollmentScreen::SetParameters(
47     EnrollmentScreenActor::EnrollmentMode enrollment_mode,
48     const std::string& management_domain,
49     const std::string& user) {
50   enrollment_mode_ = enrollment_mode;
51   user_ = user.empty() ? user : gaia::CanonicalizeEmail(user);
52   actor_->SetParameters(this, enrollment_mode_, management_domain);
53 }
54 
PrepareToShow()55 void EnrollmentScreen::PrepareToShow() {
56   actor_->PrepareToShow();
57 }
58 
Show()59 void EnrollmentScreen::Show() {
60   if (is_auto_enrollment() && !enrollment_failed_once_) {
61     actor_->Show();
62     UMA(policy::kMetricEnrollmentAutoStarted);
63     actor_->ShowEnrollmentSpinnerScreen();
64     actor_->FetchOAuthToken();
65   } else {
66     UMA(policy::kMetricEnrollmentTriggered);
67     actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen,
68                                  weak_ptr_factory_.GetWeakPtr()));
69   }
70 }
71 
Hide()72 void EnrollmentScreen::Hide() {
73   actor_->Hide();
74   weak_ptr_factory_.InvalidateWeakPtrs();
75 }
76 
GetName() const77 std::string EnrollmentScreen::GetName() const {
78   return WizardController::kEnrollmentScreenName;
79 }
80 
OnLoginDone(const std::string & user)81 void EnrollmentScreen::OnLoginDone(const std::string& user) {
82   user_ = gaia::CanonicalizeEmail(user);
83 
84   if (is_auto_enrollment())
85     UMA(policy::kMetricEnrollmentAutoRetried);
86   else if (enrollment_failed_once_)
87     UMA(policy::kMetricEnrollmentRetried);
88   else
89     UMA(policy::kMetricEnrollmentStarted);
90 
91   actor_->ShowEnrollmentSpinnerScreen();
92   actor_->FetchOAuthToken();
93 }
94 
OnAuthError(const GoogleServiceAuthError & error)95 void EnrollmentScreen::OnAuthError(const GoogleServiceAuthError& error) {
96   enrollment_failed_once_ = true;
97   actor_->ShowAuthError(error);
98 
99   switch (error.state()) {
100     case GoogleServiceAuthError::NONE:
101     case GoogleServiceAuthError::CAPTCHA_REQUIRED:
102     case GoogleServiceAuthError::TWO_FACTOR:
103     case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
104     case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
105     case GoogleServiceAuthError::REQUEST_CANCELED:
106     case GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE:
107     case GoogleServiceAuthError::SERVICE_ERROR:
108       UMAFailure(policy::kMetricEnrollmentLoginFailed);
109       LOG(ERROR) << "Auth error " << error.state();
110       return;
111     case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
112     case GoogleServiceAuthError::ACCOUNT_DELETED:
113     case GoogleServiceAuthError::ACCOUNT_DISABLED:
114       UMAFailure(policy::kMetricEnrollmentNotSupported);
115       LOG(ERROR) << "Account error " << error.state();
116       return;
117     case GoogleServiceAuthError::CONNECTION_FAILED:
118     case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
119       UMAFailure(policy::kMetricEnrollmentNetworkFailed);
120       LOG(WARNING) << "Network error " << error.state();
121       return;
122     case GoogleServiceAuthError::NUM_STATES:
123       break;
124   }
125 
126   NOTREACHED();
127   UMAFailure(policy::kMetricEnrollmentOtherFailed);
128 }
129 
OnOAuthTokenAvailable(const std::string & token)130 void EnrollmentScreen::OnOAuthTokenAvailable(
131     const std::string& token) {
132   RegisterForDevicePolicy(token);
133 }
134 
OnRetry()135 void EnrollmentScreen::OnRetry() {
136   actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen,
137                                weak_ptr_factory_.GetWeakPtr()));
138 }
139 
OnCancel()140 void EnrollmentScreen::OnCancel() {
141   if (enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_FORCED ||
142       enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_RECOVERY) {
143     actor_->ResetAuth(
144         base::Bind(&ScreenObserver::OnExit,
145                    base::Unretained(get_screen_observer()),
146                    ScreenObserver::ENTERPRISE_ENROLLMENT_BACK));
147     return;
148   }
149 
150   if (is_auto_enrollment())
151     policy::AutoEnrollmentClient::CancelAutoEnrollment();
152   UMA(is_auto_enrollment() ? policy::kMetricEnrollmentAutoCancelled
153                            : policy::kMetricEnrollmentCancelled);
154   actor_->ResetAuth(
155       base::Bind(&ScreenObserver::OnExit,
156                  base::Unretained(get_screen_observer()),
157                  ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
158 }
159 
OnConfirmationClosed()160 void EnrollmentScreen::OnConfirmationClosed() {
161   // If the machine has been put in KIOSK mode we have to restart the session
162   // here to go in the proper KIOSK mode login screen.
163   policy::BrowserPolicyConnectorChromeOS* connector =
164       g_browser_process->platform_part()->browser_policy_connector_chromeos();
165   if (connector->GetDeviceMode() == policy::DEVICE_MODE_RETAIL_KIOSK) {
166     DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
167     return;
168   }
169 
170   if (is_auto_enrollment() &&
171       !enrollment_failed_once_ &&
172       !user_.empty() &&
173       LoginUtils::IsWhitelisted(user_, NULL)) {
174     actor_->ShowLoginSpinnerScreen();
175     get_screen_observer()->OnExit(
176         ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
177   } else {
178     actor_->ResetAuth(
179         base::Bind(&ScreenObserver::OnExit,
180                    base::Unretained(get_screen_observer()),
181                    ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
182   }
183 }
184 
RegisterForDevicePolicy(const std::string & token)185 void EnrollmentScreen::RegisterForDevicePolicy(
186     const std::string& token) {
187   policy::BrowserPolicyConnectorChromeOS* connector =
188       g_browser_process->platform_part()->browser_policy_connector_chromeos();
189   if (connector->IsEnterpriseManaged() &&
190       connector->GetEnterpriseDomain() != gaia::ExtractDomainName(user_)) {
191     LOG(ERROR) << "Trying to re-enroll to a different domain than "
192                << connector->GetEnterpriseDomain();
193     UMAFailure(policy::kMetricEnrollmentWrongUserError);
194     actor_->ShowUIError(
195         EnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH);
196     return;
197   }
198 
199   policy::DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes device_modes;
200   device_modes[policy::DEVICE_MODE_ENTERPRISE] = true;
201   device_modes[policy::DEVICE_MODE_RETAIL_KIOSK] =
202       enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_MANUAL;
203   connector->ScheduleServiceInitialization(0);
204   connector->GetDeviceCloudPolicyManager()->StartEnrollment(
205       token, is_auto_enrollment(), device_modes,
206       base::Bind(&EnrollmentScreen::ReportEnrollmentStatus,
207                  weak_ptr_factory_.GetWeakPtr()));
208 }
209 
ShowEnrollmentStatusOnSuccess(const policy::EnrollmentStatus & status)210 void EnrollmentScreen::ShowEnrollmentStatusOnSuccess(
211     const policy::EnrollmentStatus& status) {
212   actor_->ShowEnrollmentStatus(status);
213   StartupUtils::MarkOobeCompleted();
214 }
215 
ReportEnrollmentStatus(policy::EnrollmentStatus status)216 void EnrollmentScreen::ReportEnrollmentStatus(
217     policy::EnrollmentStatus status) {
218   bool success = status.status() == policy::EnrollmentStatus::STATUS_SUCCESS;
219   enrollment_failed_once_ |= !success;
220   if (status.status() == policy::EnrollmentStatus::STATUS_SUCCESS) {
221     StartupUtils::MarkDeviceRegistered(
222         base::Bind(&EnrollmentScreen::ShowEnrollmentStatusOnSuccess,
223                    weak_ptr_factory_.GetWeakPtr(),
224                    status));
225     UMA(is_auto_enrollment() ? policy::kMetricEnrollmentAutoOK
226                              : policy::kMetricEnrollmentOK);
227     return;
228   }
229   actor_->ShowEnrollmentStatus(status);
230 
231   switch (status.status()) {
232     case policy::EnrollmentStatus::STATUS_REGISTRATION_FAILED:
233     case policy::EnrollmentStatus::STATUS_POLICY_FETCH_FAILED:
234       switch (status.client_status()) {
235         case policy::DM_STATUS_SUCCESS:
236         case policy::DM_STATUS_REQUEST_INVALID:
237         case policy::DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
238         case policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
239         case policy::DM_STATUS_SERVICE_ACTIVATION_PENDING:
240         case policy::DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
241         case policy::DM_STATUS_SERVICE_POLICY_NOT_FOUND:
242           UMAFailure(policy::kMetricEnrollmentOtherFailed);
243           return;
244         case policy::DM_STATUS_REQUEST_FAILED:
245         case policy::DM_STATUS_TEMPORARY_UNAVAILABLE:
246         case policy::DM_STATUS_HTTP_STATUS_ERROR:
247         case policy::DM_STATUS_RESPONSE_DECODING_ERROR:
248           UMAFailure(policy::kMetricEnrollmentNetworkFailed);
249           return;
250         case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
251           UMAFailure(policy::kMetricEnrollmentNotSupported);
252           return;
253         case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
254           UMAFailure(policy::kMetricEnrollmentInvalidSerialNumber);
255           return;
256         case policy::DM_STATUS_SERVICE_MISSING_LICENSES:
257           UMAFailure(policy::kMetricMissingLicensesError);
258           return;
259         case policy::DM_STATUS_SERVICE_DEPROVISIONED:
260           UMAFailure(policy::kMetricEnrollmentDeprovisioned);
261           return;
262         case policy::DM_STATUS_SERVICE_DOMAIN_MISMATCH:
263           UMAFailure(policy::kMetricEnrollmentDomainMismatch);
264           return;
265       }
266       break;
267     case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE:
268       UMAFailure(policy::kMetricEnrollmentInvalidEnrollmentMode);
269       return;
270     case policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT:
271       UMAFailure(policy::kMetricLockboxTimeoutError);
272       return;
273     case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER:
274       UMAFailure(policy::kMetricEnrollmentWrongUserError);
275       return;
276     case policy::EnrollmentStatus::STATUS_NO_STATE_KEYS:
277     case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED:
278     case policy::EnrollmentStatus::STATUS_STORE_ERROR:
279     case policy::EnrollmentStatus::STATUS_LOCK_ERROR:
280       UMAFailure(policy::kMetricEnrollmentOtherFailed);
281       return;
282     case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED:
283       UMAFailure(policy::kMetricEnrollmentRobotAuthCodeFetchFailed);
284       return;
285     case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED:
286       UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed);
287       return;
288     case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED:
289       UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed);
290       return;
291     case policy::EnrollmentStatus::STATUS_SUCCESS:
292       NOTREACHED();
293       return;
294   }
295 
296   NOTREACHED();
297   UMAFailure(policy::kMetricEnrollmentOtherFailed);
298 }
299 
UMA(policy::MetricEnrollment sample)300 void EnrollmentScreen::UMA(policy::MetricEnrollment sample) {
301   if (enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_RECOVERY) {
302     UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollmentRecovery, sample,
303                               policy::kMetricEnrollmentSize);
304   } else {
305     UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment, sample,
306                               policy::kMetricEnrollmentSize);
307   }
308 }
309 
UMAFailure(policy::MetricEnrollment sample)310 void EnrollmentScreen::UMAFailure(policy::MetricEnrollment sample) {
311   if (is_auto_enrollment())
312     sample = policy::kMetricEnrollmentAutoFailed;
313   UMA(sample);
314 }
315 
ShowSigninScreen()316 void EnrollmentScreen::ShowSigninScreen() {
317   actor_->Show();
318   actor_->ShowSigninScreen();
319 }
320 
321 }  // namespace chromeos
322