1 // 2 // Copyright (C) 2019 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 17 #ifndef UPDATE_ENGINE_OMAHA_REQUEST_BUILDER_XML_H_ 18 #define UPDATE_ENGINE_OMAHA_REQUEST_BUILDER_XML_H_ 19 20 #include <fcntl.h> 21 #include <sys/stat.h> 22 #include <sys/types.h> 23 24 #include <map> 25 #include <memory> 26 #include <string> 27 #include <vector> 28 29 #include <gtest/gtest_prod.h> // for FRIEND_TEST 30 31 #include <brillo/secure_blob.h> 32 #include <curl/curl.h> 33 34 #include "update_engine/common/action.h" 35 #include "update_engine/common/http_fetcher.h" 36 #include "update_engine/omaha_request_params.h" 37 #include "update_engine/omaha_response.h" 38 #include "update_engine/system_state.h" 39 40 namespace chromeos_update_engine { 41 42 extern const char kNoVersion[]; 43 extern const int kPingNeverPinged; 44 extern const int kPingUnknownValue; 45 extern const int kPingActiveValue; 46 extern const int kPingInactiveValue; 47 48 // This struct encapsulates the Omaha event information. For a 49 // complete list of defined event types and results, see 50 // http://code.google.com/p/omaha/wiki/ServerProtocol#event 51 struct OmahaEvent { 52 // The Type values correspond to EVENT_TYPE values of Omaha. 53 enum Type { 54 kTypeUnknown = 0, 55 kTypeDownloadComplete = 1, 56 kTypeInstallComplete = 2, 57 kTypeUpdateComplete = 3, 58 kTypeUpdateDownloadStarted = 13, 59 kTypeUpdateDownloadFinished = 14, 60 // Chromium OS reserved type sent after the first reboot following an update 61 // completed. 62 kTypeRebootedAfterUpdate = 54, 63 }; 64 65 // The Result values correspond to EVENT_RESULT values of Omaha. 66 enum Result { 67 kResultError = 0, 68 kResultSuccess = 1, 69 kResultUpdateDeferred = 9, // When we ignore/defer updates due to policy. 70 }; 71 OmahaEventOmahaEvent72 OmahaEvent() 73 : type(kTypeUnknown), 74 result(kResultError), 75 error_code(ErrorCode::kError) {} OmahaEventOmahaEvent76 explicit OmahaEvent(Type in_type) 77 : type(in_type), 78 result(kResultSuccess), 79 error_code(ErrorCode::kSuccess) {} OmahaEventOmahaEvent80 OmahaEvent(Type in_type, Result in_result, ErrorCode in_error_code) 81 : type(in_type), result(in_result), error_code(in_error_code) {} 82 83 Type type; 84 Result result; 85 ErrorCode error_code; 86 }; 87 88 struct OmahaAppData { 89 std::string id; 90 std::string version; 91 std::string product_components; 92 bool skip_update; 93 bool is_dlc; 94 OmahaRequestParams::AppParams app_params; 95 }; 96 97 // Encodes XML entities in a given string. Input must be ASCII-7 valid. If 98 // the input is invalid, the default value is used instead. 99 std::string XmlEncodeWithDefault(const std::string& input, 100 const std::string& default_value = ""); 101 102 // Escapes text so it can be included as character data and attribute 103 // values. The |input| string must be valid ASCII-7, no UTF-8 supported. 104 // Returns whether the |input| was valid and escaped properly in |output|. 105 bool XmlEncode(const std::string& input, std::string* output); 106 107 // Returns a boolean based on examining each character on whether it's a valid 108 // component (meaning all characters are an alphanum excluding '-', '_', '.'). 109 bool IsValidComponentID(const std::string& id); 110 111 class OmahaRequestBuilder { 112 public: 113 OmahaRequestBuilder() = default; 114 virtual ~OmahaRequestBuilder() = default; 115 116 virtual std::string GetRequest() const = 0; 117 118 private: 119 DISALLOW_COPY_AND_ASSIGN(OmahaRequestBuilder); 120 }; 121 122 class OmahaRequestBuilderXml : OmahaRequestBuilder { 123 public: OmahaRequestBuilderXml(const OmahaEvent * event,OmahaRequestParams * params,bool ping_only,bool include_ping,int ping_active_days,int ping_roll_call_days,int install_date_in_days,PrefsInterface * prefs,const std::string & session_id)124 OmahaRequestBuilderXml(const OmahaEvent* event, 125 OmahaRequestParams* params, 126 bool ping_only, 127 bool include_ping, 128 int ping_active_days, 129 int ping_roll_call_days, 130 int install_date_in_days, 131 PrefsInterface* prefs, 132 const std::string& session_id) 133 : event_(event), 134 params_(params), 135 ping_only_(ping_only), 136 include_ping_(include_ping), 137 ping_active_days_(ping_active_days), 138 ping_roll_call_days_(ping_roll_call_days), 139 install_date_in_days_(install_date_in_days), 140 prefs_(prefs), 141 session_id_(session_id) {} 142 143 ~OmahaRequestBuilderXml() override = default; 144 145 // Returns an XML that corresponds to the entire Omaha request. 146 std::string GetRequest() const override; 147 148 private: 149 FRIEND_TEST(OmahaRequestBuilderXmlTest, PlatformGetAppTest); 150 FRIEND_TEST(OmahaRequestBuilderXmlTest, DlcGetAppTest); 151 152 // Returns an XML that corresponds to the entire <os> node of the Omaha 153 // request based on the member variables. 154 std::string GetOs() const; 155 156 // Returns an XML that corresponds to all <app> nodes of the Omaha 157 // request based on the given parameters. 158 std::string GetApps() const; 159 160 // Returns an XML that corresponds to the single <app> node of the Omaha 161 // request based on the given parameters. 162 std::string GetApp(const OmahaAppData& app_data) const; 163 164 // Returns an XML that goes into the body of the <app> element of the Omaha 165 // request based on the given parameters. 166 std::string GetAppBody(const OmahaAppData& app_data) const; 167 168 // Returns the cohort* argument to include in the <app> tag for the passed 169 // |arg_name| and |prefs_key|, if any. The return value is suitable to 170 // concatenate to the list of arguments and includes a space at the end. 171 std::string GetCohortArg(const std::string arg_name, 172 const std::string prefs_key, 173 const std::string override_value = "") const; 174 175 // Returns an XML ping element if any of the elapsed days need to be 176 // sent, or an empty string otherwise. 177 std::string GetPing() const; 178 179 // Returns an XML ping element if any of the elapsed days need to be 180 // sent, or an empty string otherwise. 181 std::string GetPingDateBased( 182 const OmahaRequestParams::AppParams& app_params) const; 183 184 const OmahaEvent* event_; 185 OmahaRequestParams* params_; 186 bool ping_only_; 187 bool include_ping_; 188 int ping_active_days_; 189 int ping_roll_call_days_; 190 int install_date_in_days_; 191 PrefsInterface* prefs_; 192 std::string session_id_; 193 194 DISALLOW_COPY_AND_ASSIGN(OmahaRequestBuilderXml); 195 }; 196 197 } // namespace chromeos_update_engine 198 199 #endif // UPDATE_ENGINE_OMAHA_REQUEST_BUILDER_XML_H_ 200