1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FIRMWARE_ICHECK_H 17 #define FIRMWARE_ICHECK_H 18 19 #include <arpa/inet.h> 20 #include <sys/socket.h> 21 #include <unistd.h> 22 #include <vector> 23 24 #include "cJSON.h" 25 #include "nlohmann/json.hpp" 26 #include "openssl/err.h" 27 #include "openssl/ssl.h" 28 #include "parameter.h" 29 #include "parameters.h" 30 31 #include "anonymous_utils.h" 32 #include "firmware_check_analyze_utils.h" 33 #include "firmware_common.h" 34 #include "firmware_component.h" 35 #include "firmware_constant.h" 36 #include "device_adapter.h" 37 #include "firmware_update_helper.h" 38 #include "network_response.h" 39 #include "search_status.h" 40 #include "update_service_util.h" 41 42 constexpr int32_t PORT_NUMBER = 5022; 43 constexpr int32_t JSON_MAX_SIZE = 4096; 44 #ifndef UPDATER_UT 45 constexpr int32_t TIMEOUT_FOR_CONNECT = 10; 46 #else 47 constexpr int32_t TIMEOUT_FOR_CONNECT = 1; 48 #endif 49 50 namespace OHOS { 51 namespace UpdateEngine { 52 const std::string DEFAULT_SERVER_IP = "127.0.0.1"; 53 const std::string PARAM_NAME_FOR_SEARCH = "update.serverip.search"; 54 using CheckCallback = std::function<void(CheckStatus status, const Duration &duration, 55 const std::vector<FirmwareComponent> &firmwareCheckResultList, const CheckAndAuthInfo &checkAndAuthInfo)>; 56 57 using cJSONPtr = std::unique_ptr<cJSON, decltype(&cJSON_Delete)>; 58 struct FirmwareCheckCallback { 59 CheckCallback callback; 60 }; 61 62 class FirmwareICheck { 63 public: FirmwareICheck(const RequestType requestType)64 explicit FirmwareICheck(const RequestType requestType) 65 { 66 requestType_ = requestType; 67 } 68 virtual ~FirmwareICheck() = default; 69 DoAction(FirmwareCheckCallback checkCallback)70 void DoAction(FirmwareCheckCallback checkCallback) 71 { 72 FIRMWARE_LOGI("FirmwareCheck::DoAction"); 73 if (checkCallback.callback == nullptr) { 74 FIRMWARE_LOGE("FirmwareICheck DoAction callback is null"); 75 return; 76 } 77 int32_t engineSocket = socket(AF_INET, SOCK_STREAM, 0); 78 ENGINE_CHECK(engineSocket >= 0, 79 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 80 return, "socket error !"); 81 82 std::string serverIp = OHOS::system::GetParameter(PARAM_NAME_FOR_SEARCH, DEFAULT_SERVER_IP); 83 FIRMWARE_LOGI("CheckNewVersion serverIp: %s ", serverIp.c_str()); 84 sockaddr_in engineSin {}; 85 engineSin.sin_family = AF_INET; 86 engineSin.sin_port = htons(PORT_NUMBER); 87 int32_t ret = inet_pton(AF_INET, serverIp.c_str(), &engineSin.sin_addr); 88 ENGINE_CHECK(ret > 0, close(engineSocket); 89 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 90 return, "socket error"); 91 92 struct timeval tv = {TIMEOUT_FOR_CONNECT, 0}; 93 setsockopt(engineSocket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval)); 94 ret = connect(engineSocket, reinterpret_cast<sockaddr *>(&engineSin), sizeof(engineSin)); 95 ENGINE_CHECK(ret == 0, 96 close(engineSocket); 97 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 98 return, "connect error"); 99 NetworkResponse response {}; 100 ret = ReadDataFromSSL(engineSocket, response); 101 ENGINE_CHECK(ret == 0, 102 close(engineSocket); 103 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 104 return, "SSL ReadData error"); 105 close(engineSocket); 106 CheckStatus checkStatus; 107 if (response.status != static_cast<int64_t>(HttpConstant::SUCCESS) || response.content.empty()) { 108 checkStatus = CheckStatus::CHECK_FAIL; 109 } else { 110 nlohmann::json root = nlohmann::json::parse(response.content, nullptr, false); 111 if (!root.is_discarded()) { 112 FIRMWARE_LONG_LOGI("FirmwareCheck response: %{public}s", root.dump().c_str()); 113 } 114 FirmwareCheckAnalyzeUtils().DoAnalyze(response.content, checkResultList_, duration_, checkAndAuthInfo_); 115 checkStatus = CheckStatus::CHECK_SUCCESS; 116 } 117 checkCallback.callback(checkStatus, duration_, checkResultList_, checkAndAuthInfo_); 118 } 119 120 private: ParseJsonFile(const std::vector<char> & buffer,NetworkResponse & response)121 int32_t ParseJsonFile(const std::vector<char> &buffer, NetworkResponse &response) 122 { 123 response.content.assign(buffer.begin(), buffer.end()); 124 response.status = static_cast<int64_t>(HttpConstant::SUCCESS); 125 cJSONPtr root(cJSON_Parse(buffer.data()), cJSON_Delete); 126 ENGINE_CHECK(root != nullptr, return -1, "Error get root"); 127 cJSON *item = cJSON_GetObjectItem(root.get(), "searchStatus"); 128 ENGINE_CHECK(root != nullptr, return -1, "Error get searchStatus"); 129 if (!cJSON_IsNumber(item)) { 130 FIRMWARE_LOGE("Error json parse"); 131 return -1; 132 } 133 return CAST_INT(static_cast<SearchStatus>(item->valueint)); 134 } 135 ReadDataFromSSL(int32_t engineSocket,NetworkResponse & response)136 int32_t ReadDataFromSSL(int32_t engineSocket, NetworkResponse &response) 137 { 138 SearchStatus result = SearchStatus::SERVER_BUSY; 139 std::string errMsg = "Couldn't connect to server"; 140 std::vector<char> buffer(JSON_MAX_SIZE); 141 142 SSL_library_init(); 143 OpenSSL_add_all_algorithms(); 144 SSL_load_error_strings(); 145 SSL_CTX *sslCtx = SSL_CTX_new(SSLv23_client_method()); 146 ENGINE_CHECK(sslCtx != nullptr, return -1, "sslCtx is nullptr"); 147 SSL *ssl = SSL_new(sslCtx); 148 ENGINE_CHECK(ssl != nullptr, 149 SSL_CTX_free(sslCtx); 150 return -1, 151 "ssl is nullptr"); 152 SSL_set_fd(ssl, engineSocket); 153 int32_t ret = SSL_connect(ssl); 154 if (ret != -1) { 155 int32_t len = SSL_read(ssl, buffer.data(), JSON_MAX_SIZE); 156 if (len > 0 && ParseJsonFile(buffer, response) == 0) { 157 result = SearchStatus::HAS_NEW_VERSION; 158 errMsg = ""; 159 } else { 160 result = SearchStatus::SYSTEM_ERROR; 161 errMsg = "Couldn't read data"; 162 } 163 } else { 164 result = SearchStatus::SYSTEM_ERROR; 165 errMsg = "Couldn't connect to server"; 166 } 167 SSL_shutdown(ssl); 168 SSL_free(ssl); 169 SSL_CTX_free(sslCtx); 170 FIRMWARE_LOGI("ReadDataFromSSL errMsg: %s, result: %d", errMsg.c_str(), result); 171 return result == SearchStatus::HAS_NEW_VERSION ? 0 : -1; 172 } 173 174 RequestType requestType_ = RequestType::CHECK; 175 Duration duration_; 176 CheckAndAuthInfo checkAndAuthInfo_; 177 std::vector<FirmwareComponent> checkResultList_; 178 }; 179 } // namespace UpdateEngine 180 } // namespace OHOS 181 #endif // FIRMWARE_ICHECK_H