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