• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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