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 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 44 EnrollmentScreen::~EnrollmentScreen() {} 45 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 55 void EnrollmentScreen::PrepareToShow() { 56 actor_->PrepareToShow(); 57 } 58 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 72 void EnrollmentScreen::Hide() { 73 actor_->Hide(); 74 weak_ptr_factory_.InvalidateWeakPtrs(); 75 } 76 77 std::string EnrollmentScreen::GetName() const { 78 return WizardController::kEnrollmentScreenName; 79 } 80 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 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 130 void EnrollmentScreen::OnOAuthTokenAvailable( 131 const std::string& token) { 132 RegisterForDevicePolicy(token); 133 } 134 135 void EnrollmentScreen::OnRetry() { 136 actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen, 137 weak_ptr_factory_.GetWeakPtr())); 138 } 139 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 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 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 210 void EnrollmentScreen::ShowEnrollmentStatusOnSuccess( 211 const policy::EnrollmentStatus& status) { 212 actor_->ShowEnrollmentStatus(status); 213 StartupUtils::MarkOobeCompleted(); 214 } 215 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 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 310 void EnrollmentScreen::UMAFailure(policy::MetricEnrollment sample) { 311 if (is_auto_enrollment()) 312 sample = policy::kMetricEnrollmentAutoFailed; 313 UMA(sample); 314 } 315 316 void EnrollmentScreen::ShowSigninScreen() { 317 actor_->Show(); 318 actor_->ShowSigninScreen(); 319 } 320 321 } // namespace chromeos 322