File: auto_enrollment_controller.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (199 lines) | stat: -rw-r--r-- 9,096 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_POLICY_ENROLLMENT_AUTO_ENROLLMENT_CONTROLLER_H_
#define CHROME_BROWSER_ASH_POLICY_ENROLLMENT_AUTO_ENROLLMENT_CONTROLLER_H_

#include <memory>
#include <optional>

#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "chrome/browser/ash/policy/enrollment/auto_enrollment_state.h"
#include "chrome/browser/ash/policy/enrollment/enrollment_state_fetcher.h"
#include "chrome/browser/ash/policy/enrollment/psm/rlwe_dmserver_client_impl.h"
#include "chrome/browser/ash/settings/device_settings_service.h"
#include "chromeos/ash/components/dbus/device_management/device_management_interface.pb.h"
#include "chromeos/ash/components/network/network_state_handler_observer.h"

namespace ash {
class NetworkStateHandler;
}  // namespace ash

namespace policy {

class DeviceManagementService;
class ServerBackedStateKeysBroker;

// Drives the enrollment state determinatio (for historical reasons called
// auto-enrollment check), running an `EnrollmentStateFetcher` if appropriate to
// make a decision.
// The controller tracks network status to retry when the device is going
// online in case of a prior failure.
class AutoEnrollmentController : public ash::NetworkStateHandlerObserver {
 public:
  using ProgressCallbackList =
      base::RepeatingCallbackList<void(AutoEnrollmentState)>;
  using RlweClientFactory =
      policy::psm::RlweDmserverClientImpl::RlweClientFactory;

  explicit AutoEnrollmentController(
      scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory);

  AutoEnrollmentController(const AutoEnrollmentController&) = delete;
  AutoEnrollmentController& operator=(const AutoEnrollmentController&) = delete;

  ~AutoEnrollmentController() override;

  // Starts the auto-enrollment check.  Safe to call multiple times: aborts in
  // case a check is currently running or a decision has already been made.
  void Start();

  // Returns true if auto-enrollment check is running.
  bool IsInProgress() const;

  // Registers a callback to invoke on state changes.
  base::CallbackListSubscription RegisterProgressCallback(
      const ProgressCallbackList::CallbackType& callback);

  // ash::NetworkStateHandlerObserver:
  void PortalStateChanged(
      const ash::NetworkState* default_network,
      const ash::NetworkState::PortalState portal_state) override;
  void OnShuttingDown() override;

  const std::optional<AutoEnrollmentState>& state() const { return state_; }

  // Sets the factory function that will be used to create the
  // `psm::RlweClient` for tests.
  void SetRlweClientFactoryForTesting(RlweClientFactory test_factory);

  // Sets factory that will be used to create `EnrollmentStateFetcher`.  To use
  // the default factory again, call with `base::NullCallback()`.
  void SetEnrollmentStateFetcherFactoryForTesting(
      EnrollmentStateFetcher::Factory enrollment_state_fetcher_factory);

  // Returns safeguard timer. Used for testing
  base::OneShotTimer& SafeguardTimerForTesting() { return safeguard_timer_; }

  // The OOBE network error screen can provide a link to sign in as guest.
  // This should only be allowed if
  //   * enrollment state determination has completed,
  //   * forced enrollment is not strictly required (using guest mode would be
  //     considered an enrollment escape).
  // Use `IsGuestSigninAllowed` to determine if guest mode should be allowed.
  bool IsGuestSigninAllowed() const;

 protected:
  // Complete constructor which can be used to inject testing modules.
  AutoEnrollmentController(
      ash::DeviceSettingsService* device_settings_service,
      DeviceManagementService* device_management_service,
      ServerBackedStateKeysBroker* state_keys_broker,
      ash::NetworkStateHandler* network_state_handler,
      RlweClientFactory psm_rlwe_client_factory,
      EnrollmentStateFetcher::Factory enrollment_state_fetcher_factory,
      scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory);

 private:
  // Sets `state_` and notifies `progress_callbacks_`.
  void UpdateState(AutoEnrollmentState state);

