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 "app_mgr_interface.h"
20 #include "iam_common_defines.h"
21 #include "iam_logger.h"
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24 #include "tokenid_kit.h"
25 #ifdef HAS_OS_ACCOUNT_PART
26 #include "os_account_manager.h"
27 #endif // HAS_OS_ACCOUNT_PART
28 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
29
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
33 namespace PermissionString {
34 const std::string MANAGE_USER_IDM_PERMISSION = "ohos.permission.MANAGE_USER_IDM";
35 const std::string USE_USER_IDM_PERMISSION = "ohos.permission.USE_USER_IDM";
36 const std::string ACCESS_USER_AUTH_INTERNAL_PERMISSION = "ohos.permission.ACCESS_USER_AUTH_INTERNAL";
37 const std::string ACCESS_BIOMETRIC_PERMISSION = "ohos.permission.ACCESS_BIOMETRIC";
38 const std::string ACCESS_AUTH_RESPOOL = "ohos.permission.ACCESS_AUTH_RESPOOL";
39 const std::string ENFORCE_USER_IDM = "ohos.permission.ENFORCE_USER_IDM";
40 const std::string SUPPORT_USER_AUTH = "ohos.permission.SUPPORT_USER_AUTH";
41 }
42
43 namespace {
44 // process white list of allowing to call, <processUid, processName>
45 const std::vector<std::pair<int32_t, std::string>> manageUserIdmWhiteLists = {
46 {3058, "accountmgr"},
47 };
48
49 const std::vector<std::pair<int32_t, std::string>> enforceUserIdmWhiteLists = {
50 {3058, "accountmgr"},
51 };
52 }
53
GetCallingUserId(IPCObjectStub & stub,int32_t & userId)54 int32_t IpcCommon::GetCallingUserId(IPCObjectStub &stub, int32_t &userId)
55 {
56 if (userId != 0) {
57 return SUCCESS;
58 }
59 uint32_t tokenId = GetAccessTokenId(stub);
60 using namespace Security::AccessToken;
61 ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(tokenId);
62 if (callingType != TOKEN_HAP) {
63 IAM_LOGE("failed to get calling type");
64 return TYPE_NOT_SUPPORT;
65 }
66 HapTokenInfo hapTokenInfo;
67 int result = AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
68 if (result != SUCCESS) {
69 IAM_LOGE("failed to get hap token info, result = %{public}d", result);
70 return TYPE_NOT_SUPPORT;
71 }
72 userId = static_cast<int32_t>(hapTokenInfo.userID);
73 IAM_LOGI("get callingUserId is %{public}d", userId);
74 return SUCCESS;
75 }
76
GetActiveUserId(std::optional<int32_t> & userId)77 int32_t IpcCommon::GetActiveUserId(std::optional<int32_t> &userId)
78 {
79 if (userId.has_value() && userId.value() != 0) {
80 return SUCCESS;
81 }
82 std::vector<int32_t> ids;
83 #ifdef HAS_OS_ACCOUNT_PART
84 ErrCode queryRet = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
85 if (queryRet != ERR_OK || ids.empty()) {
86 IAM_LOGE("failed to query active account id");
87 return GENERAL_ERROR;
88 }
89 #else // HAS_OS_ACCOUNT_PART
90 const int32_t DEFAULT_OS_ACCOUNT_ID = 0;
91 ids.push_back(DEFAULT_OS_ACCOUNT_ID);
92 IAM_LOGI("there is no os account part, use default id");
93 #endif // HAS_OS_ACCOUNT_PART
94 userId = ids.front();
95 return SUCCESS;
96 }
97
GetAllUserId(std::vector<int32_t> & userIds)98 int32_t IpcCommon::GetAllUserId(std::vector<int32_t> &userIds)
99 {
100 #ifdef HAS_OS_ACCOUNT_PART
101 std::vector<OHOS::AccountSA::OsAccountInfo> accountInfos = {};
102 ErrCode ret = AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(accountInfos);
103 if (ret != ERR_OK) {
104 IAM_LOGE("failed to query all account id ret %{public}d ", ret);
105 return GENERAL_ERROR;
106 }
107
108 if (accountInfos.empty()) {
109 IAM_LOGE("accountInfos count %{public}zu", accountInfos.size());
110 return SUCCESS;
111 }
112
113 std::transform(accountInfos.begin(), accountInfos.end(), std::back_inserter(userIds),
114 [](auto &iter) { return iter.GetLocalId(); });
115 #else
116 const int32_t DEFAULT_OS_ACCOUNT_ID = 0;
117 userIds.push_back(DEFAULT_OS_ACCOUNT_ID);
118 #endif
119
120 return SUCCESS;
121 }
122
CheckForegroundApplication(const std::string & bundleName)123 bool IpcCommon::CheckForegroundApplication(const std::string &bundleName)
124 {
125 sptr<ISystemAbilityManager> samgrClient = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
126 if (samgrClient == nullptr) {
127 IAM_LOGI("Get system ability manager failed");
128 return false;
129 }
130 sptr<AppExecFwk::IAppMgr> iAppManager =
131 iface_cast<AppExecFwk::IAppMgr>(samgrClient->GetSystemAbility(APP_MGR_SERVICE_ID));
132 if (iAppManager == nullptr) {
133 IAM_LOGI("Failed to get ability manager service");
134 return false;
135 }
136 std::vector<AppExecFwk::AppStateData> foregroundAppList;
137 iAppManager->GetForegroundApplications(foregroundAppList);
138 auto it = std::find_if(foregroundAppList.begin(), foregroundAppList.end(), [bundleName] (auto foregroundApp) {
139 return bundleName.compare(foregroundApp.bundleName) == 0;
140 });
141 if (it == foregroundAppList.end()) {
142 IAM_LOGI("app : %{public}s is not foreground", bundleName.c_str());
143 return false;
144 }
145 return true;
146 }
147
CheckPermission(IPCObjectStub & stub,Permission permission)148 bool IpcCommon::CheckPermission(IPCObjectStub &stub, Permission permission)
149 {
150 switch (permission) {
151 case MANAGE_USER_IDM_PERMISSION:
152 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::MANAGE_USER_IDM_PERMISSION) &&
153 CheckNativeCallingProcessWhiteList(stub, permission);
154 case USE_USER_IDM_PERMISSION:
155 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::USE_USER_IDM_PERMISSION);
156 case ACCESS_USER_AUTH_INTERNAL_PERMISSION:
157 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::ACCESS_USER_AUTH_INTERNAL_PERMISSION);
158 case ACCESS_BIOMETRIC_PERMISSION:
159 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::ACCESS_BIOMETRIC_PERMISSION);
160 case ACCESS_AUTH_RESPOOL:
161 return CheckDirectCaller(stub, PermissionString::ACCESS_AUTH_RESPOOL);
162 case ENFORCE_USER_IDM:
163 return CheckDirectCaller(stub, PermissionString::ENFORCE_USER_IDM) &&
164 CheckNativeCallingProcessWhiteList(stub, permission);
165 case SUPPORT_USER_AUTH:
166 return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::SUPPORT_USER_AUTH);
167 case IS_SYSTEM_APP:
168 return CheckCallerIsSystemApp(stub);
169 case CLEAR_REDUNDANCY_PERMISSION:
170 return CheckDirectCaller(stub, PermissionString::ENFORCE_USER_IDM);
171 default:
172 IAM_LOGE("failed to check permission");
173 return false;
174 }
175 }
176
GetAccessTokenId(IPCObjectStub & stub)177 uint32_t IpcCommon::GetAccessTokenId(IPCObjectStub &stub)
178 {
179 uint32_t tokenId = stub.GetFirstTokenID();
180 IAM_LOGI("get first caller tokenId: %{public}u", tokenId);
181 if (tokenId == 0) {
182 IAM_LOGI("no first caller, get direct caller tokenId: %{public}u", tokenId);
183 tokenId = stub.GetCallingTokenID();
184 }
185 return tokenId;
186 }
187
GetTokenId(IPCObjectStub & stub)188 uint32_t IpcCommon::GetTokenId(IPCObjectStub &stub)
189 {
190 uint32_t tokenId = stub.GetCallingTokenID();
191 IAM_LOGI("get tokenId: %{public}u", tokenId);
192 return tokenId;
193 }
194
GetWhiteLists(Permission permission)195 std::vector<std::pair<int32_t, std::string>> IpcCommon::GetWhiteLists(Permission permission)
196 {
197 switch (permission) {
198 case MANAGE_USER_IDM_PERMISSION:
199 return manageUserIdmWhiteLists;
200 case ENFORCE_USER_IDM:
201 return enforceUserIdmWhiteLists;
202 case CLEAR_REDUNDANCY_PERMISSION:
203 case USE_USER_IDM_PERMISSION:
204 case ACCESS_USER_AUTH_INTERNAL_PERMISSION:
205 case ACCESS_BIOMETRIC_PERMISSION:
206 case ACCESS_AUTH_RESPOOL:
207 case SUPPORT_USER_AUTH:
208 case IS_SYSTEM_APP:
209 default:
210 IAM_LOGE("the permission has no white lists");
211 return {};
212 }
213 }
214
CheckNativeCallingProcessWhiteList(IPCObjectStub & stub,Permission permission)215 bool IpcCommon::CheckNativeCallingProcessWhiteList(IPCObjectStub &stub, Permission permission)
216 {
217 uint32_t tokenId = stub.GetCallingTokenID();
218 using namespace Security::AccessToken;
219 ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(tokenId);
220 if (callingType != TOKEN_NATIVE) {
221 IAM_LOGE("failed to get calling type");
222 return false;
223 }
224 NativeTokenInfo nativeTokenInfo;
225 int result = AccessTokenKit::GetNativeTokenInfo(tokenId, nativeTokenInfo);
226 if (result != SUCCESS) {
227 IAM_LOGE("failed to get native token info, result = %{public}d", result);
228 return false;
229 }
230
231 std::vector<std::pair<int32_t, std::string>> whiteLists = IpcCommon::GetWhiteLists(permission);
232 std::string processName = nativeTokenInfo.processName;
233 int32_t processUid = stub.GetCallingUid();
234 for (const auto &whiteList : whiteLists) {
235 if (whiteList.first == processUid && whiteList.second == processName) {
236 return true;
237 }
238 }
239 IAM_LOGE("failed to check process white list");
240 return false;
241 }
242
CheckDirectCallerAndFirstCallerIfSet(IPCObjectStub & stub,const std::string & permission)243 bool IpcCommon::CheckDirectCallerAndFirstCallerIfSet(IPCObjectStub &stub, const std::string &permission)
244 {
245 uint32_t firstTokenId = stub.GetFirstTokenID();
246 uint32_t callingTokenId = stub.GetCallingTokenID();
247 using namespace Security::AccessToken;
248 if ((firstTokenId != 0 && AccessTokenKit::VerifyAccessToken(firstTokenId, permission) != RET_SUCCESS) ||
249 AccessTokenKit::VerifyAccessToken(callingTokenId, permission) != RET_SUCCESS) {
250 IAM_LOGE("failed to check permission");
251 return false;
252 }
253 return true;
254 }
255
CheckDirectCaller(IPCObjectStub & stub,const std::string & permission)256 bool IpcCommon::CheckDirectCaller(IPCObjectStub &stub, const std::string &permission)
257 {
258 uint32_t callingTokenId = stub.GetCallingTokenID();
259 using namespace Security::AccessToken;
260 if (AccessTokenKit::VerifyAccessToken(callingTokenId, permission) != RET_SUCCESS) {
261 IAM_LOGE("failed to check permission");
262 return false;
263 }
264 return true;
265 }
266
CheckCallerIsSystemApp(IPCObjectStub & stub)267 bool IpcCommon::CheckCallerIsSystemApp(IPCObjectStub &stub)
268 {
269 uint32_t callingTokenId = stub.GetCallingTokenID();
270 using namespace Security::AccessToken;
271 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
272 bool checkRet = TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
273 ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(callingTokenId);
274 if (checkRet && callingType == TOKEN_HAP) {
275 IAM_LOGI("the caller is system application");
276 return true;
277 }
278 return false;
279 }
280
GetCallerName(IPCObjectStub & stub,bool & isBundleName,std::string & callerName)281 bool IpcCommon::GetCallerName(IPCObjectStub &stub, bool &isBundleName, std::string &callerName)
282 {
283 uint32_t tokenId = GetAccessTokenId(stub);
284 using namespace Security::AccessToken;
285 ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(tokenId);
286 if (callingType == TOKEN_HAP) {
287 isBundleName = true;
288 HapTokenInfo hapTokenInfo;
289 int result = AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
290 if (result != SUCCESS) {
291 IAM_LOGE("failed to get hap token info, result = %{public}d", result);
292 return false;
293 }
294 callerName = hapTokenInfo.bundleName;
295 IAM_LOGI("caller bundleName is %{public}s", callerName.c_str());
296 return true;
297 } else if (callingType == TOKEN_NATIVE) {
298 isBundleName = false;
299 NativeTokenInfo nativeTokenInfo;
300 int res = AccessTokenKit::GetNativeTokenInfo(tokenId, nativeTokenInfo);
301 if (res != SUCCESS) {
302 IAM_LOGE("failed to get native token info, res = %{public}d", res);
303 return false;
304 }
305 callerName = nativeTokenInfo.processName;
306 IAM_LOGI("caller processName is %{public}s", callerName.c_str());
307 return true;
308 }
309 isBundleName = false;
310 IAM_LOGI("caller is not a hap or a native");
311 return false;
312 }
313 } // namespace UserAuth
314 } // namespace UserIam
315 } // namespace OHOS