| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_screen.
h" | 5 #include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_screen.
h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
| 13 #include "chrome/browser/chromeos/cros/cros_library.h" | 13 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 14 #include "chrome/browser/chromeos/cros/cryptohome_library.h" | 14 #include "chrome/browser/chromeos/cros/cryptohome_library.h" |
| 15 #include "chrome/browser/chromeos/login/login_utils.h" | 15 #include "chrome/browser/chromeos/login/login_utils.h" |
| 16 #include "chrome/browser/chromeos/login/screen_observer.h" | 16 #include "chrome/browser/chromeos/login/screen_observer.h" |
| 17 #include "chrome/browser/chromeos/login/wizard_controller.h" | 17 #include "chrome/browser/chromeos/login/wizard_controller.h" |
| 18 #include "chrome/browser/policy/auto_enrollment_client.h" | 18 #include "chrome/browser/policy/auto_enrollment_client.h" |
| 19 #include "chrome/browser/policy/browser_policy_connector.h" | 19 #include "chrome/browser/policy/browser_policy_connector.h" |
| 20 #include "chrome/browser/policy/cloud_policy_data_store.h" | |
| 21 #include "chrome/browser/policy/device_cloud_policy_manager_chromeos.h" | 20 #include "chrome/browser/policy/device_cloud_policy_manager_chromeos.h" |
| 22 #include "chrome/browser/policy/enterprise_metrics.h" | 21 #include "chrome/browser/policy/enterprise_metrics.h" |
| 23 #include "chromeos/dbus/dbus_thread_manager.h" | 22 #include "chromeos/dbus/dbus_thread_manager.h" |
| 24 #include "chromeos/dbus/session_manager_client.h" | 23 #include "chromeos/dbus/session_manager_client.h" |
| 25 #include "google_apis/gaia/gaia_auth_util.h" | 24 #include "google_apis/gaia/gaia_auth_util.h" |
| 26 #include "google_apis/gaia/google_service_auth_error.h" | 25 #include "google_apis/gaia/google_service_auth_error.h" |
| 27 | 26 |
| 28 namespace chromeos { | 27 namespace chromeos { |
| 29 | 28 |
| 30 namespace { | 29 namespace { |
| 31 | 30 |
| 32 // Retry for InstallAttrs initialization every 500ms. | |
| 33 const int kLockRetryIntervalMs = 500; | |
| 34 // Maximum time to retry InstallAttrs initialization before we give up. | |
| 35 const int kLockRetryTimeoutMs = 10 * 60 * 1000; // 10 minutes. | |
| 36 | |
| 37 void UMA(int sample) { | 31 void UMA(int sample) { |
| 38 UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment, | 32 UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment, |
| 39 sample, | 33 sample, |
| 40 policy::kMetricEnrollmentSize); | 34 policy::kMetricEnrollmentSize); |
| 41 } | 35 } |
| 42 | 36 |
| 43 } // namespace | 37 } // namespace |
| 44 | 38 |
| 45 EnterpriseEnrollmentScreen::EnterpriseEnrollmentScreen( | 39 EnterpriseEnrollmentScreen::EnterpriseEnrollmentScreen( |
| 46 ScreenObserver* observer, | 40 ScreenObserver* observer, |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 get_screen_observer()->OnExit( | 175 get_screen_observer()->OnExit( |
| 182 ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED); | 176 ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED); |
| 183 } else { | 177 } else { |
| 184 actor_->ResetAuth( | 178 actor_->ResetAuth( |
| 185 base::Bind(&ScreenObserver::OnExit, | 179 base::Bind(&ScreenObserver::OnExit, |
| 186 base::Unretained(get_screen_observer()), | 180 base::Unretained(get_screen_observer()), |
| 187 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED)); | 181 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED)); |
| 188 } | 182 } |
| 189 } | 183 } |
| 190 | 184 |
| 191 void EnterpriseEnrollmentScreen::OnPolicyStateChanged( | |
| 192 policy::CloudPolicySubsystem::PolicySubsystemState state, | |
| 193 policy::CloudPolicySubsystem::ErrorDetails error_details) { | |
| 194 | |
| 195 switch (state) { | |
| 196 case policy::CloudPolicySubsystem::UNENROLLED: | |
| 197 switch (error_details) { | |
| 198 case policy::CloudPolicySubsystem::BAD_SERIAL_NUMBER: | |
| 199 ReportEnrollmentStatus( | |
| 200 policy::EnrollmentStatus::ForRegistrationError( | |
| 201 policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER)); | |
| 202 break; | |
| 203 case policy::CloudPolicySubsystem::BAD_ENROLLMENT_MODE: | |
| 204 ReportEnrollmentStatus( | |
| 205 policy::EnrollmentStatus::ForStatus( | |
| 206 policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE)); | |
| 207 break; | |
| 208 case policy::CloudPolicySubsystem::MISSING_LICENSES: | |
| 209 ReportEnrollmentStatus( | |
| 210 policy::EnrollmentStatus::ForRegistrationError( | |
| 211 policy::DM_STATUS_SERVICE_MISSING_LICENSES)); | |
| 212 break; | |
| 213 default: // Still working... | |
| 214 return; | |
| 215 } | |
| 216 break; | |
| 217 case policy::CloudPolicySubsystem::BAD_GAIA_TOKEN: | |
| 218 ReportEnrollmentStatus( | |
| 219 policy::EnrollmentStatus::ForRegistrationError( | |
| 220 policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID)); | |
| 221 break; | |
| 222 case policy::CloudPolicySubsystem::LOCAL_ERROR: | |
| 223 ReportEnrollmentStatus( | |
| 224 policy::EnrollmentStatus::ForStoreError( | |
| 225 policy::CloudPolicyStore::STATUS_STORE_ERROR, | |
| 226 policy::CloudPolicyValidatorBase::VALIDATION_OK)); | |
| 227 break; | |
| 228 case policy::CloudPolicySubsystem::UNMANAGED: | |
| 229 ReportEnrollmentStatus( | |
| 230 policy::EnrollmentStatus::ForRegistrationError( | |
| 231 policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED)); | |
| 232 break; | |
| 233 case policy::CloudPolicySubsystem::NETWORK_ERROR: | |
| 234 ReportEnrollmentStatus( | |
| 235 policy::EnrollmentStatus::ForRegistrationError( | |
| 236 policy::DM_STATUS_REQUEST_FAILED)); | |
| 237 break; | |
| 238 case policy::CloudPolicySubsystem::TOKEN_FETCHED: | |
| 239 if (!is_auto_enrollment_ || | |
| 240 g_browser_process->browser_policy_connector()-> | |
| 241 GetDeviceCloudPolicyDataStore()->device_mode() == | |
| 242 policy::DEVICE_MODE_ENTERPRISE) { | |
| 243 WriteInstallAttributesData(); | |
| 244 return; | |
| 245 } else { | |
| 246 LOG(ERROR) << "Enrollment cannot proceed because Auto-enrollment is " | |
| 247 << "not supported for non-enterprise enrollment modes."; | |
| 248 policy::AutoEnrollmentClient::CancelAutoEnrollment(); | |
| 249 is_auto_enrollment_ = false; | |
| 250 UMAFailure(policy::kMetricEnrollmentAutoEnrollmentNotSupported); | |
| 251 actor_->ShowUIError( | |
| 252 EnterpriseEnrollmentScreenActor::UI_ERROR_AUTO_ENROLLMENT_BAD_MODE); | |
| 253 NotifyTestingObservers(false); | |
| 254 // Set the error state to something distinguishable in the logs. | |
| 255 state = policy::CloudPolicySubsystem::LOCAL_ERROR; | |
| 256 error_details = policy::CloudPolicySubsystem::AUTO_ENROLLMENT_ERROR; | |
| 257 } | |
| 258 break; | |
| 259 case policy::CloudPolicySubsystem::SUCCESS: | |
| 260 // Success! | |
| 261 registrar_.reset(); | |
| 262 ReportEnrollmentStatus( | |
| 263 policy::EnrollmentStatus::ForStatus( | |
| 264 policy::EnrollmentStatus::STATUS_SUCCESS)); | |
| 265 return; | |
| 266 } | |
| 267 | |
| 268 // We have an error. | |
| 269 if (!is_auto_enrollment_) | |
| 270 UMAFailure(policy::kMetricEnrollmentPolicyFailed); | |
| 271 | |
| 272 LOG(WARNING) << "Policy subsystem error during enrollment: " << state | |
| 273 << " details: " << error_details; | |
| 274 | |
| 275 // Stop the policy infrastructure. | |
| 276 registrar_.reset(); | |
| 277 g_browser_process->browser_policy_connector()->ResetDevicePolicy(); | |
| 278 } | |
| 279 | |
| 280 void EnterpriseEnrollmentScreen::AddTestingObserver(TestingObserver* observer) { | 185 void EnterpriseEnrollmentScreen::AddTestingObserver(TestingObserver* observer) { |
| 281 observers_.AddObserver(observer); | 186 observers_.AddObserver(observer); |
| 282 } | 187 } |
| 283 | 188 |
| 284 void EnterpriseEnrollmentScreen::RemoveTestingObserver( | 189 void EnterpriseEnrollmentScreen::RemoveTestingObserver( |
| 285 TestingObserver* observer) { | 190 TestingObserver* observer) { |
| 286 observers_.RemoveObserver(observer); | 191 observers_.RemoveObserver(observer); |
| 287 } | 192 } |
| 288 | 193 |
| 289 void EnterpriseEnrollmentScreen::WriteInstallAttributesData() { | |
| 290 // Since this method is also called directly. | |
| 291 weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 292 | |
| 293 switch (g_browser_process->browser_policy_connector()->LockDevice(user_)) { | |
| 294 case policy::EnterpriseInstallAttributes::LOCK_SUCCESS: { | |
| 295 // Proceed with policy fetch. | |
| 296 policy::BrowserPolicyConnector* connector = | |
| 297 g_browser_process->browser_policy_connector(); | |
| 298 connector->FetchCloudPolicy(); | |
| 299 return; | |
| 300 } | |
| 301 case policy::EnterpriseInstallAttributes::LOCK_NOT_READY: { | |
| 302 // We wait up to |kLockRetryTimeoutMs| milliseconds and if it hasn't | |
| 303 // succeeded by then show an error to the user and stop the enrollment. | |
| 304 if (lockbox_init_duration_ < kLockRetryTimeoutMs) { | |
| 305 // InstallAttributes not ready yet, retry later. | |
| 306 LOG(WARNING) << "Install Attributes not ready yet will retry in " | |
| 307 << kLockRetryIntervalMs << "ms."; | |
| 308 MessageLoop::current()->PostDelayedTask( | |
| 309 FROM_HERE, | |
| 310 base::Bind(&EnterpriseEnrollmentScreen::WriteInstallAttributesData, | |
| 311 weak_ptr_factory_.GetWeakPtr()), | |
| 312 base::TimeDelta::FromMilliseconds(kLockRetryIntervalMs)); | |
| 313 lockbox_init_duration_ += kLockRetryIntervalMs; | |
| 314 } else { | |
| 315 ReportEnrollmentStatus( | |
| 316 policy::EnrollmentStatus::ForStatus( | |
| 317 policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT)); | |
| 318 } | |
| 319 return; | |
| 320 } | |
| 321 case policy::EnterpriseInstallAttributes::LOCK_BACKEND_ERROR: { | |
| 322 ReportEnrollmentStatus( | |
| 323 policy::EnrollmentStatus::ForStatus( | |
| 324 policy::EnrollmentStatus::STATUS_LOCK_ERROR)); | |
| 325 return; | |
| 326 } | |
| 327 case policy::EnterpriseInstallAttributes::LOCK_WRONG_USER: { | |
| 328 LOG(ERROR) << "Enrollment can not proceed because the InstallAttrs " | |
| 329 << "has been locked already!"; | |
| 330 ReportEnrollmentStatus( | |
| 331 policy::EnrollmentStatus::ForStatus( | |
| 332 policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER)); | |
| 333 return; | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 NOTREACHED(); | |
| 338 ReportEnrollmentStatus( | |
| 339 policy::EnrollmentStatus::ForStatus( | |
| 340 policy::EnrollmentStatus::STATUS_LOCK_ERROR)); | |
| 341 } | |
| 342 | |
| 343 void EnterpriseEnrollmentScreen::RegisterForDevicePolicy( | 194 void EnterpriseEnrollmentScreen::RegisterForDevicePolicy( |
| 344 const std::string& token) { | 195 const std::string& token) { |
| 345 policy::BrowserPolicyConnector* connector = | 196 policy::BrowserPolicyConnector* connector = |
| 346 g_browser_process->browser_policy_connector(); | 197 g_browser_process->browser_policy_connector(); |
| 347 if (connector->IsEnterpriseManaged() && | 198 if (connector->IsEnterpriseManaged() && |
| 348 connector->GetEnterpriseDomain() != gaia::ExtractDomainName(user_)) { | 199 connector->GetEnterpriseDomain() != gaia::ExtractDomainName(user_)) { |
| 349 LOG(ERROR) << "Trying to re-enroll to a different domain than " | 200 LOG(ERROR) << "Trying to re-enroll to a different domain than " |
| 350 << connector->GetEnterpriseDomain(); | 201 << connector->GetEnterpriseDomain(); |
| 351 UMAFailure(policy::kMetricEnrollmentWrongUserError); | 202 UMAFailure(policy::kMetricEnrollmentWrongUserError); |
| 352 actor_->ShowUIError( | 203 actor_->ShowUIError( |
| 353 EnterpriseEnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH); | 204 EnterpriseEnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH); |
| 354 NotifyTestingObservers(false); | 205 NotifyTestingObservers(false); |
| 355 return; | 206 return; |
| 356 } | 207 } |
| 357 | 208 |
| 358 // If a device cloud policy manager instance is available (i.e. new-style | 209 policy::DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes modes; |
| 359 // policy is switched on), use that path. | 210 modes[policy::DEVICE_MODE_ENTERPRISE] = true; |
| 360 // TODO(mnissler): Remove the old-style enrollment code path once the code has | 211 modes[policy::DEVICE_MODE_KIOSK] = !is_auto_enrollment_; |
| 361 // switched to the new policy code by default. | 212 connector->ScheduleServiceInitialization(0); |
| 362 if (connector->GetDeviceCloudPolicyManager()) { | 213 connector->GetDeviceCloudPolicyManager()->StartEnrollment( |
| 363 policy::DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes modes; | 214 token, is_auto_enrollment_, modes, |
| 364 modes[policy::DEVICE_MODE_ENTERPRISE] = true; | 215 base::Bind(&EnterpriseEnrollmentScreen::ReportEnrollmentStatus, |
| 365 modes[policy::DEVICE_MODE_KIOSK] = !is_auto_enrollment_; | 216 weak_ptr_factory_.GetWeakPtr())); |
| 366 connector->ScheduleServiceInitialization(0); | |
| 367 connector->GetDeviceCloudPolicyManager()->StartEnrollment( | |
| 368 token, is_auto_enrollment_, modes, | |
| 369 base::Bind(&EnterpriseEnrollmentScreen::ReportEnrollmentStatus, | |
| 370 weak_ptr_factory_.GetWeakPtr())); | |
| 371 return; | |
| 372 } else if (!connector->device_cloud_policy_subsystem()) { | |
| 373 LOG(ERROR) << "Cloud policy subsystem not initialized."; | |
| 374 } else if (connector->device_cloud_policy_subsystem()->state() == | |
| 375 policy::CloudPolicySubsystem::SUCCESS) { | |
| 376 LOG(ERROR) << "A previous enrollment already succeeded!"; | |
| 377 } else { | |
| 378 // Make sure the device policy subsystem is in a clean slate. | |
| 379 connector->ResetDevicePolicy(); | |
| 380 connector->ScheduleServiceInitialization(0); | |
| 381 registrar_.reset(new policy::CloudPolicySubsystem::ObserverRegistrar( | |
| 382 connector->device_cloud_policy_subsystem(), this)); | |
| 383 // Push the credentials to the policy infrastructure. It'll start enrollment | |
| 384 // and notify us of progress through CloudPolicySubsystem::Observer. | |
| 385 connector->RegisterForDevicePolicy(user_, token, | |
| 386 is_auto_enrollment_, | |
| 387 connector->IsEnterpriseManaged()); | |
| 388 return; | |
| 389 } | |
| 390 | |
| 391 NOTREACHED(); | |
| 392 UMAFailure(policy::kMetricEnrollmentOtherFailed); | |
| 393 actor_->ShowUIError(EnterpriseEnrollmentScreenActor::UI_ERROR_FATAL); | |
| 394 NotifyTestingObservers(false); | |
| 395 } | 217 } |
| 396 | 218 |
| 397 void EnterpriseEnrollmentScreen::ReportEnrollmentStatus( | 219 void EnterpriseEnrollmentScreen::ReportEnrollmentStatus( |
| 398 policy::EnrollmentStatus status) { | 220 policy::EnrollmentStatus status) { |
| 399 bool success = status.status() == policy::EnrollmentStatus::STATUS_SUCCESS; | 221 bool success = status.status() == policy::EnrollmentStatus::STATUS_SUCCESS; |
| 400 enrollment_failed_once_ |= !success; | 222 enrollment_failed_once_ |= !success; |
| 401 actor_->ShowEnrollmentStatus(status); | 223 actor_->ShowEnrollmentStatus(status); |
| 402 NotifyTestingObservers(success); | 224 NotifyTestingObservers(success); |
| 403 | 225 |
| 404 switch (status.status()) { | 226 switch (status.status()) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 actor_->Show(); | 287 actor_->Show(); |
| 466 actor_->ShowSigninScreen(); | 288 actor_->ShowSigninScreen(); |
| 467 } | 289 } |
| 468 | 290 |
| 469 void EnterpriseEnrollmentScreen::NotifyTestingObservers(bool succeeded) { | 291 void EnterpriseEnrollmentScreen::NotifyTestingObservers(bool succeeded) { |
| 470 FOR_EACH_OBSERVER(TestingObserver, observers_, | 292 FOR_EACH_OBSERVER(TestingObserver, observers_, |
| 471 OnEnrollmentComplete(succeeded)); | 293 OnEnrollmentComplete(succeeded)); |
| 472 } | 294 } |
| 473 | 295 |
| 474 } // namespace chromeos | 296 } // namespace chromeos |
| OLD | NEW |