• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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