  // Clears everything that needs to be cleared at OOBE if
  // the device gets the response that forced re-enrollment is not required.
  // This currently removes firmware management parameters and sets
  // block_devmode=0 in RW_VPD by making asynchronous calls to the respective
  // D-Bus services.
  // The notifications have to be sent only after the FWMP and VPD is cleared,
  // because the user might try to switch to devmode. In this case, if
  // block_devmode is in FWMP and the clear operation didn't finish, the switch
  // would be denied. Also the safeguard timer has to be active until the FWMP
  // is cleared to avoid the risk of blocked flow.
  void StartCleanupForcedReEnrollment();

  // Makes a D-Bus call to cryptohome to remove the firmware management
  // parameters (FWMP) from TPM. Stops the `safeguard_timer_` and notifies the
  // `progress_callbacks_` in case cryptohome does not become available and the
  // timer is still running.
  // `service_is_ready` indicates if the cryptohome D-Bus service is ready.
  void StartRemoveFirmwareManagementParameters(bool service_is_ready);

  // Callback for RemoveFirmwareManagementParameters(). If an error is received
  // here, it is logged only, without changing the flow after that, because
  // the FWMP is used only for newer devices.
  // This also starts the VPD clearing process.
  void OnFirmwareManagementParametersRemoved(
      std::optional<device_management::RemoveFirmwareManagementParametersReply>
          reply);

  // Makes a D-Bus call to session_manager to set block_devmode=0 in RW_VPD.
  // Stops the `safeguard_timer_` and notifies the `progress_callbacks_` in case
  // session manager does not become available and the timer is still running.
  // `service_is_ready` indicates if the session manager D-Bus service is ready.
  void StartClearBlockDevmodeVpd(bool service_is_ready);

  // Callback for `StartClearBlockDevmodeVpd`. If clearing block_devmode did
  // not succeed, it is logged only, without changing the flow after that.
  // This also notifies the `progress_callbacks_` since the forced re-enrollment
  // cleanup is finished at this point.
  void OnBlockDevmodeClearedVpd(bool succeeded);

  // Handles timeout of the safeguard timer and stops waiting for a result.
  void Timeout();

  // Used for checking ownership.
  raw_ptr<ash::DeviceSettingsService> device_settings_service_;

  // Used for communication with management service.
  raw_ptr<DeviceManagementService> device_management_service_;

  // Used for retrieving device state keys.
  raw_ptr<ServerBackedStateKeysBroker> state_keys_broker_;

  std::optional<AutoEnrollmentState> state_;
  ProgressCallbackList progress_callbacks_;

  // Constructs the PSM RLWE client. It will either create a fake or real
  // implementation of the client.
  // It is only used for PSM during creating the client for initial enrollment.
  RlweClientFactory psm_rlwe_client_factory_;

  // This timer acts as a belt-and-suspenders safety for the case where one of
  // the asynchronous steps required to make the auto-enrollment decision
  // doesn't come back. Even though in theory they should all terminate, better
  // safe than sorry: There are DBus interactions, an entire network stack etc.
  // - just too many moving pieces to be confident there are no bugs. If
  // something goes wrong, the timer will ensure that a decision gets made
  // eventually, which is crucial to not block OOBE forever. See
  // http://crbug.com/433634 for background.
  // The timer is expected to run during the state determination. The controller
  // is considered idle and can be restarted when the timer is not running.
  base::OneShotTimer safeguard_timer_;

  // Enrollment state fetcher. Invokes `UpdateState` on success or failure.
  std::unique_ptr<EnrollmentStateFetcher> enrollment_state_fetcher_;

  // Factory to create the `enrollment_state_fetcher_`. By default, it is set to
  // `EnrollmentStateFetcher::Create`, but can be overridden with
  // `SetEnrollmentStateFetcherFactoryForTesting`.
  EnrollmentStateFetcher::Factory enrollment_state_fetcher_factory_;

  // Shared factory for outgoing network requests.
  scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;

  raw_ptr<ash::NetworkStateHandler> network_state_handler_;
  // Observes network state and calls `PortalStateChanged` when it changes from
  // the start until the auto-enrollment state is resolved. Triggers a retry
  // when the device goes online.
  ash::NetworkStateHandlerScopedObservation network_state_observation_{this};

  base::WeakPtrFactory<AutoEnrollmentController> weak_ptr_factory_{this};
};

}  // namespace policy

#endif  // CHROME_BROWSER_ASH_POLICY_ENROLLMENT_AUTO_ENROLLMENT_CONTROLLER_H_