File: recovery_improved_component_installer.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 (188 lines) | stat: -rw-r--r-- 7,629 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
// Copyright 2017 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_COMPONENT_UPDATER_RECOVERY_IMPROVED_COMPONENT_INSTALLER_H_
#define CHROME_BROWSER_COMPONENT_UPDATER_RECOVERY_IMPROVED_COMPONENT_INSTALLER_H_

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/types/expected.h"
#include "base/values.h"
#include "components/component_updater/component_installer.h"
#include "components/crx_file/crx_verifier.h"
#include "components/update_client/unpacker.h"
#include "components/update_client/update_client.h"

namespace base {
class CommandLine;
class Process;
}  // namespace base

class PrefService;

namespace component_updater {

// Handles the |run| action for the recovery component.
//
// The recovery component consists of a executable program (the name of the
// program is known at build time but it depends on the operating system),
// wrapped inside a CRX container, which CRX is itself contained inside a
// component updater CRX payload. In other words, looking from outside, the
// component updater installs and updates a CRX, containing a CRX, containing
// a program. When this program is run, it can restore the functionality of
// the Chrome updater.

// The |RecoveryComponentActionHandler| is responsible for unpacking the inner
// CRX described above, and running the executable program inside it.
//
// The |RecoveryComponentActionHandler::Handle| function is invoked as a result
// of an |action| element present in the update response for the recovery
// component. Note that the |action| element can be present in the update
// response even if there are no updates for the recovery component.
//
// When Chrome is installed per-system, the CRX is being handed over to
// a system elevator, which unpacks the CRX in a secure location of the
// file system, and runs the recovery program with system privileges.
//
// When Chrome is installed per-user, the CRX is unpacked in a temporary
// directory for the user, and the recovery program runs with normal user
// privileges.
class RecoveryComponentActionHandler : public update_client::ActionHandler {
 public:
  static scoped_refptr<update_client::ActionHandler> MakeActionHandler();

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

  // Overrides for update_client::RecoveryComponentActionHandler. |action| is an
  // absolute file path to a CRX to be unpacked. |session_id| contains the
  // session id corresponding to the current update transaction. The session id
  // is passed as a command line argument to the recovery program, and sent as
  // part of the completion pings during the actual recovery.
  void Handle(const base::FilePath& action,
              const std::string& session_id,
              Callback callback) override;

 protected:
  static constexpr base::TaskTraits kThreadPoolTaskTraits = {
      base::MayBlock(), base::TaskPriority::BEST_EFFORT,
      base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN};

  // This task joins a process, hence .WithBaseSyncPrimitives().
  static constexpr base::TaskTraits kThreadPoolTaskTraitsRunCommand = {
      base::MayBlock(), base::WithBaseSyncPrimitives(),
      base::TaskPriority::BEST_EFFORT,
      base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN};

  // Accepts only the production key hash and the production proof by default.
  RecoveryComponentActionHandler(
      const std::vector<uint8_t>& key_hash = {std::begin(kKeyHash),
                                              std::end(kKeyHash)},
      crx_file::VerifierFormat verifier_format =
          crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF);
  ~RecoveryComponentActionHandler() override;

  base::FilePath crx_path() const { return crx_path_; }

  std::string session_id() const { return session_id_; }

  scoped_refptr<base::SequencedTaskRunner> main_task_runner() {
    return main_task_runner_;
  }

 private:
  // The production public key hash for the inner CRX.
  static constexpr uint8_t kKeyHash[] = {
      0x5f, 0x94, 0xe0, 0x3c, 0x64, 0x30, 0x9f, 0xbc, 0xfe, 0x00, 0x9a,
      0x27, 0x3e, 0x52, 0xbf, 0xa5, 0x84, 0xb9, 0xb3, 0x75, 0x07, 0x29,
      0xde, 0xfa, 0x32, 0x76, 0xd9, 0x93, 0xb5, 0xa3, 0xce, 0x02};

  virtual base::CommandLine MakeCommandLine(
      const base::FilePath& unpack_path) const = 0;
  virtual void PrepareFiles(const base::FilePath& unpack_path) const = 0;
  virtual void Elevate(Callback callback) = 0;

  void Unpack();
  void UnpackComplete(const update_client::Unpacker::Result& result);
  void RunCommand(const base::CommandLine& cmdline);

  // `process` contains the process object, if the process was successfully
  // created or an error value otherwise (if the error is available on that
  // platform).
  void WaitForCommand(base::expected<base::Process, int> process_or_error);

  SEQUENCE_CHECKER(sequence_checker_);

  // Executes tasks in the context of the sequence which created this object.
  scoped_refptr<base::SequencedTaskRunner> main_task_runner_ =
      base::SequencedTaskRunner::GetCurrentDefault();

  // The key hash and its proof for the inner CRX to be unpacked and run.
  const std::vector<uint8_t> key_hash_;
  const crx_file::VerifierFormat verifier_format_;

  // Contains the CRX specified as a run action.
  base::FilePath crx_path_;

  // The session id of the update transaction, as defined by |update_client|.
  std::string session_id_;

  // Called when the action is handled.
  Callback callback_;

  // Contains the path where the action CRX is unpacked in the per-user case.
  base::FilePath unpack_path_;
};

class ComponentUpdateService;

class RecoveryImprovedInstallerPolicy : public ComponentInstallerPolicy {
 public:
  explicit RecoveryImprovedInstallerPolicy(PrefService* prefs)
      : prefs_(prefs) {}
  RecoveryImprovedInstallerPolicy(const RecoveryImprovedInstallerPolicy&) =
      delete;
  RecoveryImprovedInstallerPolicy& operator=(
      const RecoveryImprovedInstallerPolicy&) = delete;

 private:
  friend class RecoveryImprovedInstallerTest;

  // ComponentInstallerPolicy implementation.
  bool SupportsGroupPolicyEnabledComponentUpdates() const override;
  bool RequiresNetworkEncryption() const override;
  update_client::CrxInstaller::Result OnCustomInstall(
      const base::Value::Dict& manifest,
      const base::FilePath& install_dir) override;
  void OnCustomUninstall() override;
  bool VerifyInstallation(const base::Value::Dict& manifest,
                          const base::FilePath& install_dir) const override;
  void ComponentReady(const base::Version& version,
                      const base::FilePath& install_dir,
                      base::Value::Dict manifest) override;
  base::FilePath GetRelativeInstallDir() const override;
  void GetHash(std::vector<uint8_t>* hash) const override;
  std::string GetName() const override;
  update_client::InstallerAttributes GetInstallerAttributes() const override;

  raw_ptr<PrefService> prefs_;
};

void RegisterRecoveryImprovedComponent(ComponentUpdateService* cus,
                                       PrefService* prefs);

}  // namespace component_updater

#endif  // CHROME_BROWSER_COMPONENT_UPDATER_RECOVERY_IMPROVED_COMPONENT_INSTALLER_H_