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 #ifndef CHROME_BROWSER_CHROMEOS_POLICY_AUTO_ENROLLMENT_CLIENT_H_ 6 #define CHROME_BROWSER_CHROMEOS_POLICY_AUTO_ENROLLMENT_CLIENT_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/callback.h" 12 #include "base/compiler_specific.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/time/time.h" 15 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 16 #include "net/base/network_change_notifier.h" 17 #include "third_party/protobuf/src/google/protobuf/repeated_field.h" 18 19 class PrefRegistrySimple; 20 class PrefService; 21 22 namespace enterprise_management { 23 class DeviceManagementResponse; 24 } 25 26 namespace net { 27 class URLRequestContextGetter; 28 } 29 30 namespace policy { 31 32 class DeviceManagementRequestJob; 33 class DeviceManagementService; 34 35 // Indicates the current state of the auto-enrollment check. 36 enum AutoEnrollmentState { 37 // Not yet started. 38 AUTO_ENROLLMENT_STATE_IDLE, 39 // Working, another event will be fired eventually. 40 AUTO_ENROLLMENT_STATE_PENDING, 41 // Failed to connect to DMServer. 42 AUTO_ENROLLMENT_STATE_CONNECTION_ERROR, 43 // Connection successful, but the server failed to generate a valid reply. 44 AUTO_ENROLLMENT_STATE_SERVER_ERROR, 45 // Check completed successfully, enrollment should be triggered. 46 AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, 47 // Check completed successfully, enrollment not applicable. 48 AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, 49 }; 50 51 // Interacts with the device management service and determines whether this 52 // machine should automatically enter the Enterprise Enrollment screen during 53 // OOBE. 54 class AutoEnrollmentClient 55 : public net::NetworkChangeNotifier::NetworkChangeObserver { 56 public: 57 // The modulus value is sent in an int64 field in the protobuf, whose maximum 58 // value is 2^63-1. So 2^64 and 2^63 can't be represented as moduli and the 59 // max is 2^62 (when the moduli are restricted to powers-of-2). 60 static const int kMaximumPower = 62; 61 62 // Used for signaling progress to a consumer. 63 typedef base::Callback<void(AutoEnrollmentState)> ProgressCallback; 64 65 // |progress_callback| will be invoked whenever some significant event happens 66 // as part of the protocol, after Start() is invoked. 67 // The result of the protocol will be cached in |local_state|. 68 // |power_initial| and |power_limit| are exponents of power-of-2 values which 69 // will be the initial modulus and the maximum modulus used by this client. 70 AutoEnrollmentClient( 71 const ProgressCallback& progress_callback, 72 DeviceManagementService* device_management_service, 73 PrefService* local_state, 74 scoped_refptr<net::URLRequestContextGetter> system_request_context, 75 const std::string& server_backed_state_key, 76 bool retrieve_device_state, 77 int power_initial, 78 int power_limit); 79 virtual ~AutoEnrollmentClient(); 80 81 // Registers preferences in local state. 82 static void RegisterPrefs(PrefRegistrySimple* registry); 83 84 // Cancels auto-enrollment. 85 // This function does not interrupt a running auto-enrollment check. It only 86 // stores a pref in |local_state| that prevents the client from entering 87 // auto-enrollment mode for the future. 88 static void CancelAutoEnrollment(); 89 90 // Starts the auto-enrollment check protocol with the device management 91 // service. Subsequent calls drop any previous requests. Notice that this 92 // call can invoke the |progress_callback_| if errors occur. 93 void Start(); 94 95 // Triggers a retry of the currently pending step. This is intended to be 96 // called by consumers when they become aware of environment changes (such as 97 // captive portal setup being complete). 98 void Retry(); 99 100 // Cancels any pending requests. |progress_callback_| will not be invoked. 101 // |this| will delete itself. 102 void CancelAndDeleteSoon(); 103 104 // Returns the device_id randomly generated for the auto-enrollment requests. 105 // It can be reused for subsequent requests to the device management service. device_id()106 std::string device_id() const { return device_id_; } 107 108 // Current state. state()109 AutoEnrollmentState state() const { return state_; } 110 111 // Implementation of net::NetworkChangeNotifier::NetworkChangeObserver: 112 virtual void OnNetworkChanged( 113 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE; 114 115 private: 116 typedef bool (AutoEnrollmentClient::*RequestCompletionHandler)( 117 DeviceManagementStatus, 118 int, 119 const enterprise_management::DeviceManagementResponse&); 120 121 // Tries to load the result of a previous execution of the protocol from 122 // local state. Returns true if that decision has been made and is valid. 123 bool GetCachedDecision(); 124 125 // Kicks protocol processing, restarting the current step if applicable. 126 // Returns true if progress has been made, false if the protocol is done. 127 bool RetryStep(); 128 129 // Cleans up and invokes |progress_callback_|. 130 void ReportProgress(AutoEnrollmentState state); 131 132 // Calls RetryStep() to make progress or determine that all is done. In the 133 // latter case, calls ReportProgress(). 134 void NextStep(); 135 136 // Sends an auto-enrollment check request to the device management service. 137 bool SendBucketDownloadRequest(); 138 139 // Sends a device state download request to the device management service. 140 bool SendDeviceStateRequest(); 141 142 // Runs the response handler for device management requests and calls 143 // NextStep(). 144 void HandleRequestCompletion( 145 RequestCompletionHandler handler, 146 DeviceManagementStatus status, 147 int net_error, 148 const enterprise_management::DeviceManagementResponse& response); 149 150 // Parses the server response to a bucket download request. 151 bool OnBucketDownloadRequestCompletion( 152 DeviceManagementStatus status, 153 int net_error, 154 const enterprise_management::DeviceManagementResponse& response); 155 156 // Parses the server response to a device state request. 157 bool OnDeviceStateRequestCompletion( 158 DeviceManagementStatus status, 159 int net_error, 160 const enterprise_management::DeviceManagementResponse& response); 161 162 // Returns true if |server_backed_state_key_hash_| is contained in |hashes|. 163 bool IsIdHashInProtobuf( 164 const google::protobuf::RepeatedPtrField<std::string>& hashes); 165 166 // Updates UMA histograms for bucket download timings. 167 void UpdateBucketDownloadTimingHistograms(); 168 169 // Callback to invoke when the protocol generates a relevant event. This can 170 // be either successful completion or an error that requires external action. 171 ProgressCallback progress_callback_; 172 173 // Current state. 174 AutoEnrollmentState state_; 175 176 // Whether the hash bucket check succeeded, indicating that the server knows 177 // this device and might have keep state for it. 178 bool has_server_state_; 179 180 // Whether the download of server-kept device state completed successfully. 181 bool device_state_available_; 182 183 // Randomly generated device id for the auto-enrollment requests. 184 std::string device_id_; 185 186 // Stable state key and its SHA-256 digest. 187 std::string server_backed_state_key_; 188 std::string server_backed_state_key_hash_; 189 190 // Whether device state should be retrieved from the server. 191 bool retrieve_device_state_; 192 193 // Power-of-2 modulus to try next. 194 int current_power_; 195 196 // Power of the maximum power-of-2 modulus that this client will accept from 197 // a retry response from the server. 198 int power_limit_; 199 200 // Number of requests for a different modulus received from the server. 201 // Used to determine if the server keeps asking for different moduli. 202 int modulus_updates_received_; 203 204 // Used to communicate with the device management service. 205 DeviceManagementService* device_management_service_; 206 scoped_ptr<DeviceManagementRequestJob> request_job_; 207 208 // PrefService where the protocol's results are cached. 209 PrefService* local_state_; 210 211 // The request context to use to perform the auto enrollment request. 212 scoped_refptr<net::URLRequestContextGetter> request_context_; 213 214 // Times used to determine the duration of the protocol, and the extra time 215 // needed to complete after the signin was complete. 216 // If |time_start_| is not null, the protocol is still running. 217 // If |time_extra_start_| is not null, the protocol is still running but our 218 // owner has relinquished ownership. 219 base::Time time_start_; 220 base::Time time_extra_start_; 221 222 DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentClient); 223 }; 224 225 } // namespace policy 226 227 #endif // CHROME_BROWSER_CHROMEOS_POLICY_AUTO_ENROLLMENT_CLIENT_H_ 228