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