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 <ohos_types.h> 21 #include <sys/socket.h> 22 #include <unistd.h> 23 #include <vector> 24 25 #include "cJSON.h" 26 #include "nlohmann/json.hpp" 27 #include "openssl/err.h" 28 #include "openssl/ssl.h" 29 #include "parameter.h" 30 #include "parameters.h" 31 32 #include "encrypt_utils.h" 33 #include "firmware_check_analyze_utils.h" 34 #include "firmware_common.h" 35 #include "firmware_component.h" 36 #include "firmware_constant.h" 37 #include "device_adapter.h" 38 #include "firmware_update_helper.h" 39 #include "network_response.h" 40 #include "update_helper.h" 41 #include "update_service_util.h" 42 43 constexpr int32_t PORT_NUMBER = 5022; 44 constexpr int32_t JSON_MAX_SIZE = 4096; 45 const std::string DEFAULT_SERVER_IP = "127.0.0.1"; 46 const std::string PARAM_NAME_FOR_SEARCH = "update.serverip.search"; 47 #ifndef UPDATER_UT 48 constexpr int32_t TIMEOUT_FOR_CONNECT = 10; 49 #else 50 constexpr int32_t TIMEOUT_FOR_CONNECT = 1; 51 #endif 52 53 namespace OHOS { 54 namespace UpdateEngine { 55 using CheckCallback = std::function<void(CheckStatus status, const Duration &duration, 56 const std::vector<FirmwareComponent> &firmwareCheckResultList, const CheckAndAuthInfo &checkAndAuthInfo)>; 57 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 int32_t engineSocket = socket(AF_INET, SOCK_STREAM, 0); 74 ENGINE_CHECK(engineSocket >= 0, 75 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 76 return, "socket error !"); 77 78 std::string serverIp = OHOS::system::GetParameter(PARAM_NAME_FOR_SEARCH, DEFAULT_SERVER_IP); 79 FIRMWARE_LOGI("CheckNewVersion serverIp: %s ", serverIp.c_str()); 80 sockaddr_in engineSin {}; 81 engineSin.sin_family = AF_INET; 82 engineSin.sin_port = htons(PORT_NUMBER); 83 int32_t ret = inet_pton(AF_INET, serverIp.c_str(), &engineSin.sin_addr); 84 ENGINE_CHECK(ret > 0, close(engineSocket); 85 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 86 return, "socket error"); 87 88 struct timeval tv = {TIMEOUT_FOR_CONNECT, 0}; 89 setsockopt(engineSocket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval)); 90 ret = connect(engineSocket, reinterpret_cast<sockaddr *>(&engineSin), sizeof(engineSin)); 91 ENGINE_CHECK(ret == 0, 92 close(engineSocket); 93 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 94 return, "connect error"); 95 NetworkResponse response {}; 96 ret = ReadDataFromSSL(engineSocket, response); 97 ENGINE_CHECK(ret == 0, 98 close(engineSocket); 99 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 100 return, "SSL ReadData error"); 101 close(engineSocket); 102 CheckStatus checkStatus; 103 if (response.status != static_cast<int64_t>(HttpConstant::SUCCESS) || response.content.empty()) { 104 checkStatus = CheckStatus::CHECK_FAIL; 105 } else { 106 nlohmann::json root = nlohmann::json::parse(response.content, nullptr, false); 107 if (!root.is_discarded()) { 108 FIRMWARE_LONG_LOGI("FirmwareCheck response: %{public}s", root.dump().c_str()); 109 } 110 FirmwareCheckAnalyzeUtils().DoAnalyze(response.content, checkResultList_, duration_, checkAndAuthInfo_); 111 checkStatus = CheckStatus::CHECK_SUCCESS; 112 } 113 checkCallback.callback(checkStatus, duration_, checkResultList_, checkAndAuthInfo_); 114 } 115 116 private: ParseJsonFile(const std::vector<char> & buffer,NetworkResponse & response)117 int32_t ParseJsonFile(const std::vector<char> &buffer, NetworkResponse &response) 118 { 119 response.content.assign(buffer.begin(), buffer.end()); 120 response.status = static_cast<int64_t>(HttpConstant::SUCCESS); 121 cJSON *root = cJSON_Parse(buffer.data()); 122 ENGINE_CHECK(root != nullptr, return -1, "Error get root"); 123 cJSON *item = cJSON_GetObjectItem(root, "searchStatus"); 124 ENGINE_CHECK(item != nullptr, cJSON_Delete(root); 125 return -1, "Error get searchStatus"); 126 return CAST_INT(static_cast<SearchStatus>(item->valueint)); 127 } 128 ReadDataFromSSL(int32_t engineSocket,NetworkResponse & response)129 int32_t ReadDataFromSSL(int32_t engineSocket, NetworkResponse &response) 130 { 131 SearchStatus result = SearchStatus::SERVER_BUSY; 132 std::string errMsg = "Couldn't connect to server"; 133 std::vector<char> buffer(JSON_MAX_SIZE); 134 135 SSL_library_init(); 136 OpenSSL_add_all_algorithms(); 137 SSL_load_error_strings(); 138 SSL_CTX *sslCtx = SSL_CTX_new(SSLv23_client_method()); 139 ENGINE_CHECK(sslCtx != nullptr, return -1, "sslCtx is nullptr"); 140 SSL *ssl = SSL_new(sslCtx); 141 ENGINE_CHECK(ssl != nullptr, 142 SSL_CTX_free(sslCtx); 143 return -1, 144 "ssl is nullptr"); 145 SSL_set_fd(ssl, engineSocket); 146 int32_t ret = SSL_connect(ssl); 147 if (ret != -1) { 148 int32_t len = SSL_read(ssl, buffer.data(), JSON_MAX_SIZE); 149 if (len > 0 && ParseJsonFile(buffer, response) == 0) { 150 result = SearchStatus::HAS_NEW_VERSION; 151 errMsg = ""; 152 } else { 153 result = SearchStatus::SYSTEM_ERROR; 154 errMsg = "Couldn't read data"; 155 } 156 } else { 157 result = SearchStatus::SYSTEM_ERROR; 158 errMsg = "Couldn't connect to server"; 159 } 160 SSL_shutdown(ssl); 161 SSL_free(ssl); 162 SSL_CTX_free(sslCtx); 163 FIRMWARE_LOGI("ReadDataFromSSL errMsg: %s, result: %d", errMsg.c_str(), result); 164 return result == SearchStatus::HAS_NEW_VERSION ? 0 : -1; 165 } 166 167 RequestType requestType_ = RequestType::CHECK; 168 Duration duration_; 169 CheckAndAuthInfo checkAndAuthInfo_; 170 std::vector<FirmwareComponent> checkResultList_; 171 }; 172 } // namespace UpdateEngine 173 } // namespace OHOS 174 #endif // FIRMWARE_ICHECK_H