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 "openssl/err.h" 26 #include "openssl/ssl.h" 27 #include "parameter.h" 28 #include "parameters.h" 29 30 #include "anonymous_utils.h" 31 #include "firmware_check_analyze_utils.h" 32 #include "firmware_common.h" 33 #include "firmware_component.h" 34 #include "firmware_constant.h" 35 #include "device_adapter.h" 36 #include "firmware_update_helper.h" 37 #include "network_response.h" 38 #include "search_status.h" 39 #include "update_service_util.h" 40 41 constexpr int32_t PORT_NUMBER = 5022; 42 constexpr int32_t JSON_MAX_SIZE = 4096; 43 #ifndef UPDATER_UT 44 constexpr int32_t TIMEOUT_FOR_CONNECT = 10; 45 #else 46 constexpr int32_t TIMEOUT_FOR_CONNECT = 1; 47 #endif 48 49 namespace OHOS { 50 namespace UpdateService { 51 const std::string DEFAULT_SERVER_IP = "127.0.0.1"; 52 const std::string PARAM_NAME_FOR_SEARCH = "update.serverip.search"; 53 using CheckCallback = std::function<void(CheckStatus status, const Duration &duration, 54 const std::vector<FirmwareComponent> &firmwareCheckResultList, const CheckAndAuthInfo &checkAndAuthInfo)>; 55 56 using cJSONPtr = std::unique_ptr<cJSON, decltype(&cJSON_Delete)>; 57 struct FirmwareCheckCallback { 58 CheckCallback callback; 59 }; 60 61 class FirmwareICheck { 62 public: FirmwareICheck(const RequestType requestType)63 explicit FirmwareICheck(const RequestType requestType) 64 { 65 requestType_ = requestType; 66 } 67 virtual ~FirmwareICheck() = default; 68 DoAction(FirmwareCheckCallback checkCallback)69 void DoAction(FirmwareCheckCallback checkCallback) 70 { 71 FIRMWARE_LOGI("FirmwareCheck::DoAction"); 72 if (checkCallback.callback == nullptr) { 73 FIRMWARE_LOGE("FirmwareICheck DoAction callback is null"); 74 return; 75 } 76 int32_t engineSocket = socket(AF_INET, SOCK_STREAM, 0); 77 ENGINE_CHECK(engineSocket >= 0, 78 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 79 return, "socket error !"); 80 81 std::string serverIp = OHOS::system::GetParameter(PARAM_NAME_FOR_SEARCH, DEFAULT_SERVER_IP); 82 FIRMWARE_LOGI("CheckNewVersion serverIp: %s ", serverIp.c_str()); 83 sockaddr_in engineSin {}; 84 engineSin.sin_family = AF_INET; 85 engineSin.sin_port = htons(PORT_NUMBER); 86 int32_t ret = inet_pton(AF_INET, serverIp.c_str(), &engineSin.sin_addr); 87 ENGINE_CHECK(ret > 0, close(engineSocket); 88 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 89 return, "socket error"); 90 91 struct timeval tv = {TIMEOUT_FOR_CONNECT, 0}; 92 setsockopt(engineSocket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval)); 93 ret = connect(engineSocket, reinterpret_cast<sockaddr *>(&engineSin), sizeof(engineSin)); 94 ENGINE_CHECK(ret == 0, 95 close(engineSocket); 96 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 97 return, "connect error"); 98 NetworkResponse response {}; 99 ret = ReadDataFromSSL(engineSocket, response); 100 ENGINE_CHECK(ret == 0, 101 close(engineSocket); 102 checkCallback.callback(CheckStatus::CHECK_FAIL, duration_, checkResultList_, checkAndAuthInfo_); 103 return, "SSL ReadData error"); 104 close(engineSocket); 105 CheckStatus checkStatus; 106 if (response.status != static_cast<int64_t>(HttpConstant::SUCCESS) || response.content.empty()) { 107 checkStatus = CheckStatus::CHECK_FAIL; 108 } else { 109 auto root = UpdateServiceJsonUtils::ParseJson(response.content.c_str()); 110 if (root == nullptr) { 111 FIRMWARE_LONG_LOGI("FirmwareCheck response: %{public}s", response.content.c_str()); 112 return; 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 cJSON *root = cJSON_Parse(buffer.data()); 126 ENGINE_CHECK(root != nullptr, 127 cJSON_Delete(root); 128 return -1, "Error get root"); 129 cJSON *item = cJSON_GetObjectItem(root, "searchStatus"); 130 ENGINE_CHECK(item != nullptr, 131 cJSON_Delete(root); 132 return -1, "Error get searchStatus"); 133 if (!cJSON_IsNumber(item)) { 134 FIRMWARE_LOGE("Error json parse"); 135 cJSON_Delete(root); 136 return -1; 137 } 138 int32_t ret = item->valueint; 139 cJSON_Delete(root); 140 return ret; 141 } 142 ReadDataFromSSL(int32_t engineSocket,NetworkResponse & response)143 int32_t ReadDataFromSSL(int32_t engineSocket, NetworkResponse &response) 144 { 145 SearchStatus result = SearchStatus::SERVER_BUSY; 146 std::string errMsg = "Couldn't connect to server"; 147 std::vector<char> buffer(JSON_MAX_SIZE); 148 149 SSL_library_init(); 150 OpenSSL_add_all_algorithms(); 151 SSL_load_error_strings(); 152 SSL_CTX *sslCtx = SSL_CTX_new(SSLv23_client_method()); 153 ENGINE_CHECK(sslCtx != nullptr, return -1, "sslCtx is nullptr"); 154 SSL *ssl = SSL_new(sslCtx); 155 ENGINE_CHECK(ssl != nullptr, 156 SSL_CTX_free(sslCtx); 157 return -1, 158 "ssl is nullptr"); 159 SSL_set_fd(ssl, engineSocket); 160 int32_t ret = SSL_connect(ssl); 161 if (ret != -1) { 162 std::string serverIp = OHOS::system::GetParameter(PARAM_NAME_FOR_SEARCH, DEFAULT_SERVER_IP); 163 std::string request = "GET /config.json HTTP/1.1\r\nHost: " + serverIp + ":" + 164 std::to_string(PORT_NUMBER) + "\r\nConnection: close\r\n\r\n"; 165 SSL_write(ssl, request.c_str(), request.size()); 166 int32_t len = SSL_read(ssl, buffer.data(), JSON_MAX_SIZE); 167 std::string resultStr = buffer.data(); 168 size_t index = resultStr.find('{'); 169 if (index != std::string::npos) { 170 buffer.erase(buffer.begin(), buffer.begin() + index); 171 } 172 if (len > 0 && ParseJsonFile(buffer, response) == 0) { 173 result = SearchStatus::HAS_NEW_VERSION; 174 errMsg = ""; 175 } else { 176 result = SearchStatus::SYSTEM_ERROR; 177 errMsg = "Couldn't read data"; 178 } 179 } else { 180 result = SearchStatus::SYSTEM_ERROR; 181 errMsg = "Couldn't connect to server"; 182 } 183 SSL_shutdown(ssl); 184 SSL_free(ssl); 185 SSL_CTX_free(sslCtx); 186 FIRMWARE_LOGI("ReadDataFromSSL errMsg: %s, result: %d", errMsg.c_str(), result); 187 return result == SearchStatus::HAS_NEW_VERSION ? 0 : -1; 188 } 189 190 RequestType requestType_ = RequestType::CHECK; 191 Duration duration_; 192 CheckAndAuthInfo checkAndAuthInfo_; 193 std::vector<FirmwareComponent> checkResultList_; 194 }; 195 } // namespace UpdateService 196 } // namespace OHOS 197 #endif // FIRMWARE_ICHECK_H