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 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21 
22 #include "hks_permission_check.h"
23 
24 #ifdef L2_STANDARD
25 #ifdef HKS_SUPPORT_ACCESS_TOKEN
26 #include <cinttypes>
27 #include <dlfcn.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31 #include "accesstoken_kit.h"
32 #include "tokenid_kit.h"
33 #include "ipc_skeleton.h"
34 #include "hks_base_check.h"
35 #include "hks_log.h"
36 #include "hks_template.h"
37 #endif
38 #endif
39 
40 #include "hks_param.h"
41 #include <stdint.h>
42 
43 #ifdef L2_STANDARD
44 #ifdef HKS_SUPPORT_ACCESS_TOKEN
45 using namespace OHOS;
SensitivePermissionCheck(const char * permission)46 int32_t SensitivePermissionCheck(const char *permission)
47 {
48     OHOS::Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
49     int result = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permission);
50     if (result == OHOS::Security::AccessToken::PERMISSION_GRANTED) {
51         HKS_LOG_I("Check Permission success!");
52         return HKS_SUCCESS;
53     } else {
54         HKS_LOG_E("Check Permission failed!%" LOG_PUBLIC "s", permission);
55         return HKS_ERROR_NO_PERMISSION;
56     }
57 }
58 
59 namespace {
CheckTokenType(void)60 static int32_t CheckTokenType(void)
61 {
62     auto accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
63     auto tokenType = OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(
64         static_cast<OHOS::Security::AccessToken::AccessTokenID>(accessTokenIDEx));
65     switch (tokenType) {
66         case OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE:
67         case OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL:
68             return HKS_SUCCESS;
69         case OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_HAP:
70             if (!OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx)) {
71                 HKS_LOG_E("not system hap, check permission failed, accessTokenIDEx %" LOG_PUBLIC PRIu64,
72                     accessTokenIDEx);
73                 return HKS_ERROR_NOT_SYSTEM_APP;
74             } else {
75                 return HKS_SUCCESS;
76             }
77         default:
78             HKS_LOG_E("unknown tokenid, accessTokenIDEx %" LOG_PUBLIC PRIu64, accessTokenIDEx);
79             return HKS_ERROR_INVALID_ACCESS_TYPE;
80     }
81 }
82 }
83 
SystemApiPermissionCheck(int callerUserId)84 int32_t SystemApiPermissionCheck(int callerUserId)
85 {
86     int32_t ret = CheckTokenType();
87     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "CheckTokenType fail %" LOG_PUBLIC "d", ret)
88     if (callerUserId < 0 || callerUserId >= HKS_ROOT_USER_UPPERBOUND) {
89         HKS_LOG_E("invalid callerUserId %" LOG_PUBLIC "d", callerUserId);
90         return HKS_ERROR_NO_PERMISSION;
91     }
92     return HKS_SUCCESS;
93 }
94 
HksCheckAcrossAccountsPermission(const struct HksParamSet * paramSet,int32_t callerUserId)95 int32_t HksCheckAcrossAccountsPermission(const struct HksParamSet *paramSet, int32_t callerUserId)
96 {
97     struct HksParam *specificUserId = NULL;
98     int32_t ret = HksGetParam(paramSet, HKS_TAG_SPECIFIC_USER_ID, &specificUserId);
99     if (ret == HKS_SUCCESS) {
100         ret = SystemApiPermissionCheck(callerUserId);
101         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check systemapi permission failed");
102         ret = SensitivePermissionCheck("ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS");
103         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check interact across local accounts permission failed")
104     } else if (ret == HKS_ERROR_PARAM_NOT_EXIST) {
105         return HKS_SUCCESS;
106     }
107     return ret;
108 }
109 #endif
110 #else
HksCheckAcrossAccountsPermission(const struct HksParamSet * paramSet,int32_t callerUserId)111 int32_t HksCheckAcrossAccountsPermission(const struct HksParamSet *paramSet, int32_t callerUserId)
112 {
113     (void)paramSet;
114     (void)callerUserId;
115     return HKS_SUCCESS;
116 }
117 #endif  // L2_STANDARD
118