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 "uri_permission_utils.h"
17
18 #include "ability_manager_errors.h"
19 #include "accesstoken_kit.h"
20 #include "bundle_mgr_client.h"
21 #include "global_constant.h"
22 #include "hilog_tag_wrapper.h"
23 #include "in_process_call_wrapper.h"
24 #include "ipc_skeleton.h"
25 #include "os_account_manager_wrapper.h"
26 #include "permission_verification.h"
27 #include "tokenid_kit.h"
28
29 namespace OHOS {
30 namespace AAFwk {
31 namespace {
32 constexpr int32_t DEFAULT_USER_ID = 0;
33 constexpr int32_t API_VERSION_MOD = 100;
34 constexpr const char* FOUNDATION_PROCESS_NAME = "foundation";
35 constexpr const char* NET_WORK_ID_MARK = "?networkid=";
36 }
37
ConnectManagerHelper()38 std::shared_ptr<AppExecFwk::BundleMgrHelper> UPMSUtils::ConnectManagerHelper()
39 {
40 if (bundleMgrHelper_ == nullptr) {
41 bundleMgrHelper_ = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
42 }
43 return bundleMgrHelper_;
44 }
45
SendShareUnPrivilegeUriEvent(uint32_t callerTokenId,uint32_t targetTokenId)46 bool UPMSUtils::SendShareUnPrivilegeUriEvent(uint32_t callerTokenId, uint32_t targetTokenId)
47 {
48 std::string callerBundleName;
49 if (!GetBundleNameByTokenId(callerTokenId, callerBundleName)) {
50 return false;
51 }
52 std::string targetBundleName;
53 if (!GetBundleNameByTokenId(targetTokenId, targetBundleName)) {
54 return false;
55 }
56 AAFwk::EventInfo eventInfo;
57 eventInfo.callerBundleName = callerBundleName;
58 eventInfo.bundleName = targetBundleName;
59 TAG_LOGD(AAFwkTag::URIPERMMGR, "Send SHARE_UNPRIVILEGED_FILE_URI Event.");
60 AAFwk::EventReport::SendGrantUriPermissionEvent(AAFwk::EventName::SHARE_UNPRIVILEGED_FILE_URI, eventInfo);
61 return true;
62 }
63
SendSystemAppGrantUriPermissionEvent(uint32_t callerTokenId,uint32_t targetTokenId,const std::vector<std::string> & uriVec,const std::vector<int32_t> & resVec)64 bool UPMSUtils::SendSystemAppGrantUriPermissionEvent(uint32_t callerTokenId, uint32_t targetTokenId,
65 const std::vector<std::string> &uriVec, const std::vector<int32_t> &resVec)
66 {
67 EventInfo eventInfo;
68 if (!CheckAndCreateEventInfo(callerTokenId, targetTokenId, eventInfo)) {
69 return false;
70 }
71 for (size_t i = 0; i < resVec.size(); i++) {
72 if (resVec[i] == 0 || resVec[i] == -EEXIST) {
73 eventInfo.uri = uriVec[i];
74 EventReport::SendGrantUriPermissionEvent(EventName::GRANT_URI_PERMISSION, eventInfo);
75 }
76 }
77 TAG_LOGD(AAFwkTag::URIPERMMGR, "Send GRANT_URI_PERMISSION Event.");
78 return true;
79 }
80
CheckAndCreateEventInfo(uint32_t callerTokenId,uint32_t targetTokenId,EventInfo & eventInfo)81 bool UPMSUtils::CheckAndCreateEventInfo(uint32_t callerTokenId, uint32_t targetTokenId,
82 EventInfo &eventInfo)
83 {
84 std::string callerBundleName;
85 if (!GetBundleNameByTokenId(callerTokenId, callerBundleName)) {
86 TAG_LOGD(AAFwkTag::URIPERMMGR, "get caller bundle name failed.");
87 return false;
88 }
89 if (!CheckIsSystemAppByBundleName(callerBundleName)) {
90 TAG_LOGD(AAFwkTag::URIPERMMGR, "caller is not system.");
91 return false;
92 }
93 std::string targetBundleName;
94 if (!GetBundleNameByTokenId(targetTokenId, targetBundleName)) {
95 TAG_LOGD(AAFwkTag::URIPERMMGR, "get target bundle name failed.");
96 return false;
97 }
98 if (CheckIsSystemAppByBundleName(targetBundleName)) {
99 TAG_LOGD(AAFwkTag::URIPERMMGR, "target is system app.");
100 return false;
101 }
102 eventInfo.callerBundleName = callerBundleName;
103 eventInfo.bundleName = targetBundleName;
104 return true;
105 }
106
GetCurrentAccountId()107 int32_t UPMSUtils::GetCurrentAccountId()
108 {
109 std::vector<int32_t> osActiveAccountIds;
110 auto ret = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
111 QueryActiveOsAccountIds(osActiveAccountIds);
112 if (ret != ERR_OK) {
113 TAG_LOGE(AAFwkTag::URIPERMMGR, "QueryActiveOsAccountIds error.");
114 return DEFAULT_USER_ID;
115 }
116 if (osActiveAccountIds.empty()) {
117 TAG_LOGE(AAFwkTag::URIPERMMGR, "the QueryActiveOsAccountIds is empty, no accounts.");
118 return DEFAULT_USER_ID;
119 }
120 return osActiveAccountIds.front();
121 }
122
IsFoundationCall()123 bool UPMSUtils::IsFoundationCall()
124 {
125 auto callerTokenId = IPCSkeleton::GetCallingTokenID();
126 TAG_LOGD(AAFwkTag::ABILITYMGR, "callerTokenId is %{public}u", callerTokenId);
127 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerTokenId);
128 if (tokenType != Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
129 TAG_LOGI(AAFwkTag::ABILITYMGR, "Is not native call");
130 return false;
131 }
132 Security::AccessToken::NativeTokenInfo nativeInfo;
133 auto result = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(callerTokenId, nativeInfo);
134 if (result != ERR_OK) {
135 TAG_LOGE(AAFwkTag::URIPERMMGR, "GetNativeTokenInfo failed, callerTokenId is %{public}u.", callerTokenId);
136 return false;
137 }
138 TAG_LOGD(AAFwkTag::URIPERMMGR, "Caller process name : %{public}s", nativeInfo.processName.c_str());
139 return nativeInfo.processName == FOUNDATION_PROCESS_NAME;
140 }
141
IsSAOrSystemAppCall()142 bool UPMSUtils::IsSAOrSystemAppCall()
143 {
144 return PermissionVerification::GetInstance()->IsSystemAppCall() ||
145 PermissionVerification::GetInstance()->IsSACall();
146 }
147
IsSystemAppCall(uint32_t tokenId)148 bool UPMSUtils::IsSystemAppCall(uint32_t tokenId)
149 {
150 if (UPMSUtils::IsFoundationCall()) {
151 return UPMSUtils::CheckIsSystemAppByTokenId(tokenId);
152 }
153 return PermissionVerification::GetInstance()->IsSystemAppCall();
154 }
155
CheckIsSystemAppByBundleName(std::string & bundleName)156 bool UPMSUtils::CheckIsSystemAppByBundleName(std::string &bundleName)
157 {
158 auto bundleMgrHelper = ConnectManagerHelper();
159 if (bundleMgrHelper == nullptr) {
160 TAG_LOGW(AAFwkTag::URIPERMMGR, "The bundleMgrHelper is nullptr.");
161 return false;
162 }
163 AppExecFwk::ApplicationInfo appInfo;
164 if (!IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(bundleName,
165 AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, GetCurrentAccountId(), appInfo))) {
166 TAG_LOGW(AAFwkTag::URIPERMMGR, "Get application info failed.");
167 return false;
168 }
169 auto isSystemApp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(appInfo.accessTokenIdEx);
170 TAG_LOGD(AAFwkTag::URIPERMMGR, "BundleName is %{public}s, isSystemApp = %{public}d", bundleName.c_str(),
171 static_cast<int32_t>(isSystemApp));
172 return isSystemApp;
173 }
174
GetBundleApiTargetVersion(const std::string & bundleName,int32_t & targetApiVersion)175 bool UPMSUtils::GetBundleApiTargetVersion(const std::string &bundleName, int32_t &targetApiVersion)
176 {
177 auto bundleMgrHelper = ConnectManagerHelper();
178 if (bundleMgrHelper == nullptr) {
179 TAG_LOGW(AAFwkTag::URIPERMMGR, "The bundleMgrHelper is nullptr.");
180 return false;
181 }
182 AppExecFwk::ApplicationInfo appInfo;
183 if (!IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(bundleName,
184 AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, GetCurrentAccountId(), appInfo))) {
185 TAG_LOGI(AAFwkTag::URIPERMMGR, "Get application info failed.");
186 return false;
187 }
188 targetApiVersion = (appInfo.apiTargetVersion % API_VERSION_MOD);
189 return true;
190 }
191
CheckIsSystemAppByTokenId(uint32_t tokenId)192 bool UPMSUtils::CheckIsSystemAppByTokenId(uint32_t tokenId)
193 {
194 std::string bundleName;
195 if (GetBundleNameByTokenId(tokenId, bundleName)) {
196 return CheckIsSystemAppByBundleName(bundleName);
197 }
198 return false;
199 }
200
GetDirByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::string & dirName)201 bool UPMSUtils::GetDirByBundleNameAndAppIndex(const std::string &bundleName, int32_t appIndex, std::string &dirName)
202 {
203 auto bmsClient = DelayedSingleton<AppExecFwk::BundleMgrClient>::GetInstance();
204 if (bmsClient == nullptr) {
205 TAG_LOGE(AAFwkTag::URIPERMMGR, "bundleMgrClient is nullptr.");
206 return false;
207 }
208 auto bmsRet = IN_PROCESS_CALL(bmsClient->GetDirByBundleNameAndAppIndex(bundleName, appIndex, dirName));
209 if (bmsRet != ERR_OK) {
210 TAG_LOGE(AAFwkTag::URIPERMMGR, "GetDirByBundleNameAndAppIndex failed, ret:%{public}d", bmsRet);
211 return false;
212 }
213 return true;
214 }
215
GetAlterableBundleNameByTokenId(uint32_t tokenId,std::string & bundleName)216 bool UPMSUtils::GetAlterableBundleNameByTokenId(uint32_t tokenId, std::string &bundleName)
217 {
218 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
219 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
220 Security::AccessToken::HapTokenInfo hapInfo;
221 auto ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo);
222 if (ret != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
223 TAG_LOGE(AAFwkTag::URIPERMMGR, "GetHapTokenInfo failed, ret is %{public}d.", ret);
224 return false;
225 }
226 return GetDirByBundleNameAndAppIndex(hapInfo.bundleName, hapInfo.instIndex, bundleName);
227 }
228 return false;
229 }
230
GetBundleNameByTokenId(uint32_t tokenId,std::string & bundleName)231 bool UPMSUtils::GetBundleNameByTokenId(uint32_t tokenId, std::string &bundleName)
232 {
233 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
234 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
235 Security::AccessToken::HapTokenInfo hapInfo;
236 auto ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo);
237 if (ret != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
238 TAG_LOGE(AAFwkTag::URIPERMMGR, "GetHapTokenInfo failed, ret is %{public}d.", ret);
239 return false;
240 }
241 bundleName = hapInfo.bundleName;
242 return true;
243 }
244 return false;
245 }
246
GetAppIdByBundleName(const std::string & bundleName,std::string & appId)247 int32_t UPMSUtils::GetAppIdByBundleName(const std::string &bundleName, std::string &appId)
248 {
249 TAG_LOGD(AAFwkTag::URIPERMMGR, "BundleName is %{public}s.", bundleName.c_str());
250 auto bms = ConnectManagerHelper();
251 if (bms == nullptr) {
252 TAG_LOGW(AAFwkTag::URIPERMMGR, "The bundleMgrHelper is nullptr.");
253 return GET_BUNDLE_MANAGER_SERVICE_FAILED;
254 }
255 auto userId = GetCurrentAccountId();
256 appId = IN_PROCESS_CALL(bms->GetAppIdByBundleName(bundleName, userId));
257 if (appId.empty()) {
258 TAG_LOGW(AAFwkTag::URIPERMMGR, "Get appId by bundle name failed, userId is %{private}d", userId);
259 return INNER_ERR;
260 }
261 return ERR_OK;
262 }
263
GetTokenIdByBundleName(const std::string & bundleName,int32_t appIndex,uint32_t & tokenId)264 int32_t UPMSUtils::GetTokenIdByBundleName(const std::string &bundleName, int32_t appIndex, uint32_t &tokenId)
265 {
266 TAG_LOGD(AAFwkTag::URIPERMMGR, "BundleName:%{public}s, appIndex:%{public}d", bundleName.c_str(), appIndex);
267 auto bms = ConnectManagerHelper();
268 if (bms == nullptr) {
269 TAG_LOGW(AAFwkTag::URIPERMMGR, "null bms");
270 return GET_BUNDLE_MANAGER_SERVICE_FAILED;
271 }
272 AppExecFwk::BundleInfo bundleInfo;
273 auto userId = GetCurrentAccountId();
274 if (appIndex == 0) {
275 auto bundleFlag = AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO;
276 if (!IN_PROCESS_CALL(bms->GetBundleInfo(bundleName, bundleFlag, bundleInfo, userId))) {
277 TAG_LOGW(AAFwkTag::URIPERMMGR, "Failed GetBundleInfo");
278 return ERR_GET_TARGET_BUNDLE_INFO_FAILED;
279 }
280 tokenId = bundleInfo.applicationInfo.accessTokenId;
281 return ERR_OK;
282 }
283 if (appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
284 auto bundleFlag = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION);
285 if (IN_PROCESS_CALL(bms->GetCloneBundleInfo(bundleName, bundleFlag, appIndex, bundleInfo, userId)) != ERR_OK) {
286 TAG_LOGW(AAFwkTag::URIPERMMGR, "Failed GetCloneBundleInfo");
287 return ERR_GET_TARGET_BUNDLE_INFO_FAILED;
288 }
289 tokenId = bundleInfo.applicationInfo.accessTokenId;
290 return ERR_OK;
291 }
292 if (IN_PROCESS_CALL(bms->GetSandboxBundleInfo(bundleName, appIndex, userId, bundleInfo) != ERR_OK)) {
293 TAG_LOGW(AAFwkTag::URIPERMMGR, "Failed GetSandboxBundleInfo");
294 return ERR_GET_TARGET_BUNDLE_INFO_FAILED;
295 }
296 tokenId = bundleInfo.applicationInfo.accessTokenId;
297 return ERR_OK;
298 }
299
CheckUriTypeIsValid(Uri & uri)300 bool UPMSUtils::CheckUriTypeIsValid(Uri &uri)
301 {
302 auto &&scheme = uri.GetScheme();
303 if (scheme != "file" && scheme != "content") {
304 TAG_LOGW(AAFwkTag::URIPERMMGR, "Type of uri is invalid, Scheme is %{public}s", scheme.c_str());
305 return false;
306 }
307 return true;
308 }
309
IsDocsCloudUri(Uri & uri)310 bool UPMSUtils::IsDocsCloudUri(Uri &uri)
311 {
312 return (uri.GetAuthority() == "docs" && uri.ToString().find(NET_WORK_ID_MARK) != std::string::npos);
313 }
314
315 std::shared_ptr<AppExecFwk::BundleMgrHelper> UPMSUtils::bundleMgrHelper_ = nullptr;
316 } // namespace AAFwk
317 } // namespace OHOS
318