| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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/policy/enrollment_handler_chromeos.h" | 
|  | 6 | 
|  | 7 #include "base/bind.h" | 
|  | 8 #include "base/logging.h" | 
|  | 9 #include "base/message_loop.h" | 
|  | 10 #include "chrome/browser/policy/cloud_policy_constants.h" | 
|  | 11 #include "chrome/browser/policy/device_cloud_policy_store_chromeos.h" | 
|  | 12 #include "chrome/browser/policy/enterprise_install_attributes.h" | 
|  | 13 #include "chrome/browser/policy/proto/device_management_backend.pb.h" | 
|  | 14 | 
|  | 15 namespace em = enterprise_management; | 
|  | 16 | 
|  | 17 namespace policy { | 
|  | 18 | 
|  | 19 namespace { | 
|  | 20 | 
|  | 21 // Retry for InstallAttrs initialization every 500ms. | 
|  | 22 const int kLockRetryIntervalMs = 500; | 
|  | 23 // Maximum time to retry InstallAttrs initialization before we give up. | 
|  | 24 const int kLockRetryTimeoutMs = 10 * 60 * 1000;  // 10 minutes. | 
|  | 25 | 
|  | 26 }  // namespace | 
|  | 27 | 
|  | 28 EnrollmentHandlerChromeOS::EnrollmentHandlerChromeOS( | 
|  | 29     DeviceCloudPolicyStoreChromeOS* store, | 
|  | 30     EnterpriseInstallAttributes* install_attributes, | 
|  | 31     scoped_ptr<CloudPolicyClient> client, | 
|  | 32     const std::string& auth_token, | 
|  | 33     const AllowedDeviceModes& allowed_device_modes, | 
|  | 34     const EnrollmentCallback& completion_callback) | 
|  | 35     : store_(store), | 
|  | 36       install_attributes_(install_attributes), | 
|  | 37       client_(client.Pass()), | 
|  | 38       auth_token_(auth_token), | 
|  | 39       allowed_device_modes_(allowed_device_modes), | 
|  | 40       completion_callback_(completion_callback), | 
|  | 41       device_mode_(DEVICE_MODE_NOT_SET), | 
|  | 42       enrollment_step_(STEP_PENDING), | 
|  | 43       lockbox_init_duration_(0), | 
|  | 44       ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 
|  | 45   CHECK(!client_->is_registered()); | 
|  | 46   CHECK_EQ(DM_STATUS_SUCCESS, client_->status()); | 
|  | 47   store_->AddObserver(this); | 
|  | 48   client_->AddObserver(this); | 
|  | 49 } | 
|  | 50 | 
|  | 51 EnrollmentHandlerChromeOS::~EnrollmentHandlerChromeOS() { | 
|  | 52   Stop(); | 
|  | 53   store_->RemoveObserver(this); | 
|  | 54 } | 
|  | 55 | 
|  | 56 void EnrollmentHandlerChromeOS::StartEnrollment() { | 
|  | 57   CHECK_EQ(STEP_PENDING, enrollment_step_); | 
|  | 58   enrollment_step_ = STEP_LOADING_STORE; | 
|  | 59   AttemptRegistration(); | 
|  | 60 } | 
|  | 61 | 
|  | 62 scoped_ptr<CloudPolicyClient> EnrollmentHandlerChromeOS::ReleaseClient() { | 
|  | 63   Stop(); | 
|  | 64   return client_.Pass(); | 
|  | 65 } | 
|  | 66 | 
|  | 67 void EnrollmentHandlerChromeOS::OnPolicyFetched(CloudPolicyClient* client) { | 
|  | 68   DCHECK_EQ(client_.get(), client); | 
|  | 69   CHECK_EQ(STEP_POLICY_FETCH, enrollment_step_); | 
|  | 70 | 
|  | 71   enrollment_step_ = STEP_VALIDATION; | 
|  | 72 | 
|  | 73   // Validate the policy. | 
|  | 74   scoped_ptr<DeviceCloudPolicyValidator> validator( | 
|  | 75       DeviceCloudPolicyValidator::Create( | 
|  | 76           scoped_ptr<em::PolicyFetchResponse>( | 
|  | 77               new em::PolicyFetchResponse(*client_->policy())), | 
|  | 78           base::Bind(&EnrollmentHandlerChromeOS::PolicyValidated, | 
|  | 79                      weak_factory_.GetWeakPtr()))); | 
|  | 80 | 
|  | 81   validator->ValidateTimestamp(base::Time(), base::Time::NowFromSystemTime(), | 
|  | 82                                false); | 
|  | 83   if (install_attributes_->IsEnterpriseDevice()) | 
|  | 84     validator->ValidateDomain(install_attributes_->GetDomain()); | 
|  | 85   validator->ValidateDMToken(client->dm_token()); | 
|  | 86   validator->ValidatePolicyType(dm_protocol::kChromeDevicePolicyType); | 
|  | 87   validator->ValidatePayload(); | 
|  | 88   validator->ValidateInitialKey(); | 
|  | 89   validator.release()->StartValidation(); | 
|  | 90 } | 
|  | 91 | 
|  | 92 void EnrollmentHandlerChromeOS::OnRegistrationStateChanged( | 
|  | 93     CloudPolicyClient* client) { | 
|  | 94   DCHECK_EQ(client_.get(), client); | 
|  | 95 | 
|  | 96   if (enrollment_step_ == STEP_REGISTRATION && client_->is_registered()) { | 
|  | 97     enrollment_step_ = STEP_POLICY_FETCH, | 
|  | 98     device_mode_ = client_->device_mode(); | 
|  | 99     if (device_mode_ == DEVICE_MODE_NOT_SET) | 
|  | 100       device_mode_ = DEVICE_MODE_ENTERPRISE; | 
|  | 101     if (!allowed_device_modes_.test(device_mode_)) { | 
|  | 102       LOG(ERROR) << "Bad device mode " << device_mode_; | 
|  | 103       ReportResult(EnrollmentStatus::ForStatus( | 
|  | 104           EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE)); | 
|  | 105       return; | 
|  | 106     } | 
|  | 107     client_->FetchPolicy(); | 
|  | 108   } else { | 
|  | 109     LOG(FATAL) << "Registration state changed to " << client_->is_registered() | 
|  | 110                << " in step " << enrollment_step_; | 
|  | 111   } | 
|  | 112 } | 
|  | 113 | 
|  | 114 void EnrollmentHandlerChromeOS::OnClientError(CloudPolicyClient* client) { | 
|  | 115   DCHECK_EQ(client_.get(), client); | 
|  | 116 | 
|  | 117   if (enrollment_step_ < STEP_POLICY_FETCH) | 
|  | 118     ReportResult(EnrollmentStatus::ForRegistrationError(client_->status())); | 
|  | 119   else | 
|  | 120     ReportResult(EnrollmentStatus::ForFetchError(client_->status())); | 
|  | 121 } | 
|  | 122 | 
|  | 123 void EnrollmentHandlerChromeOS::OnStoreLoaded(CloudPolicyStore* store) { | 
|  | 124   DCHECK_EQ(store_, store); | 
|  | 125 | 
|  | 126   if (enrollment_step_ == STEP_LOADING_STORE) { | 
|  | 127     AttemptRegistration(); | 
|  | 128   } else if (enrollment_step_ == STEP_STORE_POLICY) { | 
|  | 129     ReportResult(EnrollmentStatus::ForStatus(EnrollmentStatus::STATUS_SUCCESS)); | 
|  | 130   } | 
|  | 131 } | 
|  | 132 | 
|  | 133 void EnrollmentHandlerChromeOS::OnStoreError(CloudPolicyStore* store) { | 
|  | 134   DCHECK_EQ(store_, store); | 
|  | 135   ReportResult(EnrollmentStatus::ForStoreError(store_->status(), | 
|  | 136                                                store_->validation_status())); | 
|  | 137 } | 
|  | 138 | 
|  | 139 void EnrollmentHandlerChromeOS::AttemptRegistration() { | 
|  | 140   CHECK_EQ(STEP_LOADING_STORE, enrollment_step_); | 
|  | 141   if (store_->is_initialized()) { | 
|  | 142     enrollment_step_ = STEP_REGISTRATION; | 
|  | 143     client_->Register(auth_token_); | 
|  | 144   } | 
|  | 145 } | 
|  | 146 | 
|  | 147 void EnrollmentHandlerChromeOS::PolicyValidated( | 
|  | 148     DeviceCloudPolicyValidator* validator) { | 
|  | 149   CHECK_EQ(STEP_VALIDATION, enrollment_step_); | 
|  | 150   if (validator->success()) { | 
|  | 151     policy_ = validator->policy().Pass(); | 
|  | 152     enrollment_step_ = STEP_LOCK_DEVICE; | 
|  | 153     WriteInstallAttributes(validator->policy_data()->username(), device_mode_, | 
|  | 154                            validator->policy_data()->device_id()); | 
|  | 155   } else { | 
|  | 156     ReportResult(EnrollmentStatus::ForValidationError(validator->status())); | 
|  | 157   } | 
|  | 158 } | 
|  | 159 | 
|  | 160 void EnrollmentHandlerChromeOS::WriteInstallAttributes( | 
|  | 161     const std::string& user, | 
|  | 162     DeviceMode device_mode, | 
|  | 163     const std::string& device_id) { | 
|  | 164   CHECK_EQ(STEP_LOCK_DEVICE, enrollment_step_); | 
|  | 165   // Since this method is also called directly. | 
|  | 166   weak_factory_.InvalidateWeakPtrs(); | 
|  | 167 | 
|  | 168   EnterpriseInstallAttributes::LockResult lock_result = | 
|  | 169       install_attributes_->LockDevice(user, device_mode, device_id); | 
|  | 170   switch (lock_result) { | 
|  | 171     case EnterpriseInstallAttributes::LOCK_SUCCESS: | 
|  | 172       enrollment_step_ = STEP_STORE_POLICY; | 
|  | 173       store_->InstallInitialPolicy(*policy_); | 
|  | 174       return; | 
|  | 175     case EnterpriseInstallAttributes::LOCK_NOT_READY: | 
|  | 176       // We wait up to |kLockRetryTimeoutMs| milliseconds and if it hasn't | 
|  | 177       // succeeded by then show an error to the user and stop the enrollment. | 
|  | 178       if (lockbox_init_duration_ < kLockRetryTimeoutMs) { | 
|  | 179         // InstallAttributes not ready yet, retry later. | 
|  | 180         LOG(WARNING) << "Install Attributes not ready yet will retry in " | 
|  | 181                      << kLockRetryIntervalMs << "ms."; | 
|  | 182         MessageLoop::current()->PostDelayedTask( | 
|  | 183             FROM_HERE, | 
|  | 184             base::Bind(&EnrollmentHandlerChromeOS::WriteInstallAttributes, | 
|  | 185                        weak_factory_.GetWeakPtr(), | 
|  | 186                        user, device_mode, device_id), | 
|  | 187             base::TimeDelta::FromMilliseconds(kLockRetryIntervalMs)); | 
|  | 188         lockbox_init_duration_ += kLockRetryIntervalMs; | 
|  | 189       } else { | 
|  | 190         ReportResult(EnrollmentStatus::ForStatus( | 
|  | 191             EnrollmentStatus::STATUS_LOCK_TIMEOUT)); | 
|  | 192       } | 
|  | 193       return; | 
|  | 194     case EnterpriseInstallAttributes::LOCK_BACKEND_ERROR: | 
|  | 195       ReportResult(EnrollmentStatus::ForStatus( | 
|  | 196           EnrollmentStatus::STATUS_LOCK_ERROR)); | 
|  | 197       return; | 
|  | 198     case EnterpriseInstallAttributes::LOCK_WRONG_USER: | 
|  | 199       LOG(ERROR) << "Enrollment cannot proceed because the InstallAttrs " | 
|  | 200                  << "has been locked already!"; | 
|  | 201       ReportResult(EnrollmentStatus::ForStatus( | 
|  | 202           EnrollmentStatus::STATUS_LOCK_WRONG_USER)); | 
|  | 203       return; | 
|  | 204   } | 
|  | 205 | 
|  | 206   NOTREACHED() << "Invalid lock result " << lock_result; | 
|  | 207   ReportResult(EnrollmentStatus::ForStatus( | 
|  | 208       EnrollmentStatus::STATUS_LOCK_ERROR)); | 
|  | 209 } | 
|  | 210 | 
|  | 211 void EnrollmentHandlerChromeOS::Stop() { | 
|  | 212   if (client_.get()) | 
|  | 213     client_->RemoveObserver(this); | 
|  | 214   enrollment_step_ = STEP_FINISHED; | 
|  | 215   weak_factory_.InvalidateWeakPtrs(); | 
|  | 216   completion_callback_.Reset(); | 
|  | 217 } | 
|  | 218 | 
|  | 219 void EnrollmentHandlerChromeOS::ReportResult(EnrollmentStatus status) { | 
|  | 220   EnrollmentCallback callback = completion_callback_; | 
|  | 221   Stop(); | 
|  | 222 | 
|  | 223   if (status.status() != EnrollmentStatus::STATUS_SUCCESS) { | 
|  | 224     LOG(WARNING) << "Enrollment failed: " << status.status() | 
|  | 225                  << " " << status.client_status() | 
|  | 226                  << " " << status.validation_status() | 
|  | 227                  << " " << status.store_status(); | 
|  | 228   } | 
|  | 229 | 
|  | 230   if (!callback.is_null()) | 
|  | 231     callback.Run(status); | 
|  | 232 } | 
|  | 233 | 
|  | 234 }  // namespace policy | 
| OLD | NEW | 
|---|