Home | History | Annotate | Download | only in policy
      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.
    106   std::string device_id() const { return device_id_; }
    107 
    108   // Current 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