auto_enrollment_client.h revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_CHROMEOS_POLICY_AUTO_ENROLLMENT_CLIENT_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_CHROMEOS_POLICY_AUTO_ENROLLMENT_CLIENT_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/time/time.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/network_change_notifier.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/protobuf/src/google/protobuf/repeated_field.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrefRegistrySimple; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrefService; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace enterprise_management { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeviceManagementResponse; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestContextGetter; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeviceManagementRequestJob; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeviceManagementService; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Interacts with the device management service and determines whether this 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// machine should automatically enter the Enterprise Enrollment screen during 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OOBE. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AutoEnrollmentClient 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public net::NetworkChangeNotifier::NetworkChangeObserver { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indicates the current state of the auto-enrollment check. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum State { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Working, another event will be fired eventually. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_PENDING, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Failed to connect to DMServer. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_CONNECTION_ERROR, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Connection successful, but the server failed to generate a valid reply. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_SERVER_ERROR, 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check completed successfully, enrollment should be triggered. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_TRIGGER_ENROLLMENT, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check completed successfully, enrollment not applicable. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STATE_NO_ENROLLMENT, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used for signaling progress to a consumer. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(State)> ProgressCallback; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |progress_callback| will be invoked whenever some significant event happens 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // as part of the protocol, after Start() is invoked. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The result of the protocol will be cached in |local_state|. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |power_initial| and |power_limit| are exponents of power-of-2 values which 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be the initial modulus and the maximum modulus used by this client. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoEnrollmentClient( 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProgressCallback& progress_callback, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeviceManagementService* device_management_service, 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefService* local_state, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> system_request_context, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& server_backed_state_key, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool retrieve_device_state, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int power_initial, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int power_limit); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AutoEnrollmentClient(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Registers preferences in local state. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void RegisterPrefs(PrefRegistrySimple* registry); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if auto-enrollment is disabled in this device. In that case, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instances returned by Create() fail immediately once Start() is invoked. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsDisabled(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convenience method to create instances of this class. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static AutoEnrollmentClient* Create( 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProgressCallback& progress_callback); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancels auto-enrollment. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function does not interrupt a running auto-enrollment check. It only 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stores a pref in |local_state| that prevents the client from entering 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // auto-enrollment mode for the future. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void CancelAutoEnrollment(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts the auto-enrollment check protocol with the device management 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // service. Subsequent calls drop any previous requests. Notice that this 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call can invoke the |progress_callback_| if errors occur. 94 void Start(); 95 96 // Cancels any pending requests. |progress_callback_| will not be invoked. 97 // |this| will delete itself. 98 void CancelAndDeleteSoon(); 99 100 // Returns the device_id randomly generated for the auto-enrollment requests. 101 // It can be reused for subsequent requests to the device management service. 102 std::string device_id() const { return device_id_; } 103 104 // Current state. 105 State state() const { return state_; } 106 107 // Implementation of net::NetworkChangeNotifier::NetworkChangeObserver: 108 virtual void OnNetworkChanged( 109 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE; 110 111 private: 112 typedef bool (AutoEnrollmentClient::*RequestCompletionHandler)( 113 DeviceManagementStatus, 114 int, 115 const enterprise_management::DeviceManagementResponse&); 116 117 // Tries to load the result of a previous execution of the protocol from 118 // local state. Returns true if that decision has been made and is valid. 119 bool GetCachedDecision(); 120 121 // Kicks protocol processing, restarting the current step if applicable. 122 // Returns true if progress has been made, false if the protocol is done. 123 bool RetryStep(); 124 125 // Cleans up and invokes |progress_callback_|. 126 void ReportProgress(State state); 127 128 // Calls RetryStep() to make progress or determine that all is done. In the 129 // latter case, calls ReportProgress(). 130 void NextStep(); 131 132 // Sends an auto-enrollment check request to the device management service. 133 bool SendBucketDownloadRequest(); 134 135 // Sends a device state download request to the device management service. 136 bool SendDeviceStateRequest(); 137 138 // Runs the response handler for device management requests and calls 139 // NextStep(). 140 void HandleRequestCompletion( 141 RequestCompletionHandler handler, 142 DeviceManagementStatus status, 143 int net_error, 144 const enterprise_management::DeviceManagementResponse& response); 145 146 // Parses the server response to a bucket download request. 147 bool OnBucketDownloadRequestCompletion( 148 DeviceManagementStatus status, 149 int net_error, 150 const enterprise_management::DeviceManagementResponse& response); 151 152 // Parses the server response to a device state request. 153 bool OnDeviceStateRequestCompletion( 154 DeviceManagementStatus status, 155 int net_error, 156 const enterprise_management::DeviceManagementResponse& response); 157 158 // Returns true if |server_backed_state_key_hash_| is contained in |hashes|. 159 bool IsIdHashInProtobuf( 160 const google::protobuf::RepeatedPtrField<std::string>& hashes); 161 162 // Updates UMA histograms for bucket download timings. 163 void UpdateBucketDownloadTimingHistograms(); 164 165 // Callback to invoke when the protocol generates a relevant event. This can 166 // be either successful completion or an error that requires external action. 167 ProgressCallback progress_callback_; 168 169 // Current state. 170 State state_; 171 172 // Whether the hash bucket check succeeded, indicating that the server knows 173 // this device and might have keep state for it. 174 bool has_server_state_; 175 176 // Whether the download of server-kept device state completed successfully. 177 bool device_state_available_; 178 179 // Randomly generated device id for the auto-enrollment requests. 180 std::string device_id_; 181 182 // Stable state key and its SHA-256 digest. 183 std::string server_backed_state_key_; 184 std::string server_backed_state_key_hash_; 185 186 // Whether device state should be retrieved from the server. 187 bool retrieve_device_state_; 188 189 // Power-of-2 modulus to try next. 190 int current_power_; 191 192 // Power of the maximum power-of-2 modulus that this client will accept from 193 // a retry response from the server. 194 int power_limit_; 195 196 // Number of requests for a different modulus received from the server. 197 // Used to determine if the server keeps asking for different moduli. 198 int modulus_updates_received_; 199 200 // Used to communicate with the device management service. 201 DeviceManagementService* device_management_service_; 202 scoped_ptr<DeviceManagementRequestJob> request_job_; 203 204 // PrefService where the protocol's results are cached. 205 PrefService* local_state_; 206 207 // The request context to use to perform the auto enrollment request. 208 scoped_refptr<net::URLRequestContextGetter> request_context_; 209 210 // Times used to determine the duration of the protocol, and the extra time 211 // needed to complete after the signin was complete. 212 // If |time_start_| is not null, the protocol is still running. 213 // If |time_extra_start_| is not null, the protocol is still running but our 214 // owner has relinquished ownership. 215 base::Time time_start_; 216 base::Time time_extra_start_; 217 218 DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentClient); 219}; 220 221} // namespace policy 222 223#endif // CHROME_BROWSER_CHROMEOS_POLICY_AUTO_ENROLLMENT_CLIENT_H_ 224