1 /*
2 * Copyright (c) 2022 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 "ipc_common.h"
17 #include "ipc_skeleton.h"
18 #include "accesstoken_kit.h"
19 #include "iam_common_defines.h"
20 #include "iam_logger.h"
21 #include "tokenid_kit.h"
22 #ifdef HAS_OS_ACCOUNT_PART
23 #include "os_account_manager.h"
24 #endif // HAS_OS_ACCOUNT_PART
25 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
26
27 namespace OHOS {
28 namespace UserIam {
29 namespace UserAuth {
30 namespace PermissionString {
31 const std::string MANAGE_USER_IDM_PERMISSION = "ohos.permission.MANAGE_USER_IDM";
32 const std::string USE_USER_IDM_PERMISSION = "ohos.permission.USE_USER_IDM";
33 const std::string ACCESS_USER_AUTH_INTERNAL_PERMISSION = "ohos.permission.ACCESS_USER_AUTH_INTERNAL";
34 const std::string ACCESS_BIOMETRIC_PERMISSION = "ohos.permission.ACCESS_BIOMETRIC";
35 const std::string ACCESS_AUTH_RESPOOL = "ohos.permission.ACCESS_AUTH_RESPOOL";
36 const std::string ENFORCE_USER_IDM = "ohos.permission.ENFORCE_USER_IDM";
37 const std::string SUPPORT_USER_AUTH = "ohos.permission.SUPPORT_USER_AUTH";
38 }
39
40 namespace {
41 // process white list of allowing to call, <processUid, processName>
42 const std::vector<std::pair<int32_t, std::string>> whiteLists = {
43 {3058, "accountmgr"},
44 };
45 }
46
GetCallingUserId(IPCObjectStub & stub,int32_t & userId)47 int32_t IpcCommon::GetCallingUserId(IPCObjectStub &stub, int32_t &userId)
48 {
49 if (userId != 0) {
50 return SUCCESS;
51 }
52 uint32_t tokenId = GetAccessTokenId(stub);
53 using namespace Security::AccessToken;
54 ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(tokenId);
55 if (callingType != TOKEN_HAP) {
56 IAM_LOGE("failed to get calling type");
57 return TYPE_NOT_SUPPORT;
58 }
59 HapTokenInfo hapTokenInfo;
60 int result = AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
61 if (result != SUCCESS) {
62 IAM_LOGE("failed to get hap token info, result = %{public}d", result);
63 return TYPE_NOT_SUPPORT;
64 }
65 userId = static_cast<int32_t>(hapTokenInfo.userID);
66 IAM_LOGI("get callingUserId is %{public}d", userId);
67 return SUCCESS;
68 }
69
GetActiveUserId(std::optional<int32_t> & userId)70 int32_t IpcCommon::GetActiveUserId(std::optional<int32_t> &userId)
71 {
72 if (userId.has_value() && userId.value() != 0) {
73 return SUCCESS;
74 }
75 std::vector<int32_t> ids;
76 #ifdef HAS_OS_ACCOUNT_PART
77 ErrCode queryRet = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
78 if (queryRet != ERR_OK || ids.empty()) {
79 IAM_LOGE("failed to query active account id");
80 return GENERAL_ERROR;
81 }
82 #else // HAS_OS_ACCOUNT_PART
83 const int32_t DEFAULT_OS_ACCOUNT_ID = 0;
84 ids.push_back(DEFAULT_OS_ACCOUNT_ID);
85 IAM_LOGI("there is no os account part, use default id");
86 #endif // HAS_OS_ACCOUNT_PART
87 userId = ids.front();
88 return SUCCESS;
89 }
90
CheckPermission(IPCObjectStub & stub,Permission permission)91 bool IpcCommon::CheckPermission(IPCObjectStub &stub, Permission permission)
92 {
93 switch (permission) {
94 case MANAGE_USER_IDM_PERMISSION:
95 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::MANAGE_USER_IDM_PERMISSION) &&
96 CheckNativeCallingProcessWhiteList(stub);
97 case USE_USER_IDM_PERMISSION:
98 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::USE_USER_IDM_PERMISSION);
99 case ACCESS_USER_AUTH_INTERNAL_PERMISSION:
100 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::ACCESS_USER_AUTH_INTERNAL_PERMISSION);
101 case ACCESS_BIOMETRIC_PERMISSION:
102 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::ACCESS_BIOMETRIC_PERMISSION);
103 case ACCESS_AUTH_RESPOOL:
104 return CheckDirectCaller(stub, PermissionString::ACCESS_AUTH_RESPOOL);
105 case ENFORCE_USER_IDM:
106 return CheckDirectCaller(stub, PermissionString::ENFORCE_USER_IDM) &&
107 CheckNativeCallingProcessWhiteList(stub);
108 case SUPPORT_USER_AUTH:
109 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::SUPPORT_USER_AUTH);
110 case IS_SYSTEM_APP:
111 return CheckCallerIsSystemApp(stub);
112 default:
113 IAM_LOGE("failed to check permission");
114 return false;
115 }
116 }
117
GetAccessTokenId(IPCObjectStub & stub)118 uint32_t IpcCommon::GetAccessTokenId(IPCObjectStub &stub)
119 {
120 uint32_t tokenId = stub.GetFirstTokenID();
121 IAM_LOGI("get first caller tokenId: %{public}u", tokenId);
122 if (tokenId == 0) {
123 IAM_LOGI("no first caller, get direct caller tokenId: %{public}u", tokenId);
124 tokenId = stub.GetCallingTokenID();
125 }
126 return tokenId;
127 }
128
GetTokenId(IPCObjectStub & stub)129 uint32_t IpcCommon::GetTokenId(IPCObjectStub &stub)
130 {
131 uint32_t tokenId = stub.GetCallingTokenID();
132 IAM_LOGI("get tokenId: %{public}u", tokenId);
133 return tokenId;
134 }
135
CheckNativeCallingProcessWhiteList(IPCObjectStub & stub)136 bool IpcCommon::CheckNativeCallingProcessWhiteList(IPCObjectStub &stub)
137 {
138 uint32_t tokenId = stub.GetCallingTokenID();
139 using namespace Security::AccessToken;
140 ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(tokenId);
141 if (callingType != TOKEN_NATIVE) {
142 IAM_LOGE("failed to get calling type");
143 return false;
144 }
145 NativeTokenInfo nativeTokenInfo;
146 int result = AccessTokenKit::GetNativeTokenInfo(tokenId, nativeTokenInfo);
147 if (result != SUCCESS) {
148 IAM_LOGE("failed to get native token info, result = %{public}d", result);
149 return false;
150 }
151
152 std::string processName = nativeTokenInfo.processName;
153 int32_t processUid = stub.GetCallingUid();
154 for (const auto &whiteList : whiteLists) {
155 if (whiteList.first == processUid && whiteList.second == processName) {
156 return true;
157 }
158 }
159 IAM_LOGE("failed to check process white list");
160 return false;
161 }
162
CheckDirectCallerAndFirstCallerIfSet(IPCObjectStub & stub,const std::string & permission)163 bool IpcCommon::CheckDirectCallerAndFirstCallerIfSet(IPCObjectStub &stub, const std::string &permission)
164 {
165 uint32_t firstTokenId = stub.GetFirstTokenID();
166 uint32_t callingTokenId = stub.GetCallingTokenID();
167 using namespace Security::AccessToken;
168 if ((firstTokenId != 0 && AccessTokenKit::VerifyAccessToken(firstTokenId, permission) != RET_SUCCESS) ||
169 AccessTokenKit::VerifyAccessToken(callingTokenId, permission) != RET_SUCCESS) {
170 IAM_LOGE("failed to check permission");
171 return false;
172 }
173 return true;
174 }
175
CheckDirectCaller(IPCObjectStub & stub,const std::string & permission)176 bool IpcCommon::CheckDirectCaller(IPCObjectStub &stub, const std::string &permission)
177 {
178 uint32_t callingTokenId = stub.GetCallingTokenID();
179 using namespace Security::AccessToken;
180 if (AccessTokenKit::VerifyAccessToken(callingTokenId, permission) != RET_SUCCESS) {
181 IAM_LOGE("failed to check permission");
182 return false;
183 }
184 return true;
185 }
186
CheckCallerIsSystemApp(IPCObjectStub & stub)187 bool IpcCommon::CheckCallerIsSystemApp(IPCObjectStub &stub)
188 {
189 uint32_t callingTokenId = stub.GetCallingTokenID();
190 using namespace Security::AccessToken;
191 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
192 bool checkRet = TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
193 ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(callingTokenId);
194 if (checkRet && callingType == TOKEN_HAP) {
195 IAM_LOGI("the caller is system application");
196 return true;
197 }
198 return false;
199 }
200 } // namespace UserAuth
201 } // namespace UserIam
202 } // namespace OHOS