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