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 "accesstoken_kit.h"
17 #include "dfs_daemon_event_dfx.h"
18 #include "dfs_error.h"
19 #include "dfsu_access_token_helper.h"
20 #include "ipc_skeleton.h"
21 #include "tokenid_kit.h"
22 #include "uri_permission_manager_client.h"
23 #include "uri.h"
24 #include "utils_log.h"
25 #include "want.h"
26
27 namespace OHOS::FileManagement {
28 using namespace std;
29 using namespace Security::AccessToken;
30 using namespace Storage::DistributedFile;
31 constexpr int32_t ROOT_UID = 0;
32 constexpr int32_t BASE_USER_RANGE = 200000;
CheckCallerPermission(const std::string & permissionName)33 bool DfsuAccessTokenHelper::CheckCallerPermission(const std::string &permissionName)
34 {
35 auto tokenId = IPCSkeleton::GetCallingTokenID();
36 auto uid = IPCSkeleton::GetCallingUid();
37 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
38 if (tokenType == TOKEN_HAP || tokenType == TOKEN_NATIVE) {
39 bool isGranted = CheckPermission(tokenId, permissionName);
40 if (!isGranted) {
41 LOGE("Token Type is %{public}d", tokenType);
42 }
43 return isGranted;
44 } else if ((tokenType == TOKEN_SHELL) && (uid == ROOT_UID)) {
45 LOGI("Token type is shell");
46 return false;
47 } else {
48 LOGE("Unsupported token type:%{public}d", tokenType);
49 return false;
50 }
51 }
52
CheckPermission(uint32_t tokenId,const std::string & permissionName)53 bool DfsuAccessTokenHelper::CheckPermission(uint32_t tokenId, const std::string &permissionName)
54 {
55 int32_t ret = AccessTokenKit::VerifyAccessToken(tokenId, permissionName);
56 if (ret == PermissionState::PERMISSION_DENIED) {
57 LOGE("permission %{private}s: PERMISSION_DENIED", permissionName.c_str());
58 return false;
59 }
60 return true;
61 }
62
GetCallerBundleName(std::string & bundleName)63 int32_t DfsuAccessTokenHelper::GetCallerBundleName(std::string &bundleName)
64 {
65 auto tokenId = IPCSkeleton::GetCallingTokenID();
66 return GetBundleNameByToken(tokenId, bundleName);
67 }
68
GetBundleNameByToken(uint32_t tokenId,std::string & bundleName)69 int32_t DfsuAccessTokenHelper::GetBundleNameByToken(uint32_t tokenId, std::string &bundleName)
70 {
71 int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
72 switch (tokenType) {
73 case TOKEN_HAP: {
74 HapTokenInfo hapInfo;
75 if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
76 LOGE("[Permission Check] get hap token info fail");
77 return E_GET_TOKEN_INFO_ERROR;
78 }
79 if (hapInfo.instIndex != 0) {
80 LOGE("[Permission Check] APP twin is not supported.");
81 break;
82 }
83 bundleName = hapInfo.bundleName;
84 break;
85 }
86 case TOKEN_NATIVE:
87 // fall-through
88 case TOKEN_SHELL: {
89 NativeTokenInfo tokenInfo;
90 if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
91 LOGE("[Permission Check] get native token info fail");
92 return E_GET_TOKEN_INFO_ERROR;
93 }
94 bundleName = tokenInfo.processName;
95 break;
96 }
97 default: {
98 LOGE("[Permission Check] token type not match");
99 return E_GET_TOKEN_INFO_ERROR;
100 }
101 }
102 if (bundleName.empty()) {
103 LOGE("[Permission Check] package name is empty");
104 return E_INVAL_ARG;
105 }
106 return E_OK;
107 }
IsSystemApp()108 bool DfsuAccessTokenHelper::IsSystemApp()
109 {
110 auto tokenId = IPCSkeleton::GetCallingTokenID();
111 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
112 if (tokenType == TOKEN_HAP) {
113 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
114 return TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
115 }
116 return true;
117 }
118
GetUserId()119 int32_t DfsuAccessTokenHelper::GetUserId()
120 {
121 auto uid = IPCSkeleton::GetCallingUid();
122 return uid / BASE_USER_RANGE;
123 }
124
GetPid()125 int32_t DfsuAccessTokenHelper::GetPid()
126 {
127 auto pid = IPCSkeleton::GetCallingPid();
128 return pid;
129 }
130
CheckUriPermission(const std::string & uriStr)131 bool DfsuAccessTokenHelper::CheckUriPermission(const std::string &uriStr)
132 {
133 auto tokenId = IPCSkeleton::GetCallingTokenID();
134 string bundleName;
135 if (GetBundleNameByToken(tokenId, bundleName) != E_OK) {
136 LOGE("get caller bundle name failed");
137 return false;
138 }
139 Uri uri(uriStr);
140 auto &uriPermissionClient = AAFwk::UriPermissionManagerClient::GetInstance();
141 if (bundleName != uri.GetAuthority() &&
142 !uriPermissionClient.VerifyUriPermission(uri, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, tokenId)) {
143 RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED,
144 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
145 RadarReporter::CHECK_URI_PREMISSION_ERROR, RadarReporter::PACKAGE_NAME, RadarReporter::uriPermMgr);
146 LOGE("uri permission denied");
147 return false;
148 }
149 return true;
150 }
151 } // namespace OHOS::FileManagement