| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/policy/cloud_policy_controller.h" | 5 #include "chrome/browser/policy/cloud_policy_controller.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | |
| 11 #include "base/logging.h" | 10 #include "base/logging.h" |
| 12 #include "base/message_loop.h" | |
| 13 #include "base/rand_util.h" | 11 #include "base/rand_util.h" |
| 14 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 15 #include "chrome/browser/policy/cloud_policy_cache_base.h" | 13 #include "chrome/browser/policy/cloud_policy_cache_base.h" |
| 16 #include "chrome/browser/policy/cloud_policy_subsystem.h" | 14 #include "chrome/browser/policy/cloud_policy_subsystem.h" |
| 17 #include "chrome/browser/policy/device_management_backend.h" | |
| 18 #include "chrome/browser/policy/device_management_service.h" | 15 #include "chrome/browser/policy/device_management_service.h" |
| 19 #include "chrome/browser/policy/proto/device_management_constants.h" | 16 #include "chrome/browser/policy/proto/device_management_constants.h" |
| 17 #include "chrome/common/guid.h" |
| 18 |
| 19 namespace { |
| 20 | 20 |
| 21 // Domain names that are known not to be managed. | 21 // Domain names that are known not to be managed. |
| 22 // We don't register the device when such a user logs in. | 22 // We don't register the device when such a user logs in. |
| 23 static const char* kNonManagedDomains[] = { | 23 static const char* kNonManagedDomains[] = { |
| 24 "@googlemail.com", | 24 "@googlemail.com", |
| 25 "@gmail.com" | 25 "@gmail.com" |
| 26 }; | 26 }; |
| 27 | 27 |
| 28 // Checks the domain part of the given username against the list of known | 28 // Checks the domain part of the given username against the list of known |
| 29 // non-managed domain names. Returns false if |username| is empty or | 29 // non-managed domain names. Returns false if |username| is empty or |
| 30 // in a domain known not to be managed. | 30 // in a domain known not to be managed. |
| 31 static bool CanBeInManagedDomain(const std::string& username) { | 31 static bool CanBeInManagedDomain(const std::string& username) { |
| 32 if (username.empty()) { | 32 if (username.empty()) { |
| 33 // This means incognito user in case of ChromiumOS and | 33 // This means incognito user in case of ChromiumOS and |
| 34 // no logged-in user in case of Chromium (SigninService). | 34 // no logged-in user in case of Chromium (SigninService). |
| 35 return false; | 35 return false; |
| 36 } | 36 } |
| 37 for (size_t i = 0; i < arraysize(kNonManagedDomains); i++) { | 37 for (size_t i = 0; i < arraysize(kNonManagedDomains); i++) { |
| 38 if (EndsWith(username, kNonManagedDomains[i], true)) { | 38 if (EndsWith(username, kNonManagedDomains[i], true)) { |
| 39 return false; | 39 return false; |
| 40 } | 40 } |
| 41 } | 41 } |
| 42 return true; | 42 return true; |
| 43 } | 43 } |
| 44 | 44 |
| 45 } |
| 46 |
| 45 namespace policy { | 47 namespace policy { |
| 46 | 48 |
| 47 namespace em = enterprise_management; | 49 namespace em = enterprise_management; |
| 48 | 50 |
| 49 // The maximum ratio in percent of the policy refresh rate we use for adjusting | 51 // The maximum ratio in percent of the policy refresh rate we use for adjusting |
| 50 // the policy refresh time instant. The rationale is to avoid load spikes from | 52 // the policy refresh time instant. The rationale is to avoid load spikes from |
| 51 // many devices that were set up in sync for some reason. | 53 // many devices that were set up in sync for some reason. |
| 52 static const int kPolicyRefreshDeviationFactorPercent = 10; | 54 static const int kPolicyRefreshDeviationFactorPercent = 10; |
| 53 // Maximum deviation we are willing to accept. | 55 // Maximum deviation we are willing to accept. |
| 54 static const int64 kPolicyRefreshDeviationMaxInMilliseconds = 30 * 60 * 1000; | 56 static const int64 kPolicyRefreshDeviationMaxInMilliseconds = 30 * 60 * 1000; |
| 55 | 57 |
| 56 // These are the base values for delays before retrying after an error. They | 58 // These are the base values for delays before retrying after an error. They |
| 57 // will be doubled each time they are used. | 59 // will be doubled each time they are used. |
| 58 static const int64 kPolicyRefreshErrorDelayInMilliseconds = | 60 static const int64 kPolicyRefreshErrorDelayInMilliseconds = |
| 59 5 * 60 * 1000; // 5 minutes | 61 5 * 60 * 1000; // 5 minutes |
| 60 | 62 |
| 61 // Default value for the policy refresh rate. | 63 // Default value for the policy refresh rate. |
| 62 static const int kPolicyRefreshRateInMilliseconds = | 64 static const int kPolicyRefreshRateInMilliseconds = |
| 63 3 * 60 * 60 * 1000; // 3 hours. | 65 3 * 60 * 60 * 1000; // 3 hours. |
| 64 | 66 |
| 65 CloudPolicyController::CloudPolicyController( | 67 CloudPolicyController::CloudPolicyController( |
| 66 DeviceManagementService* service, | 68 DeviceManagementService* service, |
| 67 CloudPolicyCacheBase* cache, | 69 CloudPolicyCacheBase* cache, |
| 68 DeviceTokenFetcher* token_fetcher, | 70 DeviceTokenFetcher* token_fetcher, |
| 69 CloudPolicyIdentityStrategy* identity_strategy, | 71 CloudPolicyDataStore* data_store, |
| 70 PolicyNotifier* notifier) { | 72 PolicyNotifier* notifier) { |
| 71 Initialize(service, | 73 Initialize(service, |
| 72 cache, | 74 cache, |
| 73 token_fetcher, | 75 token_fetcher, |
| 74 identity_strategy, | 76 data_store, |
| 75 notifier, | 77 notifier, |
| 76 new DelayedWorkScheduler); | 78 new DelayedWorkScheduler); |
| 77 } | 79 } |
| 78 | 80 |
| 79 CloudPolicyController::~CloudPolicyController() { | 81 CloudPolicyController::~CloudPolicyController() { |
| 80 token_fetcher_->RemoveObserver(this); | 82 data_store_->RemoveObserver(this); |
| 81 identity_strategy_->RemoveObserver(this); | |
| 82 scheduler_->CancelDelayedWork(); | 83 scheduler_->CancelDelayedWork(); |
| 83 } | 84 } |
| 84 | 85 |
| 85 void CloudPolicyController::SetRefreshRate(int64 refresh_rate_milliseconds) { | 86 void CloudPolicyController::SetRefreshRate(int64 refresh_rate_milliseconds) { |
| 86 policy_refresh_rate_ms_ = refresh_rate_milliseconds; | 87 policy_refresh_rate_ms_ = refresh_rate_milliseconds; |
| 87 | 88 |
| 88 // Reschedule the refresh task if necessary. | 89 // Reschedule the refresh task if necessary. |
| 89 if (state_ == STATE_POLICY_VALID) | 90 if (state_ == STATE_POLICY_VALID) |
| 90 SetState(STATE_POLICY_VALID); | 91 SetState(STATE_POLICY_VALID); |
| 91 } | 92 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 case DeviceManagementBackend::kErrorRequestFailed: | 147 case DeviceManagementBackend::kErrorRequestFailed: |
| 147 case DeviceManagementBackend::kErrorTemporaryUnavailable: { | 148 case DeviceManagementBackend::kErrorTemporaryUnavailable: { |
| 148 VLOG(1) << "A temporary error in the communication with the policy server" | 149 VLOG(1) << "A temporary error in the communication with the policy server" |
| 149 << " occurred."; | 150 << " occurred."; |
| 150 // Will retry last operation but gracefully backing off. | 151 // Will retry last operation but gracefully backing off. |
| 151 SetState(STATE_POLICY_ERROR); | 152 SetState(STATE_POLICY_ERROR); |
| 152 } | 153 } |
| 153 } | 154 } |
| 154 } | 155 } |
| 155 | 156 |
| 156 void CloudPolicyController::OnDeviceTokenAvailable() { | |
| 157 identity_strategy_->OnDeviceTokenAvailable(token_fetcher_->GetDeviceToken()); | |
| 158 } | |
| 159 | |
| 160 void CloudPolicyController::OnDeviceTokenChanged() { | 157 void CloudPolicyController::OnDeviceTokenChanged() { |
| 161 if (identity_strategy_->GetDeviceToken().empty()) | 158 if (data_store_->device_token().empty()) |
| 162 SetState(STATE_TOKEN_UNAVAILABLE); | 159 SetState(STATE_TOKEN_UNAVAILABLE); |
| 163 else | 160 else |
| 164 SetState(STATE_TOKEN_VALID); | 161 SetState(STATE_TOKEN_VALID); |
| 165 } | 162 } |
| 166 | 163 |
| 167 void CloudPolicyController::OnCredentialsChanged() { | 164 void CloudPolicyController::OnCredentialsChanged() { |
| 168 notifier_->Inform(CloudPolicySubsystem::UNENROLLED, | 165 // This notification is only interesting if we don't have a device token. |
| 169 CloudPolicySubsystem::NO_DETAILS, | 166 // If we already have a device token, that must be matching the current |
| 170 PolicyNotifier::POLICY_CONTROLLER); | 167 // user, because (1) we always recreate the policy subsystem after user |
| 171 effective_policy_refresh_error_delay_ms_ = | 168 // login (2) tokens are cached per user. |
| 172 kPolicyRefreshErrorDelayInMilliseconds; | 169 if (data_store_->device_token().empty()) { |
| 173 SetState(STATE_TOKEN_UNAVAILABLE); | 170 notifier_->Inform(CloudPolicySubsystem::UNENROLLED, |
| 171 CloudPolicySubsystem::NO_DETAILS, |
| 172 PolicyNotifier::POLICY_CONTROLLER); |
| 173 effective_policy_refresh_error_delay_ms_ = |
| 174 kPolicyRefreshErrorDelayInMilliseconds; |
| 175 SetState(STATE_TOKEN_UNAVAILABLE); |
| 176 } |
| 177 } |
| 178 |
| 179 void CloudPolicyController::OnDataStoreGoingAway() { |
| 180 NOTREACHED(); |
| 174 } | 181 } |
| 175 | 182 |
| 176 CloudPolicyController::CloudPolicyController( | 183 CloudPolicyController::CloudPolicyController( |
| 177 DeviceManagementService* service, | 184 DeviceManagementService* service, |
| 178 CloudPolicyCacheBase* cache, | 185 CloudPolicyCacheBase* cache, |
| 179 DeviceTokenFetcher* token_fetcher, | 186 DeviceTokenFetcher* token_fetcher, |
| 180 CloudPolicyIdentityStrategy* identity_strategy, | 187 CloudPolicyDataStore* data_store, |
| 181 PolicyNotifier* notifier, | 188 PolicyNotifier* notifier, |
| 182 DelayedWorkScheduler* scheduler) { | 189 DelayedWorkScheduler* scheduler) { |
| 183 Initialize(service, | 190 Initialize(service, |
| 184 cache, | 191 cache, |
| 185 token_fetcher, | 192 token_fetcher, |
| 186 identity_strategy, | 193 data_store, |
| 187 notifier, | 194 notifier, |
| 188 scheduler); | 195 scheduler); |
| 189 } | 196 } |
| 190 | 197 |
| 191 void CloudPolicyController::Initialize( | 198 void CloudPolicyController::Initialize( |
| 192 DeviceManagementService* service, | 199 DeviceManagementService* service, |
| 193 CloudPolicyCacheBase* cache, | 200 CloudPolicyCacheBase* cache, |
| 194 DeviceTokenFetcher* token_fetcher, | 201 DeviceTokenFetcher* token_fetcher, |
| 195 CloudPolicyIdentityStrategy* identity_strategy, | 202 CloudPolicyDataStore* data_store, |
| 196 PolicyNotifier* notifier, | 203 PolicyNotifier* notifier, |
| 197 DelayedWorkScheduler* scheduler) { | 204 DelayedWorkScheduler* scheduler) { |
| 198 DCHECK(cache); | 205 DCHECK(cache); |
| 199 | 206 |
| 200 service_ = service; | 207 service_ = service; |
| 201 cache_ = cache; | 208 cache_ = cache; |
| 202 token_fetcher_ = token_fetcher; | 209 token_fetcher_ = token_fetcher; |
| 203 identity_strategy_ = identity_strategy; | 210 data_store_ = data_store; |
| 204 notifier_ = notifier; | 211 notifier_ = notifier; |
| 205 state_ = STATE_TOKEN_UNAVAILABLE; | 212 state_ = STATE_TOKEN_UNAVAILABLE; |
| 206 policy_refresh_rate_ms_ = kPolicyRefreshRateInMilliseconds; | 213 policy_refresh_rate_ms_ = kPolicyRefreshRateInMilliseconds; |
| 207 effective_policy_refresh_error_delay_ms_ = | 214 effective_policy_refresh_error_delay_ms_ = |
| 208 kPolicyRefreshErrorDelayInMilliseconds; | 215 kPolicyRefreshErrorDelayInMilliseconds; |
| 209 scheduler_.reset(scheduler); | 216 scheduler_.reset(scheduler); |
| 210 token_fetcher_->AddObserver(this); | 217 data_store_->AddObserver(this); |
| 211 identity_strategy_->AddObserver(this); | 218 if (!data_store_->device_token().empty()) |
| 212 if (!identity_strategy_->GetDeviceToken().empty()) | |
| 213 SetState(STATE_TOKEN_VALID); | 219 SetState(STATE_TOKEN_VALID); |
| 214 else | 220 else |
| 215 SetState(STATE_TOKEN_UNAVAILABLE); | 221 SetState(STATE_TOKEN_UNAVAILABLE); |
| 216 } | 222 } |
| 217 | 223 |
| 218 void CloudPolicyController::FetchToken() { | 224 void CloudPolicyController::FetchToken() { |
| 219 std::string username; | 225 if (data_store_->token_cache_loaded() && |
| 220 std::string auth_token; | 226 !data_store_->user_name().empty() && |
| 221 std::string device_id = identity_strategy_->GetDeviceID(); | 227 !data_store_->gaia_token().empty()) { |
| 222 std::string machine_id = identity_strategy_->GetMachineID(); | 228 if (CanBeInManagedDomain(data_store_->user_name())) { |
| 223 std::string machine_model = identity_strategy_->GetMachineModel(); | 229 // Generate a new random device id. (It'll only be kept if registration |
| 224 em::DeviceRegisterRequest_Type policy_type = | 230 // succeeds.) |
| 225 identity_strategy_->GetPolicyRegisterType(); | 231 data_store_->set_device_id(guid::GenerateGUID()); |
| 226 if (identity_strategy_->GetCredentials(&username, &auth_token)) { | 232 token_fetcher_->FetchToken(); |
| 227 if (CanBeInManagedDomain(username)) { | |
| 228 token_fetcher_->FetchToken(auth_token, device_id, policy_type, | |
| 229 machine_id, machine_model); | |
| 230 } else { | 233 } else { |
| 231 SetState(STATE_TOKEN_UNMANAGED); | 234 SetState(STATE_TOKEN_UNMANAGED); |
| 232 } | 235 } |
| 233 } | 236 } |
| 234 } | 237 } |
| 235 | 238 |
| 236 void CloudPolicyController::SendPolicyRequest() { | 239 void CloudPolicyController::SendPolicyRequest() { |
| 237 backend_.reset(service_->CreateBackend()); | 240 backend_.reset(service_->CreateBackend()); |
| 238 DCHECK(!identity_strategy_->GetDeviceToken().empty()); | 241 DCHECK(!data_store_->device_token().empty()); |
| 239 em::DevicePolicyRequest policy_request; | 242 em::DevicePolicyRequest policy_request; |
| 240 em::PolicyFetchRequest* fetch_request = policy_request.add_request(); | 243 em::PolicyFetchRequest* fetch_request = policy_request.add_request(); |
| 241 fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA); | 244 fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA); |
| 242 fetch_request->set_policy_type(identity_strategy_->GetPolicyType()); | 245 fetch_request->set_policy_type(data_store_->policy_type()); |
| 243 if (!cache_->is_unmanaged() && | 246 if (!cache_->is_unmanaged() && |
| 244 !cache_->last_policy_refresh_time().is_null()) { | 247 !cache_->last_policy_refresh_time().is_null()) { |
| 245 base::TimeDelta timestamp = | 248 base::TimeDelta timestamp = |
| 246 cache_->last_policy_refresh_time() - base::Time::UnixEpoch(); | 249 cache_->last_policy_refresh_time() - base::Time::UnixEpoch(); |
| 247 fetch_request->set_timestamp(timestamp.InMilliseconds()); | 250 fetch_request->set_timestamp(timestamp.InMilliseconds()); |
| 248 } | 251 } |
| 249 int key_version = 0; | 252 int key_version = 0; |
| 250 if (cache_->GetPublicKeyVersion(&key_version)) | 253 if (cache_->GetPublicKeyVersion(&key_version)) |
| 251 fetch_request->set_public_key_version(key_version); | 254 fetch_request->set_public_key_version(key_version); |
| 252 | 255 |
| 253 backend_->ProcessPolicyRequest(identity_strategy_->GetDeviceToken(), | 256 backend_->ProcessPolicyRequest(data_store_->device_token(), |
| 254 identity_strategy_->GetDeviceID(), | 257 data_store_->device_id(), |
| 255 policy_request, this); | 258 policy_request, this); |
| 256 } | 259 } |
| 257 | 260 |
| 258 void CloudPolicyController::DoWork() { | 261 void CloudPolicyController::DoWork() { |
| 259 switch (state_) { | 262 switch (state_) { |
| 260 case STATE_TOKEN_UNAVAILABLE: | 263 case STATE_TOKEN_UNAVAILABLE: |
| 261 case STATE_TOKEN_ERROR: | 264 case STATE_TOKEN_ERROR: |
| 262 FetchToken(); | 265 FetchToken(); |
| 263 return; | 266 return; |
| 264 case STATE_TOKEN_VALID: | 267 case STATE_TOKEN_VALID: |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 } | 356 } |
| 354 | 357 |
| 355 int64 CloudPolicyController::GetRefreshDelay() { | 358 int64 CloudPolicyController::GetRefreshDelay() { |
| 356 int64 deviation = (kPolicyRefreshDeviationFactorPercent * | 359 int64 deviation = (kPolicyRefreshDeviationFactorPercent * |
| 357 policy_refresh_rate_ms_) / 100; | 360 policy_refresh_rate_ms_) / 100; |
| 358 deviation = std::min(deviation, kPolicyRefreshDeviationMaxInMilliseconds); | 361 deviation = std::min(deviation, kPolicyRefreshDeviationMaxInMilliseconds); |
| 359 return policy_refresh_rate_ms_ - base::RandGenerator(deviation + 1); | 362 return policy_refresh_rate_ms_ - base::RandGenerator(deviation + 1); |
| 360 } | 363 } |
| 361 | 364 |
| 362 } // namespace policy | 365 } // namespace policy |
| OLD | NEW |