• 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 <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