omaha_request_action.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. //
  2. // Copyright (C) 2012 The Android Open Source Project
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #ifndef UPDATE_ENGINE_OMAHA_REQUEST_ACTION_H_
  17. #define UPDATE_ENGINE_OMAHA_REQUEST_ACTION_H_
  18. #include <fcntl.h>
  19. #include <sys/stat.h>
  20. #include <sys/types.h>
  21. #include <map>
  22. #include <memory>
  23. #include <string>
  24. #include <vector>
  25. #include <gtest/gtest_prod.h> // for FRIEND_TEST
  26. #include <brillo/secure_blob.h>
  27. #include <curl/curl.h>
  28. #include "update_engine/common/action.h"
  29. #include "update_engine/common/http_fetcher.h"
  30. #include "update_engine/omaha_response.h"
  31. #include "update_engine/system_state.h"
  32. // The Omaha Request action makes a request to Omaha and can output
  33. // the response on the output ActionPipe.
  34. namespace policy {
  35. class PolicyProvider;
  36. }
  37. namespace chromeos_update_engine {
  38. // Encodes XML entities in a given string. Input must be ASCII-7 valid. If
  39. // the input is invalid, the default value is used instead.
  40. std::string XmlEncodeWithDefault(const std::string& input,
  41. const std::string& default_value);
  42. // Escapes text so it can be included as character data and attribute
  43. // values. The |input| string must be valid ASCII-7, no UTF-8 supported.
  44. // Returns whether the |input| was valid and escaped properly in |output|.
  45. bool XmlEncode(const std::string& input, std::string* output);
  46. // This struct encapsulates the Omaha event information. For a
  47. // complete list of defined event types and results, see
  48. // http://code.google.com/p/omaha/wiki/ServerProtocol#event
  49. struct OmahaEvent {
  50. // The Type values correspond to EVENT_TYPE values of Omaha.
  51. enum Type {
  52. kTypeUnknown = 0,
  53. kTypeDownloadComplete = 1,
  54. kTypeInstallComplete = 2,
  55. kTypeUpdateComplete = 3,
  56. kTypeUpdateDownloadStarted = 13,
  57. kTypeUpdateDownloadFinished = 14,
  58. // Chromium OS reserved type sent after the first reboot following an update
  59. // completed.
  60. kTypeRebootedAfterUpdate = 54,
  61. };
  62. // The Result values correspond to EVENT_RESULT values of Omaha.
  63. enum Result {
  64. kResultError = 0,
  65. kResultSuccess = 1,
  66. kResultUpdateDeferred = 9, // When we ignore/defer updates due to policy.
  67. };
  68. OmahaEvent()
  69. : type(kTypeUnknown),
  70. result(kResultError),
  71. error_code(ErrorCode::kError) {}
  72. explicit OmahaEvent(Type in_type)
  73. : type(in_type),
  74. result(kResultSuccess),
  75. error_code(ErrorCode::kSuccess) {}
  76. OmahaEvent(Type in_type, Result in_result, ErrorCode in_error_code)
  77. : type(in_type), result(in_result), error_code(in_error_code) {}
  78. Type type;
  79. Result result;
  80. ErrorCode error_code;
  81. };
  82. class NoneType;
  83. class OmahaRequestAction;
  84. class OmahaRequestParams;
  85. class PrefsInterface;
  86. // This struct is declared in the .cc file.
  87. struct OmahaParserData;
  88. template <>
  89. class ActionTraits<OmahaRequestAction> {
  90. public:
  91. // Takes parameters on the input pipe.
  92. typedef NoneType InputObjectType;
  93. // On UpdateCheck success, puts the Omaha response on output. Event
  94. // requests do not have an output pipe.
  95. typedef OmahaResponse OutputObjectType;
  96. };
  97. class OmahaRequestAction : public Action<OmahaRequestAction>,
  98. public HttpFetcherDelegate {
  99. public:
  100. static const int kNeverPinged = -1;
  101. static const int kPingTimeJump = -2;
  102. // We choose this value of 10 as a heuristic for a work day in trying
  103. // each URL, assuming we check roughly every 45 mins. This is a good time to
  104. // wait - neither too long nor too little - so we don't give up the preferred
  105. // URLs that appear earlier in list too quickly before moving on to the
  106. // fallback ones.
  107. static const int kDefaultMaxFailureCountPerUrl = 10;
  108. // If staging is enabled, set the maximum wait time to 28 days, since that is
  109. // the predetermined wait time for staging.
  110. static const int kMaxWaitTimeStagingInDays = 28;
  111. // These are the possible outcome upon checking whether we satisfied
  112. // the wall-clock-based-wait.
  113. enum WallClockWaitResult {
  114. kWallClockWaitNotSatisfied,
  115. kWallClockWaitDoneButUpdateCheckWaitRequired,
  116. kWallClockWaitDoneAndUpdateCheckWaitNotRequired,
  117. };
  118. // The ctor takes in all the parameters that will be used for making
  119. // the request to Omaha. For some of them we have constants that
  120. // should be used.
  121. //
  122. // Takes ownership of the passed in HttpFetcher. Useful for testing.
  123. //
  124. // Takes ownership of the passed in OmahaEvent. If |event| is null,
  125. // this is an UpdateCheck request, otherwise it's an Event request.
  126. // Event requests always succeed.
  127. //
  128. // A good calling pattern is:
  129. // OmahaRequestAction(..., new OmahaEvent(...), new WhateverHttpFetcher);
  130. // or
  131. // OmahaRequestAction(..., nullptr, new WhateverHttpFetcher);
  132. OmahaRequestAction(SystemState* system_state,
  133. OmahaEvent* event,
  134. std::unique_ptr<HttpFetcher> http_fetcher,
  135. bool ping_only);
  136. ~OmahaRequestAction() override;
  137. typedef ActionTraits<OmahaRequestAction>::InputObjectType InputObjectType;
  138. typedef ActionTraits<OmahaRequestAction>::OutputObjectType OutputObjectType;
  139. void PerformAction() override;
  140. void TerminateProcessing() override;
  141. void ActionCompleted(ErrorCode code) override;
  142. int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }
  143. // Debugging/logging
  144. static std::string StaticType() { return "OmahaRequestAction"; }
  145. std::string Type() const override { return StaticType(); }
  146. // Delegate methods (see http_fetcher.h)
  147. bool ReceivedBytes(HttpFetcher* fetcher,
  148. const void* bytes,
  149. size_t length) override;
  150. void TransferComplete(HttpFetcher* fetcher, bool successful) override;
  151. // Returns true if this is an Event request, false if it's an UpdateCheck.
  152. bool IsEvent() const { return event_.get() != nullptr; }
  153. private:
  154. friend class OmahaRequestActionTest;
  155. friend class OmahaRequestActionTestProcessorDelegate;
  156. FRIEND_TEST(OmahaRequestActionTest, GetInstallDateWhenNoPrefsNorOOBE);
  157. FRIEND_TEST(OmahaRequestActionTest,
  158. GetInstallDateWhenOOBECompletedWithInvalidDate);
  159. FRIEND_TEST(OmahaRequestActionTest,
  160. GetInstallDateWhenOOBECompletedWithValidDate);
  161. FRIEND_TEST(OmahaRequestActionTest,
  162. GetInstallDateWhenOOBECompletedDateChanges);
  163. // Enumeration used in PersistInstallDate().
  164. enum InstallDateProvisioningSource {
  165. kProvisionedFromOmahaResponse,
  166. kProvisionedFromOOBEMarker,
  167. // kProvisionedMax is the count of the number of enums above. Add
  168. // any new enums above this line only.
  169. kProvisionedMax
  170. };
  171. // Gets the install date, expressed as the number of PST8PDT
  172. // calendar weeks since January 1st 2007, times seven. Returns -1 if
  173. // unknown. See http://crbug.com/336838 for details about this value.
  174. static int GetInstallDate(SystemState* system_state);
  175. // Parses the Omaha Response in |doc| and sets the
  176. // |install_date_days| field of |output_object| to the value of the
  177. // elapsed_days attribute of the daystart element. Returns True if
  178. // the value was set, False if it wasn't found.
  179. static bool ParseInstallDate(OmahaParserData* parser_data,
  180. OmahaResponse* output_object);
  181. // Returns True if the kPrefsInstallDateDays state variable is set,
  182. // False otherwise.
  183. static bool HasInstallDate(SystemState* system_state);
  184. // Writes |install_date_days| into the kPrefsInstallDateDays state
  185. // variable and emits an UMA stat for the |source| used. Returns
  186. // True if the value was written, False if an error occurred.
  187. static bool PersistInstallDate(SystemState* system_state,
  188. int install_date_days,
  189. InstallDateProvisioningSource source);
  190. // Persist the new cohort* value received in the XML file in the |prefs_key|
  191. // preference file. If the |new_value| is empty, the currently stored value
  192. // will be deleted. Don't call this function with an empty |new_value| if the
  193. // value was not set in the XML, since that would delete the stored value.
  194. bool PersistCohortData(const std::string& prefs_key,
  195. const std::string& new_value);
  196. // Parse and persist the end-of-life status flag sent back in the updatecheck
  197. // tag attributes. The flag will be validated and stored in the Prefs.
  198. bool PersistEolStatus(const std::map<std::string, std::string>& attrs);
  199. // If this is an update check request, initializes
  200. // |ping_active_days_| and |ping_roll_call_days_| to values that may
  201. // be sent as pings to Omaha.
  202. void InitPingDays();
  203. // Based on the persistent preference store values, calculates the
  204. // number of days since the last ping sent for |key|.
  205. int CalculatePingDays(const std::string& key);
  206. // Returns whether we have "active_days" or "roll_call_days" ping values to
  207. // send to Omaha and thus we should include them in the response.
  208. bool ShouldPing() const;
  209. // Returns true if the download of a new update should be deferred.
  210. // False if the update can be downloaded.
  211. bool ShouldDeferDownload(OmahaResponse* output_object);
  212. // Returns true if the basic wall-clock-based waiting period has been
  213. // satisfied based on the scattering policy setting. False otherwise.
  214. // If true, it also indicates whether the additional update-check-count-based
  215. // waiting period also needs to be satisfied before the download can begin.
  216. WallClockWaitResult IsWallClockBasedWaitingSatisfied(
  217. OmahaResponse* output_object);
  218. // Returns true if the update-check-count-based waiting period has been
  219. // satisfied. False otherwise.
  220. bool IsUpdateCheckCountBasedWaitingSatisfied();
  221. // Parses the response from Omaha that's available in |doc| using the other
  222. // helper methods below and populates the |output_object| with the relevant
  223. // values. Returns true if we should continue the parsing. False otherwise,
  224. // in which case it sets any error code using |completer|.
  225. bool ParseResponse(OmahaParserData* parser_data,
  226. OmahaResponse* output_object,
  227. ScopedActionCompleter* completer);
  228. // Parses the status property in the given update_check_node and populates
  229. // |output_object| if valid. Returns true if we should continue the parsing.
  230. // False otherwise, in which case it sets any error code using |completer|.
  231. bool ParseStatus(OmahaParserData* parser_data,
  232. OmahaResponse* output_object,
  233. ScopedActionCompleter* completer);
  234. // Parses the URL nodes in the given XML document and populates
  235. // |output_object| if valid. Returns true if we should continue the parsing.
  236. // False otherwise, in which case it sets any error code using |completer|.
  237. bool ParseUrls(OmahaParserData* parser_data,
  238. OmahaResponse* output_object,
  239. ScopedActionCompleter* completer);
  240. // Parses the other parameters in the given XML document and populates
  241. // |output_object| if valid. Returns true if we should continue the parsing.
  242. // False otherwise, in which case it sets any error code using |completer|.
  243. bool ParseParams(OmahaParserData* parser_data,
  244. OmahaResponse* output_object,
  245. ScopedActionCompleter* completer);
  246. // Called by TransferComplete() to complete processing, either
  247. // asynchronously after looking up resources via p2p or directly.
  248. void CompleteProcessing();
  249. // Helper to asynchronously look up payload on the LAN.
  250. void LookupPayloadViaP2P(const OmahaResponse& response);
  251. // Callback used by LookupPayloadViaP2P().
  252. void OnLookupPayloadViaP2PCompleted(const std::string& url);
  253. // Returns true if the current update should be ignored.
  254. bool ShouldIgnoreUpdate(const OmahaResponse& response,
  255. ErrorCode* error) const;
  256. // Return true if updates are allowed by user preferences.
  257. bool IsUpdateAllowedOverCellularByPrefs(const OmahaResponse& response) const;
  258. // Returns true if updates are allowed over the current type of connection.
  259. // False otherwise.
  260. bool IsUpdateAllowedOverCurrentConnection(
  261. ErrorCode* error, const OmahaResponse& response) const;
  262. // Returns true if rollback is enabled. Always returns false for consumer
  263. // devices.
  264. bool IsRollbackEnabled() const;
  265. // Sets the appropriate max kernel key version based on whether rollback is
  266. // enabled.
  267. void SetMaxKernelKeyVersionForRollback() const;
  268. // Reads and returns the kPrefsUpdateFirstSeenAt pref if the pref currently
  269. // exists. Otherwise saves the current wallclock time to the
  270. // kPrefsUpdateFirstSeenAt pref and returns it as a base::Time object.
  271. base::Time LoadOrPersistUpdateFirstSeenAtPref() const;
  272. // Global system context.
  273. SystemState* system_state_;
  274. // Contains state that is relevant in the processing of the Omaha request.
  275. OmahaRequestParams* params_;
  276. // Pointer to the OmahaEvent info. This is an UpdateCheck request if null.
  277. std::unique_ptr<OmahaEvent> event_;
  278. // pointer to the HttpFetcher that does the http work
  279. std::unique_ptr<HttpFetcher> http_fetcher_;
  280. // Used for fetching information about the device policy.
  281. std::unique_ptr<policy::PolicyProvider> policy_provider_;
  282. // If true, only include the <ping> element in the request.
  283. bool ping_only_;
  284. // Stores the response from the omaha server
  285. brillo::Blob response_buffer_;
  286. // Initialized by InitPingDays to values that may be sent to Omaha
  287. // as part of a ping message. Note that only positive values and -1
  288. // are sent to Omaha.
  289. int ping_active_days_;
  290. int ping_roll_call_days_;
  291. DISALLOW_COPY_AND_ASSIGN(OmahaRequestAction);
  292. };
  293. } // namespace chromeos_update_engine
  294. #endif // UPDATE_ENGINE_OMAHA_REQUEST_ACTION_H_