• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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