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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/policy/cloud_policy_controller.h" 6 7 #include <algorithm> 8 9 #include "base/logging.h" 10 #include "base/message_loop.h" 11 #include "base/rand_util.h" 12 #include "base/string_util.h" 13 #include "chrome/browser/policy/cloud_policy_cache_base.h" 14 #include "chrome/browser/policy/cloud_policy_subsystem.h" 15 #include "chrome/browser/policy/device_management_backend.h" 16 #include "chrome/browser/policy/device_management_service.h" 17 #include "chrome/browser/policy/proto/device_management_constants.h" 18 19 // Domain names that are known not to be managed. 20 // We don't register the device when such a user logs in. 21 static const char* kNonManagedDomains[] = { 22 "@googlemail.com", 23 "@gmail.com" 24 }; 25 26 // Checks the domain part of the given username against the list of known 27 // non-managed domain names. Returns false if |username| is empty or 28 // in a domain known not to be managed. 29 static bool CanBeInManagedDomain(const std::string& username) { 30 if (username.empty()) { 31 // This means incognito user in case of ChromiumOS and 32 // no logged-in user in case of Chromium (SigninService). 33 return false; 34 } 35 for (size_t i = 0; i < arraysize(kNonManagedDomains); i++) { 36 if (EndsWith(username, kNonManagedDomains[i], true)) { 37 return false; 38 } 39 } 40 return true; 41 } 42 43 namespace policy { 44 45 namespace em = enterprise_management; 46 47 // The maximum ratio in percent of the policy refresh rate we use for adjusting 48 // the policy refresh time instant. The rationale is to avoid load spikes from 49 // many devices that were set up in sync for some reason. 50 static const int kPolicyRefreshDeviationFactorPercent = 10; 51 // Maximum deviation we are willing to accept. 52 static const int64 kPolicyRefreshDeviationMaxInMilliseconds = 30 * 60 * 1000; 53 54 // These are the base values for delays before retrying after an error. They 55 // will be doubled each time they are used. 56 static const int64 kPolicyRefreshErrorDelayInMilliseconds = 57 5 * 60 * 1000; // 5 minutes 58 59 // Default value for the policy refresh rate. 60 static const int kPolicyRefreshRateInMilliseconds = 61 3 * 60 * 60 * 1000; // 3 hours. 62 63 CloudPolicyController::CloudPolicyController( 64 DeviceManagementService* service, 65 CloudPolicyCacheBase* cache, 66 DeviceTokenFetcher* token_fetcher, 67 CloudPolicyIdentityStrategy* identity_strategy, 68 PolicyNotifier* notifier) 69 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 70 Initialize(service, 71 cache, 72 token_fetcher, 73 identity_strategy, 74 notifier, 75 kPolicyRefreshRateInMilliseconds, 76 kPolicyRefreshDeviationFactorPercent, 77 kPolicyRefreshDeviationMaxInMilliseconds, 78 kPolicyRefreshErrorDelayInMilliseconds); 79 } 80 81 CloudPolicyController::~CloudPolicyController() { 82 token_fetcher_->RemoveObserver(this); 83 identity_strategy_->RemoveObserver(this); 84 CancelDelayedWork(); 85 } 86 87 void CloudPolicyController::SetRefreshRate(int64 refresh_rate_milliseconds) { 88 policy_refresh_rate_ms_ = refresh_rate_milliseconds; 89 90 // Reschedule the refresh task if necessary. 91 if (state_ == STATE_POLICY_VALID) 92 SetState(STATE_POLICY_VALID); 93 } 94 95 void CloudPolicyController::Retry() { 96 CancelDelayedWork(); 97 DoWork(); 98 } 99 100 void CloudPolicyController::StopAutoRetry() { 101 CancelDelayedWork(); 102 backend_.reset(); 103 } 104 105 void CloudPolicyController::HandlePolicyResponse( 106 const em::DevicePolicyResponse& response) { 107 if (response.response_size() > 0) { 108 if (response.response_size() > 1) { 109 LOG(WARNING) << "More than one policy in the response of the device " 110 << "management server, discarding."; 111 } 112 if (response.response(0).error_code() != 113 DeviceManagementBackend::kErrorServicePolicyNotFound) { 114 cache_->SetPolicy(response.response(0)); 115 SetState(STATE_POLICY_VALID); 116 } else { 117 SetState(STATE_POLICY_UNAVAILABLE); 118 } 119 } 120 } 121 122 void CloudPolicyController::OnError(DeviceManagementBackend::ErrorCode code) { 123 switch (code) { 124 case DeviceManagementBackend::kErrorServiceDeviceNotFound: 125 case DeviceManagementBackend::kErrorServiceManagementTokenInvalid: { 126 LOG(WARNING) << "The device token was either invalid or unknown to the " 127 << "device manager, re-registering device."; 128 // Will retry fetching a token but gracefully backing off. 129 SetState(STATE_TOKEN_ERROR); 130 break; 131 } 132 case DeviceManagementBackend::kErrorServiceManagementNotSupported: { 133 VLOG(1) << "The device is no longer managed."; 134 token_fetcher_->SetUnmanagedState(); 135 SetState(STATE_TOKEN_UNMANAGED); 136 break; 137 } 138 case DeviceManagementBackend::kErrorServicePolicyNotFound: 139 case DeviceManagementBackend::kErrorRequestInvalid: 140 case DeviceManagementBackend::kErrorServiceActivationPending: 141 case DeviceManagementBackend::kErrorResponseDecoding: 142 case DeviceManagementBackend::kErrorHttpStatus: { 143 VLOG(1) << "An error in the communication with the policy server occurred" 144 << ", will retry in a few hours."; 145 SetState(STATE_POLICY_UNAVAILABLE); 146 break; 147 } 148 case DeviceManagementBackend::kErrorRequestFailed: 149 case DeviceManagementBackend::kErrorTemporaryUnavailable: { 150 VLOG(1) << "A temporary error in the communication with the policy server" 151 << " occurred."; 152 // Will retry last operation but gracefully backing off. 153 SetState(STATE_POLICY_ERROR); 154 } 155 } 156 } 157 158 void CloudPolicyController::OnDeviceTokenAvailable() { 159 identity_strategy_->OnDeviceTokenAvailable(token_fetcher_->GetDeviceToken()); 160 } 161 162 void CloudPolicyController::OnDeviceTokenChanged() { 163 if (identity_strategy_->GetDeviceToken().empty()) 164 SetState(STATE_TOKEN_UNAVAILABLE); 165 else 166 SetState(STATE_TOKEN_VALID); 167 } 168 169 void CloudPolicyController::OnCredentialsChanged() { 170 effective_policy_refresh_error_delay_ms_ = policy_refresh_error_delay_ms_; 171 SetState(STATE_TOKEN_UNAVAILABLE); 172 } 173 174 CloudPolicyController::CloudPolicyController( 175 DeviceManagementService* service, 176 CloudPolicyCacheBase* cache, 177 DeviceTokenFetcher* token_fetcher, 178 CloudPolicyIdentityStrategy* identity_strategy, 179 PolicyNotifier* notifier, 180 int64 policy_refresh_rate_ms, 181 int policy_refresh_deviation_factor_percent, 182 int64 policy_refresh_deviation_max_ms, 183 int64 policy_refresh_error_delay_ms) 184 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 185 Initialize(service, 186 cache, 187 token_fetcher, 188 identity_strategy, 189 notifier, 190 policy_refresh_rate_ms, 191 policy_refresh_deviation_factor_percent, 192 policy_refresh_deviation_max_ms, 193 policy_refresh_error_delay_ms); 194 } 195 196 void CloudPolicyController::Initialize( 197 DeviceManagementService* service, 198 CloudPolicyCacheBase* cache, 199 DeviceTokenFetcher* token_fetcher, 200 CloudPolicyIdentityStrategy* identity_strategy, 201 PolicyNotifier* notifier, 202 int64 policy_refresh_rate_ms, 203 int policy_refresh_deviation_factor_percent, 204 int64 policy_refresh_deviation_max_ms, 205 int64 policy_refresh_error_delay_ms) { 206 DCHECK(cache); 207 208 service_ = service; 209 cache_ = cache; 210 token_fetcher_ = token_fetcher; 211 identity_strategy_ = identity_strategy; 212 notifier_ = notifier; 213 state_ = STATE_TOKEN_UNAVAILABLE; 214 delayed_work_task_ = NULL; 215 policy_refresh_rate_ms_ = policy_refresh_rate_ms; 216 policy_refresh_deviation_factor_percent_ = 217 policy_refresh_deviation_factor_percent; 218 policy_refresh_deviation_max_ms_ = policy_refresh_deviation_max_ms; 219 policy_refresh_error_delay_ms_ = policy_refresh_error_delay_ms; 220 effective_policy_refresh_error_delay_ms_ = policy_refresh_error_delay_ms; 221 222 token_fetcher_->AddObserver(this); 223 identity_strategy_->AddObserver(this); 224 if (!identity_strategy_->GetDeviceToken().empty()) 225 SetState(STATE_TOKEN_VALID); 226 else 227 SetState(STATE_TOKEN_UNAVAILABLE); 228 } 229 230 void CloudPolicyController::FetchToken() { 231 std::string username; 232 std::string auth_token; 233 std::string device_id = identity_strategy_->GetDeviceID(); 234 std::string machine_id = identity_strategy_->GetMachineID(); 235 std::string machine_model = identity_strategy_->GetMachineModel(); 236 em::DeviceRegisterRequest_Type policy_type = 237 identity_strategy_->GetPolicyRegisterType(); 238 if (identity_strategy_->GetCredentials(&username, &auth_token) && 239 CanBeInManagedDomain(username)) { 240 token_fetcher_->FetchToken(auth_token, device_id, policy_type, 241 machine_id, machine_model); 242 } 243 } 244 245 void CloudPolicyController::SendPolicyRequest() { 246 backend_.reset(service_->CreateBackend()); 247 DCHECK(!identity_strategy_->GetDeviceToken().empty()); 248 em::DevicePolicyRequest policy_request; 249 em::PolicyFetchRequest* fetch_request = policy_request.add_request(); 250 fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA); 251 fetch_request->set_policy_type(identity_strategy_->GetPolicyType()); 252 if (!cache_->is_unmanaged() && 253 !cache_->last_policy_refresh_time().is_null()) { 254 base::TimeDelta timestamp = 255 cache_->last_policy_refresh_time() - base::Time::UnixEpoch(); 256 fetch_request->set_timestamp(timestamp.InMilliseconds()); 257 } 258 int key_version = 0; 259 if (cache_->GetPublicKeyVersion(&key_version)) 260 fetch_request->set_public_key_version(key_version); 261 262 backend_->ProcessPolicyRequest(identity_strategy_->GetDeviceToken(), 263 identity_strategy_->GetDeviceID(), 264 policy_request, this); 265 } 266 267 void CloudPolicyController::DoDelayedWork() { 268 DCHECK(delayed_work_task_); 269 delayed_work_task_ = NULL; 270 DoWork(); 271 } 272 273 void CloudPolicyController::DoWork() { 274 switch (state_) { 275 case STATE_TOKEN_UNAVAILABLE: 276 case STATE_TOKEN_ERROR: 277 FetchToken(); 278 return; 279 case STATE_TOKEN_VALID: 280 case STATE_POLICY_VALID: 281 case STATE_POLICY_ERROR: 282 case STATE_POLICY_UNAVAILABLE: 283 SendPolicyRequest(); 284 return; 285 case STATE_TOKEN_UNMANAGED: 286 return; 287 } 288 289 NOTREACHED() << "Unhandled state" << state_; 290 } 291 292 void CloudPolicyController::CancelDelayedWork() { 293 if (delayed_work_task_) { 294 delayed_work_task_->Cancel(); 295 delayed_work_task_ = NULL; 296 } 297 } 298 299 void CloudPolicyController::SetState( 300 CloudPolicyController::ControllerState new_state) { 301 state_ = new_state; 302 backend_.reset(); // Discard any pending requests. 303 304 base::Time now(base::Time::NowFromSystemTime()); 305 base::Time refresh_at; 306 base::Time last_refresh(cache_->last_policy_refresh_time()); 307 if (last_refresh.is_null()) 308 last_refresh = now; 309 310 // Determine when to take the next step. 311 bool inform_notifier_done = false; 312 switch (state_) { 313 case STATE_TOKEN_UNMANAGED: 314 notifier_->Inform(CloudPolicySubsystem::UNMANAGED, 315 CloudPolicySubsystem::NO_DETAILS, 316 PolicyNotifier::POLICY_CONTROLLER); 317 break; 318 case STATE_TOKEN_UNAVAILABLE: 319 // The controller is not yet initialized and needs to immediately fetch 320 // token and policy if present. 321 case STATE_TOKEN_VALID: 322 // Immediately try to fetch the token on initialization or policy after a 323 // token update. Subsequent retries will respect the back-off strategy. 324 refresh_at = now; 325 // |notifier_| isn't informed about anything at this point, we wait for 326 // the result of the next action first. 327 break; 328 case STATE_POLICY_VALID: 329 // Delay is only reset if the policy fetch operation was successful. This 330 // will ensure the server won't get overloaded with retries in case of 331 // a bug on either side. 332 effective_policy_refresh_error_delay_ms_ = policy_refresh_error_delay_ms_; 333 refresh_at = 334 last_refresh + base::TimeDelta::FromMilliseconds(GetRefreshDelay()); 335 notifier_->Inform(CloudPolicySubsystem::SUCCESS, 336 CloudPolicySubsystem::NO_DETAILS, 337 PolicyNotifier::POLICY_CONTROLLER); 338 break; 339 case STATE_TOKEN_ERROR: 340 notifier_->Inform(CloudPolicySubsystem::NETWORK_ERROR, 341 CloudPolicySubsystem::BAD_DMTOKEN, 342 PolicyNotifier::POLICY_CONTROLLER); 343 inform_notifier_done = true; 344 case STATE_POLICY_ERROR: 345 if (!inform_notifier_done) { 346 notifier_->Inform(CloudPolicySubsystem::NETWORK_ERROR, 347 CloudPolicySubsystem::POLICY_NETWORK_ERROR, 348 PolicyNotifier::POLICY_CONTROLLER); 349 } 350 refresh_at = now + base::TimeDelta::FromMilliseconds( 351 effective_policy_refresh_error_delay_ms_); 352 effective_policy_refresh_error_delay_ms_ = 353 std::min(effective_policy_refresh_error_delay_ms_ * 2, 354 policy_refresh_rate_ms_); 355 break; 356 case STATE_POLICY_UNAVAILABLE: 357 effective_policy_refresh_error_delay_ms_ = policy_refresh_rate_ms_; 358 refresh_at = now + base::TimeDelta::FromMilliseconds( 359 effective_policy_refresh_error_delay_ms_); 360 notifier_->Inform(CloudPolicySubsystem::NETWORK_ERROR, 361 CloudPolicySubsystem::POLICY_NETWORK_ERROR, 362 PolicyNotifier::POLICY_CONTROLLER); 363 break; 364 } 365 366 // Update the delayed work task. 367 CancelDelayedWork(); 368 if (!refresh_at.is_null()) { 369 int64 delay = std::max<int64>((refresh_at - now).InMilliseconds(), 0); 370 delayed_work_task_ = method_factory_.NewRunnableMethod( 371 &CloudPolicyController::DoDelayedWork); 372 MessageLoop::current()->PostDelayedTask(FROM_HERE, delayed_work_task_, 373 delay); 374 } 375 } 376 377 int64 CloudPolicyController::GetRefreshDelay() { 378 int64 deviation = (policy_refresh_deviation_factor_percent_ * 379 policy_refresh_rate_ms_) / 100; 380 deviation = std::min(deviation, policy_refresh_deviation_max_ms_); 381 return policy_refresh_rate_ms_ - base::RandGenerator(deviation + 1); 382 } 383 384 } // namespace policy 385