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