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