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 #include <memory>
17 #include <string>
18 #include <tuple>
19 #include <vector>
20 #include "app_domain_verify_mgr_service.h"
21 #include "system_ability_definition.h"
22 #include "domain_url_util.h"
23 #include "app_domain_verify_agent_client.h"
24 #include "comm_define.h"
25 namespace OHOS {
26 namespace AppDomainVerify {
27 constexpr const char* GET_DOMAIN_VERIFY_INFO = "ohos.permission.GET_APP_DOMAIN_BUNDLE_INFO";
28 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(new AppDomainVerifyMgrService());
29 const std::string HTTPS = "https";
30 const std::set<std::string> SCHEME_WHITE_SET = { HTTPS };
31 const std::string FUZZY_HOST_START = "*.";
32
AppDomainVerifyMgrService()33 AppDomainVerifyMgrService::AppDomainVerifyMgrService() : SystemAbility(APP_DOMAIN_VERIFY_MANAGER_SA_ID, true)
34 {
35 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "new instance create.");
36 dataManager_ = std::make_shared<AppDomainVerifyDataMgr>();
37 }
~AppDomainVerifyMgrService()38 AppDomainVerifyMgrService::~AppDomainVerifyMgrService()
39 {
40 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "instance dead.");
41 }
42
VerifyDomain(const std::string & appIdentifier,const std::string & bundleName,const std::string & fingerprint,const std::vector<SkillUri> & skillUris)43 void AppDomainVerifyMgrService::VerifyDomain(const std::string& appIdentifier, const std::string& bundleName,
44 const std::string& fingerprint, const std::vector<SkillUri>& skillUris)
45 {
46 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
47 if (!PermissionManager::IsSACall()) {
48 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "only sa can call");
49 return;
50 }
51 AppVerifyBaseInfo appVerifyBaseInfo;
52 appVerifyBaseInfo.appIdentifier = appIdentifier;
53 appVerifyBaseInfo.bundleName = bundleName;
54 appVerifyBaseInfo.fingerprint = fingerprint;
55
56 VerifyResultInfo verifyResultInfo;
57 verifyResultInfo.appIdentifier = appIdentifier;
58
59 CollectDomains(skillUris, verifyResultInfo);
60
61 AppDomainVerifyAgentClient::GetInstance()->SingleVerify(appVerifyBaseInfo, verifyResultInfo);
62 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
63 }
64
ClearDomainVerifyStatus(const std::string & appIdentifier,const std::string & bundleName)65 bool AppDomainVerifyMgrService::ClearDomainVerifyStatus(const std::string& appIdentifier, const std::string& bundleName)
66 {
67 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
68 if (!PermissionManager::IsSACall()) {
69 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "only sa can call");
70 return false;
71 }
72 bool res = dataManager_->DeleteVerifyStatus(bundleName);
73 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
74 return res;
75 }
76
FilterAbilities(const OHOS::AAFwk::Want & want,const std::vector<OHOS::AppExecFwk::AbilityInfo> & originAbilityInfos,std::vector<OHOS::AppExecFwk::AbilityInfo> & filtedAbilityInfos)77 bool AppDomainVerifyMgrService::FilterAbilities(const OHOS::AAFwk::Want& want,
78 const std::vector<OHOS::AppExecFwk::AbilityInfo>& originAbilityInfos,
79 std::vector<OHOS::AppExecFwk::AbilityInfo>& filtedAbilityInfos)
80 {
81 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
82 if (!PermissionManager::IsSACall()) {
83 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "only sa can call");
84 return false;
85 }
86 if (!IsWantImplicit(want)) {
87 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "want is not implicit.");
88 return false;
89 }
90
91 std::string uriString = want.GetUriString();
92 std::string scheme = UrlUtil::GetScheme(uriString);
93 std::string host = UrlUtil::GetHost(uriString);
94 if (scheme.empty() || host.empty()) {
95 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "uriString is not valid.");
96 return false;
97 }
98 std::string hostVerifyKey = scheme + "://" + host;
99 for (auto it = originAbilityInfos.begin(); it != originAbilityInfos.end(); ++it) {
100 // todo bms AbilityInfo contains appIdentifier
101 VerifyResultInfo verifyResultInfo;
102 // get from emory variable, non-IO operation.
103 if (dataManager_->GetVerifyStatus(it->bundleName, verifyResultInfo)) {
104 auto itr = verifyResultInfo.hostVerifyStatusMap.find(hostVerifyKey);
105 if (itr != verifyResultInfo.hostVerifyStatusMap.end() &&
106 std::get<0>(itr->second) == InnerVerifyStatus::STATE_SUCCESS) {
107 filtedAbilityInfos.emplace_back(*it);
108 }
109 }
110 }
111 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
112 return true;
113 }
114
QueryDomainVerifyStatus(const std::string & bundleName,DomainVerifyStatus & domainVerificationState)115 bool AppDomainVerifyMgrService::QueryDomainVerifyStatus(
116 const std::string& bundleName, DomainVerifyStatus& domainVerificationState)
117 {
118 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
119 if (!PermissionManager::IsSACall()) {
120 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "only sa can call");
121 return false;
122 }
123 VerifyResultInfo verifyResultInfo;
124 bool res = dataManager_->GetVerifyStatus(bundleName, verifyResultInfo);
125 domainVerificationState = DomainVerifyStatus::STATE_NONE;
126 for (auto it = verifyResultInfo.hostVerifyStatusMap.begin();
127 res && it != verifyResultInfo.hostVerifyStatusMap.end(); ++it) {
128 if (std::get<0>(it->second) == InnerVerifyStatus::STATE_SUCCESS) {
129 domainVerificationState = DomainVerifyStatus::STATE_VERIFIED;
130 break;
131 }
132 }
133 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
134 return res;
135 }
136
QueryAllDomainVerifyStatus(BundleVerifyStatusInfo & bundleVerifyStatusInfo)137 bool AppDomainVerifyMgrService::QueryAllDomainVerifyStatus(BundleVerifyStatusInfo& bundleVerifyStatusInfo)
138 {
139 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
140 if (!PermissionManager::IsSACall()) {
141 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "only sa can call");
142 return false;
143 }
144 bundleVerifyStatusInfo.bundleVerifyStatusInfoMap_ = dataManager_->GetAllVerifyStatus();
145 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
146 return true;
147 }
148
SaveDomainVerifyStatus(const std::string & bundleName,const VerifyResultInfo & verifyResultInfo)149 bool AppDomainVerifyMgrService::SaveDomainVerifyStatus(
150 const std::string& bundleName, const VerifyResultInfo& verifyResultInfo)
151 {
152 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
153 if (!PermissionManager::IsSACall()) {
154 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "only sa can call");
155 return false;
156 }
157 bool res = dataManager_->SaveVerifyStatus(bundleName, verifyResultInfo);
158 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
159 return res;
160 }
IsAtomicServiceUrl(const std::string & url)161 bool AppDomainVerifyMgrService::IsAtomicServiceUrl(const std::string& url)
162 {
163 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
164 if (!PermissionManager::IsSACall()) {
165 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "only sa can call");
166 return false;
167 }
168 if (!InitConfigMgr()) {
169 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "InitConfigMgr failed.");
170 return false;
171 }
172 return whiteListConfigMgr_->IsInWhiteList(url);
173 }
ConvertToExplicitWant(OHOS::AAFwk::Want & implicitWant,sptr<IConvertCallback> & callback)174 void AppDomainVerifyMgrService::ConvertToExplicitWant(OHOS::AAFwk::Want& implicitWant, sptr<IConvertCallback>& callback)
175 {
176 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
177 if (!PermissionManager::IsSACall()) {
178 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "only sa can call");
179 return;
180 }
181 AppDomainVerifyAgentClient::GetInstance()->ConvertToExplicitWant(implicitWant, callback);
182 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
183 }
184
UpdateWhiteListUrls(const std::vector<std::string> & urls)185 void AppDomainVerifyMgrService::UpdateWhiteListUrls(const std::vector<std::string>& urls)
186 {
187 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
188 if (!PermissionManager::IsSACall()) {
189 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "only sa can call");
190 return;
191 }
192 if (!InitConfigMgr()) {
193 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "InitConfigMgr failed.");
194 return;
195 }
196 std::unordered_set<std::string> whiteList(urls.begin(), urls.end());
197 whiteListConfigMgr_->UpdateWhiteList(whiteList);
198 }
199
QueryAssociatedDomains(const std::string & bundleName,std::vector<std::string> & domains)200 int AppDomainVerifyMgrService::QueryAssociatedDomains(const std::string& bundleName, std::vector<std::string>& domains)
201 {
202 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
203 auto ret = CheckPermission();
204 if (ret != CommonErrorCode::E_OK) {
205 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "CheckPermission failed:%{public}d", ret);
206 return ret;
207 }
208 return dataManager_->QueryAssociatedDomains(bundleName, domains) ? E_OK : E_INTERNAL_ERR;
209 }
QueryAssociatedBundleNames(const std::string & domain,std::vector<std::string> & bundleNames)210 int AppDomainVerifyMgrService::QueryAssociatedBundleNames(
211 const std::string& domain, std::vector<std::string>& bundleNames)
212 {
213 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
214 auto ret = CheckPermission();
215 if (ret != CommonErrorCode::E_OK) {
216 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "CheckPermission failed:%{public}d", ret);
217 return ret;
218 }
219 return dataManager_->QueryAssociatedBundleNames(domain, bundleNames) ? E_OK : E_INTERNAL_ERR;
220 }
221
IsWantImplicit(const OHOS::AAFwk::Want & want)222 bool AppDomainVerifyMgrService::IsWantImplicit(const OHOS::AAFwk::Want& want)
223 {
224 auto element = want.GetElement();
225 std::string bundleName = element.GetBundleName();
226 std::string abilityName = element.GetAbilityName();
227 // want is explicit query
228 if (!bundleName.empty() && !abilityName.empty()) {
229 return false;
230 }
231 return true;
232 }
233
234 // sa_main进程统一调用
OnStart()235 void AppDomainVerifyMgrService::OnStart()
236 {
237 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "OnStart");
238 bool res = Publish(this);
239 if (!res) {
240 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "Publish failed");
241 }
242 }
243
OnStop()244 void AppDomainVerifyMgrService::OnStop()
245 {
246 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
247 }
OnDump()248 void AppDomainVerifyMgrService::OnDump()
249 {
250 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "OnDump");
251 }
252
Dump(int fd,const std::vector<std::u16string> & args)253 int AppDomainVerifyMgrService::Dump(int fd, const std::vector<std::u16string>& args)
254 {
255 std::string dumpString{};
256 DumpAllVerifyInfos(dumpString);
257 (void)write(fd, dumpString.c_str(), dumpString.size());
258 return 0;
259 }
DumpAllVerifyInfos(std::string & dumpString)260 void AppDomainVerifyMgrService::DumpAllVerifyInfos(std::string& dumpString)
261 {
262 BundleVerifyStatusInfo allBundleVerifyStatusInfo;
263 if (!QueryAllDomainVerifyStatus(allBundleVerifyStatusInfo)) {
264 return;
265 }
266 for (const auto& bundleVerifyStatusInfo : allBundleVerifyStatusInfo.bundleVerifyStatusInfoMap_) {
267 dumpString.append(bundleVerifyStatusInfo.first + ":\n");
268 auto verifyResultInfo = bundleVerifyStatusInfo.second;
269 dumpString.append(" appIdentifier:" + verifyResultInfo.appIdentifier);
270 dumpString.append("\n");
271 dumpString.append(" domain verify status:\n");
272 for (const auto& hostVerifyStatus : verifyResultInfo.hostVerifyStatusMap) {
273 dumpString.append(" " + hostVerifyStatus.first + ":" +
274 InnerVerifyStatusMap[std::get<0>(hostVerifyStatus.second)]);
275 dumpString.append("\n");
276 }
277 }
278 }
InitConfigMgr()279 bool AppDomainVerifyMgrService::InitConfigMgr()
280 {
281 if (whiteListConfigMgr_ != nullptr) {
282 return true;
283 }
284 std::lock_guard<std::mutex> lock(initConfigMutex_);
285 if (whiteListConfigMgr_ == nullptr) {
286 whiteListConfigMgr_ = std::make_shared<WhiteListConfigMgr>();
287 }
288 if (whiteListConfigMgr_ == nullptr) {
289 return false;
290 }
291 return true;
292 }
CheckPermission()293 int AppDomainVerifyMgrService::CheckPermission()
294 {
295 if (!PermissionManager::CheckPermission(GET_DOMAIN_VERIFY_INFO)) {
296 APP_DOMAIN_VERIFY_HILOGE(
297 APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "CheckPermission failed %{public}s.", GET_DOMAIN_VERIFY_INFO);
298 return CommonErrorCode::E_PERMISSION_DENIED;
299 }
300
301 if (!PermissionManager::IsSystemAppCall()) {
302 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "IsSystemAppCall failed .");
303 return CommonErrorCode::E_IS_NOT_SYS_APP;
304 }
305 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "CheckPermission ok .");
306 return CommonErrorCode::E_OK;
307 }
CollectDomains(const std::vector<SkillUri> & skillUris,VerifyResultInfo & verifyResultInfo)308 void AppDomainVerifyMgrService::CollectDomains(
309 const std::vector<SkillUri>& skillUris, VerifyResultInfo& verifyResultInfo)
310 {
311 for (auto it = skillUris.begin(); it != skillUris.end(); ++it) {
312 if (it->scheme.empty() || it->host.empty() || !UrlUtil::IsValidAppDomainVerifyHost(it->host) ||
313 SCHEME_WHITE_SET.find(it->scheme) == SCHEME_WHITE_SET.end()) {
314 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "invalid skillUri skip.");
315 continue;
316 }
317
318 std::string host = it->host;
319 if (it->host.substr(0, FUZZY_HOST_START.size()) == FUZZY_HOST_START) {
320 // Hosts with *.
321 host = it->host.substr(FUZZY_HOST_START.size());
322 }
323 // validUris remove duplicates
324 auto uri = it->scheme + "://" + host;
325 verifyResultInfo.hostVerifyStatusMap.insert(make_pair(
326 uri, std::make_tuple(InnerVerifyStatus::UNKNOWN, std::string(), 0)));
327 }
328 }
329 } // namespace AppDomainVerify
330 } // namespace OHOS
331