omaha_request_params.h revision 02c1864e204997175302b1aebe3e0be9c6699ea5
1// Copyright (c) 2012 The Chromium OS 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 UPDATE_ENGINE_OMAHA_REQUEST_PARAMS_H_
6#define UPDATE_ENGINE_OMAHA_REQUEST_PARAMS_H_
7
8#include <stdint.h>
9
10#include <string>
11
12#include <base/macros.h>
13#include <base/time/time.h>
14#include <gtest/gtest_prod.h>  // for FRIEND_TEST
15
16// This gathers local system information and prepares info used by the
17// Omaha request action.
18
19namespace chromeos_update_engine {
20
21// The default "official" Omaha update URL.
22extern const char kProductionOmahaUrl[];
23
24// The autoupdate test Omaha update URL.
25extern const char kAUTestOmahaUrl[];
26
27class SystemState;
28
29// This class encapsulates the data Omaha gets for the request, along with
30// essential state needed for the processing of the request/response.  The
31// strings in this struct should not be XML escaped.
32//
33// TODO(jaysri): chromium-os:39752 tracks the need to rename this class to
34// reflect its lifetime more appropriately.
35class OmahaRequestParams {
36 public:
37  explicit OmahaRequestParams(SystemState* system_state)
38      : system_state_(system_state),
39        os_platform_(kOsPlatform),
40        os_version_(kOsVersion),
41        board_app_id_(kAppId),
42        canary_app_id_(kAppId),
43        delta_okay_(true),
44        interactive_(false),
45        wall_clock_based_wait_enabled_(false),
46        update_check_count_wait_enabled_(false),
47        min_update_checks_needed_(kDefaultMinUpdateChecks),
48        max_update_checks_allowed_(kDefaultMaxUpdateChecks),
49        is_powerwash_allowed_(false),
50        force_lock_down_(false),
51        forced_lock_down_(false) {
52    InitFromLsbValue();
53  }
54
55  OmahaRequestParams(SystemState* system_state,
56                     const std::string& in_os_platform,
57                     const std::string& in_os_version,
58                     const std::string& in_os_sp,
59                     const std::string& in_os_board,
60                     const std::string& in_app_id,
61                     const std::string& in_app_version,
62                     const std::string& in_app_lang,
63                     const std::string& in_target_channel,
64                     const std::string& in_hwid,
65                     const std::string& in_fw_version,
66                     const std::string& in_ec_version,
67                     bool in_delta_okay,
68                     bool in_interactive,
69                     const std::string& in_update_url,
70                     const std::string& in_target_version_prefix)
71      : system_state_(system_state),
72        os_platform_(in_os_platform),
73        os_version_(in_os_version),
74        os_sp_(in_os_sp),
75        os_board_(in_os_board),
76        board_app_id_(in_app_id),
77        canary_app_id_(in_app_id),
78        app_version_(in_app_version),
79        app_lang_(in_app_lang),
80        current_channel_(in_target_channel),
81        target_channel_(in_target_channel),
82        hwid_(in_hwid),
83        fw_version_(in_fw_version),
84        ec_version_(in_ec_version),
85        delta_okay_(in_delta_okay),
86        interactive_(in_interactive),
87        update_url_(in_update_url),
88        target_version_prefix_(in_target_version_prefix),
89        wall_clock_based_wait_enabled_(false),
90        update_check_count_wait_enabled_(false),
91        min_update_checks_needed_(kDefaultMinUpdateChecks),
92        max_update_checks_allowed_(kDefaultMaxUpdateChecks),
93        is_powerwash_allowed_(false),
94        force_lock_down_(false),
95        forced_lock_down_(false) {}
96
97  virtual ~OmahaRequestParams() = default;
98
99  // Setters and getters for the various properties.
100  inline std::string os_platform() const { return os_platform_; }
101  inline std::string os_version() const { return os_version_; }
102  inline std::string os_sp() const { return os_sp_; }
103  inline std::string os_board() const { return os_board_; }
104  inline std::string board_app_id() const { return board_app_id_; }
105  inline std::string canary_app_id() const { return canary_app_id_; }
106  inline std::string app_lang() const { return app_lang_; }
107  inline std::string hwid() const { return hwid_; }
108  inline std::string fw_version() const { return fw_version_; }
109  inline std::string ec_version() const { return ec_version_; }
110
111  inline void set_app_version(const std::string& version) {
112    app_version_ = version;
113  }
114  inline std::string app_version() const { return app_version_; }
115
116  inline std::string current_channel() const { return current_channel_; }
117  inline std::string target_channel() const { return target_channel_; }
118  inline std::string download_channel() const { return download_channel_; }
119
120  // Can client accept a delta ?
121  inline void set_delta_okay(bool ok) { delta_okay_ = ok; }
122  inline bool delta_okay() const { return delta_okay_; }
123
124  // True if this is a user-initiated update check.
125  inline void set_interactive(bool interactive) { interactive_ = interactive; }
126  inline bool interactive() const { return interactive_; }
127
128  inline void set_update_url(const std::string& url) { update_url_ = url; }
129  inline std::string update_url() const { return update_url_; }
130
131  inline void set_target_version_prefix(const std::string& prefix) {
132    target_version_prefix_ = prefix;
133  }
134
135  inline std::string target_version_prefix() const {
136    return target_version_prefix_;
137  }
138
139  inline void set_wall_clock_based_wait_enabled(bool enabled) {
140    wall_clock_based_wait_enabled_ = enabled;
141  }
142  inline bool wall_clock_based_wait_enabled() const {
143    return wall_clock_based_wait_enabled_;
144  }
145
146  inline void set_waiting_period(base::TimeDelta period) {
147    waiting_period_ = period;
148  }
149  base::TimeDelta waiting_period() const { return waiting_period_; }
150
151  inline void set_update_check_count_wait_enabled(bool enabled) {
152    update_check_count_wait_enabled_ = enabled;
153  }
154
155  inline bool update_check_count_wait_enabled() const {
156    return update_check_count_wait_enabled_;
157  }
158
159  inline void set_min_update_checks_needed(int64_t min) {
160    min_update_checks_needed_ = min;
161  }
162  inline int64_t min_update_checks_needed() const {
163    return min_update_checks_needed_;
164  }
165
166  inline void set_max_update_checks_allowed(int64_t max) {
167    max_update_checks_allowed_ = max;
168  }
169  inline int64_t max_update_checks_allowed() const {
170    return max_update_checks_allowed_;
171  }
172
173  // True if we're trying to update to a more stable channel.
174  // i.e. index(target_channel) > index(current_channel).
175  virtual bool to_more_stable_channel() const;
176
177  // Returns the app id corresponding to the current value of the
178  // download channel.
179  virtual std::string GetAppId() const;
180
181  // Suggested defaults
182  static const char kAppId[];
183  static const char kOsPlatform[];
184  static const char kOsVersion[];
185  static const char kUpdateUrl[];
186  static const char kUpdateChannelKey[];
187  static const char kIsPowerwashAllowedKey[];
188  static const char kAutoUpdateServerKey[];
189  static const int64_t kDefaultMinUpdateChecks = 0;
190  static const int64_t kDefaultMaxUpdateChecks = 8;
191
192  // Initializes all the data in the object. Non-empty
193  // |in_app_version| or |in_update_url| prevents automatic detection
194  // of the parameter. Returns true on success, false otherwise.
195  bool Init(const std::string& in_app_version,
196            const std::string& in_update_url,
197            bool in_interactive);
198
199  // Permanently changes the release channel to |channel|. Performs a
200  // powerwash, if required and allowed.
201  // Returns true on success, false otherwise. Note: This call will fail if
202  // there's a channel change pending already. This is to serialize all the
203  // channel changes done by the user in order to avoid having to solve
204  // numerous edge cases around ensuring the powerwash happens as intended in
205  // all such cases.
206  virtual bool SetTargetChannel(const std::string& channel,
207                                bool is_powerwash_allowed);
208
209  // Updates the download channel for this particular attempt from the current
210  // value of target channel.  This method takes a "snapshot" of the current
211  // value of target channel and uses it for all subsequent Omaha requests for
212  // this attempt (i.e. initial request as well as download progress/error
213  // event requests). The snapshot will be updated only when either this method
214  // or Init is called again.
215  virtual void UpdateDownloadChannel();
216
217  virtual bool is_powerwash_allowed() const { return is_powerwash_allowed_; }
218
219  // Check if the provided update URL is official, meaning either the default
220  // autoupdate server or the autoupdate autotest server.
221  virtual bool IsUpdateUrlOfficial() const;
222
223  // For unit-tests.
224  void set_root(const std::string& root);
225  void set_current_channel(const std::string& channel) {
226    current_channel_ = channel;
227  }
228  void set_target_channel(const std::string& channel) {
229    target_channel_ = channel;
230  }
231
232  // Enforce security mode for testing purposes.
233  void SetLockDown(bool lock);
234
235 private:
236  FRIEND_TEST(OmahaRequestParamsTest, IsValidChannelTest);
237  FRIEND_TEST(OmahaRequestParamsTest, ShouldLockDownTest);
238  FRIEND_TEST(OmahaRequestParamsTest, ChannelIndexTest);
239  FRIEND_TEST(OmahaRequestParamsTest, LsbPreserveTest);
240  FRIEND_TEST(OmahaRequestParamsTest, CollectECFWVersionsTest);
241
242  // Use a validator that is a non-static member of this class so that its
243  // inputs can be mocked in unit tests (e.g., build type for IsValidChannel).
244  typedef bool(
245      OmahaRequestParams::*ValueValidator)(  // NOLINT(readability/casting)
246      const std::string&) const;
247
248  // Returns true if parameter values should be locked down for security
249  // reasons. If this is an official build running in normal boot mode, all
250  // values except the release channel are parsed only from the read-only rootfs
251  // partition and the channel values are restricted to a pre-approved set.
252  bool ShouldLockDown() const;
253
254  // Returns true if |channel| is a valid channel, false otherwise. This method
255  // restricts the channel value only if the image is official (see
256  // IsOfficialBuild).
257  bool IsValidChannel(const std::string& channel) const;
258
259  // Returns the index of the given channel.
260  int GetChannelIndex(const std::string& channel) const;
261
262  // Returns True if we should store the fw/ec versions based on our hwid_.
263  // Compares hwid to a set of whitelisted prefixes.
264  bool CollectECFWVersions() const;
265
266  // These are individual helper methods to initialize the said properties from
267  // the LSB value.
268  void SetTargetChannelFromLsbValue();
269  void SetCurrentChannelFromLsbValue();
270  void SetIsPowerwashAllowedFromLsbValue();
271
272  // Initializes the required properties from the LSB value.
273  void InitFromLsbValue();
274
275  // Fetches the value for a given key from
276  // /mnt/stateful_partition/etc/lsb-release if possible and |stateful_override|
277  // is true. Failing that, it looks for the key in /etc/lsb-release. If
278  // |validator| is non-null, uses it to validate and ignore invalid values.
279  std::string GetLsbValue(const std::string& key,
280                          const std::string& default_value,
281                          ValueValidator validator,
282                          bool stateful_override) const;
283
284  // Gets the machine type (e.g. "i686").
285  std::string GetMachineType() const;
286
287  // Global system context.
288  SystemState* system_state_;
289
290  // Basic properties of the OS and Application that go into the Omaha request.
291  std::string os_platform_;
292  std::string os_version_;
293  std::string os_sp_;
294  std::string os_board_;
295
296  // The board app id identifies the app id for the board irrespective of the
297  // channel that we're on. The canary app id identifies the app id to be used
298  // iff we're in the canary-channel. These values could be different depending
299  // on how the release tools are implemented.
300  std::string board_app_id_;
301  std::string canary_app_id_;
302
303  std::string app_version_;
304  std::string app_lang_;
305
306  // The three channel values we deal with.
307  // Current channel: is always the channel from /etc/lsb-release. It never
308  // changes. It's just read in during initialization.
309  std::string current_channel_;
310
311  // Target channel: It starts off with the value of current channel. But if
312  // the user changes the channel, then it'll have a different value. If the
313  // user changes multiple times, target channel will always contain the most
314  // recent change and is updated immediately to the user-selected value even
315  // if we're in the middle of a download (as opposed to download channel
316  // which gets updated only at the start of next download)
317  std::string target_channel_;
318
319  // The channel from which we're downloading the payload. This should normally
320  // be the same as target channel. But if the user made another channel change
321  // we started the download, then they'd be different, in which case, we'd
322  // detect elsewhere that the target channel has been changed and cancel the
323  // current download attempt.
324  std::string download_channel_;
325
326  std::string hwid_;  // Hardware Qualification ID of the client
327  std::string fw_version_;  // Chrome OS Firmware Version.
328  std::string ec_version_;  // Chrome OS EC Version.
329  bool delta_okay_;  // If this client can accept a delta
330  bool interactive_;   // Whether this is a user-initiated update check
331
332  // The URL to send the Omaha request to.
333  std::string update_url_;
334
335  // Prefix of the target OS version that the enterprise wants this device
336  // to be pinned to. It's empty otherwise.
337  std::string target_version_prefix_;
338
339  // True if scattering is enabled, in which case waiting_period_ specifies the
340  // amount of absolute time that we've to wait for before sending a request to
341  // Omaha.
342  bool wall_clock_based_wait_enabled_;
343  base::TimeDelta waiting_period_;
344
345  // True if scattering is enabled to denote the number of update checks
346  // we've to skip before we can send a request to Omaha. The min and max
347  // values establish the bounds for a random number to be chosen within that
348  // range to enable such a wait.
349  bool update_check_count_wait_enabled_;
350  int64_t min_update_checks_needed_;
351  int64_t max_update_checks_allowed_;
352
353  // True if we are allowed to do powerwash, if required, on a channel change.
354  bool is_powerwash_allowed_;
355
356  // When reading files, prepend root_ to the paths. Useful for testing.
357  std::string root_;
358
359  // Force security lock down for testing purposes.
360  bool force_lock_down_;
361  bool forced_lock_down_;
362
363  // TODO(jaysri): Uncomment this after fixing unit tests, as part of
364  // chromium-os:39752
365  // DISALLOW_COPY_AND_ASSIGN(OmahaRequestParams);
366};
367
368}  // namespace chromeos_update_engine
369
370#endif  // UPDATE_ENGINE_OMAHA_REQUEST_PARAMS_H_
371