1 /*
2 * Copyright (c) 2024 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 #include <algorithm>
17 #include <cstdint>
18 #include <tuple>
19 #include "app_domain_verify_mgr_client.h"
20 #include "datetime_ex.h"
21 #include "inner_verify_status.h"
22 #include "verify_task.h"
23 #include "domain_verifier.h"
24 #include "app_domain_verify_hilog.h"
25 #include "bundle_verify_status_info.h"
26 #include "agent_constants.h"
27 #include "domain_url_util.h"
28 #include "app_domain_verify_task_mgr.h"
29 #include "verify_http_task.h"
30
31 namespace OHOS {
32 namespace AppDomainVerify {
33 const std::string HTTPS = "https";
34 const std::set<std::string> SCHEME_WHITE_SET = { HTTPS };
35 const std::string FUZZY_HOST_START = "*.";
36 const static int CLIENT_ERR_MAX_RETRY_COUNTS = 7; // 7 times for max retry count
37 const static int CLIENT_ERR_BASE_RETRY_DURATION_S = 3600; // 1h for base duration
OnPostVerify(const std::string & uri,const OHOS::NetStack::HttpClient::HttpClientResponse & response)38 void VerifyTask::OnPostVerify(const std::string& uri, const OHOS::NetStack::HttpClient::HttpClientResponse& response)
39 {
40 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "called");
41 auto status = DomainVerifier::VerifyHost(response.GetResponseCode(), response.GetResult(), appVerifyBaseInfo_);
42 UpdateVerifyResultInfo(uri, status);
43 unVerifiedSet_.erase(uri);
44 if (unVerifiedSet_.empty()) {
45 OnSaveVerifyResult();
46 }
47 VERIFY_RESULT_EVENT(appVerifyBaseInfo_.appIdentifier, appVerifyBaseInfo_.bundleName, type_, status);
48 }
49
OnSaveVerifyResult()50 void VerifyTask::OnSaveVerifyResult()
51 {
52 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "called");
53 if (!SaveDomainVerifyStatus(appVerifyBaseInfo_.bundleName, verifyResultInfo_)) {
54 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "SaveVerifyResult failed");
55 }
56 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "call end");
57 }
OnPreRequest(OHOS::NetStack::HttpClient::HttpClientRequest & request,const std::string & uri)58 bool VerifyTask::OnPreRequest(OHOS::NetStack::HttpClient::HttpClientRequest& request, const std::string& uri)
59 {
60 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "called");
61 request.SetURL(uri + ApplinkingAssetKeys::ASSET_PATH + ApplinkingAssetKeys::ASSET_NAME);
62 request.SetMethod("GET");
63 return true;
64 }
GetType()65 OHOS::AppDomainVerify::TaskType VerifyTask::GetType()
66 {
67 return type_;
68 }
GetUriVerifyMap()69 const HostVerifyStatusMap& VerifyTask::GetUriVerifyMap()
70 {
71 return verifyResultInfo_.hostVerifyStatusMap;
72 }
InitUriUnVerifySetMap(const VerifyResultInfo & verifyResultInfo)73 void VerifyTask::InitUriUnVerifySetMap(const VerifyResultInfo& verifyResultInfo)
74 {
75 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "called");
76 for (const auto& hostVerifyStatusInfo : verifyResultInfo.hostVerifyStatusMap) {
77 if (IsNeedRetry(hostVerifyStatusInfo.second)) {
78 unVerifiedSet_.insert(hostVerifyStatusInfo.first);
79 }
80 }
81
82 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "call end");
83 }
84
VerifyTask(OHOS::AppDomainVerify::TaskType type,const AppVerifyBaseInfo & appVerifyBaseInfo,const VerifyResultInfo & verifyResultInfo)85 VerifyTask::VerifyTask(OHOS::AppDomainVerify::TaskType type, const AppVerifyBaseInfo& appVerifyBaseInfo,
86 const VerifyResultInfo& verifyResultInfo)
87 : type_(type), appVerifyBaseInfo_(appVerifyBaseInfo), verifyResultInfo_(verifyResultInfo)
88 {
89 staHandlerMap[STATE_SUCCESS] = [this](std::string time, int cnt)->bool {
90 return HandleStateSuccess(time, cnt);
91 };
92 staHandlerMap[FAILURE_CLIENT_ERROR] = [this](std::string time, int cnt)->bool {
93 return HandleFailureClientError(time, cnt);
94 };
95 staHandlerMap[FORBIDDEN_FOREVER] = [this](std::string time, int cnt)->bool {
96 return HandleForbiddenForever(time, cnt);
97 };
98 InitUriUnVerifySetMap(verifyResultInfo);
99 }
100
GetTaskType()101 OHOS::AppDomainVerify::TaskType& VerifyTask::GetTaskType()
102 {
103 return type_;
104 }
GetAppVerifyBaseInfo()105 AppVerifyBaseInfo& VerifyTask::GetAppVerifyBaseInfo()
106 {
107 return appVerifyBaseInfo_;
108 }
109
SaveDomainVerifyStatus(const std::string & bundleName,const VerifyResultInfo & verifyResultInfo)110 bool VerifyTask::SaveDomainVerifyStatus(const std::string& bundleName, const VerifyResultInfo& verifyResultInfo)
111 {
112 return AppDomainVerifyMgrClient::GetInstance()->SaveDomainVerifyStatus(bundleName, verifyResultInfo);
113 }
114
Execute()115 void VerifyTask::Execute()
116 {
117 for (auto& hostVerifyStatusInfo : verifyResultInfo_.hostVerifyStatusMap) {
118 if (unVerifiedSet_.count(hostVerifyStatusInfo.first) != 0) {
119 auto verifyHttpTask = std::make_shared<VerifyHttpTask>(hostVerifyStatusInfo.first, shared_from_this());
120 AppDomainVerifyTaskMgr::GetInstance()->AddTask(verifyHttpTask);
121 }
122 }
123 }
124
IsNeedRetry(const std::tuple<InnerVerifyStatus,std::string,int> & info)125 bool VerifyTask::IsNeedRetry(const std::tuple<InnerVerifyStatus, std::string, int>& info)
126 {
127 auto [status, verifyTime, verifyCnt] = info;
128 auto iter = staHandlerMap.find(status);
129 if (iter != staHandlerMap.end()) {
130 return iter->second(verifyTime, verifyCnt);
131 }
132 return true;
133 }
134
CalcRetryDuration(int verifyCnt)135 int64_t VerifyTask::CalcRetryDuration(int verifyCnt)
136 {
137 int64_t duration = pow(2, verifyCnt) * CLIENT_ERR_BASE_RETRY_DURATION_S; // base * 2 ^ verifyCnt
138 return duration;
139 }
140
HandleFailureClientError(std::string verifyTime,int verifyCnt)141 bool VerifyTask::HandleFailureClientError(std::string verifyTime, int verifyCnt)
142 {
143 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MODULE_EXTENSION, "called");
144 if (!verifyTime.empty()) {
145 int64_t currTs = GetSecondsSince1970ToNow();
146 int64_t lastTs{};
147 try {
148 lastTs = static_cast<int64_t>(std::stoll(verifyTime));
149 } catch (...) {
150 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_EXTENSION, "get verifyTime error");
151 return false;
152 }
153 int64_t duration = currTs - lastTs;
154 int64_t currRetryDuration = CalcRetryDuration(verifyCnt);
155 if (duration <= currRetryDuration) {
156 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_EXTENSION,
157 "last time:%{public}s, curr time:%{public}s, "
158 "duration:%{public}s "
159 "is less than max retry duration:%{public}s, not retry",
160 std::to_string(lastTs).c_str(),
161 std::to_string(currTs).c_str(),
162 std::to_string(duration).c_str(),
163 std::to_string(currRetryDuration).c_str());
164 return false;
165 }
166 }
167 return true;
168 }
169
HandleStateSuccess(std::string verifyTime,int verifyCnt)170 bool VerifyTask::HandleStateSuccess(std::string verifyTime, int verifyCnt)
171 {
172 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MODULE_EXTENSION, "called");
173 return false;
174 }
175
HandleForbiddenForever(std::string verifyTime,int verifyCnt)176 bool VerifyTask::HandleForbiddenForever(std::string verifyTime, int verifyCnt)
177 {
178 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MODULE_EXTENSION, "called");
179 return false;
180 }
181
UpdateVerifyResultInfo(const std::string & uri,InnerVerifyStatus status)182 void VerifyTask::UpdateVerifyResultInfo(const std::string& uri, InnerVerifyStatus status)
183 {
184 auto verifyStatus = status;
185 auto currTs = GetSecondsSince1970ToNow();
186 std::string verifyTs = std::to_string(currTs);
187 int verifyCnt = 0;
188 auto& hostVerifyStatusMap = verifyResultInfo_.hostVerifyStatusMap;
189 auto iter = hostVerifyStatusMap.find(uri);
190 if (iter == hostVerifyStatusMap.end()) {
191 hostVerifyStatusMap.insert_or_assign(uri, std::make_tuple(verifyStatus, verifyTs, verifyCnt));
192 return;
193 }
194 if (verifyStatus == InnerVerifyStatus::FAILURE_CLIENT_ERROR) {
195 std::tie(std::ignore, std::ignore, verifyCnt) = iter->second;
196 verifyCnt++;
197 if (verifyCnt >= CLIENT_ERR_MAX_RETRY_COUNTS) {
198 verifyStatus = InnerVerifyStatus::FORBIDDEN_FOREVER;
199 }
200 }
201 std::get<0>(iter->second) = verifyStatus;
202 std::get<1>(iter->second) = verifyTs;
203 std::get<2>(iter->second) = verifyCnt; // 2 is cnt
204 }
205
206 }
207 }